KDChartPercentLyingBarDiagram_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 "KDChartPercentLyingBarDiagram_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 PercentLyingBarDiagram::PercentLyingBarDiagram( BarDiagram* d )
00035 : BarDiagramType( d )
00036 {
00037 }
00038
00039 BarDiagram::BarType PercentLyingBarDiagram::type() const
00040 {
00041 return BarDiagram::Percent;
00042 }
00043
00044 const QPair<QPointF, QPointF> PercentLyingBarDiagram::calculateDataBoundaries() const
00045 {
00046
00047
00048
00049 const double xMin = 0;
00050 const double xMax = diagram()->model() ? diagram()->model()->rowCount( diagram()->rootIndex() ) : 0;
00051 double yMin = 0.0, yMax = 100.0;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 if ( yMax == yMin ) {
00066 if ( yMin == 0.0 )
00067 yMax = 0.1;
00068 else
00069 yMax = 0.0;
00070 }
00071 const QPointF bottomLeft( QPointF( yMin, xMin ) );
00072 const QPointF topRight( QPointF( yMax, xMax ) );
00073
00074
00075 return QPair< QPointF, QPointF >( bottomLeft, topRight );
00076 }
00077
00078 void PercentLyingBarDiagram::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 = boundLeft.y() - boundRight.y();
00094 QPointF testVector = boundRight - boundLeft;
00095 double groupWidth = width/ (rowCount + 2);
00096 double spaceBetweenBars = 0;
00097 double spaceBetweenGroups = 0;
00098
00099 if ( ba.useFixedBarWidth() ) {
00100 barWidth = ba.fixedBarWidth();
00101 groupWidth += barWidth;
00102
00103
00104
00105 if ( groupWidth < 0 )
00106 groupWidth = 0;
00107
00108 if ( groupWidth * rowCount > width )
00109 groupWidth = width / rowCount;
00110 }
00111
00112
00113
00114 double maxLimit = rowCount * (groupWidth + ((colCount-1) * ba.fixedDataValueGap()) );
00115
00116
00117
00118 if ( ba.useFixedDataValueGap() ) {
00119 if ( width > maxLimit )
00120 spaceBetweenBars += ba.fixedDataValueGap();
00121 else
00122 spaceBetweenBars = ((ctx->rectangle().width()/rowCount) - groupWidth)/(colCount-1);
00123 }
00124
00125 if ( ba.useFixedValueBlockGap() )
00126 spaceBetweenGroups += ba.fixedValueBlockGap();
00127
00128 calculateValueAndGapWidths( rowCount, colCount,groupWidth,
00129 barWidth, spaceBetweenBars, spaceBetweenGroups );
00130
00131 DataValueTextInfoList list;
00132 const double maxValue = 100.0;
00133 double sumValues = 0;
00134 QVector <double > sumValuesVector;
00135
00136
00137 for( int row = 0; row < rowCount; ++row )
00138 {
00139 for( int col = 0; col < colCount; ++col )
00140 {
00141 const CartesianDiagramDataCompressor::CachePosition position( row, col );
00142 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position );
00143
00144 sumValues += qMax( point.value, -point.value );
00145 if ( col == colCount - 1 ) {
00146 sumValuesVector << sumValues ;
00147 sumValues = 0;
00148 }
00149 }
00150 }
00151
00152
00153 for( int curRow = rowCount - 1; curRow >= 0; --curRow )
00154 {
00155 double offset = spaceBetweenGroups;
00156 if( ba.useFixedBarWidth() )
00157 offset -= ba.fixedBarWidth();
00158
00159 if( offset < 0 )
00160 offset = 0;
00161
00162 for( int col = 0; col < colCount ; ++col )
00163 {
00164 double threeDOffset = 0.0;
00165 const CartesianDiagramDataCompressor::CachePosition position( curRow, col );
00166 const CartesianDiagramDataCompressor::DataPoint p = compressor().data( position );
00167 QModelIndex sourceIndex = attributesModel()->mapToSource( p.index );
00168 ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( sourceIndex );
00169
00170 if ( threeDAttrs.isEnabled() ){
00171 if ( barWidth > 0 ) {
00172 barWidth = (width - ((offset+(threeDAttrs.depth()))*rowCount))/ rowCount;
00173 threeDOffset = threeDAttrs.depth();
00174 }
00175 if ( barWidth <= 0 ) {
00176 barWidth = 0.1;
00177 threeDOffset = (width - (offset*rowCount))/ rowCount;
00178 }
00179 }else{
00180 barWidth = (width - (offset*rowCount))/ rowCount;
00181 }
00182
00183 const double value = qMax( p.value, -p.value );
00184 double stackedValues = 0.0;
00185 double key = 0.0;
00186
00187
00188
00189 for( int k = col; k >= 0 ; --k )
00190 {
00191 const CartesianDiagramDataCompressor::CachePosition position( curRow, k );
00192 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position );
00193 stackedValues += qMax( point.value, -point.value );
00194 key = point.key;
00195 }
00196
00197 QPointF point, previousPoint;
00198 if( sumValuesVector.at( curRow ) != 0 && value > 0 ) {
00199 QPointF dataPoint( ( stackedValues / sumValuesVector.at( curRow ) * maxValue ), rowCount - key );
00200 point = ctx->coordinatePlane()->translate( dataPoint );
00201 point.ry() += offset / 2 + threeDOffset;
00202
00203 previousPoint = ctx->coordinatePlane()->translate( QPointF( ( ( stackedValues - value) / sumValuesVector.at( curRow ) * maxValue ), rowCount - key ) );
00204 }
00205
00206 const double barHeight = point.x() - previousPoint.x();
00207
00208 point.setX ( point.x() - barHeight );
00209
00210 const QRectF rect( point, QSizeF( barHeight, barWidth ) );
00211 appendDataValueTextInfoToList( diagram(), list, sourceIndex, PositionPoints( rect ),
00212 Position::NorthEast, Position::SouthWest,
00213 value );
00214 paintBars( ctx, sourceIndex, rect, maxDepth );
00215 }
00216 }
00217 paintDataValueTextsAndMarkers( diagram(), ctx, list, false );
00218 }