KD Chart 2
[rev.2.5]
|
00001 /**************************************************************************** 00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB. All rights reserved. 00003 ** 00004 ** This file is part of the KD Chart library. 00005 ** 00006 ** Licensees holding valid commercial KD Chart licenses may use this file in 00007 ** accordance with the KD Chart Commercial License Agreement provided with 00008 ** the Software. 00009 ** 00010 ** 00011 ** This file may be distributed and/or modified under the terms of the 00012 ** GNU General Public License version 2 and version 3 as published by the 00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. 00014 ** 00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 ** 00018 ** Contact info@kdab.com if any conditions of this licensing are not 00019 ** clear to you. 00020 ** 00021 **********************************************************************/ 00022 00023 #include "KDChartNormalPlotter_p.h" 00024 #include "KDChartPlotter.h" 00025 #include "PaintingHelpers_p.h" 00026 00027 #include <limits> 00028 00029 using namespace KDChart; 00030 using namespace std; 00031 00032 NormalPlotter::NormalPlotter( Plotter* d ) 00033 : PlotterType( d ) 00034 { 00035 } 00036 00037 Plotter::PlotType NormalPlotter::type() const 00038 { 00039 return Plotter::Normal; 00040 } 00041 00042 const QPair< QPointF, QPointF > NormalPlotter::calculateDataBoundaries() const 00043 { 00044 if ( diagram()->useDataCompression() != Plotter::NONE ) 00045 return plotterCompressor().dataBoundaries(); 00046 else 00047 return compressor().dataBoundaries(); 00048 } 00049 00050 void NormalPlotter::paint( PaintContext* ctx ) 00051 { 00052 reverseMapper().clear(); 00053 00054 Q_ASSERT( dynamic_cast< CartesianCoordinatePlane* >( ctx->coordinatePlane() ) ); 00055 const CartesianCoordinatePlane* const plane = static_cast< CartesianCoordinatePlane* >( ctx->coordinatePlane() ); 00056 const int colCount = compressor().modelDataColumns(); 00057 const int rowCount = compressor().modelDataRows(); 00058 00059 LabelPaintCache lpc; 00060 00061 if ( diagram()->useDataCompression() != Plotter::NONE ) 00062 { 00063 for ( int dataset = 0; dataset < plotterCompressor().datasetCount(); ++dataset ) 00064 { 00065 LineAttributesInfoList lineList; 00066 LineAttributes laPreviousCell; 00067 PlotterDiagramCompressor::DataPoint lastPoint; 00068 for ( PlotterDiagramCompressor::Iterator it = plotterCompressor().begin( dataset ); it != plotterCompressor().end( dataset ); ++ it ) 00069 { 00070 const PlotterDiagramCompressor::DataPoint point = *it; 00071 00072 const QModelIndex sourceIndex = attributesModel()->mapToSource( point.index ); 00073 LineAttributes laCell = diagram()->lineAttributes( sourceIndex ); 00074 const LineAttributes::MissingValuesPolicy policy = laCell.missingValuesPolicy(); 00075 00076 if( ISNAN( point.key ) || ISNAN( point.value ) ) 00077 { 00078 switch( policy ) 00079 { 00080 case LineAttributes::MissingValuesAreBridged: // we just bridge both values 00081 continue; 00082 case LineAttributes::MissingValuesShownAsZero: // fall-through since that attribute makes no sense for the plotter 00083 case LineAttributes::MissingValuesHideSegments: // fall-through since they're just hidden 00084 default: 00085 lastPoint = PlotterDiagramCompressor::DataPoint(); 00086 continue; 00087 } 00088 } 00089 00090 // area corners, a + b are the line ends: 00091 const QPointF a( plane->translate( QPointF( lastPoint.key, lastPoint.value ) ) ); 00092 const QPointF b( plane->translate( QPointF( point.key, point.value ) ) ); 00093 if( a.toPoint() == b.toPoint() ) 00094 continue; 00095 00096 const QPointF c( plane->translate( QPointF( lastPoint.key, 0.0 ) ) ); 00097 const QPointF d( plane->translate( QPointF( point.key, 0.0 ) ) ); 00098 00099 // add the pieces to painting if this is not hidden: 00100 if ( !point.hidden /*&& !ISNAN( lastPoint.key ) && !ISNAN( lastPoint.value ) */) { 00101 // add data point labels: 00102 const PositionPoints pts = PositionPoints( b, a, d, c ); 00103 // if necessary, add the area to the area list: 00104 QList<QPolygonF> areas; 00105 if ( laCell.displayArea() ) { 00106 QPolygonF polygon; 00107 polygon << a << b << d << c; 00108 areas << polygon; 00109 } 00110 addLabel( &lpc, sourceIndex, pts, Position::NorthWest, 00111 Position::SouthWest, point.value ); 00112 if( !ISNAN( lastPoint.key ) && !ISNAN( lastPoint.value ) ) 00113 { 00114 PaintingHelpers::paintAreas( m_private, ctx, 00115 attributesModel()->mapToSource( lastPoint.index ), 00116 areas, laCell.transparency() ); 00117 lineList.append( LineAttributesInfo( sourceIndex, a, b ) ); 00118 } 00119 } 00120 00121 // wrap it up: 00122 laPreviousCell = laCell; 00123 lastPoint = point; 00124 } 00125 PaintingHelpers::paintElements( m_private, ctx, lpc, lineList ); 00126 } 00127 } 00128 else 00129 { 00130 if( colCount == 0 || rowCount == 0 ) 00131 return; 00132 for( int column = 0; column < colCount; ++column ) 00133 { 00134 LineAttributesInfoList lineList; 00135 LineAttributes laPreviousCell; 00136 CartesianDiagramDataCompressor::CachePosition previousCellPosition; 00137 CartesianDiagramDataCompressor::DataPoint lastPoint; 00138 00139 for( int row = 0; row < rowCount; ++row ) 00140 { 00141 const CartesianDiagramDataCompressor::CachePosition position( row, column ); 00142 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position ); 00143 00144 const QModelIndex sourceIndex = attributesModel()->mapToSource( point.index ); 00145 LineAttributes laCell = diagram()->lineAttributes( sourceIndex ); 00146 const LineAttributes::MissingValuesPolicy policy = laCell.missingValuesPolicy(); 00147 00148 if( ISNAN( point.key ) || ISNAN( point.value ) ) 00149 { 00150 switch( policy ) 00151 { 00152 case LineAttributes::MissingValuesAreBridged: // we just bridge both values 00153 continue; 00154 case LineAttributes::MissingValuesShownAsZero: // fall-through since that attribute makes no sense for the plotter 00155 case LineAttributes::MissingValuesHideSegments: // fall-through since they're just hidden 00156 default: 00157 previousCellPosition = CartesianDiagramDataCompressor::CachePosition(); 00158 lastPoint = CartesianDiagramDataCompressor::DataPoint(); 00159 continue; 00160 } 00161 } 00162 00163 // area corners, a + b are the line ends: 00164 const QPointF a( plane->translate( QPointF( lastPoint.key, lastPoint.value ) ) ); 00165 const QPointF b( plane->translate( QPointF( point.key, point.value ) ) ); 00166 if ( a.toPoint() == b.toPoint() || ISNAN( a.x() ) || ISNAN( a.y() ) 00167 || ISNAN( b.x() ) || ISNAN( b.y() ) ) { 00168 lastPoint = point; 00169 continue; 00170 } 00171 00172 const QPointF c( plane->translate( QPointF( lastPoint.key, 0.0 ) ) ); 00173 const QPointF d( plane->translate( QPointF( point.key, 0.0 ) ) ); 00174 00175 // add the pieces to painting if this is not hidden: 00176 if ( !point.hidden ) { 00177 // add data point labels: 00178 const PositionPoints pts = PositionPoints( b, a, d, c ); 00179 // if necessary, add the area to the area list: 00180 QList<QPolygonF> areas; 00181 if ( laCell.displayArea() ) { 00182 QPolygonF polygon; 00183 polygon << a << b << d << c; 00184 areas << polygon; 00185 } 00186 addLabel( &lpc, sourceIndex, pts, Position::NorthWest, 00187 Position::SouthWest, point.value ); 00188 PaintingHelpers::paintAreas( m_private, ctx, 00189 attributesModel()->mapToSource( lastPoint.index ), 00190 areas, laCell.transparency() ); 00191 lineList.append( LineAttributesInfo( sourceIndex, a, b ) ); 00192 } 00193 00194 // wrap it up: 00195 previousCellPosition = position; 00196 laPreviousCell = laCell; 00197 lastPoint = point; 00198 } 00199 PaintingHelpers::paintElements( m_private, ctx, lpc, lineList ); 00200 } 00201 } 00202 }