##// END OF EJS Templates
Better support for negative values in stacked barcharts. Negative values are stacked from zero to negative direction. Positive values are stacked from zero to positive direction.
sauimone -
r1897:c0fc53c8ab57
parent child
Show More
@@ -1,95 +1,103
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "horizontalstackedbarchartitem_p.h"
22 22 #include "qabstractbarseries_p.h"
23 23 #include "qbarset_p.h"
24 24 #include "bar_p.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 HorizontalStackedBarChartItem::HorizontalStackedBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter) :
29 29 AbstractBarChartItem(series, presenter)
30 30 {
31 31 }
32 32
33 33 QVector<QRectF> HorizontalStackedBarChartItem::calculateLayout()
34 34 {
35 35 QVector<QRectF> layout;
36 36
37 37 // Use temporary qreals for accuracy
38 38 qreal categoryCount = m_series->d_func()->categoryCount();
39 39 qreal setCount = m_series->count();
40 40 bool barsVisible = m_series->isVisible();
41 41
42 42 // Domain:
43 43 qreal width = geometry().width();
44 44 qreal height = geometry().height();
45 45 qreal rangeY = m_domainMaxY - m_domainMinY;
46 46 qreal rangeX = m_domainMaxX - m_domainMinX;
47 47 qreal scaleY = (height / rangeY);
48 48 qreal scaleX = (width / rangeX);
49 49 qreal barHeight = scaleY * m_series->d_func()->barWidth(); // On horizontal chart barWidth of the barseries means height of the rect.
50 50
51 51 int itemIndex(0);
52 52 for (int category = 0; category < categoryCount; category++) {
53 qreal xPos = -scaleX * m_domainMinX + geometry().left();
53 qreal xMax = -scaleX * m_domainMinX + geometry().left();
54 qreal xMin = -scaleX * m_domainMinX + geometry().left();
54 55 for (int set = 0; set < setCount; set++) {
55 56 QBarSetPrivate* barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
56 57
57 58 qreal yPos = (m_domainMinY +0.5 -barSet->pos(category)) * scaleY + m_rect.bottom() - barHeight/2;
58 59
59 60 qreal barWidth = barSet->value(category) * scaleX;
60 61 Bar* bar = m_bars.at(itemIndex);
61 62
62 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
63 layout.append(rect);
64 63 bar->setPen(barSet->m_pen);
65 64 bar->setBrush(barSet->m_brush);
66 65 if (qFuzzyIsNull(barHeight)) {
67 66 bar->setVisible(false);
68 67 } else {
69 68 bar->setVisible(barsVisible);
70 69 }
71 70
72 71 QGraphicsSimpleTextItem* label = m_labels.at(itemIndex);
73 72
74 73 if (!qFuzzyIsNull(barSet->value(category))) {
75 74 label->setText(QString::number(barSet->value(category)));
76 75 } else {
77 76 label->setText(QString(""));
78 77 }
79
80 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
81 ,yPos - barHeight/2 - label->boundingRect().height()/2);
82 78 label->setFont(barSet->m_labelFont);
83 79 label->setBrush(barSet->m_labelBrush);
84 80
81 if (barWidth > 0) {
82 QRectF rect(xMax, yPos - barHeight, barWidth, barHeight);
83 layout.append(rect);
84 label->setPos(xMax + (rect.width()/2 - label->boundingRect().width()/2)
85 ,yPos - barHeight/2 - label->boundingRect().height()/2);
86 xMax += barWidth;
87 } else {
88 QRectF rect(xMin, yPos - barHeight, barWidth, barHeight);
89 layout.append(rect);
90 label->setPos(xMin + (rect.width()/2 - label->boundingRect().width()/2)
91 ,yPos - barHeight/2 - label->boundingRect().height()/2);
92 xMin += barWidth;
93 }
85 94 itemIndex++;
86 xPos += barWidth;
87 95 }
88 96 }
89 97 return layout;
90 98 }
91 99
92 100 #include "moc_horizontalstackedbarchartitem_p.cpp"
93 101
94 102 QTCOMMERCIALCHART_END_NAMESPACE
95 103
@@ -1,92 +1,91
1 1 #include "qhorizontalstackedbarseries.h"
2 2 #include "qhorizontalstackedbarseries_p.h"
3 3 #include "horizontalstackedbarchartitem_p.h"
4 4 #include "horizontalstackedbaranimation_p.h"
5 5
6 6 #include "chartdataset_p.h"
7 7 #include "charttheme_p.h"
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10 /*!
11 11 \class QHorizontalStackedBarSeries
12 12 \brief Series for creating horizontal stacked bar chart
13 13 \mainclass
14 14
15 15 QHorizontalStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
16 16 as groups, where bars in same category are grouped next to each other. QHorizontalStackedBarSeries groups the data
17 17 from sets to categories, which are defined by a QStringList.
18 18
19 19 See the \l {HorizontalStackedBarChart Example} {horizontal stacked bar chart example} to learn how to create a horizontal stacked bar chart.
20 20 \image examples_horizontalstackedbarchart.png
21 21
22 22 \sa QBarSet, QBarSeries, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries, QHorizontalPercentBarSeries, QHorizontalBarSeries
23 23 */
24 24
25 25 /*!
26 26 Constructs empty QHorizontalStackedBarSeries.
27 27 QHorizontalStackedBarSeries is QObject which is a child of a \a parent.
28 28 */
29 29 QHorizontalStackedBarSeries::QHorizontalStackedBarSeries(QObject *parent) :
30 30 QAbstractBarSeries(*new QHorizontalStackedBarSeriesPrivate(this), parent)
31 31 {
32 32 }
33 33
34 34 /*!
35 35 Destructor
36 36 Removes series from chart.
37 37 */
38 38 QHorizontalStackedBarSeries::~QHorizontalStackedBarSeries()
39 39 {
40 40 Q_D(QHorizontalStackedBarSeries);
41 41 if(d->m_dataset) {
42 42 d->m_dataset->removeSeries(this);
43 43 }
44 44 }
45 45
46 46 /*!
47 47 Returns QChartSeries::SeriesTypeHorizontalStackedBar.
48 48 */
49 49 QAbstractSeries::SeriesType QHorizontalStackedBarSeries::type() const
50 50 {
51 51 return QAbstractSeries::SeriesTypeHorizontalStackedBar;
52 52 }
53 53
54 54 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
55 55
56 56 QHorizontalStackedBarSeriesPrivate::QHorizontalStackedBarSeriesPrivate(QHorizontalStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
57 57 {
58 58
59 59 }
60 60
61 61 void QHorizontalStackedBarSeriesPrivate::scaleDomain(Domain& domain)
62 62 {
63 63 qreal minX(domain.minX());
64 64 qreal minY(domain.minY());
65 65 qreal maxX(domain.maxX());
66 66 qreal maxY(domain.maxY());
67 67
68 68 qreal y = categoryCount();
69 qreal x = maxCategorySum();
70 minX = qMin(minX, x);
69 minX = qMin(minX, bottom());
71 70 minY = qMin(minY, - (qreal)0.5);
72 maxX = qMax(maxX, x);
71 maxX = qMax(maxX, top());
73 72 maxY = qMax(maxY, y - (qreal)0.5);
74 73
75 74 domain.setRange(minX,maxX,minY,maxY);
76 75 }
77 76
78 77 ChartElement* QHorizontalStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
79 78 {
80 79 Q_Q(QHorizontalStackedBarSeries);
81 80
82 81 HorizontalStackedBarChartItem* bar = new HorizontalStackedBarChartItem(q,presenter);
83 82 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
84 83 bar->setAnimation(new HorizontalStackedBarAnimation(bar));
85 84 }
86 85 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
87 86 return bar;
88 87 }
89 88
90 89 #include "moc_qhorizontalstackedbarseries.cpp"
91 90
92 91 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,835 +1,888
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qabstractbarseries.h"
22 22 #include "qabstractbarseries_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "domain_p.h"
26 26 #include "legendmarker_p.h"
27 27 #include "chartdataset_p.h"
28 28 #include "charttheme_p.h"
29 29 #include "qvalueaxis.h"
30 30 #include "qbarcategoryaxis.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QAbstractBarSeries
36 36 \brief Series for creating a bar chart
37 37 \mainclass
38 38
39 39 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
40 40 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
41 41 and y-value is the height of the bar. The category names are ignored with this series and x-axis
42 42 shows the x-values.
43 43
44 44 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
45 45 \image examples_barchart.png
46 46
47 47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
48 48 */
49 49 /*!
50 50 \qmlclass AbstractBarSeries QAbstractBarSeries
51 51 \inherits QAbstractSeries
52 52
53 53 The following QML shows how to create a simple bar chart:
54 54 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
55 55
56 56 \beginfloatleft
57 57 \image demos_qmlchart6.png
58 58 \endfloat
59 59 \clearfloat
60 60 */
61 61
62 62 /*!
63 63 \property QAbstractBarSeries::barWidth
64 64 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
65 65 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
66 66 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
67 67 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
68 68 \sa QBarSeries
69 69 */
70 70 /*!
71 71 \qmlproperty real AbstractBarSeries::barWidth
72 72 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
73 73 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
74 74 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
75 75 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
76 76 */
77 77
78 78 /*!
79 79 \property QAbstractBarSeries::count
80 80 Holds the number of sets in series.
81 81 */
82 82 /*!
83 83 \qmlproperty int AbstractBarSeries::count
84 84 Holds the number of sets in series.
85 85 */
86 86
87 87 /*!
88 88 \property QAbstractBarSeries::labelsVisible
89 89 Defines the visibility of the labels in series
90 90 */
91 91 /*!
92 92 \qmlproperty bool AbstractBarSeries::labelsVisible
93 93 Defines the visibility of the labels in series
94 94 */
95 95
96 96 /*!
97 97 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
98 98 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
99 99 Clicked bar inside set is indexed by \a index
100 100 */
101 101 /*!
102 102 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
103 103 The signal is emitted if the user clicks with a mouse on top of BarSet.
104 104 Clicked bar inside set is indexed by \a index
105 105 */
106 106
107 107 /*!
108 108 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
109 109
110 110 The signal is emitted if mouse is hovered on top of series.
111 111 Parameter \a barset is the pointer of barset, where hover happened.
112 112 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
113 113 */
114 114 /*!
115 115 \qmlsignal AbstractBarSeries::onHovered(bool status, BarSet barset)
116 116
117 117 The signal is emitted if mouse is hovered on top of series.
118 118 Parameter \a barset is the pointer of barset, where hover happened.
119 119 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
120 120 */
121 121
122 122 /*!
123 123 \fn void QAbstractBarSeries::countChanged()
124 124 This signal is emitted when barset count has been changed, for example by append or remove.
125 125 */
126 126 /*!
127 127 \qmlsignal AbstractBarSeries::onCountChanged()
128 128 This signal is emitted when barset count has been changed, for example by append or remove.
129 129 */
130 130
131 131 /*!
132 132 \fn void QAbstractBarSeries::labelsVisibleChanged()
133 133 This signal is emitted when labels visibility have changed.
134 134 \sa isLabelsVisible(), setLabelsVisible()
135 135 */
136 136
137 137 /*!
138 138 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
139 139 This signal is emitted when \a sets have been added to the series.
140 140 \sa append(), insert()
141 141 */
142 142 /*!
143 143 \qmlsignal AbstractBarSeries::onAdded(BarSet barset)
144 144 Emitted when \a barset has been added to the series.
145 145 */
146 146
147 147 /*!
148 148 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
149 149 This signal is emitted when \a sets have been removed from the series.
150 150 \sa remove()
151 151 */
152 152 /*!
153 153 \qmlsignal AbstractBarSeries::onRemoved(BarSet barset)
154 154 Emitted when \a barset has been removed from the series.
155 155 */
156 156
157 157 /*!
158 158 \qmlmethod BarSet AbstractBarSeries::at(int index)
159 159 Returns bar set at \a index. Returns null if the index is not valid.
160 160 */
161 161
162 162 /*!
163 163 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
164 164 Adds a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
165 165 For example:
166 166 \code
167 167 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
168 168 myBarSeries.append("set 2", [Qt.point(0, 1), Qt.point(2, 2.5), Qt.point(3.5, 2.2)]);
169 169 \endcode
170 170 */
171 171
172 172 /*!
173 173 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
174 174 Inserts a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
175 175 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
176 176 appended.
177 177 \sa AbstractBarSeries::append()
178 178 */
179 179
180 180 /*!
181 181 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
182 182 Removes the barset from the series. Returns true if successfull, false otherwise.
183 183 */
184 184
185 185 /*!
186 186 \qmlmethod AbstractBarSeries::clear()
187 187 Removes all barsets from the series.
188 188 */
189 189
190 190 /*!
191 This is depreciated constructor.
192 \a parent
193 */
194 QAbstractBarSeries::QAbstractBarSeries(QObject *parent) :
195 QAbstractSeries(*(QAbstractBarSeriesPrivate*)(0),parent)
196 {
197 }
198
199 /*!
200 191 Destructs abstractbarseries and owned barsets.
201 192 */
202 193 QAbstractBarSeries::~QAbstractBarSeries()
203 194 {
204 195
205 196 }
206 197
207 198 /*!
208 199 \internal
209 200 */
210 201 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &d, QObject *parent) :
211 202 QAbstractSeries(d,parent)
212 203 {
213 204 }
214 205
215 206 /*!
216 207 Sets the width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
217 208 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
218 209 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
219 210 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
220 211 */
221 212 void QAbstractBarSeries::setBarWidth(qreal width)
222 213 {
223 214 Q_D(QAbstractBarSeries);
224 215 d->setBarWidth(width);
225 216 }
226 217
227 218 /*!
228 219 Returns the width of the bars of the series.
229 220 \sa setBarWidth()
230 221 */
231 222 qreal QAbstractBarSeries::barWidth() const
232 223 {
233 224 Q_D(const QAbstractBarSeries);
234 225 return d->barWidth();
235 226 }
236 227
237 228 /*!
238 229 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
239 230 Returns true, if appending succeeded.
240 231 */
241 232 bool QAbstractBarSeries::append(QBarSet *set)
242 233 {
243 234 Q_D(QAbstractBarSeries);
244 235 bool success = d->append(set);
245 236 if (success) {
246 237 QList<QBarSet*> sets;
247 238 sets.append(set);
248 239 set->setParent(this);
249 240 emit barsetsAdded(sets);
250 241 emit countChanged();
251 242 }
252 243 return success;
253 244 }
254 245
255 246 /*!
256 247 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
257 248 was successful.
258 249 Returns true, if set was removed.
259 250 */
260 251 bool QAbstractBarSeries::remove(QBarSet *set)
261 252 {
262 253 Q_D(QAbstractBarSeries);
263 254 bool success = d->remove(set);
264 255 if (success) {
265 256 QList<QBarSet*> sets;
266 257 sets.append(set);
267 258 set->setParent(0);
268 259 emit barsetsRemoved(sets);
269 260 emit countChanged();
270 261 delete set;
271 262 set = 0;
272 263 }
273 264 return success;
274 265 }
275 266
276 267 /*!
277 268 Takes a single \a set from the series. Does not delete the barset object.
278 269
279 270 NOTE: The series remains as the barset's parent object. You must set the
280 271 parent object to take full ownership.
281 272
282 273 Returns true if take was successfull.
283 274 */
284 275 bool QAbstractBarSeries::take(QBarSet *set)
285 276 {
286 277 Q_D(QAbstractBarSeries);
287 278 bool success = d->remove(set);
288 279 if (success) {
289 280 QList<QBarSet*> sets;
290 281 sets.append(set);
291 282 emit barsetsRemoved(sets);
292 283 emit countChanged();
293 284 }
294 285 return success;
295 286 }
296 287
297 288 /*!
298 289 Adds a list of barsets to series. Takes ownership of \a sets.
299 290 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
300 291 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
301 292 and function returns false.
302 293 */
303 294 bool QAbstractBarSeries::append(QList<QBarSet* > sets)
304 295 {
305 296 Q_D(QAbstractBarSeries);
306 297 bool success = d->append(sets);
307 298 if (success) {
308 299 emit barsetsAdded(sets);
309 300 emit countChanged();
310 301 }
311 302 return success;
312 303 }
313 304
314 305 /*!
315 306 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
316 307 Returns true, if inserting succeeded.
317 308
318 309 */
319 310 bool QAbstractBarSeries::insert(int index, QBarSet *set)
320 311 {
321 312 Q_D(QAbstractBarSeries);
322 313 bool success = d->insert(index, set);
323 314 if (success) {
324 315 QList<QBarSet*> sets;
325 316 sets.append(set);
326 317 emit barsetsAdded(sets);
327 318 emit countChanged();
328 319 }
329 320 return success;
330 321 }
331 322
332 323 /*!
333 324 Removes all barsets from the series. Deletes removed sets.
334 325 */
335 326 void QAbstractBarSeries::clear()
336 327 {
337 328 Q_D(QAbstractBarSeries);
338 329 QList<QBarSet *> sets = barSets();
339 330 bool success = d->remove(sets);
340 331 if (success) {
341 332 emit barsetsRemoved(sets);
342 333 emit countChanged();
343 334 foreach (QBarSet* set, sets) {
344 335 delete set;
345 336 }
346 337 }
347 338 }
348 339
349 340 /*!
350 341 Returns number of sets in series.
351 342 */
352 343 int QAbstractBarSeries::count() const
353 344 {
354 345 Q_D(const QAbstractBarSeries);
355 346 return d->m_barSets.count();
356 347 }
357 348
358 349 /*!
359 350 Returns a list of sets in series. Keeps ownership of sets.
360 351 */
361 352 QList<QBarSet*> QAbstractBarSeries::barSets() const
362 353 {
363 354 Q_D(const QAbstractBarSeries);
364 355 return d->m_barSets;
365 356 }
366 357
367 358 /*!
368 359 Sets the visibility of labels in series to \a visible
369 360 */
370 361 void QAbstractBarSeries::setLabelsVisible(bool visible)
371 362 {
372 363 Q_D(QAbstractBarSeries);
373 364 if (d->m_labelsVisible != visible) {
374 365 d->setLabelsVisible(visible);
375 366 emit labelsVisibleChanged();
376 367 }
377 368 }
378 369
379 370 /*!
380 371 Returns the visibility of labels
381 372 */
382 373 bool QAbstractBarSeries::isLabelsVisible() const
383 374 {
384 375 Q_D(const QAbstractBarSeries);
385 376 return d->m_labelsVisible;
386 377 }
387 378
388 379 /*!
389 380 Sets the overlap drawing mode for bars. If \a overlap is true, then the bars
390 381 are drawn at same position inside group. Can be used for example to draw negative bars
391 382 at same position on axis than positive bars. By default overlap is false and bars are drawn
392 383 next to each other. Note that this setting doesn't affect stacked and percent bar series.
393 384 */
394 385 void QAbstractBarSeries::setOverlap(bool overlap)
395 386 {
396 387 Q_D(QAbstractBarSeries);
397 388 d->setOverlap(overlap);
398 389 }
399 390
400 391
401 392
402 393 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
403 394
404 395 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
405 396 QAbstractSeriesPrivate(q),
406 397 m_barWidth(0.5), // Default value is 50% of category width
407 398 m_labelsVisible(false),
408 399 m_visible(true),
409 400 m_overlap(false)
410 401 {
411 402 }
412 403
413 404 int QAbstractBarSeriesPrivate::categoryCount() const
414 405 {
415 406 // No categories defined. return count of longest set.
416 407 int count = 0;
417 408 for (int i=0; i<m_barSets.count(); i++) {
418 409 if (m_barSets.at(i)->count() > count) {
419 410 count = m_barSets.at(i)->count();
420 411 }
421 412 }
422 413
423 414 return count;
424 415 }
425 416
426 417 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
427 418 {
428 419 if (width < 0.0) {
429 420 width = 0.0;
430 421 }
431 422 m_barWidth = width;
432 423 emit updatedBars();
433 424 }
434 425
435 426 qreal QAbstractBarSeriesPrivate::barWidth() const
436 427 {
437 428 return m_barWidth;
438 429 }
439 430
440 431 QBarSet* QAbstractBarSeriesPrivate::barsetAt(int index)
441 432 {
442 433 return m_barSets.at(index);
443 434 }
444 435
445 436 void QAbstractBarSeriesPrivate::setVisible(bool visible)
446 437 {
447 438 m_visible = visible;
448 439 emit updatedBars();
449 440 }
450 441
451 442 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
452 443 {
453 444 m_labelsVisible = visible;
454 445 emit labelsVisibleChanged(visible);
455 446 }
456 447
457 448 void QAbstractBarSeriesPrivate::setOverlap(bool overlap)
458 449 {
459 450 if (m_overlap != overlap) {
460 451 m_overlap = overlap;
461 452 emit updatedBars();
462 453 }
463 454 }
464 455
465 456 qreal QAbstractBarSeriesPrivate::min()
466 457 {
467 458 if (m_barSets.count() <= 0) {
468 459 return 0;
469 460 }
470 461 qreal min = INT_MAX;
471 462
472 463 for (int i = 0; i < m_barSets.count(); i++) {
473 464 int categoryCount = m_barSets.at(i)->count();
474 465 for (int j = 0; j < categoryCount; j++) {
475 466 qreal temp = m_barSets.at(i)->at(j);
476 467 if (temp < min)
477 468 min = temp;
478 469 }
479 470 }
480 471 return min;
481 472 }
482 473
483 474 qreal QAbstractBarSeriesPrivate::max()
484 475 {
485 476 if (m_barSets.count() <= 0) {
486 477 return 0;
487 478 }
488 479 qreal max = INT_MIN;
489 480
490 481 for (int i = 0; i < m_barSets.count(); i++) {
491 482 int categoryCount = m_barSets.at(i)->count();
492 483 for (int j = 0; j < categoryCount; j++) {
493 484 qreal temp = m_barSets.at(i)->at(j);
494 485 if (temp > max)
495 486 max = temp;
496 487 }
497 488 }
498 489
499 490 return max;
500 491 }
501 492
502 493 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
503 494 {
504 495 if ((set < 0) || (set >= m_barSets.count())) {
505 496 // No set, no value.
506 497 return 0;
507 498 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
508 499 // No category, no value.
509 500 return 0;
510 501 }
511 502
512 503 return m_barSets.at(set)->at(category);
513 504 }
514 505
515 506 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
516 507 {
517 508 if ((set < 0) || (set >= m_barSets.count())) {
518 509 // No set, no value.
519 510 return 0;
520 511 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
521 512 // No category, no value.
522 513 return 0;
523 514 }
524 515
525 516 qreal value = m_barSets.at(set)->at(category);
526 517 qreal sum = categorySum(category);
527 518 if ( qFuzzyIsNull(sum) ) {
528 519 return 0;
529 520 }
530 521
531 522 return value / sum;
532 523 }
533 524
534 525 qreal QAbstractBarSeriesPrivate::categorySum(int category)
535 526 {
536 527 qreal sum(0);
537 528 int count = m_barSets.count(); // Count sets
538 529 for (int set = 0; set < count; set++) {
539 530 if (category < m_barSets.at(set)->count())
540 531 sum += m_barSets.at(set)->at(category);
541 532 }
542 533 return sum;
543 534 }
544 535
545 536 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
546 537 {
547 538 qreal sum(0);
548 539 int count = m_barSets.count(); // Count sets
549 540 for (int set = 0; set < count; set++) {
550 541 if (category < m_barSets.at(set)->count())
551 542 sum += qAbs(m_barSets.at(set)->at(category));
552 543 }
553 544 return sum;
554 545 }
555 546
556 547 qreal QAbstractBarSeriesPrivate::maxCategorySum()
557 548 {
558 549 qreal max = INT_MIN;
559 550 int count = categoryCount();
560 551 for (int i = 0; i < count; i++) {
561 552 qreal sum = categorySum(i);
562 553 if (sum > max)
563 554 max = sum;
564 555 }
565 556 return max;
566 557 }
567 558
568 559 qreal QAbstractBarSeriesPrivate::minX()
569 560 {
570 561 if (m_barSets.count() <= 0) {
571 562 return 0;
572 563 }
573 564 qreal min = INT_MAX;
574 565
575 566 for (int i = 0; i < m_barSets.count(); i++) {
576 567 int categoryCount = m_barSets.at(i)->count();
577 568 for (int j = 0; j < categoryCount; j++) {
578 569 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
579 570 if (temp < min)
580 571 min = temp;
581 572 }
582 573 }
583 574 return min;
584 575 }
585 576
586 577 qreal QAbstractBarSeriesPrivate::maxX()
587 578 {
588 579 if (m_barSets.count() <= 0) {
589 580 return 0;
590 581 }
591 582 qreal max = INT_MIN;
592 583
593 584 for (int i = 0; i < m_barSets.count(); i++) {
594 585 int categoryCount = m_barSets.at(i)->count();
595 586 for (int j = 0; j < categoryCount; j++) {
596 587 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
597 588 if (temp > max)
598 589 max = temp;
599 590 }
600 591 }
601 592
602 593 return max;
603 594 }
604 595
596 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
597 {
598 // Returns top (sum of all positive values) of category.
599 // Returns 0, if all values are negative
600 qreal top(0);
601 int count = m_barSets.count();
602 for (int set = 0; set < count; set++) {
603 if (category < m_barSets.at(set)->count()) {
604 qreal temp = m_barSets.at(set)->at(category);
605 if (temp > 0) {
606 top += temp;
607 }
608 }
609 }
610 return top;
611 }
612
613 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
614 {
615 // Returns bottom (sum of all negative values) of category
616 // Returns 0, if all values are positive
617 qreal bottom(0);
618 int count = m_barSets.count();
619 for (int set = 0; set < count; set++) {
620 if (category < m_barSets.at(set)->count()) {
621 qreal temp = m_barSets.at(set)->at(category);
622 if (temp < 0) {
623 bottom += temp;
624 }
625 }
626 }
627 return bottom;
628 }
629
630 qreal QAbstractBarSeriesPrivate::top()
631 {
632 // Returns top of all categories
633 qreal top(0);
634 int count = categoryCount();
635 for (int i=0; i<count; i++) {
636 qreal temp = categoryTop(i);
637 if (temp > top) {
638 top = temp;
639 }
640 }
641 return top;
642 }
643
644 qreal QAbstractBarSeriesPrivate::bottom()
645 {
646 // Returns bottom of all categories
647 qreal bottom(0);
648 int count = categoryCount();
649 for (int i=0; i<count; i++) {
650 qreal temp = categoryBottom(i);
651 if (temp < bottom) {
652 bottom = temp;
653 }
654 }
655 return bottom;
656 }
657
605 658
606 659 void QAbstractBarSeriesPrivate::scaleDomain(Domain& domain)
607 660 {
608 661 qreal minX(domain.minX());
609 662 qreal minY(domain.minY());
610 663 qreal maxX(domain.maxX());
611 664 qreal maxY(domain.maxY());
612 665
613 666 qreal seriesMinX = this->minX();
614 667 qreal seriesMaxX = this->maxX();
615 668 qreal y = max();
616 669 minX = qMin(minX, seriesMinX - (qreal)0.5);
617 670 minY = qMin(minY, y);
618 671 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
619 672 maxY = qMax(maxY, y);
620 673
621 674 domain.setRange(minX,maxX,minY,maxY);
622 675 }
623 676
624 677 ChartElement* QAbstractBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
625 678 {
626 679 Q_UNUSED(presenter);
627 680 qWarning() << "QAbstractBarSeriesPrivate::createGraphics called";
628 681 return 0;
629 682 }
630 683
631 684 QList<LegendMarker*> QAbstractBarSeriesPrivate::createLegendMarker(QLegend* legend)
632 685 {
633 686 Q_Q(QAbstractBarSeries);
634 687 QList<LegendMarker*> markers;
635 688 foreach(QBarSet* set, q->barSets()) {
636 689 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
637 690 markers << marker;
638 691 }
639 692
640 693 return markers;
641 694 }
642 695
643 696 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
644 697 {
645 698 Q_Q(QAbstractBarSeries);
646 699 if ((m_barSets.contains(set)) || (set == 0)) {
647 700 // Fail if set is already in list or set is null.
648 701 return false;
649 702 }
650 703 m_barSets.append(set);
651 704 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
652 705 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
653 706 emit restructuredBars(); // this notifies barchartitem
654 707 if (m_dataset) {
655 708 m_dataset->updateSeries(q); // this notifies legend
656 709 }
657 710 return true;
658 711 }
659 712
660 713 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
661 714 {
662 715 Q_Q(QAbstractBarSeries);
663 716 if (!m_barSets.contains(set)) {
664 717 // Fail if set is not in list
665 718 return false;
666 719 }
667 720 m_barSets.removeOne(set);
668 721 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
669 722 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
670 723 emit restructuredBars(); // this notifies barchartitem
671 724 if (m_dataset) {
672 725 m_dataset->updateSeries(q); // this notifies legend
673 726 }
674 727 return true;
675 728 }
676 729
677 730 bool QAbstractBarSeriesPrivate::append(QList<QBarSet* > sets)
678 731 {
679 732 Q_Q(QAbstractBarSeries);
680 733 foreach (QBarSet* set, sets) {
681 734 if ((set == 0) || (m_barSets.contains(set))) {
682 735 // Fail if any of the sets is null or is already appended.
683 736 return false;
684 737 }
685 738 if (sets.count(set) != 1) {
686 739 // Also fail if same set is more than once in given list.
687 740 return false;
688 741 }
689 742 }
690 743
691 744 foreach (QBarSet* set, sets) {
692 745 m_barSets.append(set);
693 746 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
694 747 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
695 748 }
696 749 emit restructuredBars(); // this notifies barchartitem
697 750 if (m_dataset) {
698 751 m_dataset->updateSeries(q); // this notifies legend
699 752 }
700 753 return true;
701 754 }
702 755
703 756 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet* > sets)
704 757 {
705 758 Q_Q(QAbstractBarSeries);
706 759 if (sets.count() == 0) {
707 760 return false;
708 761 }
709 762 foreach (QBarSet* set, sets) {
710 763 if ((set == 0) || (!m_barSets.contains(set))) {
711 764 // Fail if any of the sets is null or is not in series
712 765 return false;
713 766 }
714 767 if (sets.count(set) != 1) {
715 768 // Also fail if same set is more than once in given list.
716 769 return false;
717 770 }
718 771 }
719 772
720 773 foreach (QBarSet* set, sets) {
721 774 m_barSets.removeOne(set);
722 775 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
723 776 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
724 777 }
725 778
726 779 emit restructuredBars(); // this notifies barchartitem
727 780 if (m_dataset) {
728 781 m_dataset->updateSeries(q); // this notifies legend
729 782 }
730 783 return true;
731 784 }
732 785
733 786 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
734 787 {
735 788 Q_Q(QAbstractBarSeries);
736 789 if ((m_barSets.contains(set)) || (set == 0)) {
737 790 // Fail if set is already in list or set is null.
738 791 return false;
739 792 }
740 793 m_barSets.insert(index, set);
741 794 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
742 795 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
743 796 emit restructuredBars(); // this notifies barchartitem
744 797 if (m_dataset) {
745 798 m_dataset->updateSeries(q); // this notifies legend
746 799 }
747 800 return true;
748 801 }
749 802
750 803 void QAbstractBarSeriesPrivate::initializeAxis(QAbstractAxis* axis)
751 804 {
752 805 Q_Q(QAbstractBarSeries);
753 806
754 807 if(axis->type()==QAbstractAxis::AxisTypeBarCategory) {
755 808
756 809 switch(q->type()) {
757 810
758 811 case QAbstractSeries::SeriesTypeHorizontalBar:
759 812 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
760 813 case QAbstractSeries::SeriesTypeHorizontalStackedBar: {
761 814
762 815 if(axis->orientation()==Qt::Vertical)
763 816 {
764 817 populateCategories(qobject_cast<QBarCategoryAxis*>(axis));
765 818 }
766 819 break;
767 820 }
768 821 case QAbstractSeries::SeriesTypeBar:
769 822 case QAbstractSeries::SeriesTypePercentBar:
770 823 case QAbstractSeries::SeriesTypeStackedBar: {
771 824
772 825 if(axis->orientation()==Qt::Horizontal)
773 826 {
774 827 populateCategories(qobject_cast<QBarCategoryAxis*>(axis));
775 828 }
776 829 break;
777 830 }
778 831 default:
779 832 qWarning()<<"Unexpected series type";
780 833 break;
781 834
782 835 }
783 836 }
784 837 }
785 838
786 839 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
787 840 {
788 841 Q_Q(const QAbstractBarSeries);
789 842
790 843 switch(q->type()) {
791 844
792 845 case QAbstractSeries::SeriesTypeHorizontalBar:
793 846 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
794 847 case QAbstractSeries::SeriesTypeHorizontalStackedBar: {
795 848
796 849 if(orientation==Qt::Vertical)
797 850 {
798 851 return QAbstractAxis::AxisTypeBarCategory;
799 852 }
800 853 break;
801 854 }
802 855 case QAbstractSeries::SeriesTypeBar:
803 856 case QAbstractSeries::SeriesTypePercentBar:
804 857 case QAbstractSeries::SeriesTypeStackedBar: {
805 858
806 859 if(orientation==Qt::Horizontal)
807 860 {
808 861 return QAbstractAxis::AxisTypeBarCategory;
809 862 }
810 863 break;
811 864 }
812 865 default:
813 866 qWarning()<<"Unexpected series type";
814 867 break;
815 868
816 869 }
817 870 return QAbstractAxis::AxisTypeValue;
818 871
819 872 }
820 873
821 874 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis* axis)
822 875 {
823 876 QStringList categories;
824 877 if(axis->categories().isEmpty()) {
825 878 for (int i(1); i < categoryCount()+1; i++)
826 879 categories << QString::number(i);
827 880 axis->append(categories);
828 881 }
829 882 }
830 883
831 884 #include "moc_qabstractbarseries.cpp"
832 885 #include "moc_qabstractbarseries_p.cpp"
833 886
834 887
835 888 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,89 +1,85
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef ABSTRACTBARSERIES_H
22 22 #define ABSTRACTBARSERIES_H
23 23
24 24 #include <qabstractseries.h>
25 25 #include <QStringList>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 class QBarSet;
30 30 class QAbstractBarSeriesPrivate;
31 31
32 32 // Container for series
33 33 class QTCOMMERCIALCHART_EXPORT QAbstractBarSeries : public QAbstractSeries
34 34 {
35 35 Q_OBJECT
36 36 Q_PROPERTY(qreal barWidth READ barWidth WRITE setBarWidth)
37 37 Q_PROPERTY(int count READ count NOTIFY countChanged)
38 38 Q_PROPERTY(bool labelsVisible READ isLabelsVisible WRITE setLabelsVisible NOTIFY labelsVisibleChanged)
39 39
40 protected:
41 //TODO DEPRECIATED
42 explicit QAbstractBarSeries(QObject *parent = 0);
43
44 40 public:
45 41 virtual ~QAbstractBarSeries();
46 42
47 43 void setBarWidth(qreal width);
48 44 qreal barWidth() const;
49 45
50 46 bool append(QBarSet *set);
51 47 bool remove(QBarSet *set);
52 48 bool take(QBarSet *set);
53 49 bool append(QList<QBarSet* > sets);
54 50 bool insert(int index, QBarSet *set);
55 51 int count() const;
56 52 QList<QBarSet*> barSets() const;
57 53 void clear();
58 54
59 55 void setLabelsVisible(bool visible = true);
60 56 bool isLabelsVisible() const;
61 57
62 58 void setOverlap(bool overlap = true);
63 59
64 60 protected:
65 61 explicit QAbstractBarSeries(QAbstractBarSeriesPrivate &d,QObject *parent = 0);
66 62
67 63 Q_SIGNALS:
68 64 void clicked(int index, QBarSet *barset);
69 65 void hovered(bool status, QBarSet *barset);
70 66 void countChanged();
71 67 void labelsVisibleChanged();
72 68
73 69 void barsetsAdded(QList<QBarSet*> sets);
74 70 void barsetsRemoved(QList<QBarSet*> sets);
75 71
76 72 protected:
77 73 Q_DECLARE_PRIVATE(QAbstractBarSeries)
78 74 friend class AbstractBarChartItem;
79 75 friend class PercentBarChartItem;
80 76 friend class StackedBarChartItem;
81 77 friend class BarChartItem;
82 78 friend class HorizontalBarChartItem;
83 79 friend class HorizontalStackedBarChartItem;
84 80 friend class HorizontalPercentBarChartItem;
85 81 };
86 82
87 83 QTCOMMERCIALCHART_END_NAMESPACE
88 84
89 85 #endif // ABSTRACTBARSERIES_H
@@ -1,105 +1,109
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QABSTRACTBARSERIES_P_H
31 31 #define QABSTRACTBARSERIES_P_H
32 32
33 33 #include "qabstractbarseries.h"
34 34 #include "qabstractseries_p.h"
35 35 #include <QStringList>
36 36 #include <QAbstractSeries>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class QBarModelMapper;
41 41 class QBarCategoryAxis;
42 42
43 43 class QAbstractBarSeriesPrivate : public QAbstractSeriesPrivate
44 44 {
45 45 Q_OBJECT
46 46 public:
47 47 QAbstractBarSeriesPrivate(QAbstractBarSeries *parent);
48 48 int categoryCount() const;
49 49
50 50 void setBarWidth(qreal width);
51 51 qreal barWidth() const;
52 52
53 53 void setVisible(bool visible);
54 54 void setLabelsVisible(bool visible);
55 55 void setOverlap(bool overlap);
56 56
57 57 void scaleDomain(Domain& domain);
58 58 ChartElement* createGraphics(ChartPresenter* presenter);
59 59 QList<LegendMarker*> createLegendMarker(QLegend* legend);
60 60
61 61 void initializeAxis(QAbstractAxis* axis);
62 62 virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
63 63
64 64 bool append(QBarSet *set);
65 65 bool remove(QBarSet *set);
66 66 bool append(QList<QBarSet* > sets);
67 67 bool remove(QList<QBarSet* > sets);
68 68 bool insert(int index, QBarSet *set);
69 69
70 70 QBarSet* barsetAt(int index);
71 71 qreal min();
72 72 qreal max();
73 73 qreal valueAt(int set, int category);
74 74 qreal percentageAt(int set, int category);
75 75 qreal categorySum(int category);
76 76 qreal absoluteCategorySum(int category);
77 77 qreal maxCategorySum();
78 78 qreal minX();
79 79 qreal maxX();
80 qreal categoryTop(int category);
81 qreal categoryBottom(int category);
82 qreal top();
83 qreal bottom();
80 84
81 85 Q_SIGNALS:
82 86 void clicked(int index, QBarSet *barset);
83 87 void updatedBars();
84 88 void restructuredBars();
85 89 void labelsVisibleChanged(bool visible);
86 90
87 91 private:
88 92 void populateCategories(QBarCategoryAxis* axis);
89 93
90 94 protected:
91 95 QList<QBarSet *> m_barSets;
92 96 qreal m_barWidth;
93 97 bool m_labelsVisible;
94 98 bool m_visible;
95 99 bool m_overlap;
96 100
97 101 private:
98 102 Q_DECLARE_PUBLIC(QAbstractBarSeries)
99 103 friend class HorizontalBarChartItem;
100 104 friend class BarChartItem;
101 105 };
102 106
103 107 QTCOMMERCIALCHART_END_NAMESPACE
104 108
105 109 #endif // QABSTRACTBARSERIES_P_H
@@ -1,125 +1,123
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qstackedbarseries.h"
22 22 #include "qstackedbarseries_p.h"
23 23 #include "stackedbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "qvalueaxis.h"
27 27 #include "stackedbaranimation_p.h"
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 /*!
32 32 \class QStackedBarSeries
33 33 \brief Series for creating stacked bar chart
34 34 \mainclass
35 35
36 36 QStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
37 37 as stacks, where bars in same category are stacked on top of each other.
38 38 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
39 39
40 40 See the \l {StackedbarChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
41 41 \image examples_stackedbarchart.png
42 42
43 43 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries
44 44 */
45 45
46 46 /*!
47 47 \qmlclass StackedBarSeries QStackedBarSeries
48 48 \inherits AbstractBarSeries
49 49
50 50 The following QML shows how to create a simple stacked bar chart:
51 51 \snippet ../demos/qmlchart/qml/qmlchart/View7.qml 1
52 52 \beginfloatleft
53 53 \image demos_qmlchart7.png
54 54 \endfloat
55 55 \clearfloat
56 56 */
57 57
58 58 /*!
59 59 Constructs empty QStackedBarSeries.
60 60 QStackedBarSeries is QObject which is a child of a \a parent.
61 61 */
62 62 QStackedBarSeries::QStackedBarSeries(QObject *parent)
63 63 : QAbstractBarSeries(*new QStackedBarSeriesPrivate(this), parent)
64 64 {
65 65 }
66 66
67 67 /*!
68 68 Destructor. Removes series from chart.
69 69 */
70 70 QStackedBarSeries::~QStackedBarSeries()
71 71 {
72 72 Q_D(QStackedBarSeries);
73 73 if(d->m_dataset) {
74 74 d->m_dataset->removeSeries(this);
75 75 }
76 76 }
77 77 /*!
78 78 Returns QChartSeries::SeriesTypeStackedBar.
79 79 */
80 80 QAbstractSeries::SeriesType QStackedBarSeries::type() const
81 81 {
82 82 return QAbstractSeries::SeriesTypeStackedBar;
83 83 }
84 84
85 85 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86 86
87 87 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
88 88 {
89 89
90 90 }
91 91
92 92 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
93 93 {
94 94 qreal minX(domain.minX());
95 95 qreal minY(domain.minY());
96 96 qreal maxX(domain.maxX());
97 97 qreal maxY(domain.maxY());
98 98
99 99 qreal x = categoryCount();
100 qreal y = maxCategorySum();
101 100 minX = qMin(minX, - (qreal)0.5);
102 minY = qMin(minY, y);
101 minY = qMin(minY, bottom());
103 102 maxX = qMax(maxX, x - (qreal)0.5);
104 maxY = qMax(maxY, y);
103 maxY = qMax(maxY, top());
105 104
106 105 domain.setRange(minX,maxX,minY,maxY);
107 106 }
108 107
109
110 108 ChartElement* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
111 109 {
112 110 Q_Q(QStackedBarSeries);
113 111
114 112 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
115 113 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
116 114 bar->setAnimation(new StackedBarAnimation(bar));
117 115 }
118 116 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
119 117 return bar;
120 118 }
121 119
122 120 #include "moc_qstackedbarseries.cpp"
123 121
124 122 QTCOMMERCIALCHART_END_NAMESPACE
125 123
@@ -1,94 +1,103
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "stackedbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qbarset_p.h"
24 24 #include "qabstractbarseries_p.h"
25 25 #include "qbarset.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter) :
30 30 AbstractBarChartItem(series, presenter)
31 31 {
32 32 }
33 33
34 34 QVector<QRectF> StackedBarChartItem::calculateLayout()
35 35 {
36 36 QVector<QRectF> layout;
37 37 // Use temporary qreals for accuracy
38 38 qreal categoryCount = m_series->d_func()->categoryCount();
39 39 qreal setCount = m_series->count();
40 40 bool barsVisible = m_series->isVisible();
41 41
42 42 // Domain:
43 43 qreal width = geometry().width();
44 44 qreal height = geometry().height();
45 45 qreal rangeY = m_domainMaxY - m_domainMinY;
46 46 qreal rangeX = m_domainMaxX - m_domainMinX;
47 47 qreal scaleY = (height / rangeY);
48 48 qreal scaleX = (width / rangeX);
49 49 qreal barWidth = scaleX * m_series->d_func()->barWidth();
50 50
51 51 int itemIndex(0);
52 52 for (int category = 0; category < categoryCount; category++) {
53 qreal yPos = height + rangeY * m_domainMinY + geometry().topLeft().y();
53 qreal yMax = height + scaleY * m_domainMinY + geometry().topLeft().y();
54 qreal yMin = height + scaleY * m_domainMinY + geometry().topLeft().y();
54 55 for (int set=0; set < setCount; set++) {
55 56 QBarSetPrivate* barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
56 57
57 58 qreal xPos = (barSet->pos(category) - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
58 59
59 60 qreal barHeight = barSet->value(category) * scaleY;
60 61 Bar* bar = m_bars.at(itemIndex);
61 62 bar->setPen(barSet->m_pen);
62 63 bar->setBrush(barSet->m_brush);
63 64 if (qFuzzyIsNull(barHeight)) {
64 65 bar->setVisible(false);
65 66 } else {
66 67 bar->setVisible(barsVisible);
67 68 }
68 69
69 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
70 layout.append(rect);
71
72 70 QGraphicsSimpleTextItem* label = m_labels.at(itemIndex);
73 71
74 72 if (!qFuzzyIsNull(barSet->value(category))) {
75 73 label->setText(QString::number(barSet->value(category)));
76 74 } else {
77 75 label->setText(QString(""));
78 76 }
79
80 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
81 ,yPos - barHeight/2 - label->boundingRect().height()/2);
82 77 label->setFont(barSet->m_labelFont);
83 78 label->setBrush(barSet->m_labelBrush);
79
80 if (barHeight < 0) {
81 QRectF rect(xPos, yMax-barHeight, barWidth, barHeight);
82 layout.append(rect);
83 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
84 ,yMax - barHeight/2 - label->boundingRect().height()/2);
85 yMax -= barHeight;
86 } else {
87 QRectF rect(xPos, yMin-barHeight, barWidth, barHeight);
88 layout.append(rect);
89 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
90 ,yMin - barHeight/2 - label->boundingRect().height()/2);
91 yMin -= barHeight;
92 }
93
84 94 itemIndex++;
85 yPos -= barHeight;
86 95 }
87 96 }
88 97
89 98 return layout;
90 99 }
91 100
92 101 #include "moc_stackedbarchartitem_p.cpp"
93 102
94 103 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now