##// END OF EJS Templates
Fixed documentation issues in QML API
Tero Ahola -
r2331:d7e6106b698e
parent child
Show More
@@ -1,769 +1,765
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 "declarativechart.h"
22 22 #include <QPainter>
23 23 #include <QDeclarativeEngine>
24 24 #include "declarativelineseries.h"
25 25 #include "declarativeareaseries.h"
26 26 #include "declarativebarseries.h"
27 27 #include "declarativepieseries.h"
28 28 #include "declarativesplineseries.h"
29 29 #include "declarativescatterseries.h"
30 30 #include "qbarcategoryaxis.h"
31 31 #include "qvalueaxis.h"
32 32 #include "qcategoryaxis.h"
33 33 #include "qabstractseries_p.h"
34 34 #include "declarativemargins.h"
35 35 #include "chartdataset_p.h"
36 36 #include "declarativeaxes.h"
37 37 #include "qchart_p.h"
38 38
39 39 #ifndef QT_ON_ARM
40 40 #include "qdatetimeaxis.h"
41 41 #endif
42 42
43 43 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44 44
45 45 /*!
46 46 \qmlclass ChartView DeclarativeChart
47 47
48 48 ChartView element is the parent that is responsible for showing different chart series types.
49 49
50 50 The following QML shows how to create a simple chart with one pie series:
51 51 \snippet ../examples/qmlpiechart/qml/qmlpiechart/main.qml 1
52 52 \snippet ../examples/qmlpiechart/qml/qmlpiechart/main.qml 2
53 53 \snippet ../examples/qmlpiechart/qml/qmlpiechart/main.qml 3
54 54
55 55 \beginfloatleft
56 56 \image examples_qmlpiechart.png
57 57 \endfloat
58 58 \clearfloat
59 59 */
60 60
61 61 /*!
62 62 \qmlproperty Theme ChartView::theme
63 63 Theme defines the visual appearance of the chart, including for example colors, fonts, line
64 64 widths and chart background.
65 65 */
66 66
67 67 /*!
68 68 \qmlproperty Animation ChartView::animationOptions
69 69 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
70 70 ChartView.SeriesAnimations or ChartView.AllAnimations.
71 71 */
72 72
73 73 /*!
74 74 \qmlproperty Font ChartView::titleFont
75 75 The title font of the chart
76 76
77 77 See the \l {Font} {QML Font Element} for detailed documentation.
78 78 */
79 79
80 80 /*!
81 81 \qmlproperty string ChartView::title
82 82 The title of the chart, shown on top of the chart.
83 83 \sa ChartView::titleColor
84 84 */
85 85
86 86 /*!
87 87 \qmlproperty color ChartView::titleColor
88 88 The color of the title text.
89 89 */
90 90
91 91 /*!
92 92 \qmlproperty Legend ChartView::legend
93 93 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
94 94 */
95 95
96 96 /*!
97 97 \qmlproperty int ChartView::count
98 98 The count of series added to the chart.
99 99 */
100 100
101 101 /*!
102 102 \qmlproperty color ChartView::backgroundColor
103 103 The color of the chart's background. By default background color is defined by chart theme.
104 104 \sa ChartView::theme
105 105 */
106 106
107 107 /*!
108 108 \qmlproperty bool ChartView::dropShadowEnabled
109 109 The chart's border drop shadow. Set to true to enable drop shadow.
110 110 */
111 111
112 112 /*!
113 113 \qmlproperty real ChartView::topMargin
114 114 Deprecated. Use minimumMargins and plotArea instead.
115 115 */
116 116
117 117 /*!
118 118 \qmlproperty real ChartView::bottomMargin
119 119 Deprecated. Use minimumMargins and plotArea instead.
120 120 */
121 121
122 122 /*!
123 123 \qmlproperty real ChartView::leftMargin
124 124 Deprecated. Use minimumMargins and plotArea instead.
125 125 */
126 126
127 127 /*!
128 128 \qmlproperty real ChartView::rightMargin
129 129 Deprecated. Use minimumMargins and plotArea instead.
130 130 */
131 131
132 132 /*!
133 133 \qmlproperty Margins ChartView::minimumMargins
134 134 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
135 135 area of ChartView is used for drawing title, axes and legend. Please note that setting the
136 136 properties of minimumMargins may be bigger than the defined value, depending on other ChartView
137 137 properties that affect it's layout. If you need to know the actual plotting area used at any
138 138 given time, you can check ChartView::plotArea instead.
139 139 */
140 140
141 141 /*!
142 142 \qmlproperty rect ChartView::plotArea
143 143 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
144 144 margins.
145 145 \sa ChartView::minimumMargins
146 146 */
147 147
148 148 /*!
149 149 \qmlmethod AbstractSeries ChartView::series(int index)
150 150 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
151 151 the count property of the chart.
152 152 */
153 153
154 154 /*!
155 155 \qmlmethod AbstractSeries ChartView::series(string name)
156 156 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
157 157 */
158 158
159 159 /*!
160 160 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
161 161 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
162 162 optional axis \a axisY. For example:
163 163 \code
164 164 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
165 165 var myAxisX = chartView.axisX(lineSeries);
166 166 var myAxisY = chartView.axisY(lineSeries);
167 167 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
168 168 \endcode
169 169 */
170 170
171 171 /*!
172 172 \qmlmethod ChartView::removeSeries(AbstractSeries series)
173 173 Removes the \a series from the chart. The series object is also destroyed.
174 174 */
175 175
176 176 /*!
177 177 \qmlmethod ChartView::removeAllSeries()
178 178 Removes all series from the chart. All the series objects are also destroyed.
179 179 */
180 180
181 181 /*!
182 182 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
183 183 The x-axis of the series.
184 184 */
185 185
186 186 /*!
187 187 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
188 188 The y-axis of the series.
189 189 */
190 190
191 191 /*!
192 192 \qmlmethod ChartView::zoomY(real factor)
193 193 Zooms in by \a factor on the center of the chart.
194 194 */
195 195
196 196 /*!
197 197 \qmlmethod ChartView::scrollLeft(real pixels)
198 198 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
199 \sa ValueAxis::min, ValueAxis::max, BarCategoryAxis::min, BarCategoryAxis::max
200 199 */
201 200
202 201 /*!
203 202 \qmlmethod ChartView::scrollRight(real pixels)
204 203 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
205 \sa ValueAxis::min, ValueAxis::max, BarCategoryAxis::min, BarCategoryAxis::max
206 204 */
207 205
208 206 /*!
209 207 \qmlmethod ChartView::scrollUp(real pixels)
210 208 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
211 \sa ValueAxis::min, ValueAxis::max, BarCategoryAxis::min, BarCategoryAxis::max
212 209 */
213 210
214 211 /*!
215 212 \qmlmethod ChartView::scrollDown(real pixels)
216 213 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
217 \sa ValueAxis::min, ValueAxis::max, BarCategoryAxis::min, BarCategoryAxis::max
218 214 */
219 215
220 216 /*!
221 217 \qmlsignal ChartView::onPlotAreaChanged(rect plotArea)
222 218 The plot area of the chart has changed. This may happen for example, if you modify minimumMargins
223 219 or if you resize the chart, or if you modify font size related properties of the legend or chart
224 220 title.
225 221 */
226 222
227 223 /*!
228 224 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
229 225 The \a series has been added to the chart.
230 226 */
231 227
232 228 /*!
233 229 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
234 230 The \a series has been removed from the chart. Please note that \a series is no longer a valid
235 231 object after the signal handler has completed.
236 232 */
237 233
238 234 DeclarativeChart::DeclarativeChart(QDeclarativeItem *parent)
239 235 : QDeclarativeItem(parent),
240 236 m_chart(new QChart(this))
241 237 {
242 238 setFlag(QGraphicsItem::ItemHasNoContents, false);
243 239 m_margins = new DeclarativeMargins(this);
244 240 m_margins->setTop(m_chart->margins().top());
245 241 m_margins->setLeft(m_chart->margins().left());
246 242 m_margins->setRight(m_chart->margins().right());
247 243 m_margins->setBottom(m_chart->margins().bottom());
248 244 connect(m_margins, SIGNAL(topChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
249 245 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
250 246 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
251 247 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
252 248 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
253 249 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
254 250 }
255 251
256 252 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
257 253 {
258 254 emit seriesAdded(series);
259 255 }
260 256
261 257 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
262 258 {
263 259 m_chart->setMargins(QMargins(left, top, right, bottom));
264 260 emit minimumMarginsChanged();
265 261 emit plotAreaChanged(m_chart->plotArea());
266 262 }
267 263
268 264 DeclarativeChart::~DeclarativeChart()
269 265 {
270 266 delete m_chart;
271 267 }
272 268
273 269 void DeclarativeChart::childEvent(QChildEvent *event)
274 270 {
275 271 if (event->type() == QEvent::ChildAdded) {
276 272 if (qobject_cast<QAbstractSeries *>(event->child())) {
277 273 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
278 274 }
279 275 }
280 276 }
281 277
282 278 void DeclarativeChart::componentComplete()
283 279 {
284 280 foreach (QObject *child, children()) {
285 281 if (qobject_cast<QAbstractSeries *>(child)) {
286 282 // Add series to the chart
287 283 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
288 284 m_chart->addSeries(series);
289 285
290 286 // Connect to axis changed signals (unless this is a pie series)
291 287 if (!qobject_cast<DeclarativePieSeries *>(series)) {
292 288 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
293 289 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
294 290 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
295 291 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
296 292 }
297 293
298 294 initializeAxes(series);
299 295 }
300 296 }
301 297
302 298 QDeclarativeItem::componentComplete();
303 299 }
304 300
305 301 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
306 302 {
307 303 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
308 304 if (axis && s) {
309 305 if (!m_chart->axes(Qt::Horizontal).contains(axis))
310 306 m_chart->addAxis(axis, Qt::AlignBottom);
311 307 if (!s->attachedAxes().contains(axis))
312 308 s->attachAxis(axis);
313 309 } else {
314 310 qWarning() << "Trying to set axisX to null.";
315 311 }
316 312 }
317 313
318 314 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
319 315 {
320 316 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
321 317 if (axis && s) {
322 318 if (!m_chart->axes(Qt::Horizontal).contains(axis))
323 319 m_chart->addAxis(axis, Qt::AlignTop);
324 320 if (!s->attachedAxes().contains(axis))
325 321 s->attachAxis(axis);
326 322 } else {
327 323 qWarning() << "Trying to set axisXTop to null.";
328 324 }
329 325 }
330 326
331 327 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
332 328 {
333 329 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
334 330 if (axis && s) {
335 331 if (!m_chart->axes(Qt::Vertical).contains(axis))
336 332 m_chart->addAxis(axis, Qt::AlignLeft);
337 333 if (!s->attachedAxes().contains(axis))
338 334 s->attachAxis(axis);
339 335 } else {
340 336 qWarning() << "Trying to set axisY to null.";
341 337 }
342 338 }
343 339
344 340 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
345 341 {
346 342 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
347 343 if (axis && s) {
348 344 if (!m_chart->axes(Qt::Vertical).contains(axis))
349 345 m_chart->addAxis(axis, Qt::AlignRight);
350 346 if (!s->attachedAxes().contains(axis))
351 347 s->attachAxis(axis);
352 348 } else {
353 349 qWarning() << "Trying to set axisYRight to null.";
354 350 }
355 351 }
356 352
357 353 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
358 354 {
359 355 // qDebug() << "DeclarativeChart::geometryChanged" << newGeometry.width() << newGeometry.height();
360 356 if (newGeometry.isValid()) {
361 357 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
362 358 m_chart->resize(newGeometry.width(), newGeometry.height());
363 359 }
364 360 }
365 361 QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
366 362
367 363 // It would be better to trigger the plotAreaChanged signal from QChart::plotAreaChanged or
368 364 // similar. Since that kind of a signal is not clearly needed in the C++ API the work-around is
369 365 // to implement it here for the QML API purposes.
370 366 emit plotAreaChanged(m_chart->plotArea());
371 367 }
372 368
373 369 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
374 370 {
375 371 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
376 372 if (chartTheme != m_chart->theme())
377 373 m_chart->setTheme(chartTheme);
378 374 }
379 375
380 376 DeclarativeChart::Theme DeclarativeChart::theme()
381 377 {
382 378 return (DeclarativeChart::Theme) m_chart->theme();
383 379 }
384 380
385 381 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
386 382 {
387 383 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
388 384 if (animationOptions != m_chart->animationOptions())
389 385 m_chart->setAnimationOptions(animationOptions);
390 386 }
391 387
392 388 DeclarativeChart::Animation DeclarativeChart::animationOptions()
393 389 {
394 390 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
395 391 return DeclarativeChart::AllAnimations;
396 392 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
397 393 return DeclarativeChart::GridAxisAnimations;
398 394 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
399 395 return DeclarativeChart::SeriesAnimations;
400 396 else
401 397 return DeclarativeChart::NoAnimation;
402 398 }
403 399
404 400 void DeclarativeChart::setTitle(QString title)
405 401 {
406 402 if (title != m_chart->title())
407 403 m_chart->setTitle(title);
408 404 }
409 405 QString DeclarativeChart::title()
410 406 {
411 407 return m_chart->title();
412 408 }
413 409
414 410 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
415 411 {
416 412 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
417 413 if (axes.count())
418 414 return axes[0];
419 415 return 0;
420 416 }
421 417
422 418 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
423 419 {
424 420 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
425 421 if (axes.count())
426 422 return axes[0];
427 423 return 0;
428 424 }
429 425
430 426 QLegend *DeclarativeChart::legend()
431 427 {
432 428 return m_chart->legend();
433 429 }
434 430
435 431 void DeclarativeChart::setTitleColor(QColor color)
436 432 {
437 433 QBrush b = m_chart->titleBrush();
438 434 if (color != b.color()) {
439 435 b.setColor(color);
440 436 m_chart->setTitleBrush(b);
441 437 emit titleColorChanged(color);
442 438 }
443 439 }
444 440
445 441 QFont DeclarativeChart::titleFont() const
446 442 {
447 443 return m_chart->titleFont();
448 444 }
449 445
450 446 void DeclarativeChart::setTitleFont(const QFont &font)
451 447 {
452 448 m_chart->setTitleFont(font);
453 449 }
454 450
455 451 QColor DeclarativeChart::titleColor()
456 452 {
457 453 return m_chart->titleBrush().color();
458 454 }
459 455
460 456 void DeclarativeChart::setBackgroundColor(QColor color)
461 457 {
462 458 QBrush b = m_chart->backgroundBrush();
463 459 if (b.style() != Qt::SolidPattern || color != b.color()) {
464 460 b.setStyle(Qt::SolidPattern);
465 461 b.setColor(color);
466 462 m_chart->setBackgroundBrush(b);
467 463 emit backgroundColorChanged();
468 464 }
469 465 }
470 466
471 467 QColor DeclarativeChart::backgroundColor()
472 468 {
473 469 return m_chart->backgroundBrush().color();
474 470 }
475 471
476 472 int DeclarativeChart::count()
477 473 {
478 474 return m_chart->series().count();
479 475 }
480 476
481 477 void DeclarativeChart::setDropShadowEnabled(bool enabled)
482 478 {
483 479 if (enabled != m_chart->isDropShadowEnabled()) {
484 480 m_chart->setDropShadowEnabled(enabled);
485 481 dropShadowEnabledChanged(enabled);
486 482 }
487 483 }
488 484
489 485 bool DeclarativeChart::dropShadowEnabled()
490 486 {
491 487 return m_chart->isDropShadowEnabled();
492 488 }
493 489
494 490 qreal DeclarativeChart::topMargin()
495 491 {
496 492 qWarning() << "ChartView.topMargin is deprecated. Use minimumMargins and plotArea instead.";
497 493 return m_chart->plotArea().top();
498 494 }
499 495
500 496 qreal DeclarativeChart::bottomMargin()
501 497 {
502 498
503 499 qWarning() << "ChartView.bottomMargin is deprecated. Use minimumMargins and plotArea instead.";
504 500 return m_chart->plotArea().bottom();
505 501 }
506 502
507 503 qreal DeclarativeChart::leftMargin()
508 504 {
509 505 qWarning() << "ChartView.leftMargin is deprecated. Use minimumMargins and plotArea instead.";
510 506 return m_chart->plotArea().left();
511 507 }
512 508
513 509 qreal DeclarativeChart::rightMargin()
514 510 {
515 511 qWarning() << "ChartView.rightMargin is deprecated. Use minimumMargins and plotArea instead.";
516 512 return m_chart->plotArea().right();
517 513 }
518 514
519 515 void DeclarativeChart::zoom(qreal factor)
520 516 {
521 517 m_chart->zoom(factor);
522 518 }
523 519
524 520 void DeclarativeChart::scrollLeft(qreal pixels)
525 521 {
526 522 m_chart->scroll(-pixels, 0);
527 523 }
528 524
529 525 void DeclarativeChart::scrollRight(qreal pixels)
530 526 {
531 527 m_chart->scroll(pixels, 0);
532 528 }
533 529
534 530 void DeclarativeChart::scrollUp(qreal pixels)
535 531 {
536 532 m_chart->scroll(0, pixels);
537 533 }
538 534
539 535 void DeclarativeChart::scrollDown(qreal pixels)
540 536 {
541 537 m_chart->scroll(0, -pixels);
542 538 }
543 539
544 540 QDeclarativeListProperty<QAbstractAxis> DeclarativeChart::axes()
545 541 {
546 542 return QDeclarativeListProperty<QAbstractAxis>(this, 0,
547 543 &DeclarativeChart::axesAppendFunc,
548 544 &DeclarativeChart::axesCountFunc,
549 545 &DeclarativeChart::axesAtFunc);
550 546 }
551 547
552 548 void DeclarativeChart::axesAppendFunc(QDeclarativeListProperty<QAbstractAxis> *list, QAbstractAxis *element)
553 549 {
554 550 // Empty implementation
555 551 Q_UNUSED(list);
556 552 Q_UNUSED(element);
557 553 }
558 554
559 555 int DeclarativeChart::axesCountFunc(QDeclarativeListProperty<QAbstractAxis> *list)
560 556 {
561 557 if (qobject_cast<DeclarativeChart *>(list->object)) {
562 558 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
563 559 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
564 560 }
565 561 return 0;
566 562 }
567 563
568 564 QAbstractAxis *DeclarativeChart::axesAtFunc(QDeclarativeListProperty<QAbstractAxis> *list, int index)
569 565 {
570 566 if (qobject_cast<DeclarativeChart *>(list->object)) {
571 567 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
572 568 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
573 569 return axes.at(index);
574 570 }
575 571 return 0;
576 572 }
577 573
578 574 QAbstractSeries *DeclarativeChart::series(int index)
579 575 {
580 576 if (index < m_chart->series().count()) {
581 577 return m_chart->series().at(index);
582 578 }
583 579 return 0;
584 580 }
585 581
586 582 QAbstractSeries *DeclarativeChart::series(QString seriesName)
587 583 {
588 584 foreach (QAbstractSeries *series, m_chart->series()) {
589 585 if (series->name() == seriesName)
590 586 return series;
591 587 }
592 588 return 0;
593 589 }
594 590
595 591 QAbstractSeries *DeclarativeChart::createSeries(DeclarativeChart::SeriesType type, QString name)
596 592 {
597 593 return createSeries(type, name, 0, 0);
598 594 }
599 595
600 596 QAbstractSeries *DeclarativeChart::createSeries(DeclarativeChart::SeriesType type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
601 597 {
602 598 QAbstractSeries *series = 0;
603 599
604 600 switch (type) {
605 601 case DeclarativeChart::SeriesTypeLine:
606 602 series = new DeclarativeLineSeries();
607 603 break;
608 604 case DeclarativeChart::SeriesTypeArea: {
609 605 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
610 606 area->setUpperSeries(new DeclarativeLineSeries());
611 607 series = area;
612 608 break;
613 609 }
614 610 case DeclarativeChart::SeriesTypeStackedBar:
615 611 series = new DeclarativeStackedBarSeries();
616 612 break;
617 613 case DeclarativeChart::SeriesTypePercentBar:
618 614 series = new DeclarativePercentBarSeries();
619 615 break;
620 616 case DeclarativeChart::SeriesTypeBar:
621 617 series = new DeclarativeBarSeries();
622 618 break;
623 619 case DeclarativeChart::SeriesTypeHorizontalBar:
624 620 series = new DeclarativeHorizontalBarSeries();
625 621 break;
626 622 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
627 623 series = new DeclarativeHorizontalPercentBarSeries();
628 624 break;
629 625 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
630 626 series = new DeclarativeHorizontalStackedBarSeries();
631 627 break;
632 628 case DeclarativeChart::SeriesTypePie:
633 629 series = new DeclarativePieSeries();
634 630 break;
635 631 case DeclarativeChart::SeriesTypeScatter:
636 632 series = new DeclarativeScatterSeries();
637 633 break;
638 634 case DeclarativeChart::SeriesTypeSpline:
639 635 series = new DeclarativeSplineSeries();
640 636 break;
641 637 default:
642 638 qWarning() << "Illegal series type";
643 639 }
644 640
645 641 if (series) {
646 642 // Connect to axis changed signals (unless this is a pie series)
647 643 if (!qobject_cast<DeclarativePieSeries *>(series)) {
648 644 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
649 645 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
650 646 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
651 647 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
652 648 }
653 649
654 650 series->setName(name);
655 651 m_chart->addSeries(series);
656 652
657 653 if (axisX)
658 654 setAxisX(axisX, series);
659 655 if (axisY)
660 656 setAxisY(axisY, series);
661 657
662 658 if (series->attachedAxes().count() < 2)
663 659 initializeAxes(series);
664 660 }
665 661
666 662 return series;
667 663 }
668 664
669 665 void DeclarativeChart::removeSeries(QAbstractSeries *series)
670 666 {
671 667 if (series)
672 668 m_chart->removeSeries(series);
673 669 else
674 670 qWarning("removeSeries: cannot remove null");
675 671 }
676 672
677 673 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
678 674 {
679 675 if (axis)
680 676 m_chart->setAxisX(axis, series);
681 677 }
682 678
683 679 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
684 680 {
685 681 if (axis)
686 682 m_chart->setAxisY(axis, series);
687 683 }
688 684
689 685 void DeclarativeChart::createDefaultAxes()
690 686 {
691 687 qWarning() << "ChartView.createDefaultAxes() is deprecated. Axes are created automatically.";
692 688 }
693 689
694 690 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
695 691 {
696 692 if (!series) {
697 693 qWarning() << "No axis type defined for null series";
698 694 return 0;
699 695 }
700 696
701 697 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
702 698 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
703 699 return existingAxis;
704 700 }
705 701
706 702 switch (series->d_ptr->defaultAxisType(orientation)) {
707 703 case QAbstractAxis::AxisTypeValue:
708 704 return new QValueAxis(this);
709 705 case QAbstractAxis::AxisTypeBarCategory:
710 706 return new QBarCategoryAxis(this);
711 707 case QAbstractAxis::AxisTypeCategory:
712 708 return new QCategoryAxis(this);
713 709 #ifndef QT_ON_ARM
714 710 case QAbstractAxis::AxisTypeDateTime:
715 711 return new QDateTimeAxis(this);
716 712 #endif
717 713 default:
718 714 // assume AxisTypeNoAxis
719 715 return 0;
720 716 }
721 717 }
722 718
723 719 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
724 720 {
725 721 if (qobject_cast<DeclarativeLineSeries *>(series))
726 722 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
727 723 else if (qobject_cast<DeclarativeScatterSeries *>(series))
728 724 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
729 725 else if (qobject_cast<DeclarativeSplineSeries *>(series))
730 726 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
731 727 else if (qobject_cast<DeclarativeAreaSeries *>(series))
732 728 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
733 729 else if (qobject_cast<DeclarativeBarSeries *>(series))
734 730 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
735 731 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
736 732 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
737 733 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
738 734 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
739 735 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
740 736 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
741 737 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
742 738 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
743 739 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
744 740 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
745 741 // else: do nothing
746 742 }
747 743
748 744 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
749 745 {
750 746 // Initialize axis X
751 747 if (axes->axisX())
752 748 axes->emitAxisXChanged();
753 749 else if (axes->axisXTop())
754 750 axes->emitAxisXTopChanged();
755 751 else
756 752 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
757 753
758 754 // Initialize axis Y
759 755 if (axes->axisY())
760 756 axes->emitAxisYChanged();
761 757 else if (axes->axisYRight())
762 758 axes->emitAxisYRightChanged();
763 759 else
764 760 axes->setAxisY(defaultAxis(Qt::Vertical, series));
765 761 }
766 762
767 763 #include "moc_declarativechart.cpp"
768 764
769 765 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,599 +1,598
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 "qbarcategoryaxis.h"
22 22 #include "qbarcategoryaxis_p.h"
23 23 #include "chartbarcategoryaxisx_p.h"
24 24 #include "chartbarcategoryaxisy_p.h"
25 25 #include "abstractdomain_p.h"
26 26 #include "qchart.h"
27 27 #include <qmath.h>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 /*!
31 31 \class QBarCategoryAxis
32 32 \brief The QBarCategoryAxis class is used for manipulating chart's axis.
33 33 \mainclass
34 34
35 35 BarCategoryAxis can be setup to show axis line with tick marks, grid lines and shades.
36 36 Categories are drawn between ticks. Note that you can use this also with lineseries too.
37 37 See the \l {Line and BarChart Example} {Line and BarChart Example} to learn how to do that.
38 38
39 39 Example code on how to use QBarCategoryAxis.
40 40 \code
41 41 QChartView *chartView = new QChartView;
42 42 QBarSeries *series = new QBarSeries;
43 43 // ...
44 44 chartView->chart()->addSeries(series);
45 45 chartView->chart()->createDefaultAxes();
46 46
47 47 QBarCategoryAxis *axisX = new QBarCategoryAxis;
48 48 QStringList categories;
49 49 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
50 50 axisX->append(categories);
51 51 axisX->setRange("Feb", "May");
52 52 chartView->chart()->setAxisX(axisX, series);
53 53 \endcode
54 54 */
55 55
56 56 /*!
57 57 \qmlclass BarCategoryAxis QBarCategoryAxis
58 58 \inherits AbstractAxis
59 59 \brief The Axis element is used for manipulating chart's axes.
60 60
61 61 Axis can be setup to show axis line with tick marks, grid lines and shades.
62 62 Categories are drawn between ticks. Note that you can use this also with lineseries too.
63 63
64 64 To access BarCategoryAxis you can use ChartView API. For example:
65 65 \code
66 66 ChartView {
67 67 BarCategoryAxis {
68 68 id: categoryAxis
69 69 categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ]
70 70 }
71 71 // Add a few series...
72 72 }
73 73 \endcode
74 74 */
75 75
76 76 /*!
77 77 \property QBarCategoryAxis::categories
78 78 Defines the categories of axis
79 79 */
80 80 /*!
81 81 \qmlproperty QStringList BarCategoryAxis::categories
82 82 Defines the categories of axis
83 83 */
84 84
85 85 /*!
86 86 \property QBarCategoryAxis::min
87 87 Defines the minimum value on the axis.
88 88 */
89 89 /*!
90 \qmlproperty QString Bar if (d->m_chart)
91 d->m_chart->removeAxis(this);CategoryAxis::min
90 \qmlproperty string BarCategoryAxis::min
92 91 Defines the minimum value on the axis.
93 92 */
94 93
95 94 /*!
96 95 \property QBarCategoryAxis::max
97 96 Defines the maximum value on the axis.
98 97 */
99 98 /*!
100 \qmlproperty QString BarCategoryAxis::max
99 \qmlproperty string BarCategoryAxis::max
101 100 Defines the maximum value on the axis.
102 101 */
103 102
104 103 /*!
105 104 \property QBarCategoryAxis::count
106 105 The count of categories.
107 106 */
108 107 /*!
109 108 \qmlproperty int BarCategoryAxis::count
110 109 The count of categories.
111 110 */
112 111
113 112 /*!
114 113 \fn void QBarCategoryAxis::categoriesChanged()
115 114 Axis emits signal when the categories of the axis has changed.
116 115 */
117 116
118 117 /*!
119 118 \fn void QBarCategoryAxis::minChanged(const QString &min)
120 119 Axis emits signal when \a min of axis has changed.
121 120 */
122 121 /*!
123 122 \qmlsignal BarCategoryAxis::onMinChanged(const QString &min)
124 123 Axis emits signal when \a min of axis has changed.
125 124 */
126 125
127 126 /*!
128 127 \fn void QBarCategoryAxis::maxChanged(const QString &max)
129 128 Axis emits signal when \a max of axis has changed.
130 129 */
131 130 /*!
132 131 \qmlsignal BarCategoryAxis::onMaxChanged(const QString &max)
133 132 Axis emits signal when \a max of axis has changed.
134 133 */
135 134
136 135 /*!
137 136 \fn void QBarCategoryAxis::countChanged()
138 137 Axis emits signal when the count of categories has changed.
139 138 */
140 139 /*!
141 140 \qmlsignal BarCategoryAxis::onCountChanged()
142 141 Axis emits signal when the count of categories has changed.
143 142 */
144 143
145 144 /*!
146 145 \fn void QBarCategoryAxis::rangeChanged(const QString &min, const QString &max)
147 146 Axis emits signal when \a min or \a max of axis has changed.
148 147 */
149 148
150 149 /*!
151 150 Constructs an axis object which is a child of \a parent.
152 151 */
153 152 QBarCategoryAxis::QBarCategoryAxis(QObject *parent):
154 153 QAbstractAxis(*new QBarCategoryAxisPrivate(this), parent)
155 154 {
156 155 }
157 156
158 157 /*!
159 158 Destroys the object
160 159 */
161 160 QBarCategoryAxis::~QBarCategoryAxis()
162 161 {
163 162 Q_D(QBarCategoryAxis);
164 163 if (d->m_chart)
165 164 d->m_chart->removeAxis(this);
166 165 }
167 166
168 167 /*!
169 168 \internal
170 169 */
171 170 QBarCategoryAxis::QBarCategoryAxis(QBarCategoryAxisPrivate &d, QObject *parent)
172 171 : QAbstractAxis(d, parent)
173 172 {
174 173
175 174 }
176 175
177 176 /*!
178 177 Appends \a categories to axis. A maximum of the axis will be changed to last category in \a categories.
179 178 If there were no categories previously defined, minimum of axis will be also changed to first category in \a categories.
180 179 A category has to be valid QStrings and can not be duplicated. Duplicated categories will not be appended.
181 180 */
182 181 void QBarCategoryAxis::append(const QStringList &categories)
183 182 {
184 183 if (categories.isEmpty())
185 184 return;
186 185
187 186 Q_D(QBarCategoryAxis);
188 187
189 188 int count = d->m_categories.count();
190 189
191 190 foreach(QString category, categories) {
192 191 if (!d->m_categories.contains(category) && !category.isNull()) {
193 192 d->m_categories.append(category);
194 193 }
195 194 }
196 195
197 196 if (d->m_categories.count() == count)
198 197 return;
199 198
200 199 if (count == 0)
201 200 setRange(d->m_categories.first(), d->m_categories.last());
202 201 else
203 202 setRange(d->m_minCategory, d->m_categories.last());
204 203
205 204 emit categoriesChanged();
206 205 emit countChanged();
207 206 }
208 207
209 208 /*!
210 209 Appends \a category to axis. A maximum of the axis will be changed to last \a category.
211 210 If there were no categories previously defined, minimum of axis will be also changed to \a category.
212 211 A \a category has to be valid QStrings and can not be duplicated. Duplicated categories will not be appended.
213 212 */
214 213 void QBarCategoryAxis::append(const QString &category)
215 214 {
216 215 Q_D(QBarCategoryAxis);
217 216
218 217 int count = d->m_categories.count();
219 218
220 219 if (!d->m_categories.contains(category) && !category.isNull())
221 220 d->m_categories.append(category);
222 221
223 222 if (d->m_categories.count() == count)
224 223 return;
225 224
226 225 if (count == 0)
227 226 setRange(d->m_categories.last(), d->m_categories.last());
228 227 else
229 228 setRange(d->m_minCategory, d->m_categories.last());
230 229
231 230 emit categoriesChanged();
232 231 emit countChanged();
233 232 }
234 233
235 234 /*!
236 235 Removes \a category from axis. Removing category which is currently maximum or minimum
237 236 will affect the axis range.
238 237 */
239 238 void QBarCategoryAxis::remove(const QString &category)
240 239 {
241 240 Q_D(QBarCategoryAxis);
242 241
243 242 if (d->m_categories.contains(category)) {
244 243 d->m_categories.removeAt(d->m_categories.indexOf(category));
245 244 if (!d->m_categories.isEmpty()) {
246 245 if (d->m_minCategory == category) {
247 246 setRange(d->m_categories.first(), d->m_maxCategory);
248 247 } else if (d->m_maxCategory == category) {
249 248 setRange(d->m_minCategory, d->m_categories.last());
250 249 } else {
251 250 d->updateCategoryDomain();
252 251 //TODO:: d->emitUpdated();
253 252 }
254 253 } else {
255 254 setRange(QString::null, QString::null);
256 255 }
257 256 emit categoriesChanged();
258 257 emit countChanged();
259 258 }
260 259 }
261 260
262 261 /*!
263 262 Inserts \a category to axis at \a index. A \a category has to be valid QStrings and can not be duplicated.
264 263 If \a category is prepended or appended to categories, minimum and maximum of axis is updated accordingly.
265 264 */
266 265 void QBarCategoryAxis::insert(int index, const QString &category)
267 266 {
268 267 Q_D(QBarCategoryAxis);
269 268
270 269 int count = d->m_categories.count();
271 270
272 271 if (!d->m_categories.contains(category) && !category.isNull())
273 272 d->m_categories.insert(index, category);
274 273
275 274 if (d->m_categories.count() == count)
276 275 return;
277 276
278 277 if (count == 0) {
279 278 setRange(d->m_categories.first(), d->m_categories.first());
280 279 } else if (index == 0) {
281 280 setRange(d->m_categories.first(), d->m_maxCategory);
282 281 } else if (index == count) {
283 282 setRange(d->m_minCategory, d->m_categories.last());
284 283 } else {
285 284 d->updateCategoryDomain();
286 285 //TODO:: d->emitUpdated();
287 286 }
288 287
289 288 emit categoriesChanged();
290 289 emit countChanged();
291 290 }
292 291
293 292 /*!
294 293 Replaces \a oldCategory with \a newCategory. If \a oldCategory does not exits on the axis nothing is done.
295 294 A \a newCategory has to be valid QStrings and can not be duplicated. In case of replacing minimum or maximum category,
296 295 minimum and maximum of axis is updated accordingly.
297 296 */
298 297 void QBarCategoryAxis::replace(const QString &oldCategory, const QString &newCategory)
299 298 {
300 299 Q_D(QBarCategoryAxis);
301 300
302 301 int pos = d->m_categories.indexOf(oldCategory);
303 302
304 303 if (pos != -1 && !d->m_categories.contains(newCategory) && !newCategory.isNull()) {
305 304 d->m_categories.replace(pos, newCategory);
306 305 if (d->m_minCategory == oldCategory) {
307 306 setRange(newCategory, d->m_maxCategory);
308 307 } else if (d->m_maxCategory == oldCategory) {
309 308 setRange(d->m_minCategory, newCategory);
310 309 } else {
311 310 //TODO:: d->emitUpdated();
312 311 }
313 312 emit categoriesChanged();
314 313 emit countChanged();
315 314 }
316 315 }
317 316
318 317 /*!
319 318 Removes all categories. Sets the maximum and minimum of the axis's range to QString::null.
320 319 */
321 320 void QBarCategoryAxis::clear()
322 321 {
323 322 Q_D(QBarCategoryAxis);
324 323 d->m_categories.clear();
325 324 setRange(QString::null, QString::null);
326 325 emit categoriesChanged();
327 326 emit countChanged();
328 327 }
329 328
330 329 /*!
331 330 Set \a categories and discards the old ones, range of axis is adjusted to match first and last category in \a categories.
332 331 A category has to be valid QStrings and can not be duplicated.
333 332 */
334 333 void QBarCategoryAxis::setCategories(const QStringList &categories)
335 334 {
336 335 Q_D(QBarCategoryAxis);
337 336 d->m_categories.clear();
338 337 d->m_minCategory = QString::null;
339 338 d->m_maxCategory = QString::null;
340 339 d->m_min = 0;
341 340 d->m_max = 0;
342 341 d->m_count = 0;
343 342 append(categories);
344 343 }
345 344
346 345 /*!
347 346 Returns categories
348 347 */
349 348 QStringList QBarCategoryAxis::categories()
350 349 {
351 350 Q_D(QBarCategoryAxis);
352 351 return d->m_categories;
353 352 }
354 353
355 354 /*!
356 355 Returns number of categories.
357 356 */
358 357 int QBarCategoryAxis::count() const
359 358 {
360 359 Q_D(const QBarCategoryAxis);
361 360 return d->m_categories.count();
362 361 }
363 362
364 363 /*!
365 364 Returns category at \a index. Index must be valid.
366 365 */
367 366 QString QBarCategoryAxis::at(int index) const
368 367 {
369 368 Q_D(const QBarCategoryAxis);
370 369 return d->m_categories.at(index);
371 370 }
372 371
373 372 /*!
374 373 Sets minimum category to \a min.
375 374 */
376 375 void QBarCategoryAxis::setMin(const QString &min)
377 376 {
378 377 Q_D(QBarCategoryAxis);
379 378 d->setRange(min, d->m_maxCategory);
380 379 }
381 380
382 381 /*!
383 382 Returns minimum category.
384 383 */
385 384 QString QBarCategoryAxis::min() const
386 385 {
387 386 Q_D(const QBarCategoryAxis);
388 387 return d->m_minCategory;
389 388 }
390 389
391 390 /*!
392 391 Sets maximum category to \a max.
393 392 */
394 393 void QBarCategoryAxis::setMax(const QString &max)
395 394 {
396 395 Q_D(QBarCategoryAxis);
397 396 d->setRange(d->m_minCategory, max);
398 397 }
399 398
400 399 /*!
401 400 Returns maximum category
402 401 */
403 402 QString QBarCategoryAxis::max() const
404 403 {
405 404 Q_D(const QBarCategoryAxis);
406 405 return d->m_maxCategory;
407 406 }
408 407
409 408 /*!
410 409 Sets range from \a minCategory to \a maxCategory
411 410 */
412 411 void QBarCategoryAxis::setRange(const QString &minCategory, const QString &maxCategory)
413 412 {
414 413 Q_D(QBarCategoryAxis);
415 414 d->setRange(minCategory,maxCategory);
416 415 }
417 416
418 417 /*!
419 418 Returns the type of the axis
420 419 */
421 420 QAbstractAxis::AxisType QBarCategoryAxis::type() const
422 421 {
423 422 return AxisTypeBarCategory;
424 423 }
425 424
426 425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
427 426
428 427 QBarCategoryAxisPrivate::QBarCategoryAxisPrivate(QBarCategoryAxis *q)
429 428 : QAbstractAxisPrivate(q),
430 429 m_min(0.0),
431 430 m_max(0.0),
432 431 m_count(0)
433 432 {
434 433
435 434 }
436 435
437 436 QBarCategoryAxisPrivate::~QBarCategoryAxisPrivate()
438 437 {
439 438
440 439 }
441 440
442 441 void QBarCategoryAxisPrivate::setMin(const QVariant &min)
443 442 {
444 443 setRange(min, m_maxCategory);
445 444 }
446 445
447 446 void QBarCategoryAxisPrivate::setMax(const QVariant &max)
448 447 {
449 448 setRange(m_minCategory, max);
450 449 }
451 450
452 451 void QBarCategoryAxisPrivate::setRange(const QVariant &min, const QVariant &max)
453 452 {
454 453 QString value1 = min.toString();
455 454 QString value2 = max.toString();
456 455 setRange(value1, value2);
457 456 }
458 457
459 458 void QBarCategoryAxisPrivate::setRange(qreal min, qreal max)
460 459 {
461 460 Q_Q(QBarCategoryAxis);
462 461
463 462 bool categoryChanged = false;
464 463 bool changed = false;
465 464
466 465 if (min > max)
467 466 return;
468 467
469 468 if (!qFuzzyIsNull(m_min - min)) {
470 469 m_min = min;
471 470 changed = true;
472 471
473 472 int imin = m_min + 0.5;
474 473 if (imin >= 0 && imin < m_categories.count()) {
475 474 QString minCategory = m_categories.at(imin);
476 475 if (m_minCategory != minCategory && !minCategory.isEmpty()) {
477 476 m_minCategory = minCategory;
478 477 categoryChanged = true;
479 478 emit q->minChanged(minCategory);
480 479 }
481 480 }
482 481
483 482 }
484 483
485 484 if (!qFuzzyIsNull(m_max - max)) {
486 485 m_max = max;
487 486 changed = true;
488 487
489 488 int imax = m_max - 0.5;
490 489 if (imax >= 0 && imax < m_categories.count()) {
491 490 QString maxCategory = m_categories.at(imax);
492 491 if (m_maxCategory != maxCategory && !maxCategory.isEmpty()) {
493 492 m_maxCategory = maxCategory;
494 493 categoryChanged = true;
495 494 emit q->maxChanged(maxCategory);
496 495 }
497 496 }
498 497 }
499 498
500 499 if (categoryChanged){
501 500 emit q->rangeChanged(m_minCategory, m_maxCategory);
502 501 }
503 502
504 503 if (changed) {
505 504 emit rangeChanged(m_min,m_max);
506 505 }
507 506 }
508 507
509 508 void QBarCategoryAxisPrivate::setRange(const QString &minCategory, const QString &maxCategory)
510 509 {
511 510 Q_Q(QBarCategoryAxis);
512 511 bool changed = false;
513 512
514 513 //special case in case or clearing all categories
515 514 if (minCategory.isNull() && maxCategory.isNull()) {
516 515 m_minCategory = minCategory;
517 516 m_maxCategory = maxCategory;
518 517 m_min = 0;
519 518 m_max = 0;
520 519 m_count = 0;
521 520 emit q->minChanged(minCategory);
522 521 emit q->maxChanged(maxCategory);
523 522 emit q->rangeChanged(m_minCategory, m_maxCategory);
524 523 emit rangeChanged(m_min,m_max);
525 524 }
526 525
527 526 if (m_categories.indexOf(maxCategory) < m_categories.indexOf(minCategory))
528 527 return;
529 528
530 529 if (!minCategory.isEmpty() && m_minCategory != minCategory && m_categories.contains(minCategory)) {
531 530 m_minCategory = minCategory;
532 531 m_min = m_categories.indexOf(m_minCategory) - 0.5;
533 532 changed = true;
534 533 emit q->minChanged(minCategory);
535 534 }
536 535
537 536 if (!maxCategory.isEmpty() && m_maxCategory != maxCategory && m_categories.contains(maxCategory)) {
538 537 m_maxCategory = maxCategory;
539 538 m_max = m_categories.indexOf(m_maxCategory) + 0.5;
540 539 changed = true;
541 540 emit q->maxChanged(maxCategory);
542 541 }
543 542
544 543 if (changed) {
545 544 m_count = m_max - m_min;
546 545 emit q->rangeChanged(m_minCategory, m_maxCategory);
547 546 emit rangeChanged(m_min,m_max);
548 547 }
549 548 }
550 549
551 550 void QBarCategoryAxisPrivate::initializeGraphics(QGraphicsItem* parent)
552 551 {
553 552 Q_Q(QBarCategoryAxis);
554 553 ChartAxis* axis(0);
555 554 if (orientation() == Qt::Vertical)
556 555 axis = new ChartBarCategoryAxisY(q,parent);
557 556 if (orientation() == Qt::Horizontal)
558 557 axis = new ChartBarCategoryAxisX(q,parent);
559 558
560 559 m_item.reset(axis);
561 560 QAbstractAxisPrivate::initializeGraphics(parent);
562 561 }
563 562
564 563 void QBarCategoryAxisPrivate::updateCategoryDomain()
565 564 {
566 565 m_min = m_categories.indexOf(m_minCategory) - 0.5;
567 566 m_max = m_categories.indexOf(m_maxCategory) + 0.5;
568 567 m_count = m_max - m_min;
569 568 }
570 569
571 570
572 571 void QBarCategoryAxisPrivate::initializeDomain(AbstractDomain *domain)
573 572 {
574 573 Q_Q(QBarCategoryAxis);
575 574 if (m_max == m_min) {
576 575 int min;
577 576 int max;
578 577 if (orientation() == Qt::Vertical) {
579 578 min = domain->minY() + 0.5;
580 579 max = domain->maxY() - 0.5;
581 580 } else {
582 581 min = domain->minX() + 0.5;
583 582 max = domain->maxX() - 0.5;
584 583 }
585 584
586 585 if (min > 0 && min < m_categories.count() && max > 0 && max < m_categories.count())
587 586 q->setRange(m_categories.at(min), m_categories.at(max));
588 587 } else {
589 588 if (orientation() == Qt::Vertical)
590 589 domain->setRangeY(m_min, m_max);
591 590 else
592 591 domain->setRangeX(m_min, m_max);
593 592 }
594 593 }
595 594
596 595 #include "moc_qbarcategoryaxis.cpp"
597 596 #include "moc_qbarcategoryaxis_p.cpp"
598 597
599 598 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,873 +1,901
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 "abstractdomain_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "charttheme_p.h"
28 28 #include "qvalueaxis.h"
29 29 #include "qbarcategoryaxis.h"
30 30 #include "qbarlegendmarker.h"
31 31 #include "baranimation_p.h"
32 32 #include "abstractbarchartitem_p.h"
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 /*!
37 37 \class QAbstractBarSeries
38 38 \brief Series for creating a bar chart
39 39 \mainclass
40 40
41 41 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
42 42 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
43 43 and y-value is the height of the bar. The category names are ignored with this series and x-axis
44 44 shows the x-values.
45 45
46 46 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
47 47 \image examples_barchart.png
48 48
49 49 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
50 50 */
51 51 /*!
52 52 \qmlclass AbstractBarSeries QAbstractBarSeries
53 53 \inherits QAbstractSeries
54 54
55 55 The following QML shows how to create a simple bar chart:
56 56 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
57 57
58 58 \beginfloatleft
59 59 \image demos_qmlchart6.png
60 60 \endfloat
61 61 \clearfloat
62 62 */
63 63
64 64 /*!
65 \qmlproperty AbstractAxis AbstractBarSeries::axisX
66 The x axis used for the series. If you leave both axisX and axisXTop undefined, a BarCategoriesAxis is created for
67 the series.
68 \sa axisXTop
69 */
70
71 /*!
72 \qmlproperty AbstractAxis AbstractBarSeries::axisY
73 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
74 the series.
75 \sa axisYRight
76 */
77
78 /*!
79 \qmlproperty AbstractAxis AbstractBarSeries::axisXTop
80 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
81 axisXTop, but not both.
82 \sa axisX
83 */
84
85 /*!
86 \qmlproperty AbstractAxis AbstractBarSeries::axisYRight
87 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
88 or axisYRight, but not both.
89 \sa axisY
90 */
91
92 /*!
65 93 \property QAbstractBarSeries::barWidth
66 94 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
67 95 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
68 96 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
69 97 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
70 98 \sa QBarSeries
71 99 */
72 100 /*!
73 101 \qmlproperty real AbstractBarSeries::barWidth
74 102 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
75 103 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
76 104 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
77 105 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
78 106 */
79 107
80 108 /*!
81 109 \property QAbstractBarSeries::count
82 110 Holds the number of sets in series.
83 111 */
84 112 /*!
85 113 \qmlproperty int AbstractBarSeries::count
86 114 Holds the number of sets in series.
87 115 */
88 116
89 117 /*!
90 118 \property QAbstractBarSeries::labelsVisible
91 119 Defines the visibility of the labels in series
92 120 */
93 121 /*!
94 122 \qmlproperty bool AbstractBarSeries::labelsVisible
95 123 Defines the visibility of the labels in series
96 124 */
97 125
98 126 /*!
99 127 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
100 128 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
101 129 Clicked bar inside set is indexed by \a index
102 130 */
103 131 /*!
104 132 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
105 133 The signal is emitted if the user clicks with a mouse on top of BarSet.
106 134 Clicked bar inside set is indexed by \a index
107 135 */
108 136
109 137 /*!
110 138 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
111 139
112 140 The signal is emitted if mouse is hovered on top of series.
113 141 Parameter \a barset is the pointer of barset, where hover happened.
114 142 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
115 143 */
116 144 /*!
117 145 \qmlsignal AbstractBarSeries::onHovered(bool status, BarSet barset)
118 146
119 147 The signal is emitted if mouse is hovered on top of series.
120 148 Parameter \a barset is the pointer of barset, where hover happened.
121 149 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
122 150 */
123 151
124 152 /*!
125 153 \fn void QAbstractBarSeries::countChanged()
126 154 This signal is emitted when barset count has been changed, for example by append or remove.
127 155 */
128 156 /*!
129 157 \qmlsignal AbstractBarSeries::onCountChanged()
130 158 This signal is emitted when barset count has been changed, for example by append or remove.
131 159 */
132 160
133 161 /*!
134 162 \fn void QAbstractBarSeries::labelsVisibleChanged()
135 163 This signal is emitted when labels visibility have changed.
136 164 \sa isLabelsVisible(), setLabelsVisible()
137 165 */
138 166
139 167 /*!
140 168 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
141 169 This signal is emitted when \a sets have been added to the series.
142 170 \sa append(), insert()
143 171 */
144 172 /*!
145 173 \qmlsignal AbstractBarSeries::onBarsetsAdded(BarSet barset)
146 174 Emitted when \a barset has been added to the series.
147 175 */
148 176
149 177 /*!
150 178 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
151 179 This signal is emitted when \a sets have been removed from the series.
152 180 \sa remove()
153 181 */
154 182 /*!
155 183 \qmlsignal AbstractBarSeries::onBarsetsRemoved(BarSet barset)
156 184 Emitted when \a barset has been removed from the series.
157 185 */
158 186
159 187 /*!
160 188 \qmlmethod BarSet AbstractBarSeries::at(int index)
161 189 Returns bar set at \a index. Returns null if the index is not valid.
162 190 */
163 191
164 192 /*!
165 193 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
166 194 Adds a new bar set with \a label and \a values to \a index. Values is a list of reals.
167 195 For example:
168 196 \code
169 197 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
170 198 \endcode
171 199 */
172 200
173 201 /*!
174 202 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
175 203 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.
176 204 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
177 205 appended.
178 206 \sa AbstractBarSeries::append()
179 207 */
180 208
181 209 /*!
182 210 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
183 211 Removes the barset from the series. Returns true if successful, false otherwise.
184 212 */
185 213
186 214 /*!
187 215 \qmlmethod AbstractBarSeries::clear()
188 216 Removes all barsets from the series.
189 217 */
190 218
191 219 /*!
192 220 Destructs abstractbarseries and owned barsets.
193 221 */
194 222 QAbstractBarSeries::~QAbstractBarSeries()
195 223 {
196 224
197 225 }
198 226
199 227 /*!
200 228 \internal
201 229 */
202 230 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &o, QObject *parent)
203 231 : QAbstractSeries(o, parent)
204 232 {
205 233 Q_D(QAbstractSeries);
206 234 QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
207 235 }
208 236
209 237 /*!
210 238 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
211 239 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
212 240 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
213 241 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
214 242 */
215 243 void QAbstractBarSeries::setBarWidth(qreal width)
216 244 {
217 245 Q_D(QAbstractBarSeries);
218 246 d->setBarWidth(width);
219 247 }
220 248
221 249 /*!
222 250 Returns the width of the bars of the series.
223 251 \sa setBarWidth()
224 252 */
225 253 qreal QAbstractBarSeries::barWidth() const
226 254 {
227 255 Q_D(const QAbstractBarSeries);
228 256 return d->barWidth();
229 257 }
230 258
231 259 /*!
232 260 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.
233 261 Returns true, if appending succeeded.
234 262 */
235 263 bool QAbstractBarSeries::append(QBarSet *set)
236 264 {
237 265 Q_D(QAbstractBarSeries);
238 266 bool success = d->append(set);
239 267 if (success) {
240 268 QList<QBarSet *> sets;
241 269 sets.append(set);
242 270 set->setParent(this);
243 271 emit barsetsAdded(sets);
244 272 emit countChanged();
245 273 }
246 274 return success;
247 275 }
248 276
249 277 /*!
250 278 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
251 279 was successful.
252 280 Returns true, if set was removed.
253 281 */
254 282 bool QAbstractBarSeries::remove(QBarSet *set)
255 283 {
256 284 Q_D(QAbstractBarSeries);
257 285 bool success = d->remove(set);
258 286 if (success) {
259 287 QList<QBarSet *> sets;
260 288 sets.append(set);
261 289 set->setParent(0);
262 290 emit barsetsRemoved(sets);
263 291 emit countChanged();
264 292 delete set;
265 293 set = 0;
266 294 }
267 295 return success;
268 296 }
269 297
270 298 /*!
271 299 Takes a single \a set from the series. Does not delete the barset object.
272 300
273 301 NOTE: The series remains as the barset's parent object. You must set the
274 302 parent object to take full ownership.
275 303
276 304 Returns true if take was successful.
277 305 */
278 306 bool QAbstractBarSeries::take(QBarSet *set)
279 307 {
280 308 Q_D(QAbstractBarSeries);
281 309 bool success = d->remove(set);
282 310 if (success) {
283 311 QList<QBarSet *> sets;
284 312 sets.append(set);
285 313 emit barsetsRemoved(sets);
286 314 emit countChanged();
287 315 }
288 316 return success;
289 317 }
290 318
291 319 /*!
292 320 Adds a list of barsets to series. Takes ownership of \a sets.
293 321 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
294 322 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
295 323 and function returns false.
296 324 */
297 325 bool QAbstractBarSeries::append(QList<QBarSet *> sets)
298 326 {
299 327 Q_D(QAbstractBarSeries);
300 328 bool success = d->append(sets);
301 329 if (success) {
302 330 emit barsetsAdded(sets);
303 331 emit countChanged();
304 332 }
305 333 return success;
306 334 }
307 335
308 336 /*!
309 337 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.
310 338 Returns true, if inserting succeeded.
311 339
312 340 */
313 341 bool QAbstractBarSeries::insert(int index, QBarSet *set)
314 342 {
315 343 Q_D(QAbstractBarSeries);
316 344 bool success = d->insert(index, set);
317 345 if (success) {
318 346 QList<QBarSet *> sets;
319 347 sets.append(set);
320 348 emit barsetsAdded(sets);
321 349 emit countChanged();
322 350 }
323 351 return success;
324 352 }
325 353
326 354 /*!
327 355 Removes all barsets from the series. Deletes removed sets.
328 356 */
329 357 void QAbstractBarSeries::clear()
330 358 {
331 359 Q_D(QAbstractBarSeries);
332 360 QList<QBarSet *> sets = barSets();
333 361 bool success = d->remove(sets);
334 362 if (success) {
335 363 emit barsetsRemoved(sets);
336 364 emit countChanged();
337 365 foreach (QBarSet *set, sets)
338 366 delete set;
339 367 }
340 368 }
341 369
342 370 /*!
343 371 Returns number of sets in series.
344 372 */
345 373 int QAbstractBarSeries::count() const
346 374 {
347 375 Q_D(const QAbstractBarSeries);
348 376 return d->m_barSets.count();
349 377 }
350 378
351 379 /*!
352 380 Returns a list of sets in series. Keeps ownership of sets.
353 381 */
354 382 QList<QBarSet *> QAbstractBarSeries::barSets() const
355 383 {
356 384 Q_D(const QAbstractBarSeries);
357 385 return d->m_barSets;
358 386 }
359 387
360 388 /*!
361 389 Sets the visibility of labels in series to \a visible
362 390 */
363 391 void QAbstractBarSeries::setLabelsVisible(bool visible)
364 392 {
365 393 Q_D(QAbstractBarSeries);
366 394 if (d->m_labelsVisible != visible) {
367 395 d->setLabelsVisible(visible);
368 396 emit labelsVisibleChanged();
369 397 }
370 398 }
371 399
372 400 /*!
373 401 Returns the visibility of labels
374 402 */
375 403 bool QAbstractBarSeries::isLabelsVisible() const
376 404 {
377 405 Q_D(const QAbstractBarSeries);
378 406 return d->m_labelsVisible;
379 407 }
380 408
381 409 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
382 410
383 411 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
384 412 QAbstractSeriesPrivate(q),
385 413 m_barWidth(0.5), // Default value is 50% of category width
386 414 m_labelsVisible(false),
387 415 m_visible(true)
388 416 {
389 417 }
390 418
391 419 int QAbstractBarSeriesPrivate::categoryCount() const
392 420 {
393 421 // No categories defined. return count of longest set.
394 422 int count = 0;
395 423 for (int i = 0; i < m_barSets.count(); i++) {
396 424 if (m_barSets.at(i)->count() > count)
397 425 count = m_barSets.at(i)->count();
398 426 }
399 427
400 428 return count;
401 429 }
402 430
403 431 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
404 432 {
405 433 if (width < 0.0)
406 434 width = 0.0;
407 435 m_barWidth = width;
408 436 emit updatedLayout();
409 437 }
410 438
411 439 qreal QAbstractBarSeriesPrivate::barWidth() const
412 440 {
413 441 return m_barWidth;
414 442 }
415 443
416 444 QBarSet *QAbstractBarSeriesPrivate::barsetAt(int index)
417 445 {
418 446 return m_barSets.at(index);
419 447 }
420 448
421 449 void QAbstractBarSeriesPrivate::setVisible(bool visible)
422 450 {
423 451 m_visible = visible;
424 452 emit visibleChanged();
425 453 }
426 454
427 455 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
428 456 {
429 457 m_labelsVisible = visible;
430 458 emit labelsVisibleChanged(visible);
431 459 }
432 460
433 461 qreal QAbstractBarSeriesPrivate::min()
434 462 {
435 463 if (m_barSets.count() <= 0)
436 464 return 0;
437 465
438 466 qreal min = INT_MAX;
439 467
440 468 for (int i = 0; i < m_barSets.count(); i++) {
441 469 int categoryCount = m_barSets.at(i)->count();
442 470 for (int j = 0; j < categoryCount; j++) {
443 471 qreal temp = m_barSets.at(i)->at(j);
444 472 if (temp < min)
445 473 min = temp;
446 474 }
447 475 }
448 476 return min;
449 477 }
450 478
451 479 qreal QAbstractBarSeriesPrivate::max()
452 480 {
453 481 if (m_barSets.count() <= 0)
454 482 return 0;
455 483
456 484 qreal max = INT_MIN;
457 485
458 486 for (int i = 0; i < m_barSets.count(); i++) {
459 487 int categoryCount = m_barSets.at(i)->count();
460 488 for (int j = 0; j < categoryCount; j++) {
461 489 qreal temp = m_barSets.at(i)->at(j);
462 490 if (temp > max)
463 491 max = temp;
464 492 }
465 493 }
466 494
467 495 return max;
468 496 }
469 497
470 498 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
471 499 {
472 500 if ((set < 0) || (set >= m_barSets.count()))
473 501 return 0; // No set, no value.
474 502 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
475 503 return 0; // No category, no value.
476 504
477 505 return m_barSets.at(set)->at(category);
478 506 }
479 507
480 508 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
481 509 {
482 510 if ((set < 0) || (set >= m_barSets.count()))
483 511 return 0; // No set, no value.
484 512 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
485 513 return 0; // No category, no value.
486 514
487 515 qreal value = m_barSets.at(set)->at(category);
488 516 qreal sum = categorySum(category);
489 517 if (qFuzzyCompare(sum, 0))
490 518 return 0;
491 519
492 520 return value / sum;
493 521 }
494 522
495 523 qreal QAbstractBarSeriesPrivate::categorySum(int category)
496 524 {
497 525 qreal sum(0);
498 526 int count = m_barSets.count(); // Count sets
499 527 for (int set = 0; set < count; set++) {
500 528 if (category < m_barSets.at(set)->count())
501 529 sum += m_barSets.at(set)->at(category);
502 530 }
503 531 return sum;
504 532 }
505 533
506 534 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
507 535 {
508 536 qreal sum(0);
509 537 int count = m_barSets.count(); // Count sets
510 538 for (int set = 0; set < count; set++) {
511 539 if (category < m_barSets.at(set)->count())
512 540 sum += qAbs(m_barSets.at(set)->at(category));
513 541 }
514 542 return sum;
515 543 }
516 544
517 545 qreal QAbstractBarSeriesPrivate::maxCategorySum()
518 546 {
519 547 qreal max = INT_MIN;
520 548 int count = categoryCount();
521 549 for (int i = 0; i < count; i++) {
522 550 qreal sum = categorySum(i);
523 551 if (sum > max)
524 552 max = sum;
525 553 }
526 554 return max;
527 555 }
528 556
529 557 qreal QAbstractBarSeriesPrivate::minX()
530 558 {
531 559 if (m_barSets.count() <= 0)
532 560 return 0;
533 561
534 562 qreal min = INT_MAX;
535 563
536 564 for (int i = 0; i < m_barSets.count(); i++) {
537 565 int categoryCount = m_barSets.at(i)->count();
538 566 for (int j = 0; j < categoryCount; j++) {
539 567 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
540 568 if (temp < min)
541 569 min = temp;
542 570 }
543 571 }
544 572 return min;
545 573 }
546 574
547 575 qreal QAbstractBarSeriesPrivate::maxX()
548 576 {
549 577 if (m_barSets.count() <= 0)
550 578 return 0;
551 579
552 580 qreal max = INT_MIN;
553 581
554 582 for (int i = 0; i < m_barSets.count(); i++) {
555 583 int categoryCount = m_barSets.at(i)->count();
556 584 for (int j = 0; j < categoryCount; j++) {
557 585 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
558 586 if (temp > max)
559 587 max = temp;
560 588 }
561 589 }
562 590
563 591 return max;
564 592 }
565 593
566 594 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
567 595 {
568 596 // Returns top (sum of all positive values) of category.
569 597 // Returns 0, if all values are negative
570 598 qreal top(0);
571 599 int count = m_barSets.count();
572 600 for (int set = 0; set < count; set++) {
573 601 if (category < m_barSets.at(set)->count()) {
574 602 qreal temp = m_barSets.at(set)->at(category);
575 603 if (temp > 0) {
576 604 top += temp;
577 605 }
578 606 }
579 607 }
580 608 return top;
581 609 }
582 610
583 611 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
584 612 {
585 613 // Returns bottom (sum of all negative values) of category
586 614 // Returns 0, if all values are positive
587 615 qreal bottom(0);
588 616 int count = m_barSets.count();
589 617 for (int set = 0; set < count; set++) {
590 618 if (category < m_barSets.at(set)->count()) {
591 619 qreal temp = m_barSets.at(set)->at(category);
592 620 if (temp < 0) {
593 621 bottom += temp;
594 622 }
595 623 }
596 624 }
597 625 return bottom;
598 626 }
599 627
600 628 qreal QAbstractBarSeriesPrivate::top()
601 629 {
602 630 // Returns top of all categories
603 631 qreal top(0);
604 632 int count = categoryCount();
605 633 for (int i = 0; i < count; i++) {
606 634 qreal temp = categoryTop(i);
607 635 if (temp > top)
608 636 top = temp;
609 637 }
610 638 return top;
611 639 }
612 640
613 641 qreal QAbstractBarSeriesPrivate::bottom()
614 642 {
615 643 // Returns bottom of all categories
616 644 qreal bottom(0);
617 645 int count = categoryCount();
618 646 for (int i = 0; i < count; i++) {
619 647 qreal temp = categoryBottom(i);
620 648 if (temp < bottom)
621 649 bottom = temp;
622 650 }
623 651 return bottom;
624 652 }
625 653
626 654
627 655 void QAbstractBarSeriesPrivate::initializeDomain()
628 656 {
629 657 qreal minX(domain()->minX());
630 658 qreal minY(domain()->minY());
631 659 qreal maxX(domain()->maxX());
632 660 qreal maxY(domain()->maxY());
633 661
634 662 qreal seriesMinX = this->minX();
635 663 qreal seriesMaxX = this->maxX();
636 664 qreal y = max();
637 665 minX = qMin(minX, seriesMinX - (qreal)0.5);
638 666 minY = qMin(minY, y);
639 667 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
640 668 maxY = qMax(maxY, y);
641 669
642 670 domain()->setRange(minX, maxX, minY, maxY);
643 671 }
644 672
645 673 QList<QLegendMarker*> QAbstractBarSeriesPrivate::createLegendMarkers(QLegend* legend)
646 674 {
647 675 Q_Q(QAbstractBarSeries);
648 676 QList<QLegendMarker*> markers;
649 677
650 678 foreach(QBarSet* set, q->barSets()) {
651 679 QBarLegendMarker* marker = new QBarLegendMarker(q,set,legend);
652 680 markers << marker;
653 681 }
654 682 return markers;
655 683 }
656 684
657 685
658 686 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
659 687 {
660 688 if ((m_barSets.contains(set)) || (set == 0))
661 689 return false; // Fail if set is already in list or set is null.
662 690
663 691 m_barSets.append(set);
664 692 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
665 693 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
666 694 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
667 695
668 696 emit restructuredBars(); // this notifies barchartitem
669 697 return true;
670 698 }
671 699
672 700 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
673 701 {
674 702 if (!m_barSets.contains(set))
675 703 return false; // Fail if set is not in list
676 704
677 705 m_barSets.removeOne(set);
678 706 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
679 707 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
680 708 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
681 709
682 710 emit restructuredBars(); // this notifies barchartitem
683 711 return true;
684 712 }
685 713
686 714 bool QAbstractBarSeriesPrivate::append(QList<QBarSet * > sets)
687 715 {
688 716 foreach (QBarSet *set, sets) {
689 717 if ((set == 0) || (m_barSets.contains(set)))
690 718 return false; // Fail if any of the sets is null or is already appended.
691 719 if (sets.count(set) != 1)
692 720 return false; // Also fail if same set is more than once in given list.
693 721 }
694 722
695 723 foreach (QBarSet *set, sets) {
696 724 m_barSets.append(set);
697 725 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
698 726 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
699 727 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
700 728 }
701 729
702 730 emit restructuredBars(); // this notifies barchartitem
703 731 return true;
704 732 }
705 733
706 734 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet * > sets)
707 735 {
708 736 if (sets.count() == 0)
709 737 return false;
710 738
711 739 foreach (QBarSet *set, sets) {
712 740 if ((set == 0) || (!m_barSets.contains(set)))
713 741 return false; // Fail if any of the sets is null or is not in series
714 742 if (sets.count(set) != 1)
715 743 return false; // Also fail if same set is more than once in given list.
716 744 }
717 745
718 746 foreach (QBarSet *set, sets) {
719 747 m_barSets.removeOne(set);
720 748 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
721 749 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
722 750 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
723 751 }
724 752
725 753 emit restructuredBars(); // this notifies barchartitem
726 754
727 755 return true;
728 756 }
729 757
730 758 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
731 759 {
732 760 if ((m_barSets.contains(set)) || (set == 0))
733 761 return false; // Fail if set is already in list or set is null.
734 762
735 763 m_barSets.insert(index, set);
736 764 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
737 765 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
738 766 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
739 767
740 768 emit restructuredBars(); // this notifies barchartitem
741 769 return true;
742 770 }
743 771
744 772 void QAbstractBarSeriesPrivate::initializeAxes()
745 773 {
746 774 Q_Q(QAbstractBarSeries);
747 775
748 776 foreach(QAbstractAxis* axis, m_axes) {
749 777
750 778 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
751 779 switch (q->type()) {
752 780 case QAbstractSeries::SeriesTypeHorizontalBar:
753 781 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
754 782 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
755 783 if (axis->orientation() == Qt::Vertical)
756 784 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
757 785 break;
758 786 case QAbstractSeries::SeriesTypeBar:
759 787 case QAbstractSeries::SeriesTypePercentBar:
760 788 case QAbstractSeries::SeriesTypeStackedBar:
761 789 if (axis->orientation() == Qt::Horizontal)
762 790 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
763 791 break;
764 792 default:
765 793 qWarning() << "Unexpected series type";
766 794 break;
767 795 }
768 796 }
769 797 }
770 798 }
771 799
772 800 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
773 801 {
774 802 Q_Q(const QAbstractBarSeries);
775 803
776 804 switch (q->type()) {
777 805 case QAbstractSeries::SeriesTypeHorizontalBar:
778 806 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
779 807 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
780 808 if (orientation == Qt::Vertical)
781 809 return QAbstractAxis::AxisTypeBarCategory;
782 810 break;
783 811 case QAbstractSeries::SeriesTypeBar:
784 812 case QAbstractSeries::SeriesTypePercentBar:
785 813 case QAbstractSeries::SeriesTypeStackedBar:
786 814 if (orientation == Qt::Horizontal)
787 815 return QAbstractAxis::AxisTypeBarCategory;
788 816 break;
789 817 default:
790 818 qWarning() << "Unexpected series type";
791 819 break;
792 820 }
793 821 return QAbstractAxis::AxisTypeValue;
794 822
795 823 }
796 824
797 825 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
798 826 {
799 827 QStringList categories;
800 828 if (axis->categories().isEmpty()) {
801 829 for (int i(1); i < categoryCount() + 1; i++)
802 830 categories << QString::number(i);
803 831 axis->append(categories);
804 832 }
805 833 }
806 834
807 835 QAbstractAxis* QAbstractBarSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
808 836 {
809 837 Q_UNUSED(orientation);
810 838 return 0;
811 839 }
812 840
813 841 void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
814 842 {
815 843 const QList<QGradient> gradients = theme->seriesGradients();
816 844
817 845 QBrush brush;
818 846 QPen pen;
819 847
820 848 qreal takeAtPos = 0.5;
821 849 qreal step = 0.2;
822 850 if (m_barSets.count() > 1) {
823 851 step = 1.0 / (qreal) m_barSets.count();
824 852 if (m_barSets.count() % gradients.count())
825 853 step *= gradients.count();
826 854 else
827 855 step *= (gradients.count() - 1);
828 856 }
829 857
830 858 for (int i(0); i < m_barSets.count(); i++) {
831 859 int colorIndex = (index + i) % gradients.count();
832 860 if (i > 0 && i %gradients.count() == 0) {
833 861 // There is no dedicated base color for each sets, generate more colors
834 862 takeAtPos += step;
835 863 if (takeAtPos == 1.0)
836 864 takeAtPos += step;
837 865 takeAtPos -= (int) takeAtPos;
838 866 }
839 867 if (forced || brush == m_barSets.at(i)->brush())
840 868 m_barSets.at(i)->setBrush(ChartThemeManager::colorAt(gradients.at(colorIndex), takeAtPos));
841 869
842 870 // Pick label color from the opposite end of the gradient.
843 871 // 0.3 as a boundary seems to work well.
844 872 if (forced || brush == m_barSets.at(i)->labelBrush()) {
845 873 if (takeAtPos < 0.3)
846 874 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 1));
847 875 else
848 876 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0));
849 877 }
850 878
851 879 if (forced || pen == m_barSets.at(i)->pen()) {
852 880 QColor c = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0);
853 881 m_barSets.at(i)->setPen(c);
854 882 }
855 883 }
856 884 }
857 885
858 886 void QAbstractBarSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
859 887 {
860 888 AbstractBarChartItem *bar = static_cast<AbstractBarChartItem *>(m_item.data());
861 889 Q_ASSERT(bar);
862 890 if (options.testFlag(QChart::SeriesAnimations)) {
863 891 bar->setAnimation(new BarAnimation(bar));
864 892 }else{
865 893 bar->setAnimation(0);
866 894 }
867 895 QAbstractSeriesPrivate::initializeAnimations(options);
868 896 }
869 897
870 898 #include "moc_qabstractbarseries.cpp"
871 899 #include "moc_qabstractbarseries_p.cpp"
872 900
873 901 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,174 +1,162
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 "qlineseries.h"
22 22 #include "qlineseries_p.h"
23 23 #include "linechartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 /*!
30 30 \class QLineSeries
31 31 \brief The QLineSeries class is used for making line charts.
32 32
33 33 \mainclass
34 34
35 35 A line chart is used to show information as a series of data points
36 36 connected by straight lines.
37 37
38 38 \image examples_linechart.png
39 39
40 40 Creating basic line chart is simple:
41 41 \code
42 42 QLineSeries* series = new QLineSeries();
43 43 series->append(0, 6);
44 44 series->append(2, 4);
45 45 ...
46 46 chart->addSeries(series);
47 47 \endcode
48 48 */
49 49 /*!
50 50 \qmlclass LineSeries QLineSeries
51 51 \inherits XYSeries
52 52
53 53 The following QML shows how to create a simple line chart:
54 54 \snippet ../demos/qmlchart/qml/qmlchart/View2.qml 1
55 55 \beginfloatleft
56 56 \image demos_qmlchart2.png
57 57 \endfloat
58 58 \clearfloat
59 59 */
60 60
61 61 /*!
62 62 \fn virtual SeriesType QLineSeries::type() const
63 63 \brief Returns type of series.
64 64 \sa QAbstractSeries, SeriesType
65 65 */
66 66
67 67 /*!
68 \qmlproperty AbstractAxis LineSeries::axisX
69 The x axis used for the series. If you leave the x axis undefined, a ValueAxis is created for
70 the series.
71 */
72
73 /*!
74 \qmlproperty AbstractAxis LineSeries::axisY
75 The y axis used for the series. If you leave the y axis undefined, a ValueAxis is created for
76 the series.
77 */
78
79 /*!
80 68 \qmlproperty real LineSeries::width
81 69 The width of the line. By default the width is 2.0.
82 70 */
83 71
84 72 /*!
85 73 \qmlproperty Qt::PenStyle LineSeries::style
86 74 Controls the style of the line. Set to one of Qt.NoPen, Qt.SolidLine, Qt.DashLine, Qt.DotLine,
87 75 Qt.DashDotLine or Qt.DashDotDotLine. Using Qt.CustomDashLine is not supported in the QML API.
88 76 By default the style is Qt.SolidLine.
89 77 */
90 78
91 79 /*!
92 80 \qmlproperty Qt::PenCapStyle LineSeries::capStyle
93 81 Controls the cap style of the line. Set to one of Qt.FlatCap, Qt.SquareCap or Qt.RoundCap. By
94 82 default the cap style is Qt.SquareCap.
95 83 */
96 84
97 85 /*!
98 86 Constructs empty series object which is a child of \a parent.
99 87 When series object is added to QChartView or QChart instance ownerships is transferred.
100 88 */
101 89 QLineSeries::QLineSeries(QObject *parent)
102 90 : QXYSeries(*new QLineSeriesPrivate(this), parent)
103 91 {
104 92
105 93 }
106 94
107 95 /*!
108 96 \internal
109 97 */
110 98 QLineSeries::QLineSeries(QLineSeriesPrivate &d, QObject *parent)
111 99 : QXYSeries(d, parent)
112 100 {
113 101
114 102 }
115 103 /*!
116 104 Destroys the object. Series added to QChartView or QChart instances are owned by those,
117 105 and are deleted when mentioned object are destroyed.
118 106 */
119 107 QLineSeries::~QLineSeries()
120 108 {
121 109 Q_D(QLineSeries);
122 110 if (d->m_chart)
123 111 d->m_chart->removeSeries(this);
124 112 }
125 113
126 114 QAbstractSeries::SeriesType QLineSeries::type() const
127 115 {
128 116 return QAbstractSeries::SeriesTypeLine;
129 117 }
130 118
131 119 /*
132 120 QDebug operator<< (QDebug debug, const QLineSeries series)
133 121 {
134 122 Q_ASSERT(series.d_func()->m_x.size() == series.d_func()->m_y.size());
135 123 int size = series.d_func()->m_x.size();
136 124 for (int i=0; i<size; i++) {
137 125 debug.nospace() << "(" << series.d_func()->m_x.at(i) << ','<< series.d_func()->m_y.at(i) << ") ";
138 126 }
139 127 return debug.space();
140 128 }
141 129 */
142 130
143 131 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
144 132
145 133 QLineSeriesPrivate::QLineSeriesPrivate(QLineSeries *q)
146 134 : QXYSeriesPrivate(q)
147 135 {
148 136
149 137 };
150 138
151 139 void QLineSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
152 140 {
153 141 Q_Q(QLineSeries);
154 142 LineChartItem *line = new LineChartItem(q,parent);
155 143 m_item.reset(line);
156 144 QAbstractSeriesPrivate::initializeGraphics(parent);
157 145 }
158 146
159 147 void QLineSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
160 148 {
161 149 Q_Q(QLineSeries);
162 150 const QList<QColor> colors = theme->seriesColors();
163 151
164 152 QPen pen;
165 153 if (forced || pen == m_pen) {
166 154 pen.setColor(colors.at(index % colors.size()));
167 155 pen.setWidthF(2);
168 156 q->setPen(pen);
169 157 }
170 158 }
171 159
172 160 #include "moc_qlineseries.cpp"
173 161
174 162 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,284 +1,272
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 "qsplineseries.h"
22 22 #include "qsplineseries_p.h"
23 23 #include "splinechartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "splineanimation_p.h"
27 27
28 28 /*!
29 29 \class QSplineSeries
30 30 \brief Series type used to store data needed to draw a spline.
31 31
32 32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
34 34
35 35 \image examples_splinechart.png
36 36
37 37 Creating basic spline chart is simple:
38 38 \code
39 39 QSplineSeries* series = new QSplineSeries();
40 40 series->append(0, 6);
41 41 series->append(2, 4);
42 42 ...
43 43 chart->addSeries(series);
44 44 \endcode
45 45 */
46 46
47 47 /*!
48 48 \qmlclass SplineSeries QSplineSeries
49 49 \inherits XYSeries
50 50
51 51 The following QML shows how to create a simple spline chart:
52 52 \snippet ../demos/qmlchart/qml/qmlchart/View3.qml 1
53 53 \beginfloatleft
54 54 \image demos_qmlchart3.png
55 55 \endfloat
56 56 \clearfloat
57 57 */
58 58
59 59 /*!
60 60 \fn QSeriesType QSplineSeries::type() const
61 61 Returns the type of the series
62 62 */
63 63
64 64 /*!
65 \qmlproperty AbstractAxis SplineSeries::axisX
66 The x axis used for the series. If you leave the x axis undefined, a ValueAxis is created for
67 the series.
68 */
69
70 /*!
71 \qmlproperty AbstractAxis SplineSeries::axisY
72 The y axis used for the series. If you leave the y axis undefined, a ValueAxis is created for
73 the series.
74 */
75
76 /*!
77 65 \qmlproperty real SplineSeries::width
78 66 The width of the line. By default the width is 2.0.
79 67 */
80 68
81 69 /*!
82 70 \qmlproperty Qt::PenStyle SplineSeries::style
83 71 Controls the style of the line. Set to one of Qt.NoPen, Qt.SolidLine, Qt.DashLine, Qt.DotLine,
84 72 Qt.DashDotLine or Qt.DashDotDotLine. Using Qt.CustomDashLine is not supported in the QML API.
85 73 By default the style is Qt.SolidLine.
86 74 */
87 75
88 76 /*!
89 77 \qmlproperty Qt::PenCapStyle SplineSeries::capStyle
90 78 Controls the cap style of the line. Set to one of Qt.FlatCap, Qt.SquareCap or Qt.RoundCap. By
91 79 default the cap style is Qt.SquareCap.
92 80 */
93 81
94 82 QTCOMMERCIALCHART_BEGIN_NAMESPACE
95 83
96 84 /*!
97 85 Constructs empty series object which is a child of \a parent.
98 86 When series object is added to QChartView or QChart instance then the ownerships is transferred.
99 87 */
100 88
101 89 QSplineSeries::QSplineSeries(QObject *parent)
102 90 : QLineSeries(*new QSplineSeriesPrivate(this), parent)
103 91 {
104 92 Q_D(QSplineSeries);
105 93 QObject::connect(this, SIGNAL(pointAdded(int)), d, SLOT(updateControlPoints()));
106 94 QObject::connect(this, SIGNAL(pointRemoved(int)), d, SLOT(updateControlPoints()));
107 95 QObject::connect(this, SIGNAL(pointReplaced(int)), d, SLOT(updateControlPoints()));
108 96 QObject::connect(this, SIGNAL(pointsReplaced()), d, SLOT(updateControlPoints()));
109 97 }
110 98
111 99 /*!
112 100 Destroys the object.
113 101 */
114 102 QSplineSeries::~QSplineSeries()
115 103 {
116 104 Q_D(QSplineSeries);
117 105 if (d->m_chart)
118 106 d->m_chart->removeSeries(this);
119 107 }
120 108
121 109 QAbstractSeries::SeriesType QSplineSeries::type() const
122 110 {
123 111 return QAbstractSeries::SeriesTypeSpline;
124 112 }
125 113
126 114 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
127 115
128 116 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries *q)
129 117 : QLineSeriesPrivate(q)
130 118 {
131 119 }
132 120
133 121 /*!
134 122 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
135 123 */
136 124 void QSplineSeriesPrivate::calculateControlPoints()
137 125 {
138 126 Q_Q(QSplineSeries);
139 127
140 128 const QList<QPointF>& points = q->points();
141 129
142 130 int n = points.count() - 1;
143 131
144 132 if (n == 1) {
145 133 //for n==1
146 134 m_controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
147 135 m_controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
148 136 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - points[0].x());
149 137 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - points[0].y());
150 138 return;
151 139 }
152 140
153 141 // Calculate first Bezier control points
154 142 // Set of equations for P0 to Pn points.
155 143 //
156 144 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
157 145 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
158 146 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
159 147 // | . . . . . . . . . . . . | | ... | | ... |
160 148 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
161 149 // | . . . . . . . . . . . . | | ... | | ... |
162 150 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
163 151 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
164 152 //
165 153 QVector<qreal> vector;
166 154 vector.resize(n);
167 155
168 156 vector[0] = points[0].x() + 2 * points[1].x();
169 157
170 158
171 159 for (int i = 1; i < n - 1; ++i)
172 160 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
173 161
174 162 vector[n - 1] = (8 * points[n - 1].x() + points[n].x()) / 2.0;
175 163
176 164 QVector<qreal> xControl = firstControlPoints(vector);
177 165
178 166 vector[0] = points[0].y() + 2 * points[1].y();
179 167
180 168 for (int i = 1; i < n - 1; ++i)
181 169 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
182 170
183 171 vector[n - 1] = (8 * points[n - 1].y() + points[n].y()) / 2.0;
184 172
185 173 QVector<qreal> yControl = firstControlPoints(vector);
186 174
187 175 for (int i = 0, j = 0; i < n; ++i, ++j) {
188 176
189 177 m_controlPoints[j].setX(xControl[i]);
190 178 m_controlPoints[j].setY(yControl[i]);
191 179
192 180 j++;
193 181
194 182 if (i < n - 1) {
195 183 m_controlPoints[j].setX(2 * points[i + 1].x() - xControl[i + 1]);
196 184 m_controlPoints[j].setY(2 * points[i + 1].y() - yControl[i + 1]);
197 185 } else {
198 186 m_controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
199 187 m_controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
200 188 }
201 189 }
202 190 }
203 191
204 192 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
205 193 {
206 194 QVector<qreal> result;
207 195
208 196 int count = vector.count();
209 197 result.resize(count);
210 198 result[0] = vector[0] / 2.0;
211 199
212 200 QVector<qreal> temp;
213 201 temp.resize(count);
214 202 temp[0] = 0;
215 203
216 204 qreal b = 2.0;
217 205
218 206 for (int i = 1; i < count; i++) {
219 207 temp[i] = 1 / b;
220 208 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
221 209 result[i] = (vector[i] - result[i - 1]) / b;
222 210 }
223 211
224 212 for (int i = 1; i < count; i++)
225 213 result[count - i - 1] -= temp[count - i] * result[count - i];
226 214
227 215 return result;
228 216 }
229 217
230 218 QPointF QSplineSeriesPrivate::controlPoint(int index) const
231 219 {
232 220 return m_controlPoints[index];
233 221 }
234 222
235 223 /*!
236 224 Updates the control points, besed on currently avaiable knots.
237 225 */
238 226 void QSplineSeriesPrivate::updateControlPoints()
239 227 {
240 228 Q_Q(QSplineSeries);
241 229 if (q->count() > 1) {
242 230 m_controlPoints.resize(2 * q->count() - 2);
243 231 calculateControlPoints();
244 232 }
245 233 }
246 234
247 235 void QSplineSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
248 236 {
249 237 Q_Q(QSplineSeries);
250 238 SplineChartItem *spline = new SplineChartItem(q,parent);
251 239 m_item.reset(spline);
252 240 QAbstractSeriesPrivate::initializeGraphics(parent);
253 241 }
254 242
255 243 void QSplineSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
256 244 {
257 245 Q_Q(QSplineSeries);
258 246 const QList<QColor> colors = theme->seriesColors();
259 247
260 248 QPen pen;
261 249 if (forced || pen == m_pen) {
262 250 pen.setColor(colors.at(index % colors.size()));
263 251 pen.setWidthF(2);
264 252 q->setPen(pen);
265 253 }
266 254 }
267 255
268 256
269 257 void QSplineSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
270 258 {
271 259 SplineChartItem *item = static_cast<SplineChartItem *>(m_item.data());
272 260 Q_ASSERT(item);
273 261 if (options.testFlag(QChart::SeriesAnimations)) {
274 262 item->setAnimation(new SplineAnimation(item));
275 263 }else{
276 264 item->setAnimation(0);
277 265 }
278 266 QAbstractSeriesPrivate::initializeAnimations(options);
279 267 }
280 268
281 269 #include "moc_qsplineseries.cpp"
282 270 #include "moc_qsplineseries_p.cpp"
283 271
284 272 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,490 +1,518
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 "qxyseries.h"
22 22 #include "qxyseries_p.h"
23 23 #include "abstractdomain_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include "xychart_p.h"
26 26 #include "qxylegendmarker.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 /*!
31 31 \class QXYSeries
32 32 \brief The QXYSeries class is a base class for line, spline and scatter series.
33 33 */
34 34 /*!
35 35 \qmlclass XYSeries
36 36 \inherits AbstractSeries
37 37 The XYSeries class is a base class for line, spline and scatter series.
38 38
39 39 The class cannot be instantiated directly.
40 40 */
41 41
42 42 /*!
43 \qmlproperty AbstractAxis XYSeries::axisX
44 The x axis used for the series. If you leave both axisX and axisXTop undefined, a ValueAxis is created for
45 the series.
46 \sa axisXTop
47 */
48
49 /*!
50 \qmlproperty AbstractAxis XYSeries::axisY
51 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
52 the series.
53 \sa axisYRight
54 */
55
56 /*!
57 \qmlproperty AbstractAxis XYSeries::axisXTop
58 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
59 axisXTop, but not both.
60 \sa axisX
61 */
62
63 /*!
64 \qmlproperty AbstractAxis XYSeries::axisYRight
65 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
66 or axisYRight, but not both.
67 \sa axisY
68 */
69
70 /*!
43 71 \property QXYSeries::pointsVisible
44 72 Controls if the data points are visible and should be drawn.
45 73 */
46 74 /*!
47 75 \qmlproperty bool XYSeries::pointsVisible
48 76 Controls if the data points are visible and should be drawn.
49 77 */
50 78
51 79 /*!
52 80 \fn QPen QXYSeries::pen() const
53 81 \brief Returns pen used to draw points for series.
54 82 \sa setPen()
55 83 */
56 84
57 85 /*!
58 86 \fn QBrush QXYSeries::brush() const
59 87 \brief Returns brush used to draw points for series.
60 88 \sa setBrush()
61 89 */
62 90
63 91 /*!
64 92 \property QXYSeries::color
65 93 The color of the series. This is line (pen) color in case of QLineSeries or QSplineSeries and
66 94 fill (brush) color in case of QScatterSeries or QAreaSeries.
67 95 \sa QXYSeries::pen(), QXYSeries::brush()
68 96 */
69 97 /*!
70 98 \qmlproperty color XYSeries::color
71 99 The color of the series. This is line (pen) color in case of LineSeries or SplineSeries and
72 100 fill (brush) color in case of ScatterSeries or AreaSeries.
73 101 */
74 102
75 103 /*!
76 104 \fn void QXYSeries::clicked(const QPointF& point)
77 105 \brief Signal is emitted when user clicks the \a point on chart.
78 106 */
79 107 /*!
80 108 \qmlsignal XYSeries::onClicked(QPointF point)
81 109 Signal is emitted when user clicks the \a point on chart. For example:
82 110 \code
83 111 LineSeries {
84 112 XYPoint { x: 0; y: 0 }
85 113 XYPoint { x: 1.1; y: 2.1 }
86 114 onClicked: console.log("onClicked: " + point.x + ", " + point.y);
87 115 }
88 116 \endcode
89 117 */
90 118
91 119 /*!
92 120 \fn void QXYSeries::pointReplaced(int index)
93 121 Signal is emitted when a point has been replaced at \a index.
94 122 \sa replace()
95 123 */
96 124 /*!
97 125 \qmlsignal XYSeries::onPointReplaced(int index)
98 126 Signal is emitted when a point has been replaced at \a index.
99 127 */
100 128
101 129 /*!
102 130 \fn void QXYSeries::pointsReplaced()
103 131 Signal is emitted when all points have been replaced with another points.
104 132 \sa replace()
105 133 */
106 134 /*!
107 135 \qmlsignal XYSeries::onPointsReplaced()
108 136 */
109 137
110 138 /*!
111 139 \fn void QXYSeries::pointAdded(int index)
112 140 Signal is emitted when a point has been added at \a index.
113 141 \sa append(), insert()
114 142 */
115 143 /*!
116 144 \qmlsignal XYSeries::onPointAdded(int index)
117 145 Signal is emitted when a point has been added at \a index.
118 146 */
119 147
120 148 /*!
121 149 \fn void QXYSeries::pointRemoved(int index)
122 150 Signal is emitted when a point has been removed from \a index.
123 151 \sa remove()
124 152 */
125 153 /*!
126 154 \qmlsignal XYSeries::onPointRemoved(int index)
127 155 Signal is emitted when a point has been removed from \a index.
128 156 */
129 157
130 158 /*!
131 159 \fn void QXYSeries::colorChanged(QColor color)
132 160 \brief Signal is emitted when the line (pen) color has changed to \a color.
133 161 */
134 162 /*!
135 163 \qmlsignal XYSeries::onColorChanged(color color)
136 164 Signal is emitted when the line (pen) color has changed to \a color.
137 165 */
138 166
139 167 /*!
140 168 \fn void QXYSeriesPrivate::updated()
141 169 \brief \internal
142 170 */
143 171
144 172 /*!
145 173 \qmlmethod XYSeries::append(real x, real y)
146 174 Append point (\a x, \a y) to the series
147 175 */
148 176
149 177 /*!
150 178 \qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY)
151 179 Replaces point (\a oldX, \a oldY) with point (\a newX, \a newY). Does nothing, if point (oldX, oldY) does not
152 180 exist.
153 181 */
154 182
155 183 /*!
156 184 \qmlmethod XYSeries::remove(real x, real y)
157 185 Removes point (\a x, \a y) from the series. Does nothing, if point (x, y) does not exist.
158 186 */
159 187
160 188 /*!
161 189 \qmlmethod XYSeries::insert(int index, real x, real y)
162 190 Inserts point (\a x, \a y) to the \a index. If index is 0 or smaller than 0 the point is prepended to the list of
163 191 points. If index is the same as or bigger than count, the point is appended to the list of points.
164 192 */
165 193
166 194 /*!
167 195 \qmlmethod QPointF XYSeries::at(int index)
168 196 Returns point at \a index. Returns (0, 0) if the index is not valid.
169 197 */
170 198
171 199 /*!
172 200 \internal
173 201
174 202 Constructs empty series object which is a child of \a parent.
175 203 When series object is added to QChartView or QChart instance ownerships is transferred.
176 204 */
177 205 QXYSeries::QXYSeries(QXYSeriesPrivate &d, QObject *parent)
178 206 : QAbstractSeries(d, parent)
179 207 {
180 208 }
181 209
182 210 /*!
183 211 Destroys the object. Series added to QChartView or QChart instances are owned by those,
184 212 and are deleted when mentioned object are destroyed.
185 213 */
186 214 QXYSeries::~QXYSeries()
187 215 {
188 216 }
189 217
190 218 /*!
191 219 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
192 220 */
193 221 void QXYSeries::append(qreal x, qreal y)
194 222 {
195 223 append(QPointF(x, y));
196 224 }
197 225
198 226 /*!
199 227 This is an overloaded function.
200 228 Adds data \a point to the series. Points are connected with lines on the chart.
201 229 */
202 230 void QXYSeries::append(const QPointF &point)
203 231 {
204 232 Q_D(QXYSeries);
205 233 d->m_points << point;
206 234 emit pointAdded(d->m_points.count() - 1);
207 235 }
208 236
209 237 /*!
210 238 This is an overloaded function.
211 239 Adds list of data \a points to the series. Points are connected with lines on the chart.
212 240 */
213 241 void QXYSeries::append(const QList<QPointF> &points)
214 242 {
215 243 foreach (const QPointF &point , points)
216 244 append(point);
217 245 }
218 246
219 247 /*!
220 248 Replaces data point \a oldX \a oldY with data point \a newX \a newY.
221 249 \sa QXYSeries::pointReplaced()
222 250 */
223 251 void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY)
224 252 {
225 253 replace(QPointF(oldX, oldY), QPointF(newX, newY));
226 254 }
227 255
228 256 /*!
229 257 Replaces \a oldPoint with \a newPoint.
230 258 \sa QXYSeries::pointReplaced()
231 259 */
232 260 void QXYSeries::replace(const QPointF &oldPoint, const QPointF &newPoint)
233 261 {
234 262 Q_D(QXYSeries);
235 263 int index = d->m_points.indexOf(oldPoint);
236 264 if (index == -1)
237 265 return;
238 266 d->m_points[index] = newPoint;
239 267 emit pointReplaced(index);
240 268 }
241 269
242 270 /*!
243 271 Replaces the current points with \a points. This is faster than replacing data points one by one,
244 272 or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced()
245 273 when the points have been replaced.
246 274 \sa QXYSeries::pointsReplaced()
247 275 */
248 276 void QXYSeries::replace(QList<QPointF> points)
249 277 {
250 278 Q_D(QXYSeries);
251 279 d->m_points = points.toVector();
252 280 emit pointsReplaced();
253 281 }
254 282
255 283 /*!
256 284 Removes current \a x and \a y value.
257 285 */
258 286 void QXYSeries::remove(qreal x, qreal y)
259 287 {
260 288 remove(QPointF(x, y));
261 289 }
262 290
263 291 /*!
264 292 Removes current \a point x value.
265 293
266 294 Note: point y value is ignored.
267 295 */
268 296 void QXYSeries::remove(const QPointF &point)
269 297 {
270 298 Q_D(QXYSeries);
271 299 int index = d->m_points.indexOf(point);
272 300 if (index == -1)
273 301 return;
274 302 d->m_points.remove(index);
275 303 emit pointRemoved(index);
276 304 }
277 305
278 306 /*!
279 307 Inserts a \a point in the series at \a index position.
280 308 */
281 309 void QXYSeries::insert(int index, const QPointF &point)
282 310 {
283 311 Q_D(QXYSeries);
284 312 d->m_points.insert(index, point);
285 313 emit pointAdded(index);
286 314 }
287 315
288 316 /*!
289 317 Removes all points from the series.
290 318 */
291 319 void QXYSeries::clear()
292 320 {
293 321 Q_D(QXYSeries);
294 322 for (int i = d->m_points.size() - 1; i >= 0; i--)
295 323 remove(d->m_points.at(i));
296 324 }
297 325
298 326 /*!
299 327 Returns list of points in the series.
300 328 */
301 329 QList<QPointF> QXYSeries::points() const
302 330 {
303 331 Q_D(const QXYSeries);
304 332 return d->m_points.toList();
305 333 }
306 334
307 335 /*!
308 336 Returns number of data points within series.
309 337 */
310 338 int QXYSeries::count() const
311 339 {
312 340 Q_D(const QXYSeries);
313 341 return d->m_points.count();
314 342 }
315 343
316 344
317 345 /*!
318 346 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
319 347 pen from chart theme is used.
320 348 \sa QChart::setTheme()
321 349 */
322 350 void QXYSeries::setPen(const QPen &pen)
323 351 {
324 352 Q_D(QXYSeries);
325 353 if (d->m_pen != pen) {
326 354 bool emitColorChanged = d->m_pen.color() != pen.color();
327 355 d->m_pen = pen;
328 356 emit d->updated();
329 357 if (emitColorChanged)
330 358 emit colorChanged(pen.color());
331 359 }
332 360 }
333 361
334 362 QPen QXYSeries::pen() const
335 363 {
336 364 Q_D(const QXYSeries);
337 365 return d->m_pen;
338 366 }
339 367
340 368 /*!
341 369 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
342 370 from chart theme setting is used.
343 371 \sa QChart::setTheme()
344 372 */
345 373 void QXYSeries::setBrush(const QBrush &brush)
346 374 {
347 375 Q_D(QXYSeries);
348 376 if (d->m_brush != brush) {
349 377 d->m_brush = brush;
350 378 emit d->updated();
351 379 }
352 380 }
353 381
354 382 QBrush QXYSeries::brush() const
355 383 {
356 384 Q_D(const QXYSeries);
357 385 return d->m_brush;
358 386 }
359 387
360 388 void QXYSeries::setColor(const QColor &color)
361 389 {
362 390 QPen p = pen();
363 391 if (p.color() != color) {
364 392 p.setColor(color);
365 393 setPen(p);
366 394 }
367 395 }
368 396
369 397 QColor QXYSeries::color() const
370 398 {
371 399 return pen().color();
372 400 }
373 401
374 402 void QXYSeries::setPointsVisible(bool visible)
375 403 {
376 404 Q_D(QXYSeries);
377 405 if (d->m_pointsVisible != visible) {
378 406 d->m_pointsVisible = visible;
379 407 emit d->updated();
380 408 }
381 409 }
382 410
383 411 bool QXYSeries::pointsVisible() const
384 412 {
385 413 Q_D(const QXYSeries);
386 414 return d->m_pointsVisible;
387 415 }
388 416
389 417
390 418 /*!
391 419 Stream operator for adding a data \a point to the series.
392 420 \sa append()
393 421 */
394 422 QXYSeries &QXYSeries::operator<< (const QPointF &point)
395 423 {
396 424 append(point);
397 425 return *this;
398 426 }
399 427
400 428
401 429 /*!
402 430 Stream operator for adding a list of \a points to the series.
403 431 \sa append()
404 432 */
405 433
406 434 QXYSeries &QXYSeries::operator<< (const QList<QPointF>& points)
407 435 {
408 436 append(points);
409 437 return *this;
410 438 }
411 439
412 440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
413 441
414 442
415 443 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q)
416 444 : QAbstractSeriesPrivate(q),
417 445 m_pointsVisible(false)
418 446 {
419 447 }
420 448
421 449 void QXYSeriesPrivate::initializeDomain()
422 450 {
423 451 qreal minX(0);
424 452 qreal minY(0);
425 453 qreal maxX(1);
426 454 qreal maxY(1);
427 455
428 456 Q_Q(QXYSeries);
429 457
430 458 const QList<QPointF>& points = q->points();
431 459
432 460 if (!points.isEmpty()) {
433 461 minX = points[0].x();
434 462 minY = points[0].y();
435 463 maxX = minX;
436 464 maxY = minY;
437 465
438 466 for (int i = 0; i < points.count(); i++) {
439 467 qreal x = points[i].x();
440 468 qreal y = points[i].y();
441 469 minX = qMin(minX, x);
442 470 minY = qMin(minY, y);
443 471 maxX = qMax(maxX, x);
444 472 maxY = qMax(maxY, y);
445 473 }
446 474 }
447 475
448 476 domain()->setRange(minX, maxX, minY, maxY);
449 477 }
450 478
451 479 QList<QLegendMarker*> QXYSeriesPrivate::createLegendMarkers(QLegend* legend)
452 480 {
453 481 Q_Q(QXYSeries);
454 482 QList<QLegendMarker*> list;
455 483 return list << new QXYLegendMarker(q,legend);
456 484 }
457 485
458 486 void QXYSeriesPrivate::initializeAxes()
459 487 {
460 488
461 489 }
462 490
463 491 QAbstractAxis::AxisType QXYSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
464 492 {
465 493 Q_UNUSED(orientation);
466 494 return QAbstractAxis::AxisTypeValue;
467 495 }
468 496
469 497 QAbstractAxis* QXYSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
470 498 {
471 499 Q_UNUSED(orientation);
472 500 return 0;
473 501 }
474 502
475 503 void QXYSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
476 504 {
477 505 XYChart *item = static_cast<XYChart *>(m_item.data());
478 506 Q_ASSERT(item);
479 507 if (options.testFlag(QChart::SeriesAnimations)) {
480 508 item->setAnimation(new XYAnimation(item));
481 509 }else{
482 510 item->setAnimation(0);
483 511 }
484 512 QAbstractSeriesPrivate::initializeAnimations(options);
485 513 }
486 514
487 515 #include "moc_qxyseries.cpp"
488 516 #include "moc_qxyseries_p.cpp"
489 517
490 518 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now