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