Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <limits>
00024
00025 #include <QAbstractItemModel>
00026
00027 #include "KDChartBarDiagram.h"
00028 #include "KDChartLineDiagram.h"
00029 #include "KDChartTextAttributes.h"
00030 #include "KDChartAttributesModel.h"
00031 #include "KDChartAbstractCartesianDiagram.h"
00032 #include "KDChartNormalLineDiagram_p.h"
00033
00034 using namespace KDChart;
00035 using namespace std;
00036
00037 NormalLineDiagram::NormalLineDiagram( LineDiagram* d )
00038 : LineDiagramType( d )
00039 {
00040 }
00041
00042 LineDiagram::LineType NormalLineDiagram::type() const
00043 {
00044 return LineDiagram::Normal;
00045 }
00046
00047 const QPair< QPointF, QPointF > NormalLineDiagram::calculateDataBoundaries() const
00048 {
00049 const int rowCount = compressor().modelDataRows();
00050 const int colCount = compressor().modelDataColumns();
00051 const double xMin = 0.0;
00052 double xMax = diagram()->model() ? diagram()->model()->rowCount( diagram()->rootIndex() ) : 0;
00053 if ( !diagram()->centerDataPoints() && diagram()->model() )
00054 xMax -= 1;
00055 double yMin = std::numeric_limits< double >::quiet_NaN();
00056 double yMax = std::numeric_limits< double >::quiet_NaN();
00057
00058 for( int column = 0; column < colCount; ++column )
00059 {
00060 for ( int row = 0; row < rowCount; ++row )
00061 {
00062 const CartesianDiagramDataCompressor::CachePosition position( row, column );
00063 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position );
00064 const double value = ISNAN( point.value ) ? 0.0 : point.value;
00065
00066 if ( ISNAN( yMin ) ) {
00067 yMin = value;
00068 yMax = value;
00069 } else {
00070 yMin = qMin( yMin, value );
00071 yMax = qMax( yMax, value );
00072 }
00073 }
00074 }
00075
00076
00077
00078
00079 const QPointF bottomLeft( QPointF( xMin, yMin ) );
00080 const QPointF topRight( QPointF( xMax, yMax ) );
00081 return QPair< QPointF, QPointF >( bottomLeft, topRight );
00082 }
00083
00084 void NormalLineDiagram::paint( PaintContext* ctx )
00085 {
00086 reverseMapper().clear();
00087 Q_ASSERT( dynamic_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() ) );
00088 CartesianCoordinatePlane* plane = static_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() );
00089 const int columnCount = compressor().modelDataColumns();
00090 const int rowCount = compressor().modelDataRows();
00091 if ( columnCount == 0 || rowCount == 0 ) return;
00092
00093
00094
00095 int maxFound = 0;
00096
00097
00098
00099
00100
00101
00102
00103 maxFound = columnCount;
00104
00105
00106
00107 bool rev = diagram()->reverseDatasetOrder();
00108 for( int column = rev ? columnCount - 1 : 0;
00109 rev ? (column >= 0) : (column < columnCount);
00110 rev ? --column : ++column ) {
00111 DataValueTextInfoList textInfoList;
00112 LineAttributesInfoList lineList;
00113 LineAttributes laPreviousCell;
00114 CartesianDiagramDataCompressor::DataPoint lastPoint;
00115 qreal lastAreaBoundingValue = 0;
00116
00117
00118 const qreal minYValue = qMin(plane->visibleDataRange().bottom(), plane->visibleDataRange().top());
00119
00120 CartesianDiagramDataCompressor::CachePosition previousCellPosition;
00121 for ( int row = 0; row < rowCount; ++row ) {
00122 const CartesianDiagramDataCompressor::CachePosition position( row, column );
00123
00124 CartesianDiagramDataCompressor::DataPoint point = compressor().data( position );
00125
00126 const QModelIndex sourceIndex = attributesModel()->mapToSource( point.index );
00127
00128 const LineAttributes laCell = diagram()->lineAttributes( sourceIndex );
00129 const LineAttributes::MissingValuesPolicy policy = laCell.missingValuesPolicy();
00130
00131
00132 qreal areaBoundingValue;
00133 if ( laCell.areaBoundingDataset() != -1 ) {
00134 const CartesianDiagramDataCompressor::CachePosition areaBoundingCachePosition( row, laCell.areaBoundingDataset() );
00135 areaBoundingValue = compressor().data( areaBoundingCachePosition ).value;
00136 } else
00137
00138 areaBoundingValue = minYValue;
00139
00140 if( ISNAN( point.value ) )
00141 {
00142 switch( policy )
00143 {
00144 case LineAttributes::MissingValuesAreBridged:
00145
00146 continue;
00147 case LineAttributes::MissingValuesShownAsZero:
00148
00149 point.value = 0.0;
00150 break;
00151 case LineAttributes::MissingValuesHideSegments:
00152
00153 break;
00154 default:
00155 break;
00156
00157 }
00158 }
00159
00160
00161 const QPointF a( plane->translate( QPointF( diagram()->centerDataPoints() ? lastPoint.key + 0.5 : lastPoint.key, lastPoint.value ) ) );
00162 const QPointF b( plane->translate( QPointF( diagram()->centerDataPoints() ? point.key + 0.5 : point.key, point.value ) ) );
00163 const QPointF c( plane->translate( QPointF( diagram()->centerDataPoints() ? lastPoint.key + 0.5 : lastPoint.key, lastAreaBoundingValue ) ) );
00164 const QPointF d( plane->translate( QPointF( diagram()->centerDataPoints() ? point.key + 0.5 : point.key, areaBoundingValue ) ) );
00165
00166
00167 const PositionPoints pts = PositionPoints( b, a, d, c );
00168
00169 QList<QPolygonF> areas;
00170 if ( !ISNAN( point.value ) && !ISNAN( lastPoint.value ) && laCell.displayArea() ) {
00171 areas << ( QPolygonF() << a << b << d << c );
00172 }
00173
00174 if ( ! point.hidden && !ISNAN( point.value ) )
00175 {
00176 appendDataValueTextInfoToList( diagram(), textInfoList, sourceIndex, &position,
00177 pts, Position::NorthWest, Position::SouthWest,
00178 point.value );
00179 paintAreas( ctx, attributesModel()->mapToSource( lastPoint.index ), areas, laCell.transparency() );
00180
00181 if( row > 0 && !ISNAN( lastPoint.value ) )
00182 lineList.append( LineAttributesInfo( sourceIndex, a, b ) );
00183 }
00184
00185
00186 previousCellPosition = position;
00187 laPreviousCell = laCell;
00188 lastAreaBoundingValue = areaBoundingValue;
00189 lastPoint = point;
00190 }
00191
00192 LineAttributes::MissingValuesPolicy policy = LineAttributes::MissingValuesAreBridged;
00193 paintElements( ctx, textInfoList, lineList, policy );
00194 }
00195 }