##// END OF EJS Templates
correct x-positioning for barcharts
sauimone -
r1228:0d57f24390a8
parent child
Show More
@@ -1,87 +1,90
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 "groupedbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barlabel_p.h"
24 24 #include "qbarset_p.h"
25 25 #include "qbarseries_p.h"
26 26 #include "qbarset.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 GroupedBarChartItem::GroupedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
31 31 BarChartItem(series, presenter)
32 32 {
33 33 }
34 34
35 35 QVector<QRectF> GroupedBarChartItem::calculateLayout()
36 36 {
37 37 QVector<QRectF> layout;
38 38
39 39 // Use temporary qreals for accurancy
40 40 qreal categoryCount = m_series->categoryCount();
41 41 qreal setCount = m_series->barsetCount();
42 42
43 43 // Domain:
44 44 qreal width = geometry().width();
45 45 qreal height = geometry().height();
46 qreal range = m_domainMaxY - m_domainMinY;
47 qreal scale = (height / range);
46 qreal rangeY = m_domainMaxY - m_domainMinY;
47 qreal rangeX = m_domainMaxX - m_domainMinX;
48 qreal scaleY = (height / rangeY);
49 qreal scaleX = (width / rangeX);
48 50 qreal categoryWidth = width / categoryCount;
49 qreal barWidth = categoryWidth / (setCount+1);
51 qreal barWidth = categoryWidth / setCount - categoryWidth * m_series->d_func()->barMargin();
50 52
51 53 int itemIndex(0);
52 54 for (int category = 0; category < categoryCount; category++) {
53 qreal xPos = categoryWidth * category + barWidth / 2 + geometry().topLeft().x();
54 qreal yPos = height + scale * m_domainMinY + geometry().topLeft().y();
55 qreal yPos = height + scaleY * m_domainMinY + geometry().topLeft().y();
55 56 for (int set = 0; set < setCount; set++) {
56 57 QBarSet* barSet = m_series->d_func()->barsetAt(set);
57 58
58 qreal barHeight = barSet->at(category).y() * scale;
59 qreal xPos = (barSet->at(category).x() - m_domainMinX) * scaleX + m_rect.left();
60 xPos -= setCount*barWidth/2;
61 xPos += set*barWidth;
62 qreal barHeight = barSet->at(category).y() * scaleY;
59 63 Bar* bar = m_bars.at(itemIndex);
60 64
61 65 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
62 66 layout.append(rect);
63 67 bar->setPen(barSet->pen());
64 68 bar->setBrush(barSet->brush());
65 69
66 70 BarLabel* label = m_labels.at(itemIndex);
67 71
68 72 if (!qFuzzyIsNull(barSet->at(category).y())) {
69 73 label->setText(QString::number(barSet->at(category).y()));
70 74 } else {
71 75 label->setText(QString(""));
72 76 }
73 77
74 78 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
75 79 ,yPos - barHeight/2 - label->boundingRect().height()/2);
76 80 label->setFont(barSet->labelFont());
77 81
78 82 itemIndex++;
79 xPos += barWidth;
80 83 }
81 84 }
82 85 return layout;
83 86 }
84 87
85 88 #include "moc_groupedbarchartitem_p.cpp"
86 89
87 90 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,90 +1,94
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 "percentbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barlabel_p.h"
24 24 #include "qbarseries_p.h"
25 25 #include "qbarset.h"
26 26 #include <QDebug>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
31 31 BarChartItem(series, presenter)
32 32 {
33 33 }
34 34
35 35 QVector<QRectF> PercentBarChartItem::calculateLayout()
36 36 {
37 37 QVector<QRectF> layout;
38 38
39 39 // Use temporary qreals for accurancy
40 qreal width = geometry().width();
41 qreal height = geometry().height();
42
43 40 qreal categoryCount = m_series->categoryCount();
44 qreal barWidth = width / (m_series->categoryCount() * 2);
45 qreal xStep = width / categoryCount;
46 qreal xPos = xStep / 2 - barWidth / 2 + geometry().topLeft().x();
41 qreal setCount = m_series->barsetCount();
47 42
48 qreal range = m_domainMaxY - m_domainMinY;
49 qreal domainScale = (height / range);
43 // Domain:
44 qreal width = geometry().width();
45 qreal height = geometry().height();
46 qreal rangeY = m_domainMaxY - m_domainMinY;
47 qreal rangeX = m_domainMaxX - m_domainMinX;
48 qreal scaleY = (height / rangeY);
49 qreal scaleX = (width / rangeX);
50 qreal categoryWidth = width / categoryCount;
51 qreal barWidth = categoryWidth / setCount - categoryWidth * m_series->d_func()->barMargin();
50 52
51 53 int itemIndex(0);
52 54 for (int category = 0; category < categoryCount; category++) {
53 55 qreal colSum = m_series->d_func()->categorySum(category);
54 56 qreal percentage = (100 / colSum);
55 qreal yPos = height + domainScale * m_domainMinY + geometry().topLeft().y();
56 for (int set=0; set < m_series->barsetCount(); set++) {
57 qreal yPos = height + scaleY * m_domainMinY + geometry().topLeft().y();
58 for (int set=0; set < setCount; set++) {
57 59 QBarSet* barSet = m_series->d_func()->barsetAt(set);
58 qreal barHeight = barSet->at(category).y() * percentage * domainScale;
60
61 qreal xPos = (barSet->at(category).x() - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
62
63 qreal barHeight = barSet->at(category).y() * percentage * scaleY;
59 64 Bar* bar = m_bars.at(itemIndex);
60 65 bar->setPen(barSet->pen());
61 66 bar->setBrush(barSet->brush());
62 67 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
63 68 layout.append(rect);
64 69
65 70 BarLabel* label = m_labels.at(itemIndex);
66 71
67 72 if (!qFuzzyIsNull(m_series->d_func()->valueAt(set,category))) {
68 73 int p = m_series->d_func()->percentageAt(set,category) * 100;
69 74 QString vString(QString::number(p));
70 75 vString.truncate(3);
71 76 vString.append("%");
72 77 label->setText(vString);
73 78 } else {
74 79 label->setText(QString(""));
75 80 }
76 81
77 82 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
78 83 ,yPos - barHeight/2 - label->boundingRect().height()/2);
79 84 label->setFont(barSet->labelFont());
80 85 itemIndex++;
81 86 yPos -= barHeight;
82 87 }
83 xPos += xStep;
84 88 }
85 89 return layout;
86 90 }
87 91
88 92 #include "moc_percentbarchartitem_p.cpp"
89 93
90 94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,654 +1,654
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 "qbarseries.h"
22 22 #include "qbarseries_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 "chartanimator_p.h"
30 30
31 31 #include <QAbstractItemModel>
32 32 #include <QModelIndex>
33 33 #include <QBarModelMapper>
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 /*!
38 38 \class QBarSeries
39 39 \brief part of QtCommercial chart API.
40 40 \mainclass
41 41
42 42 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
43 43 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
44 44 and y-value is the height of the bar. The category names are ignored with this series and x-axis
45 45 shows the x-values.
46 46
47 47 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
48 48 \image examples_barchart.png
49 49
50 50 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
51 51 */
52 52
53 53 /*!
54 54 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
55 55
56 56 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
57 57 contained by the series.
58 58 */
59 59
60 60 /*!
61 61 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
62 62
63 63 The signal is emitted if mouse is hovered on top of series.
64 64 Parameter \a barset is the pointer of barset, where hover happened.
65 65 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
66 66 */
67 67
68 68 /*!
69 69 Constructs empty QBarSeries.
70 70 QBarSeries is QObject which is a child of a \a parent.
71 71 */
72 72 QBarSeries::QBarSeries(QObject *parent) :
73 73 QAbstractSeries(*new QBarSeriesPrivate(this),parent)
74 74 {
75 75 }
76 76
77 77 /*!
78 78 Destructs barseries and owned barsets.
79 79 */
80 80 QBarSeries::~QBarSeries()
81 81 {
82 82 // NOTE: d_ptr destroyed by QObject
83 83 }
84 84
85 85 /*!
86 86 \internal
87 87 */
88 88 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
89 89 QAbstractSeries(d,parent)
90 90 {
91 91 }
92 92
93 93 /*!
94 94 Returns the type of series. Derived classes override this.
95 95 */
96 96 QAbstractSeries::SeriesType QBarSeries::type() const
97 97 {
98 98 return QAbstractSeries::SeriesTypeBar;
99 99 }
100 100
101 101 /*!
102 102 Sets the \a categories, which are used to to group the data.
103 103 */
104 104 void QBarSeries::setCategories(QBarCategories categories)
105 105 {
106 106 Q_D(QBarSeries);
107 107 d->setCategories(categories);
108 108 emit d->categoriesUpdated();
109 109 }
110 110
111 111 /*!
112 112 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.
113 113 Returns true, if appending succeeded.
114 114
115 115 */
116 116 bool QBarSeries::append(QBarSet *set)
117 117 {
118 118 Q_D(QBarSeries);
119 119 if ((d->m_barSets.contains(set)) || (set == 0)) {
120 120 // Fail if set is already in list or set is null.
121 121 return false;
122 122 }
123 123 d->m_barSets.append(set);
124 124 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
125 125 emit d->restructuredBars();
126 126 return true;
127 127 }
128 128
129 129 /*!
130 130 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
131 131 Returns true, if set was removed.
132 132 */
133 133 bool QBarSeries::remove(QBarSet *set)
134 134 {
135 135 Q_D(QBarSeries);
136 136 if (!d->m_barSets.contains(set)) {
137 137 // Fail if set is not in list
138 138 return false;
139 139 }
140 140 d->m_barSets.removeOne(set);
141 141 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
142 142 emit d->restructuredBars();
143 143 return true;
144 144 }
145 145
146 146 /*!
147 147 Adds a list of barsets to series. Takes ownership of \a sets.
148 148 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
149 149 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
150 150 and function returns false.
151 151 */
152 152 bool QBarSeries::append(QList<QBarSet* > sets)
153 153 {
154 154 Q_D(QBarSeries);
155 155 foreach (QBarSet* set, sets) {
156 156 if ((set == 0) || (d->m_barSets.contains(set))) {
157 157 // Fail if any of the sets is null or is already appended.
158 158 return false;
159 159 }
160 160 if (sets.count(set) != 1) {
161 161 // Also fail if same set is more than once in given list.
162 162 return false;
163 163 }
164 164 }
165 165
166 166 foreach (QBarSet* set, sets) {
167 167 d->m_barSets.append(set);
168 168 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
169 169 }
170 170 emit d->restructuredBars();
171 171 return true;
172 172 }
173 173
174 174 /*!
175 175 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
176 176 */
177 177 bool QBarSeries::remove(QList<QBarSet* > sets)
178 178 {
179 179 Q_D(QBarSeries);
180 180
181 181 bool setsRemoved = false;
182 182 foreach (QBarSet* set, sets) {
183 183 if (d->m_barSets.contains(set)) {
184 184 d->m_barSets.removeOne(set);
185 185 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
186 186 setsRemoved = true;
187 187 }
188 188 }
189 189
190 190 if (setsRemoved) {
191 191 emit d->restructuredBars();
192 192 }
193 193 return setsRemoved;
194 194 }
195 195
196 196 /*!
197 197 Returns number of sets in series.
198 198 */
199 199 int QBarSeries::barsetCount() const
200 200 {
201 201 Q_D(const QBarSeries);
202 202 return d->m_barSets.count();
203 203 }
204 204
205 205 /*!
206 206 Returns number of categories in series
207 207 */
208 208 int QBarSeries::categoryCount() const
209 209 {
210 210 Q_D(const QBarSeries);
211 211 return d->categoryCount();
212 212 }
213 213
214 214 /*!
215 215 Returns a list of sets in series. Keeps ownership of sets.
216 216 */
217 217 QList<QBarSet*> QBarSeries::barSets() const
218 218 {
219 219 Q_D(const QBarSeries);
220 220 return d->m_barSets;
221 221 }
222 222
223 223 /*!
224 224 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
225 225 Sets the \a model to be used as a data source
226 226 */
227 227 void QBarSeries::setModel(QAbstractItemModel *model)
228 228 {
229 229 Q_D(QBarSeries);
230 230 // disconnect signals from old model
231 231 if(d->m_model)
232 232 {
233 233 disconnect(d->m_model, 0, this, 0);
234 234 }
235 235
236 236 // set new model
237 237 if(model)
238 238 {
239 239 d->m_model = model;
240 240
241 241 // connect the signals
242 242 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
243 243 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
244 244 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
245 245 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
246 246 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
247 247
248 248 if (d->m_mapper)
249 249 d->initializeDataFromModel();
250 250 }
251 251 else
252 252 {
253 253 d->m_model = 0;
254 254 }
255 255 }
256 256
257 257 void QBarSeries::setModelMapper(QBarModelMapper *mapper)
258 258 {
259 259 Q_D(QBarSeries);
260 260 // disconnect signals from old mapper
261 261 if (d->m_mapper) {
262 262 QObject::disconnect(d->m_mapper, 0, this, 0);
263 263 }
264 264
265 265 if (mapper) {
266 266 d->m_mapper = mapper;
267 267 // connect the signal from the mapper
268 268 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializeDataFromModel()));
269 269
270 270 if (d->m_model)
271 271 d->initializeDataFromModel();
272 272 } else {
273 273 d->m_mapper = 0;
274 274 }
275 275 }
276 276
277 277 QBarModelMapper* QBarSeries::modelMapper() const
278 278 {
279 279 Q_D(const QBarSeries);
280 280 return d->m_mapper;
281 281 }
282 282
283 283 /*!
284 284 Returns the bar categories of the series.
285 285 */
286 286 QBarCategories QBarSeries::categories() const
287 287 {
288 288 Q_D(const QBarSeries);
289 289 return d->categories();
290 290 }
291 291
292 292 /*!
293 293 Sets the visibility of labels in series to \a visible
294 294 */
295 295 void QBarSeries::setLabelsVisible(bool visible)
296 296 {
297 297 foreach (QBarSet* s, barSets()) {
298 298 s->setLabelsVisible(visible);
299 299 }
300 300 }
301 301
302 302 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
303 303
304 304 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
305 305 QAbstractSeriesPrivate(q),
306 306 m_barMargin(0.05), // Default value is 5% of category width
307 307 m_mapper(0)
308 308 {
309 309 }
310 310
311 311 void QBarSeriesPrivate::setCategories(QBarCategories categories)
312 312 {
313 313 m_categories = categories;
314 314 }
315 315
316 316 void QBarSeriesPrivate::insertCategory(int index, const QString category)
317 317 {
318 318 m_categories.insert(index, category);
319 319 emit categoriesUpdated();
320 320 }
321 321
322 322 void QBarSeriesPrivate::removeCategory(int index)
323 323 {
324 324 m_categories.removeAt(index);
325 325 emit categoriesUpdated();
326 326 }
327 327
328 328 int QBarSeriesPrivate::categoryCount() const
329 329 {
330 330 if (m_categories.count() > 0) {
331 331 return m_categories.count();
332 332 }
333 333
334 334 // No categories defined. return count of longest set.
335 335 int count = 0;
336 336 for (int i=0; i<m_barSets.count(); i++) {
337 337 if (m_barSets.at(i)->count() > count) {
338 338 count = m_barSets.at(i)->count();
339 339 }
340 340 }
341 341
342 342 return count;
343 343 }
344 344
345 345 QBarCategories QBarSeriesPrivate::categories() const
346 346 {
347 347 if (m_categories.count() > 0) {
348 348 return m_categories;
349 349 }
350 350
351 351 // No categories defined. retun list of indices.
352 352 QBarCategories categories;
353 353
354 354 int count = categoryCount();
355 355 for (int i = 0; i < count; i++) {
356 356 categories.append(QString::number(i));
357 357 }
358 358 return categories;
359 359 }
360 360
361 361 void QBarSeriesPrivate::setBarMargin(qreal margin)
362 362 {
363 363 if (margin > 1.0) {
364 364 margin = 1.0;
365 365 } else if (margin < 0.0) {
366 366 margin = 0.0;
367 367 }
368 368
369 369 m_barMargin = margin;
370 370 emit updatedBars();
371 371 }
372 372
373 373 qreal QBarSeriesPrivate::barMargin()
374 374 {
375 375 return m_barMargin;
376 376 }
377 377
378 378 QBarSet* QBarSeriesPrivate::barsetAt(int index)
379 379 {
380 380 return m_barSets.at(index);
381 381 }
382 382
383 383 QString QBarSeriesPrivate::categoryName(int category)
384 384 {
385 385 if ((category >= 0) && (category < m_categories.count())) {
386 386 return m_categories.at(category);
387 387 }
388 388
389 389 return QString::number(category);
390 390 }
391 391
392 392 qreal QBarSeriesPrivate::min()
393 393 {
394 394 if (m_barSets.count() <= 0) {
395 395 return 0;
396 396 }
397 397 qreal min = INT_MAX;
398 398
399 399 for (int i = 0; i < m_barSets.count(); i++) {
400 400 int categoryCount = m_barSets.at(i)->count();
401 401 for (int j = 0; j < categoryCount; j++) {
402 402 qreal temp = m_barSets.at(i)->at(j).y();
403 403 if (temp < min)
404 404 min = temp;
405 405 }
406 406 }
407 407 return min;
408 408 }
409 409
410 410 qreal QBarSeriesPrivate::max()
411 411 {
412 412 if (m_barSets.count() <= 0) {
413 413 return 0;
414 414 }
415 415 qreal max = INT_MIN;
416 416
417 417 for (int i = 0; i < m_barSets.count(); i++) {
418 418 int categoryCount = m_barSets.at(i)->count();
419 419 for (int j = 0; j < categoryCount; j++) {
420 420 qreal temp = m_barSets.at(i)->at(j).y();
421 421 if (temp > max)
422 422 max = temp;
423 423 }
424 424 }
425 425
426 426 return max;
427 427 }
428 428
429 429 qreal QBarSeriesPrivate::valueAt(int set, int category)
430 430 {
431 431 if ((set < 0) || (set >= m_barSets.count())) {
432 432 // No set, no value.
433 433 return 0;
434 434 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
435 435 // No category, no value.
436 436 return 0;
437 437 }
438 438
439 439 return m_barSets.at(set)->at(category).y();
440 440 }
441 441
442 442 qreal QBarSeriesPrivate::percentageAt(int set, int category)
443 443 {
444 444 if ((set < 0) || (set >= m_barSets.count())) {
445 445 // No set, no value.
446 446 return 0;
447 447 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
448 448 // No category, no value.
449 449 return 0;
450 450 }
451 451
452 452 qreal value = m_barSets.at(set)->at(category).y();
453 453 qreal sum = categorySum(category);
454 454 if ( qFuzzyIsNull(sum) ) {
455 455 return 0;
456 456 }
457 457
458 458 return value / sum;
459 459 }
460 460
461 461 qreal QBarSeriesPrivate::categorySum(int category)
462 462 {
463 463 qreal sum(0);
464 464 int count = m_barSets.count(); // Count sets
465 465 for (int set = 0; set < count; set++) {
466 466 if (category < m_barSets.at(set)->count())
467 467 sum += m_barSets.at(set)->at(category).y();
468 468 }
469 469 return sum;
470 470 }
471 471
472 472 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
473 473 {
474 474 qreal sum(0);
475 475 int count = m_barSets.count(); // Count sets
476 476 for (int set = 0; set < count; set++) {
477 477 if (category < m_barSets.at(set)->count())
478 478 sum += qAbs(m_barSets.at(set)->at(category).y());
479 479 }
480 480 return sum;
481 481 }
482 482
483 483 qreal QBarSeriesPrivate::maxCategorySum()
484 484 {
485 485 qreal max = INT_MIN;
486 486 int count = categoryCount();
487 487 for (int i = 0; i < count; i++) {
488 488 qreal sum = categorySum(i);
489 489 if (sum > max)
490 490 max = sum;
491 491 }
492 492 return max;
493 493 }
494 494
495 495 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
496 496 {
497 497 if (m_model == 0 || m_mapper == 0)
498 498 return;
499 499
500 500 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
501 501 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
502 502 if (m_mapper->orientation() == Qt::Vertical)
503 503 {
504 504 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
505 505 if ( row >= m_mapper->first() && (m_mapper->count() == - 1 || row < m_mapper->first() + m_mapper->count())) {
506 506 if (column >= m_mapper->mapBarBottom() && column <= m_mapper->mapBarTop())
507 507 barsetAt(column - m_mapper->mapBarBottom())->replace(row - m_mapper->first(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
508 508 // if (column == m_mapper->mapCategories());// TODO:
509 509 }
510 510 }
511 511 else
512 512 {
513 513 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
514 514 if (column >= m_mapper->first() && (m_mapper->count() == - 1 || column < m_mapper->first() + m_mapper->count())) {
515 515 if (row >= m_mapper->mapBarBottom() && row <= m_mapper->mapBarTop())
516 516 barsetAt(row - m_mapper->mapBarBottom())->replace(column - m_mapper->first(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
517 517 // if (row == m_mapper->mapCategories());// TODO:
518 518 }
519 519 }
520 520 }
521 521 }
522 522 }
523 523
524 524 void QBarSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
525 525 {
526 526 Q_UNUSED(parent);
527 527 Q_UNUSED(start);
528 528 Q_UNUSED(end);
529 529 initializeDataFromModel();
530 530 }
531 531
532 532 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
533 533 {
534 534 Q_UNUSED(parent);
535 535 Q_UNUSED(start);
536 536 Q_UNUSED(end);
537 537 initializeDataFromModel();
538 538 }
539 539
540 540 void QBarSeriesPrivate::initializeDataFromModel()
541 541 {
542 542 Q_Q(QBarSeries);
543 543
544 544 // create the initial bars
545 545 m_categories.clear();
546 546 m_barSets.clear();
547 547
548 548 if (m_model == 0 || m_mapper == 0)
549 549 return;
550 550
551 551 // check if mappings are set
552 552 if (m_mapper->mapBarBottom() == -1 || m_mapper->mapBarTop() == -1 || m_mapper->mapCategories() == -1)
553 553 return;
554 554
555 555 // emit restructuredBars();
556 556 if (m_mapper->orientation() == Qt::Vertical) {
557 557 if (m_mapCategories >= m_model->columnCount())
558 558 return;
559 559 int rowCount = 0;
560 560 if(m_mapper->count() == -1)
561 561 rowCount = m_model->rowCount() - m_mapper->first();
562 562 else
563 563 rowCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
564 564 for (int k = m_mapper->first(); k < m_mapper->first() + rowCount; k++) {
565 565 m_categories << m_model->data(m_model->index(k, m_mapper->mapCategories()), Qt::DisplayRole).toString();
566 566 }
567 567
568 568 int lastAvailableBarSet = qMin(m_model->columnCount() - 1, m_mapper->mapBarTop());
569 569 for (int i = m_mapper->mapBarBottom(); i <= lastAvailableBarSet; i++) {
570 570 // for (int i = m_mapper->mapBarBottom(); i <= m_mapper->mapBarTop(); i++) {
571 571 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
572 572 for(int m = m_mapper->first(); m < m_mapper->first() + rowCount; m++)
573 573 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
574 574 q->append(barSet);
575 575 }
576 576 } else {
577 577 if (m_mapCategories >= m_model->rowCount())
578 578 return;
579 579 int columnCount = 0;
580 580 if(m_mapper->count() == -1)
581 581 columnCount = m_model->columnCount() - m_mapper->first();
582 582 else
583 583 columnCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
584 584 for (int k = m_mapper->first(); k < m_mapper->first() + columnCount; k++) {
585 585 m_categories << m_model->data(m_model->index(m_mapper->mapCategories(), k), Qt::DisplayRole).toString();
586 586 }
587 587
588 588 int lastAvailableBarSet = qMin(m_model->rowCount() - 1, m_mapper->mapBarTop());
589 589 for (int i = m_mapper->mapBarBottom(); i <= lastAvailableBarSet; i++) {
590 590 // for (int i = m_mapper->mapBarBottom(); i <= m_mapper->mapBarTop(); i++) {
591 591 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString());
592 592 for(int m = m_mapper->first(); m < m_mapper->first() + columnCount; m++)
593 593 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
594 594 q->append(barSet);
595 595 }
596 596 }
597 597 emit restructuredBars();
598 598 // emit updatedBars();
599 599 }
600 600
601 601 void QBarSeriesPrivate::barsetChanged()
602 602 {
603 603 emit updatedBars();
604 604 }
605 605
606 606 void QBarSeriesPrivate::scaleDomain(Domain& domain)
607 607 {
608 608 qreal minX(domain.minX());
609 609 qreal minY(domain.minY());
610 610 qreal maxX(domain.maxX());
611 611 qreal maxY(domain.maxY());
612 612 int tickXCount(domain.tickXCount());
613 613 int tickYCount(domain.tickYCount());
614 614
615 615 qreal x = categoryCount();
616 616 qreal y = max();
617 minX = qMin(minX, x);
617 minX = qMin(minX, x) - 0.5;
618 618 minY = qMin(minY, y);
619 maxX = qMax(maxX, x);
619 maxX = qMax(maxX, x) - 0.5;
620 620 maxY = qMax(maxY, y);
621 621 tickXCount = x+1;
622 622
623 623 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
624 624 }
625 625
626 626 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
627 627 {
628 628 Q_Q(QBarSeries);
629 629
630 630 BarChartItem* bar = new BarChartItem(q,presenter);
631 631 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
632 632 presenter->animator()->addAnimation(bar);
633 633 }
634 634 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
635 635 return bar;
636 636
637 637 }
638 638
639 639 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
640 640 {
641 641 Q_Q(QBarSeries);
642 642 QList<LegendMarker*> markers;
643 643 foreach(QBarSet* set, q->barSets()) {
644 644 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
645 645 markers << marker;
646 646 }
647 647
648 648 return markers;
649 649 }
650 650
651 651 #include "moc_qbarseries.cpp"
652 652 #include "moc_qbarseries_p.cpp"
653 653
654 654 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,109 +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 #include "qgroupedbarseries.h"
22 22 #include "qgroupedbarseries_p.h"
23 23 #include "groupedbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 /*!
31 31 \class QGroupedBarSeries
32 32 \brief part of QtCommercial chart API.
33 33 \mainclass
34 34
35 35 QGroupedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
36 36 as groups, where bars in same category are grouped next to each other. QGroupedBarSeries groups the data
37 37 from sets to categories, which are defined by a QStringList.
38 38
39 39 See the \l {GroupedbarChart Example} {grouped bar chart example} to learn how to create a grouped bar chart.
40 40 \image examples_groupedbarchart.png
41 41
42 42 \sa QBarSet, QPercentBarSeries, QBarSeries, QStackedBarSeries
43 43 */
44 44
45 45 /*!
46 46 \fn virtual QSeriesType QGroupedBarSeries::type() const
47 47 \brief Returns type of series.
48 48 \sa QAbstractSeries, QSeriesType
49 49 */
50 50
51 51 /*!
52 52 Constructs empty QGroupedBarSeries.
53 53 QGroupedBarSeries is QObject which is a child of a \a parent.
54 54 */
55 55 QGroupedBarSeries::QGroupedBarSeries(QObject *parent)
56 56 : QBarSeries(*new QGroupedBarSeriesPrivate(this), parent)
57 57 {
58 58 }
59 59
60 60 QAbstractSeries::SeriesType QGroupedBarSeries::type() const
61 61 {
62 62 return QAbstractSeries::SeriesTypeGroupedBar;
63 63 }
64 64
65 65 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 66
67 67 QGroupedBarSeriesPrivate::QGroupedBarSeriesPrivate(QGroupedBarSeries *q) : QBarSeriesPrivate(q)
68 68 {
69 69
70 70 }
71 71
72 72 void QGroupedBarSeriesPrivate::scaleDomain(Domain& domain)
73 73 {
74 74 Q_Q(QGroupedBarSeries);
75 75 qreal minX(domain.minX());
76 76 qreal minY(domain.minY());
77 77 qreal maxX(domain.maxX());
78 78 qreal maxY(domain.maxY());
79 79 int tickXCount(domain.tickXCount());
80 80 int tickYCount(domain.tickYCount());
81 81
82 82 qreal x = q->categoryCount();
83 83 qreal y = max();
84 minX = qMin(minX, x);
84 minX = qMin(minX, x) - 0.5;
85 85 minY = qMin(minY, y);
86 maxX = qMax(maxX, x);
86 maxX = qMax(maxX, x) - 0.5;
87 87 maxY = qMax(maxY, y);
88 88 tickXCount = x+1;
89 89
90 90 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
91 91 }
92 92
93 93
94 94 Chart* QGroupedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
95 95 {
96 96 Q_Q(QGroupedBarSeries);
97 97
98 98 GroupedBarChartItem* bar = new GroupedBarChartItem(q,presenter);
99 99 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
100 100 presenter->animator()->addAnimation(bar);
101 101 }
102 102 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
103 103 return bar;
104 104 }
105 105
106 106 #include "moc_qgroupedbarseries.cpp"
107 107
108 108 QTCOMMERCIALCHART_END_NAMESPACE
109 109
@@ -1,108 +1,108
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 "qpercentbarseries.h"
22 22 #include "qpercentbarseries_p.h"
23 23 #include "percentbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 /*!
31 31 \class QPercentBarSeries
32 32 \brief part of QtCommercial chart API.
33 33 \mainclass
34 34
35 35 QPercentBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
36 36 as stacks, where each bar is shown as percentage of all bars in that category.
37 37 QPercentBarSeries groups the data from sets to categories, which are defined by a QStringList.
38 38
39 39 See the \l {PercentbarChart Example} {percent bar chart example} to learn how to create a percent bar chart.
40 40 \image examples_percentbarchart.png
41 41
42 42 \sa QBarSet, QStackedBarSeries, QBarSeries
43 43 */
44 44
45 45 /*!
46 46 \fn virtual QSeriesType QPercentBarSeries::type() const
47 47 \brief Returns type of series.
48 48 \sa QAbstractSeries, QSeriesType
49 49 */
50 50
51 51 /*!
52 52 Constructs empty QPercentBarSeries.
53 53 QPercentBarSeries is QObject which is a child of a \a parent.
54 54 */
55 55 QPercentBarSeries::QPercentBarSeries(QObject *parent)
56 56 : QBarSeries(*new QPercentBarSeriesPrivate(this), parent)
57 57 {
58 58 }
59 59
60 60 QAbstractSeries::SeriesType QPercentBarSeries::type() const
61 61 {
62 62 return QAbstractSeries::SeriesTypePercentBar;
63 63 }
64 64
65 65 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 66
67 67 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QPercentBarSeries *q) : QBarSeriesPrivate(q)
68 68 {
69 69
70 70 }
71 71
72 72 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
73 73 {
74 74 Q_Q(QPercentBarSeries);
75 75 qreal minX(domain.minX());
76 76 qreal minY(domain.minY());
77 77 qreal maxX(domain.maxX());
78 78 qreal maxY(domain.maxY());
79 79 int tickXCount(domain.tickXCount());
80 80 int tickYCount(domain.tickYCount());
81 81
82 82 qreal x = q->categoryCount();
83 minX = qMin(minX, x);
84 maxX = qMax(maxX, x);
83 minX = qMin(minX, x) - 0.5;
84 maxX = qMax(maxX, x) - 0.5;
85 85 minY = 0;
86 86 maxY = 100;
87 87 tickXCount = x+1;
88 88
89 89 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
90 90 }
91 91
92 92
93 93 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
94 94 {
95 95 Q_Q(QPercentBarSeries);
96 96
97 97 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
98 98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
99 99 presenter->animator()->addAnimation(bar);
100 100 }
101 101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
102 102 return bar;
103 103 }
104 104
105 105 #include "moc_qpercentbarseries.cpp"
106 106
107 107 QTCOMMERCIALCHART_END_NAMESPACE
108 108
@@ -1,109 +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 #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 "chartanimator_p.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 /*!
31 31 \class QStackedBarSeries
32 32 \brief part of QtCommercial chart API.
33 33 \mainclass
34 34
35 35 QStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
36 36 as stacks, where bars in same category are stacked on top of each other.
37 37 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
38 38
39 39 See the \l {StackedbarChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
40 40 \image examples_stackedbarchart.png
41 41
42 42 \sa QBarSet, QPercentBarSeries, QBarSeries
43 43 */
44 44
45 45 /*!
46 46 \fn virtual QSeriesType QStackedBarSeries::type() const
47 47 \brief Returns type of series.
48 48 \sa QAbstractSeries, QSeriesType
49 49 */
50 50
51 51 /*!
52 52 Constructs empty QStackedBarSeries.
53 53 QStackedBarSeries is QObject which is a child of a \a parent.
54 54 */
55 55 QStackedBarSeries::QStackedBarSeries(QObject *parent)
56 56 : QBarSeries(*new QStackedBarSeriesPrivate(this), parent)
57 57 {
58 58 }
59 59
60 60 QAbstractSeries::SeriesType QStackedBarSeries::type() const
61 61 {
62 62 return QAbstractSeries::SeriesTypeStackedBar;
63 63 }
64 64
65 65 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 66
67 67 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QStackedBarSeries *q) : QBarSeriesPrivate(q)
68 68 {
69 69
70 70 }
71 71
72 72 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
73 73 {
74 74 Q_Q(QStackedBarSeries);
75 75 qreal minX(domain.minX());
76 76 qreal minY(domain.minY());
77 77 qreal maxX(domain.maxX());
78 78 qreal maxY(domain.maxY());
79 79 int tickXCount(domain.tickXCount());
80 80 int tickYCount(domain.tickYCount());
81 81
82 82 qreal x = q->categoryCount();
83 83 qreal y = maxCategorySum();
84 minX = qMin(minX, x);
84 minX = qMin(minX, x) - 0.5;
85 85 minY = qMin(minY, y);
86 maxX = qMax(maxX, x);
86 maxX = qMax(maxX, x) - 0.5;
87 87 maxY = qMax(maxY, y);
88 88 tickXCount = x+1;
89 89
90 90 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
91 91 }
92 92
93 93
94 94 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
95 95 {
96 96 Q_Q(QStackedBarSeries);
97 97
98 98 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
99 99 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
100 100 presenter->animator()->addAnimation(bar);
101 101 }
102 102 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
103 103 return bar;
104 104 }
105 105
106 106 #include "moc_qstackedbarseries.cpp"
107 107
108 108 QTCOMMERCIALCHART_END_NAMESPACE
109 109
@@ -1,85 +1,88
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 "barlabel_p.h"
24 24 #include "qbarset_p.h"
25 25 #include "qbarseries_p.h"
26 26 #include "qbarset.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
31 31 BarChartItem(series, presenter)
32 32 {
33 33 }
34 34
35 35 QVector<QRectF> StackedBarChartItem::calculateLayout()
36 36 {
37 37 QVector<QRectF> layout;
38 38 // Use temporary qreals for accurancy
39 qreal categoryCount = m_series->categoryCount();
40 qreal setCount = m_series->barsetCount();
39 41
40 42 // Domain:
41 qreal range = m_domainMaxY - m_domainMinY;
42 qreal height = geometry().height();
43 43 qreal width = geometry().width();
44 qreal scale = (height / range);
45 qreal categotyCount = m_series->categoryCount();
46 qreal barWidth = width / (categotyCount * 2);
47 qreal xStep = width / categotyCount;
48 qreal xPos = xStep / 2 - barWidth / 2 + geometry().topLeft().x();
44 qreal height = geometry().height();
45 qreal rangeY = m_domainMaxY - m_domainMinY;
46 qreal rangeX = m_domainMaxX - m_domainMinX;
47 qreal scaleY = (height / rangeY);
48 qreal scaleX = (width / rangeX);
49 qreal categoryWidth = width / categoryCount;
50 qreal barWidth = categoryWidth / setCount - categoryWidth * m_series->d_func()->barMargin();
49 51
50 52 int itemIndex(0);
51 for (int category = 0; category < categotyCount; category++) {
52 qreal yPos = height + scale * m_domainMinY + geometry().topLeft().y();
53 for (int category = 0; category < categoryCount; category++) {
54 qreal yPos = height + rangeY * m_domainMinY + geometry().topLeft().y();
53 55 for (int set=0; set < m_series->barsetCount(); set++) {
54 56 QBarSet* barSet = m_series->d_func()->barsetAt(set);
55 57
56 qreal barHeight = barSet->at(category).y() * scale;
58 qreal xPos = (barSet->at(category).x() - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
59
60 qreal barHeight = barSet->at(category).y() * scaleY;
57 61 Bar* bar = m_bars.at(itemIndex);
58 62 bar->setPen(barSet->pen());
59 63 bar->setBrush(barSet->brush());
60 64 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
61 65 layout.append(rect);
62 66
63 67 BarLabel* label = m_labels.at(itemIndex);
64 68
65 69 if (!qFuzzyIsNull(barSet->at(category).y())) {
66 70 label->setText(QString::number(barSet->at(category).y()));
67 71 } else {
68 72 label->setText(QString(""));
69 73 }
70 74
71 75 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
72 76 ,yPos - barHeight/2 - label->boundingRect().height()/2);
73 77 label->setFont(barSet->labelFont());
74 78 itemIndex++;
75 79 yPos -= barHeight;
76 80 }
77 xPos += xStep;
78 81 }
79 82
80 83 return layout;
81 84 }
82 85
83 86 #include "moc_stackedbarchartitem_p.cpp"
84 87
85 88 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now