KD Chart 2  [rev.2.5.1]
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
KDChartBarDiagram_p.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2013 Klaralvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Chart library.
5 **
6 ** Licensees holding valid commercial KD Chart licenses may use this file in
7 ** accordance with the KD Chart Commercial License Agreement provided with
8 ** the Software.
9 **
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 and version 3 as published by the
13 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
14 **
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 **
18 ** Contact info@kdab.com if any conditions of this licensing are not
19 ** clear to you.
20 **
21 **********************************************************************/
22 
23 #include "KDChartBarDiagram.h"
24 #include "KDChartBarDiagram_p.h"
25 
27 #include "KDChartPainterSaver_p.h"
28 
29 using namespace KDChart;
30 
31 BarDiagram::Private::Private( const Private& rhs )
32  : AbstractCartesianDiagram::Private( rhs )
33 {
34 }
35 
36 void BarDiagram::BarDiagramType::paintBars( PaintContext* ctx, const QModelIndex& index, const QRectF& bar, qreal& maxDepth )
37 {
38  QRectF isoRect;
39  QPolygonF topPoints, sidePoints;
40  ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( index );
41  qreal usedDepth = 0;
42 
43  //Pending Michel: configure threeDBrush settings - shadowColor etc...
44  QBrush indexBrush( diagram()->brush( index ) );
45  QPen indexPen( diagram()->pen( index ) );
46  PainterSaver painterSaver( ctx->painter() );
47 
48  ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram()->antiAliasing() );
49  if ( threeDAttrs.isEnabled() )
50  indexBrush = threeDAttrs.threeDBrush( indexBrush, bar );
51  ctx->painter()->setBrush( indexBrush );
52  ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
53 
54  if ( threeDAttrs.isEnabled() ) {
55  bool stackedMode = false;
56  bool percentMode = false;
57  bool paintTop = true;
58  if ( maxDepth )
59  threeDAttrs.setDepth( -maxDepth );
60  //fixme adjust the painting to reasonable depth value
61  switch ( type() )
62  {
63  case BarDiagram::Normal:
64  usedDepth = threeDAttrs.depth()/4;
65  stackedMode = false;
66  percentMode = false;
67  break;
69  usedDepth = threeDAttrs.depth();
70  stackedMode = true;
71  percentMode = false;
72  break;
74  usedDepth = threeDAttrs.depth();
75  stackedMode = false;
76  percentMode = true;
77  break;
78  default:
79  Q_ASSERT_X ( false, "dataBoundaries()",
80  "Type item does not match a defined bar chart Type." );
81  }
82  isoRect = bar.translated( usedDepth, -usedDepth );
83  // we need to find out if the height is negative
84  // and in this case paint it up and down
85  //qDebug() << isoRect.height();
86  if ( isoRect.height() < 0 ) {
87  topPoints << isoRect.bottomLeft() << isoRect.bottomRight()
88  << bar.bottomRight() << bar.bottomLeft();
89  if ( stackedMode ) {
90  // fix it when several negative stacked values
91  if ( index.column() == 0 ) {
92  paintTop = true;
93  }
94  else
95  paintTop = false;
96  }
97 
98  } else {
99  reverseMapper().addRect( index.row(), index.column(), isoRect );
100  ctx->painter()->drawRect( isoRect );
101  topPoints << bar.topLeft() << bar.topRight() << isoRect.topRight() << isoRect.topLeft();
102  }
103 
104  if ( percentMode && isoRect.height() == 0 )
105  paintTop = false;
106 
107  bool needToSetClippingOffForTop = false;
108  if ( paintTop ) {
109  // Draw the top, if at least one of the top's points is
110  // either inside or near at the edge of the coordinate plane:
111  bool drawIt = false;
112  bool hasPointOutside = false;
113  const QRectF r( ctx->rectangle().adjusted(0,-1,1,0) );
114  KDAB_FOREACH( QPointF pt, topPoints ) {
115  if ( r.contains( pt ) )
116  drawIt = true;
117  else
118  hasPointOutside = true;
119  }
120  if ( drawIt ) {
121  const PainterSaver p( ctx->painter() );
122  needToSetClippingOffForTop = hasPointOutside && ctx->painter()->hasClipping();
123  if ( needToSetClippingOffForTop )
124  ctx->painter()->setClipping( false );
125  reverseMapper().addPolygon( index.row(), index.column(), topPoints );
126  ctx->painter()->drawPolygon( topPoints );
127  }
128  }
129 
130 
131 
132  sidePoints << bar.topRight() << isoRect.topRight() << isoRect.bottomRight() << bar.bottomRight();
133  if ( bar.height() != 0 ) {
134  const PainterSaver p( ctx->painter() );
135  if ( needToSetClippingOffForTop )
136  ctx->painter()->setClipping( false );
137  reverseMapper().addPolygon( index.row(), index.column(), sidePoints );
138  ctx->painter()->drawPolygon( sidePoints );
139  }
140  }
141 
142  if ( bar.height() != 0 )
143  {
144  reverseMapper().addRect( index.row(), index.column(), bar );
145  ctx->painter()->drawRect( bar );
146  }
147  // reset
148  //diagram()->maxDepth = threeDAttrs.depth();
149 }
150 
151 AttributesModel* BarDiagram::BarDiagramType::attributesModel() const
152 {
153  return m_private->attributesModel;
154 }
155 
156 QModelIndex BarDiagram::BarDiagramType::attributesModelRootIndex() const
157 {
158  return diagram()->attributesModelRootIndex();
159 }
160 
161 BarDiagram* BarDiagram::BarDiagramType::diagram() const
162 {
163  return static_cast< BarDiagram* >( m_private->diagram );
164 }
165 
166 void BarDiagram::BarDiagramType::calculateValueAndGapWidths( int rowCount,int colCount,
167  qreal groupWidth,
168  qreal& outBarWidth,
169  qreal& outSpaceBetweenBars,
170  qreal& outSpaceBetweenGroups )
171 {
172 
173  Q_UNUSED( rowCount );
174 
175  BarAttributes ba = diagram()->barAttributes();
176 
177  // Pending Michel Fixme
178  /* We are colCount groups to paint. Each group is centered around the
179  * horizontal point position on the grid. The full area covers the
180  * values -1 to colCount + 1. A bar has a relative width of one unit,
181  * the gaps between bars are 0.5 wide, and the gap between groups is
182  * also one unit, by default. */
183 
184  qreal units;
185  if ( type() == Normal )
186  units = colCount // number of bars in group * 1.0
187  + (colCount-1) * ba.barGapFactor() // number of bar gaps
188  + 1 * ba.groupGapFactor(); // number of group gaps
189  else
190  units = 1 + 1 * ba.groupGapFactor();
191 
192  qreal unitWidth = groupWidth / units;
193  outBarWidth = unitWidth;
194  outSpaceBetweenBars += unitWidth * ba.barGapFactor();
195 
196  // Pending Michel - minLimit: allow space between bars to be reduced until the bars are displayed next to each other.
197  // is that what we want?
198  // sebsauer; in the case e.g. CartesianCoordinatePlane::setHorizontalRangeReversed(true) was
199  // used to reverse the values, we deal with negative outSpaceBetweenBars and unitWidth here
200  // and since that's correct we don't like to lose e.g. the spacing here.
201  //if ( outSpaceBetweenBars < 0 )
202  // outSpaceBetweenBars = 0;
203 
204  outSpaceBetweenGroups += unitWidth * ba.groupGapFactor();
205 }
206 
207 ReverseMapper& BarDiagram::BarDiagramType::reverseMapper()
208 {
209  return m_private->reverseMapper;
210 }
211 
212 CartesianDiagramDataCompressor& BarDiagram::BarDiagramType::compressor() const
213 {
214  return m_private->compressor;
215 }

Klarälvdalens Datakonsult AB (KDAB)
Qt-related services and products
http://www.kdab.com/
http://www.kdab.com/products/kd-chart/