KDChartPercentBarDiagram_p.cpp
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 "KDChartPercentBarDiagram_p.h"
00024
00025 #include <QModelIndex>
00026
00027 #include "KDChartBarDiagram.h"
00028 #include "KDChartTextAttributes.h"
00029 #include "KDChartAttributesModel.h"
00030 #include "KDChartAbstractCartesianDiagram.h"
00031
00032 using namespace KDChart;
00033
00034 PercentBarDiagram::PercentBarDiagram( BarDiagram* d )
00035 : BarDiagramType( d )
00036 {
00037 }
00038
00039 BarDiagram::BarType PercentBarDiagram::type() const
00040 {
00041 return BarDiagram::Percent;
00042 }
00043
00044 const QPair<QPointF, QPointF> PercentBarDiagram::calculateDataBoundaries() const
00045 {
00046 const double xMin = 0.0;
00047 const double xMax = diagram()->model() ? diagram()->model()->rowCount( diagram()->rootIndex() ) : 0;
00048 const double yMin = 0.0;
00049 const double yMax = 100.0;
00050
00051 const int rowCount = xMax;
00052 const int colCount = diagram()->model() ? diagram()->model()->columnCount( diagram()->rootIndex() ) : 0;
00053
00054 double usedDepth = 0;
00055
00056 for( int row = 0; row < rowCount ; ++row )
00057 {
00058 for( int col = 0; col < colCount; ++col ) {
00059 const CartesianDiagramDataCompressor::CachePosition position( row, col );
00060 const CartesianDiagramDataCompressor::DataPoint p = compressor().data( position );
00061 QModelIndex sourceIndex = attributesModel()->mapToSource( p.index );
00062 ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( sourceIndex );
00063
00064 if( threeDAttrs.isEnabled() )
00065 if( threeDAttrs.depth() > usedDepth )
00066 usedDepth = threeDAttrs.depth();
00067 }
00068
00069 }
00070
00071 const QPointF bottomLeft( QPointF( xMin, yMin ) );
00072 const QPointF topRight( QPointF( xMax, yMax + usedDepth * 0.3 ) );
00073
00074
00075 return QPair< QPointF, QPointF >( bottomLeft, topRight );
00076 }
00077
00078 void PercentBarDiagram::paint( PaintContext* ctx )
00079 {
00080 reverseMapper().clear();
00081
00082 const QPair<QPointF,QPointF> boundaries = diagram()->dataBoundaries();
00083
00084 const QPointF boundLeft = ctx->coordinatePlane()->translate( boundaries.first ) ;
00085 const QPointF boundRight = ctx->coordinatePlane()->translate( boundaries.second );
00086
00087 const int rowCount = compressor().modelDataRows();
00088 const int colCount = compressor().modelDataColumns();
00089
00090 BarAttributes ba = diagram()->barAttributes( diagram()->model()->index( 0, 0, diagram()->rootIndex() ) );
00091 double barWidth = 0;
00092 double maxDepth = 0;
00093 double width = boundRight.x() - boundLeft.x();
00094 double groupWidth = width/ (rowCount + 2);
00095 double spaceBetweenBars = 0;
00096 double spaceBetweenGroups = 0;
00097
00098 if ( ba.useFixedBarWidth() ) {
00099 barWidth = ba.fixedBarWidth();
00100 groupWidth += barWidth;
00101
00102
00103
00104 if ( groupWidth < 0 )
00105 groupWidth = 0;
00106
00107 if ( groupWidth * rowCount > width )
00108 groupWidth = width / rowCount;
00109 }
00110
00111
00112
00113 double maxLimit = rowCount * (groupWidth + ((colCount-1) * ba.fixedDataValueGap()) );
00114
00115
00116
00117 if ( ba.useFixedDataValueGap() ) {
00118 if ( width > maxLimit )
00119 spaceBetweenBars += ba.fixedDataValueGap();
00120 else
00121 spaceBetweenBars = ((width/rowCount) - groupWidth)/(colCount-1);
00122 }
00123
00124 if ( ba.useFixedValueBlockGap() )
00125 spaceBetweenGroups += ba.fixedValueBlockGap();
00126
00127 calculateValueAndGapWidths( rowCount, colCount,groupWidth,
00128 barWidth, spaceBetweenBars, spaceBetweenGroups );
00129
00130 DataValueTextInfoList list;
00131 const double maxValue = 100;
00132 double sumValues = 0;
00133 QVector <double > sumValuesVector;
00134
00135
00136 for( int row = 0; row < rowCount; ++row )
00137 {
00138 for( int col = 0; col < colCount; ++col )
00139 {
00140 const CartesianDiagramDataCompressor::CachePosition position( row, col );
00141 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position );
00142
00143 sumValues += qMax( point.value, -point.value );
00144 if ( col == colCount - 1 ) {
00145 sumValuesVector << sumValues ;
00146 sumValues = 0;
00147 }
00148 }
00149 }
00150
00151
00152 for( int col = 0; col < colCount; ++col )
00153 {
00154 double offset = spaceBetweenGroups;
00155 if( ba.useFixedBarWidth() )
00156 offset -= ba.fixedBarWidth();
00157
00158 if( offset < 0 )
00159 offset = 0;
00160
00161 for( int row = 0; row < rowCount ; ++row )
00162 {
00163 const CartesianDiagramDataCompressor::CachePosition position( row, col );
00164 const CartesianDiagramDataCompressor::DataPoint p = compressor().data( position );
00165 QModelIndex sourceIndex = attributesModel()->mapToSource( p.index );
00166 ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( sourceIndex );
00167
00168 if ( threeDAttrs.isEnabled() ){
00169 if ( barWidth > 0 )
00170 barWidth = (width - ((offset+(threeDAttrs.depth()))*rowCount))/ rowCount;
00171 if ( barWidth <= 0 ) {
00172 barWidth = 0;
00173 maxDepth = offset - ( width/rowCount);
00174 }
00175 }else{
00176 barWidth = (width - (offset*rowCount))/ rowCount;
00177 }
00178
00179 const double value = qMax( p.value, -p.value );
00180 double stackedValues = 0.0;
00181 double key = 0.0;
00182
00183
00184
00185 for( int k = col; k >= 0 ; --k )
00186 {
00187 const CartesianDiagramDataCompressor::CachePosition position( row, k );
00188 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position );
00189 stackedValues += qMax( point.value, -point.value );
00190 key = point.key;
00191 }
00192
00193 QPointF point, previousPoint;
00194 if( sumValuesVector.at( row ) != 0 && value > 0 ) {
00195 point = ctx->coordinatePlane()->translate( QPointF( key, stackedValues / sumValuesVector.at( row ) * maxValue ) );
00196 point.rx() += offset / 2;
00197
00198 previousPoint = ctx->coordinatePlane()->translate( QPointF( key, ( stackedValues - value)/sumValuesVector.at(row)* maxValue ) );
00199 }
00200 const double barHeight = previousPoint.y() - point.y();
00201
00202 const QRectF rect( point, QSizeF( barWidth, barHeight ) );
00203 appendDataValueTextInfoToList( diagram(), list, sourceIndex, PositionPoints( rect ),
00204 Position::NorthWest, Position::SouthEast,
00205 value );
00206 paintBars( ctx, sourceIndex, rect, maxDepth );
00207 }
00208 }
00209 paintDataValueTextsAndMarkers( diagram(), ctx, list, false );
00210 }