##// END OF EJS Templates
Added QChart::localizeNumbers...
Miikka Heikkinen -
r2707:ef2ab40bd1b9
parent child
Show More
@@ -1,1032 +1,1054
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "declarativelineseries.h"
24 24 #include "declarativeareaseries.h"
25 25 #include "declarativebarseries.h"
26 26 #include "declarativepieseries.h"
27 27 #include "declarativesplineseries.h"
28 28 #include "declarativeboxplotseries.h"
29 29 #include "declarativescatterseries.h"
30 30 #include "qbarcategoryaxis.h"
31 31 #include "qvalueaxis.h"
32 32 #include "qlogvalueaxis.h"
33 33 #include "qcategoryaxis.h"
34 34 #include "qabstractseries_p.h"
35 35 #include "declarativemargins.h"
36 36 #include "chartdataset_p.h"
37 37 #include "declarativeaxes.h"
38 38 #include "qchart_p.h"
39 39 #include "qpolarchart.h"
40 40
41 41 #ifndef QT_ON_ARM
42 42 #include "qdatetimeaxis.h"
43 43 #endif
44 44
45 45 #ifdef CHARTS_FOR_QUICK2
46 46 #include <QGraphicsSceneMouseEvent>
47 47 #include <QGraphicsSceneHoverEvent>
48 48 #include <QApplication>
49 49 #include <QTimer>
50 50 #include <QThread>
51 51 #endif
52 52
53 53 QTCOMMERCIALCHART_BEGIN_NAMESPACE
54 54
55 55 #ifdef QDOC_QT5
56 56 /*!
57 57 \qmltype ChartView
58 58 \instantiates DeclarativeChart
59 59 \inqmlmodule QtCommercial.Chart
60 60
61 61 \include doc/src/chartview.qdocinc
62 62 */
63 63 #else
64 64 /*!
65 65 \qmlclass ChartView DeclarativeChart
66 66
67 67 \include ../doc/src/chartview.qdocinc
68 68 */
69 69 #endif
70 70
71 71 /*!
72 72 \qmlproperty Theme ChartView::theme
73 73 Theme defines the visual appearance of the chart, including for example colors, fonts, line
74 74 widths and chart background.
75 75 */
76 76
77 77 /*!
78 78 \qmlproperty Animation ChartView::animationOptions
79 79 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
80 80 ChartView.SeriesAnimations or ChartView.AllAnimations.
81 81 */
82 82
83 83 /*!
84 84 \qmlproperty Font ChartView::titleFont
85 85 The title font of the chart.
86 86
87 87 See the Qt documentation for more details of Font.
88 88 */
89 89
90 90 /*!
91 91 \qmlproperty string ChartView::title
92 92 The title of the chart, shown on top of the chart.
93 93 \sa ChartView::titleColor
94 94 */
95 95
96 96 /*!
97 97 \qmlproperty color ChartView::titleColor
98 98 The color of the title text.
99 99 */
100 100
101 101 /*!
102 102 \qmlproperty Legend ChartView::legend
103 103 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
104 104 */
105 105
106 106 /*!
107 107 \qmlproperty int ChartView::count
108 108 The count of series added to the chart.
109 109 */
110 110
111 111 /*!
112 112 \qmlproperty color ChartView::backgroundColor
113 113 The color of the chart's background. By default background color is defined by chart theme.
114 114 \sa ChartView::theme
115 115 */
116 116
117 117 /*!
118 118 \qmlproperty real ChartView::backgroundRoundness
119 119 The diameter of the rounding cirle at the corners of the chart background.
120 120 */
121 121
122 122 /*!
123 123 \qmlproperty color ChartView::plotAreaColor
124 124 The color of the background of the chart's plot area. By default plot area background uses chart's
125 125 background color.
126 126 \sa ChartView::backgroundColor
127 127 */
128 128
129 129 /*!
130 130 \qmlproperty bool ChartView::dropShadowEnabled
131 131 The chart's border drop shadow. Set to true to enable drop shadow.
132 132 */
133 133
134 134 /*!
135 135 \qmlproperty real ChartView::topMargin
136 136 Deprecated; use margins instead.
137 137 */
138 138
139 139 /*!
140 140 \qmlproperty real ChartView::bottomMargin
141 141 Deprecated; use margins instead.
142 142 */
143 143
144 144 /*!
145 145 \qmlproperty real ChartView::leftMargin
146 146 Deprecated; use margins instead.
147 147 */
148 148
149 149 /*!
150 150 \qmlproperty real ChartView::rightMargin
151 151 Deprecated; use margins instead.
152 152 */
153 153
154 154 /*!
155 155 \qmlproperty Margins ChartView::minimumMargins
156 156 Deprecated; use margins instead.
157 157 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
158 158 area of ChartView is used for drawing title, axes and legend. Please note that setting the
159 159 properties of minimumMargins may be bigger than the defined value, depending on other ChartView
160 160 properties that affect it's layout. If you need to know the actual plotting area used at any
161 161 given time, you can check ChartView::plotArea instead.
162 162 */
163 163
164 164 /*!
165 165 \qmlproperty rect ChartView::plotArea
166 166 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
167 167 margins.
168 168 \sa ChartView::minimumMargins
169 169 */
170 170
171 171 /*!
172 172 \qmlproperty Margins ChartView::margins
173 173 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
174 174 area of ChartView is used for drawing title, axes and legend.
175 175 */
176 176
177 177 /*!
178 \qmlproperty bool ChartView::localizeNumbers
179 \since QtCharts 2.0
180 When \c{true}, all generated numbers appearing in various series and axis labels will be
181 localized using the default QLocale of the application, which defaults to the system locale.
182 When \c{false}, the "C" locale is always used.
183 Defaults to \c{false}.
184 */
185
186 /*!
178 187 \qmlmethod AbstractSeries ChartView::series(int index)
179 188 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
180 189 the count property of the chart.
181 190 */
182 191
183 192 /*!
184 193 \qmlmethod AbstractSeries ChartView::series(string name)
185 194 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
186 195 */
187 196
188 197 /*!
189 198 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
190 199 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
191 200 optional axis \a axisY. For example:
192 201 \code
193 202 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
194 203 var myAxisX = chartView.axisX(lineSeries);
195 204 var myAxisY = chartView.axisY(lineSeries);
196 205 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
197 206 \endcode
198 207 */
199 208
200 209 /*!
201 210 \qmlmethod ChartView::removeSeries(AbstractSeries series)
202 211 Removes the \a series from the chart. The series object is also destroyed.
203 212 */
204 213
205 214 /*!
206 215 \qmlmethod ChartView::removeAllSeries()
207 216 Removes all series from the chart. All the series objects are also destroyed.
208 217 */
209 218
210 219 /*!
211 220 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
212 221 The x-axis of the series.
213 222 */
214 223
215 224 /*!
216 225 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
217 226 The y-axis of the series.
218 227 */
219 228
220 229 /*!
221 230 \qmlmethod ChartView::zoomY(real factor)
222 231 Zooms in by \a factor on the center of the chart.
223 232 */
224 233
225 234 /*!
226 235 \qmlmethod ChartView::scrollLeft(real pixels)
227 236 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
228 237 */
229 238
230 239 /*!
231 240 \qmlmethod ChartView::scrollRight(real pixels)
232 241 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
233 242 */
234 243
235 244 /*!
236 245 \qmlmethod ChartView::scrollUp(real pixels)
237 246 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
238 247 */
239 248
240 249 /*!
241 250 \qmlmethod ChartView::scrollDown(real pixels)
242 251 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
243 252 */
244 253
245 254 /*!
246 255 \qmlsignal ChartView::onPlotAreaChanged(rect plotArea)
247 256 The plot area of the chart has changed. This may happen for example, if you modify minimumMargins
248 257 or if you resize the chart, or if you modify font size related properties of the legend or chart
249 258 title.
250 259 */
251 260
252 261 /*!
253 262 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
254 263 The \a series has been added to the chart.
255 264 */
256 265
257 266 /*!
258 267 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
259 268 The \a series has been removed from the chart. Please note that \a series is no longer a valid
260 269 object after the signal handler has completed.
261 270 */
262 271
263 272 DeclarativeChart::DeclarativeChart(QDECLARATIVE_ITEM *parent)
264 273 : QDECLARATIVE_PAINTED_ITEM(parent)
265 274 {
266 275 initChart(QChart::ChartTypeCartesian);
267 276 }
268 277
269 278 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QDECLARATIVE_ITEM *parent)
270 279 : QDECLARATIVE_PAINTED_ITEM(parent)
271 280 {
272 281 initChart(type);
273 282 }
274 283
275 284 void DeclarativeChart::initChart(QChart::ChartType type)
276 285 {
277 286 #ifdef CHARTS_FOR_QUICK2
278 287 m_currentSceneImage = 0;
279 288 m_guiThreadId = QThread::currentThreadId();
280 289 m_paintThreadId = 0;
281 290 m_updatePending = false;
282 291
283 292 if (type == QChart::ChartTypePolar)
284 293 m_chart = new QPolarChart();
285 294 else
286 295 m_chart = new QChart();
287 296
288 297 m_scene = new QGraphicsScene(this);
289 298 m_scene->addItem(m_chart);
290 299
291 300 setAntialiasing(QQuickItem::antialiasing());
292 301 connect(m_scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(sceneChanged(QList<QRectF>)));
293 302 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
294 303
295 304 setAcceptedMouseButtons(Qt::AllButtons);
296 305 setAcceptHoverEvents(true);
297 306 #else
298 307 if (type == QChart::ChartTypePolar)
299 308 m_chart = new QPolarChart(this);
300 309 else
301 310 m_chart = new QChart(this);
302 311
303 312 setFlag(QGraphicsItem::ItemHasNoContents, false);
304 313 #endif
305 314
306 315 m_margins = new DeclarativeMargins(this);
307 316 m_margins->setTop(m_chart->margins().top());
308 317 m_margins->setLeft(m_chart->margins().left());
309 318 m_margins->setRight(m_chart->margins().right());
310 319 m_margins->setBottom(m_chart->margins().bottom());
311 320 connect(m_margins, SIGNAL(topChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
312 321 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
313 322 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
314 323 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
315 324 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
316 325 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
317 326 }
318 327
319 328 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
320 329 {
321 330 emit seriesAdded(series);
322 331 }
323 332
324 333 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
325 334 {
326 335 m_chart->setMargins(QMargins(left, top, right, bottom));
327 336 emit minimumMarginsChanged();
328 337 emit plotAreaChanged(m_chart->plotArea());
329 338 }
330 339
331 340 DeclarativeChart::~DeclarativeChart()
332 341 {
333 342 delete m_chart;
334 343 #ifdef CHARTS_FOR_QUICK2
335 344 m_sceneImageLock.lock();
336 345 delete m_currentSceneImage;
337 346 m_currentSceneImage = 0;
338 347 m_sceneImageLock.unlock();
339 348 #endif
340 349 }
341 350
342 351 void DeclarativeChart::childEvent(QChildEvent *event)
343 352 {
344 353 if (event->type() == QEvent::ChildAdded) {
345 354 if (qobject_cast<QAbstractSeries *>(event->child())) {
346 355 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
347 356 }
348 357 }
349 358 }
350 359
351 360 void DeclarativeChart::componentComplete()
352 361 {
353 362 foreach (QObject *child, children()) {
354 363 if (qobject_cast<QAbstractSeries *>(child)) {
355 364 // Add series to the chart
356 365 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
357 366 m_chart->addSeries(series);
358 367
359 368 // Connect to axis changed signals (unless this is a pie series)
360 369 if (!qobject_cast<DeclarativePieSeries *>(series)) {
361 370 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
362 371 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
363 372 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
364 373 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
365 374 }
366 375
367 376 initializeAxes(series);
368 377 }
369 378 }
370 379
371 380 QDECLARATIVE_ITEM::componentComplete();
372 381 }
373 382
374 383 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
375 384 {
376 385 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
377 386 if (axis && s) {
378 387 if (!m_chart->axes(Qt::Horizontal).contains(axis))
379 388 m_chart->setAxisX(axis, s);
380 389 if (!s->attachedAxes().contains(axis))
381 390 s->attachAxis(axis);
382 391 } else {
383 392 qWarning() << "Trying to set axisX to null.";
384 393 }
385 394 }
386 395
387 396 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
388 397 {
389 398 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
390 399 if (axis && s) {
391 400 if (!m_chart->axes(Qt::Horizontal).contains(axis)) {
392 401 QList<QAbstractAxis *> oldAxes = m_chart->axes(Qt::Horizontal, s);
393 402 foreach (QAbstractAxis* a, oldAxes) {
394 403 m_chart->removeAxis(a);
395 404 delete a;
396 405 }
397 406 m_chart->addAxis(axis, Qt::AlignTop);
398 407 }
399 408 if (!s->attachedAxes().contains(axis))
400 409 s->attachAxis(axis);
401 410 } else {
402 411 qWarning() << "Trying to set axisXTop to null.";
403 412 }
404 413 }
405 414
406 415 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
407 416 {
408 417 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
409 418 if (axis && s) {
410 419 if (!m_chart->axes(Qt::Vertical).contains(axis))
411 420 m_chart->setAxisY(axis, s);
412 421 if (!s->attachedAxes().contains(axis))
413 422 s->attachAxis(axis);
414 423 } else {
415 424 qWarning() << "Trying to set axisY to null.";
416 425 }
417 426 }
418 427
419 428 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
420 429 {
421 430 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
422 431 if (axis && s) {
423 432 if (!m_chart->axes(Qt::Vertical).contains(axis)) {
424 433 QList<QAbstractAxis *> oldAxes = m_chart->axes((Qt::Vertical), s);
425 434 foreach (QAbstractAxis* a, oldAxes) {
426 435 m_chart->removeAxis(a);
427 436 delete a;
428 437 }
429 438 m_chart->addAxis(axis, Qt::AlignRight);
430 439 }
431 440 if (!s->attachedAxes().contains(axis))
432 441 s->attachAxis(axis);
433 442 } else {
434 443 qWarning() << "Trying to set axisYRight to null.";
435 444 }
436 445 }
437 446
438 447 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
439 448 {
440 449 if (newGeometry.isValid()) {
441 450 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
442 451 m_chart->resize(newGeometry.width(), newGeometry.height());
443 452 }
444 453 }
445 454 QDECLARATIVE_ITEM::geometryChanged(newGeometry, oldGeometry);
446 455
447 456 // It would be better to trigger the plotAreaChanged signal from QChart::plotAreaChanged or
448 457 // similar. Since that kind of a signal is not clearly needed in the C++ API the work-around is
449 458 // to implement it here for the QML API purposes.
450 459 emit plotAreaChanged(m_chart->plotArea());
451 460 }
452 461
453 462 #ifdef CHARTS_FOR_QUICK2
454 463 void DeclarativeChart::sceneChanged(QList<QRectF> region)
455 464 {
456 465 Q_UNUSED(region);
457 466
458 467 if (m_guiThreadId == m_paintThreadId) {
459 468 // Rendering in gui thread, no need for shenannigans, just update
460 469 update();
461 470 } else {
462 471 // Multi-threaded rendering, need to ensure scene is actually rendered in gui thread
463 472 if (!m_updatePending) {
464 473 m_updatePending = true;
465 474 // Do async render to avoid some unnecessary renders.
466 475 QTimer::singleShot(0, this, SLOT(renderScene()));
467 476 }
468 477 }
469 478 }
470 479
471 480 void DeclarativeChart::renderScene()
472 481 {
473 482 m_updatePending = false;
474 483 m_sceneImageLock.lock();
475 484 delete m_currentSceneImage;
476 485 m_currentSceneImage = new QImage(m_chart->size().toSize(), QImage::Format_ARGB32);
477 486 m_currentSceneImage->fill(Qt::transparent);
478 487 QPainter painter(m_currentSceneImage);
479 488 if (antialiasing())
480 489 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
481 490 QRect renderRect(QPoint(0, 0), m_chart->size().toSize());
482 491 m_scene->render(&painter, renderRect, renderRect);
483 492 m_sceneImageLock.unlock();
484 493
485 494 update();
486 495 }
487 496
488 497 void DeclarativeChart::paint(QPainter *painter)
489 498 {
490 499 if (!m_paintThreadId) {
491 500 m_paintThreadId = QThread::currentThreadId();
492 501 if (m_guiThreadId == m_paintThreadId) {
493 502 // No need for scene image in single threaded rendering, so delete
494 503 // the one that got made by default before the rendering type was
495 504 // detected.
496 505 delete m_currentSceneImage;
497 506 m_currentSceneImage = 0;
498 507 }
499 508 }
500 509
501 510 if (m_guiThreadId == m_paintThreadId) {
502 511 QRectF renderRect(QPointF(0, 0), m_chart->size());
503 512 m_scene->render(painter, renderRect, renderRect);
504 513 } else {
505 514 m_sceneImageLock.lock();
506 515 if (m_currentSceneImage) {
507 516 QRect imageRect(QPoint(0, 0), m_currentSceneImage->size());
508 517 QRect itemRect(QPoint(0, 0), QSize(width(), height()));
509 518 painter->drawImage(itemRect, *m_currentSceneImage, imageRect);
510 519 }
511 520 m_sceneImageLock.unlock();
512 521 }
513 522 }
514 523
515 524 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
516 525 {
517 526 m_mousePressScenePoint = event->pos();
518 527 m_mousePressScreenPoint = event->globalPos();
519 528 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
520 529 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
521 530 m_mousePressButton = event->button();
522 531 m_mousePressButtons = event->buttons();
523 532
524 533 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
525 534 mouseEvent.setWidget(0);
526 535 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
527 536 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
528 537 mouseEvent.setScenePos(m_mousePressScenePoint);
529 538 mouseEvent.setScreenPos(m_mousePressScreenPoint);
530 539 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
531 540 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
532 541 mouseEvent.setButtons(m_mousePressButtons);
533 542 mouseEvent.setButton(m_mousePressButton);
534 543 mouseEvent.setModifiers(event->modifiers());
535 544 mouseEvent.setAccepted(false);
536 545
537 546 QApplication::sendEvent(m_scene, &mouseEvent);
538 547 }
539 548
540 549 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
541 550 {
542 551 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
543 552 mouseEvent.setWidget(0);
544 553 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
545 554 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
546 555 mouseEvent.setScenePos(event->pos());
547 556 mouseEvent.setScreenPos(event->globalPos());
548 557 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
549 558 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
550 559 mouseEvent.setButtons(event->buttons());
551 560 mouseEvent.setButton(event->button());
552 561 mouseEvent.setModifiers(event->modifiers());
553 562 mouseEvent.setAccepted(false);
554 563
555 564 QApplication::sendEvent(m_scene, &mouseEvent);
556 565
557 566 m_mousePressButtons = event->buttons();
558 567 m_mousePressButton = Qt::NoButton;
559 568 }
560 569
561 570 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
562 571 {
563 572 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
564 573 // QGraphicsScene generates hover events from mouse move events, so we don't need
565 574 // to pass hover events there.
566 575 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
567 576 mouseEvent.setWidget(0);
568 577 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
569 578 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
570 579 mouseEvent.setScenePos(event->pos());
571 580 // Hover events do not have global pos in them, and the screen position doesn't seem to
572 581 // matter anyway in this use case, so just pass event pos instead of trying to
573 582 // calculate the real screen position.
574 583 mouseEvent.setScreenPos(event->pos());
575 584 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
576 585 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
577 586 mouseEvent.setButtons(m_mousePressButtons);
578 587 mouseEvent.setButton(m_mousePressButton);
579 588 mouseEvent.setModifiers(event->modifiers());
580 589 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
581 590 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
582 591 mouseEvent.setAccepted(false);
583 592
584 593 QApplication::sendEvent(m_scene, &mouseEvent);
585 594 }
586 595
587 596 void DeclarativeChart::handleAntialiasingChanged(bool enable)
588 597 {
589 598 setAntialiasing(enable);
590 599 }
591 600 #endif
592 601
593 602 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
594 603 {
595 604 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
596 605 if (chartTheme != m_chart->theme())
597 606 m_chart->setTheme(chartTheme);
598 607 }
599 608
600 609 DeclarativeChart::Theme DeclarativeChart::theme()
601 610 {
602 611 return (DeclarativeChart::Theme) m_chart->theme();
603 612 }
604 613
605 614 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
606 615 {
607 616 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
608 617 if (animationOptions != m_chart->animationOptions())
609 618 m_chart->setAnimationOptions(animationOptions);
610 619 }
611 620
612 621 DeclarativeChart::Animation DeclarativeChart::animationOptions()
613 622 {
614 623 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
615 624 return DeclarativeChart::AllAnimations;
616 625 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
617 626 return DeclarativeChart::GridAxisAnimations;
618 627 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
619 628 return DeclarativeChart::SeriesAnimations;
620 629 else
621 630 return DeclarativeChart::NoAnimation;
622 631 }
623 632
624 633 void DeclarativeChart::setTitle(QString title)
625 634 {
626 635 if (title != m_chart->title())
627 636 m_chart->setTitle(title);
628 637 }
629 638 QString DeclarativeChart::title()
630 639 {
631 640 return m_chart->title();
632 641 }
633 642
634 643 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
635 644 {
636 645 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
637 646 if (axes.count())
638 647 return axes[0];
639 648 return 0;
640 649 }
641 650
642 651 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
643 652 {
644 653 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
645 654 if (axes.count())
646 655 return axes[0];
647 656 return 0;
648 657 }
649 658
650 659 QLegend *DeclarativeChart::legend()
651 660 {
652 661 return m_chart->legend();
653 662 }
654 663
655 664 void DeclarativeChart::setTitleColor(QColor color)
656 665 {
657 666 QBrush b = m_chart->titleBrush();
658 667 if (color != b.color()) {
659 668 b.setColor(color);
660 669 m_chart->setTitleBrush(b);
661 670 emit titleColorChanged(color);
662 671 }
663 672 }
664 673
665 674 QFont DeclarativeChart::titleFont() const
666 675 {
667 676 return m_chart->titleFont();
668 677 }
669 678
670 679 void DeclarativeChart::setTitleFont(const QFont &font)
671 680 {
672 681 m_chart->setTitleFont(font);
673 682 }
674 683
675 684 QColor DeclarativeChart::titleColor()
676 685 {
677 686 return m_chart->titleBrush().color();
678 687 }
679 688
680 689 void DeclarativeChart::setBackgroundColor(QColor color)
681 690 {
682 691 QBrush b = m_chart->backgroundBrush();
683 692 if (b.style() != Qt::SolidPattern || color != b.color()) {
684 693 b.setStyle(Qt::SolidPattern);
685 694 b.setColor(color);
686 695 m_chart->setBackgroundBrush(b);
687 696 emit backgroundColorChanged();
688 697 }
689 698 }
690 699
691 700 QColor DeclarativeChart::backgroundColor()
692 701 {
693 702 return m_chart->backgroundBrush().color();
694 703 }
695 704
696 705 void QtCommercialChart::DeclarativeChart::setPlotAreaColor(QColor color)
697 706 {
698 707 QBrush b = m_chart->plotAreaBackgroundBrush();
699 708 if (b.style() != Qt::SolidPattern || color != b.color()) {
700 709 b.setStyle(Qt::SolidPattern);
701 710 b.setColor(color);
702 711 m_chart->setPlotAreaBackgroundBrush(b);
703 712 m_chart->setPlotAreaBackgroundVisible(true);
704 713 emit plotAreaColorChanged();
705 714 }
706 715 }
707 716
708 717 QColor QtCommercialChart::DeclarativeChart::plotAreaColor()
709 718 {
710 719 return m_chart->plotAreaBackgroundBrush().color();
711 720 }
712 721
722 void DeclarativeChart::setLocalizeNumbers(bool localize)
723 {
724 if (m_chart->localizeNumbers() != localize) {
725 m_chart->setLocalizeNumbers(localize);
726 emit localizeNumbersChanged();
727 }
728 }
729
730 bool DeclarativeChart::localizeNumbers() const
731 {
732 return m_chart->localizeNumbers();
733 }
734
713 735 int DeclarativeChart::count()
714 736 {
715 737 return m_chart->series().count();
716 738 }
717 739
718 740 void DeclarativeChart::setDropShadowEnabled(bool enabled)
719 741 {
720 742 if (enabled != m_chart->isDropShadowEnabled()) {
721 743 m_chart->setDropShadowEnabled(enabled);
722 744 dropShadowEnabledChanged(enabled);
723 745 }
724 746 }
725 747
726 748 bool DeclarativeChart::dropShadowEnabled()
727 749 {
728 750 return m_chart->isDropShadowEnabled();
729 751 }
730 752
731 753 qreal DeclarativeChart::backgroundRoundness() const
732 754 {
733 755 return m_chart->backgroundRoundness();
734 756 }
735 757
736 758 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
737 759 {
738 760 if (m_chart->backgroundRoundness() != diameter) {
739 761 m_chart->setBackgroundRoundness(diameter);
740 762 emit backgroundRoundnessChanged(diameter);
741 763 }
742 764 }
743 765
744 766 qreal DeclarativeChart::topMargin()
745 767 {
746 768 qWarning() << "ChartView.topMargin is deprecated. Use margins instead.";
747 769 return m_chart->margins().top();
748 770 }
749 771
750 772 qreal DeclarativeChart::bottomMargin()
751 773 {
752 774 qWarning() << "ChartView.bottomMargin is deprecated. Use margins instead.";
753 775 return m_chart->margins().bottom();
754 776 }
755 777
756 778 qreal DeclarativeChart::leftMargin()
757 779 {
758 780 qWarning() << "ChartView.leftMargin is deprecated. Use margins instead.";
759 781 return m_chart->margins().left();
760 782 }
761 783
762 784 qreal DeclarativeChart::rightMargin()
763 785 {
764 786 qWarning() << "ChartView.rightMargin is deprecated. Use margins instead.";
765 787 return m_chart->margins().right();
766 788 }
767 789
768 790 void DeclarativeChart::zoom(qreal factor)
769 791 {
770 792 m_chart->zoom(factor);
771 793 }
772 794
773 795 void DeclarativeChart::scrollLeft(qreal pixels)
774 796 {
775 797 m_chart->scroll(-pixels, 0);
776 798 }
777 799
778 800 void DeclarativeChart::scrollRight(qreal pixels)
779 801 {
780 802 m_chart->scroll(pixels, 0);
781 803 }
782 804
783 805 void DeclarativeChart::scrollUp(qreal pixels)
784 806 {
785 807 m_chart->scroll(0, pixels);
786 808 }
787 809
788 810 void DeclarativeChart::scrollDown(qreal pixels)
789 811 {
790 812 m_chart->scroll(0, -pixels);
791 813 }
792 814
793 815 QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> DeclarativeChart::axes()
794 816 {
795 817 return QDECLARATIVE_LIST_PROPERTY<QAbstractAxis>(this, 0,
796 818 &DeclarativeChart::axesAppendFunc,
797 819 &DeclarativeChart::axesCountFunc,
798 820 #ifdef CHARTS_FOR_QUICK2
799 821 &DeclarativeChart::axesAtFunc,
800 822 &DeclarativeChart::axesClearFunc);
801 823 #else
802 824 &DeclarativeChart::axesAtFunc);
803 825 #endif
804 826 }
805 827
806 828 void DeclarativeChart::axesAppendFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, QAbstractAxis *element)
807 829 {
808 830 // Empty implementation
809 831 Q_UNUSED(list);
810 832 Q_UNUSED(element);
811 833 }
812 834
813 835 int DeclarativeChart::axesCountFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list)
814 836 {
815 837 if (qobject_cast<DeclarativeChart *>(list->object)) {
816 838 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
817 839 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
818 840 }
819 841 return 0;
820 842 }
821 843
822 844 QAbstractAxis *DeclarativeChart::axesAtFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, int index)
823 845 {
824 846 if (qobject_cast<DeclarativeChart *>(list->object)) {
825 847 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
826 848 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
827 849 return axes.at(index);
828 850 }
829 851 return 0;
830 852 }
831 853
832 854 void DeclarativeChart::axesClearFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list)
833 855 {
834 856 // Empty implementation
835 857 Q_UNUSED(list);
836 858 }
837 859
838 860
839 861 QAbstractSeries *DeclarativeChart::series(int index)
840 862 {
841 863 if (index < m_chart->series().count()) {
842 864 return m_chart->series().at(index);
843 865 }
844 866 return 0;
845 867 }
846 868
847 869 QAbstractSeries *DeclarativeChart::series(QString seriesName)
848 870 {
849 871 foreach (QAbstractSeries *series, m_chart->series()) {
850 872 if (series->name() == seriesName)
851 873 return series;
852 874 }
853 875 return 0;
854 876 }
855 877
856 878 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
857 879 {
858 880 QAbstractSeries *series = 0;
859 881
860 882 switch (type) {
861 883 case DeclarativeChart::SeriesTypeLine:
862 884 series = new DeclarativeLineSeries();
863 885 break;
864 886 case DeclarativeChart::SeriesTypeArea: {
865 887 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
866 888 area->setUpperSeries(new DeclarativeLineSeries());
867 889 series = area;
868 890 break;
869 891 }
870 892 case DeclarativeChart::SeriesTypeStackedBar:
871 893 series = new DeclarativeStackedBarSeries();
872 894 break;
873 895 case DeclarativeChart::SeriesTypePercentBar:
874 896 series = new DeclarativePercentBarSeries();
875 897 break;
876 898 case DeclarativeChart::SeriesTypeBar:
877 899 series = new DeclarativeBarSeries();
878 900 break;
879 901 case DeclarativeChart::SeriesTypeHorizontalBar:
880 902 series = new DeclarativeHorizontalBarSeries();
881 903 break;
882 904 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
883 905 series = new DeclarativeHorizontalPercentBarSeries();
884 906 break;
885 907 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
886 908 series = new DeclarativeHorizontalStackedBarSeries();
887 909 break;
888 910 case DeclarativeChart::SeriesTypeBoxPlot:
889 911 series = new DeclarativeBoxPlotSeries();
890 912 break;
891 913 case DeclarativeChart::SeriesTypePie:
892 914 series = new DeclarativePieSeries();
893 915 break;
894 916 case DeclarativeChart::SeriesTypeScatter:
895 917 series = new DeclarativeScatterSeries();
896 918 break;
897 919 case DeclarativeChart::SeriesTypeSpline:
898 920 series = new DeclarativeSplineSeries();
899 921 break;
900 922 default:
901 923 qWarning() << "Illegal series type";
902 924 }
903 925
904 926 if (series) {
905 927 // Connect to axis changed signals (unless this is a pie series)
906 928 if (!qobject_cast<DeclarativePieSeries *>(series)) {
907 929 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
908 930 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
909 931 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
910 932 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
911 933 }
912 934
913 935 series->setName(name);
914 936 m_chart->addSeries(series);
915 937
916 938 if (axisX)
917 939 setAxisX(axisX, series);
918 940 if (axisY)
919 941 setAxisY(axisY, series);
920 942
921 943 if (series->attachedAxes().count() < 2)
922 944 initializeAxes(series);
923 945 }
924 946
925 947 return series;
926 948 }
927 949
928 950 void DeclarativeChart::removeSeries(QAbstractSeries *series)
929 951 {
930 952 if (series)
931 953 m_chart->removeSeries(series);
932 954 else
933 955 qWarning("removeSeries: cannot remove null");
934 956 }
935 957
936 958 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
937 959 {
938 960 if (axis)
939 961 m_chart->setAxisX(axis, series);
940 962 }
941 963
942 964 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
943 965 {
944 966 if (axis)
945 967 m_chart->setAxisY(axis, series);
946 968 }
947 969
948 970 void DeclarativeChart::createDefaultAxes()
949 971 {
950 972 qWarning() << "ChartView.createDefaultAxes() is deprecated. Axes are created automatically.";
951 973 }
952 974
953 975 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
954 976 {
955 977 if (!series) {
956 978 qWarning() << "No axis type defined for null series";
957 979 return 0;
958 980 }
959 981
960 982 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
961 983 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
962 984 return existingAxis;
963 985 }
964 986
965 987 switch (series->d_ptr->defaultAxisType(orientation)) {
966 988 case QAbstractAxis::AxisTypeValue:
967 989 return new QValueAxis(this);
968 990 case QAbstractAxis::AxisTypeBarCategory:
969 991 return new QBarCategoryAxis(this);
970 992 case QAbstractAxis::AxisTypeCategory:
971 993 return new QCategoryAxis(this);
972 994 #ifndef QT_ON_ARM
973 995 case QAbstractAxis::AxisTypeDateTime:
974 996 return new QDateTimeAxis(this);
975 997 #endif
976 998 case QAbstractAxis::AxisTypeLogValue:
977 999 return new QLogValueAxis(this);
978 1000 default:
979 1001 // assume AxisTypeNoAxis
980 1002 return 0;
981 1003 }
982 1004 }
983 1005
984 1006 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
985 1007 {
986 1008 if (qobject_cast<DeclarativeLineSeries *>(series))
987 1009 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
988 1010 else if (qobject_cast<DeclarativeScatterSeries *>(series))
989 1011 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
990 1012 else if (qobject_cast<DeclarativeSplineSeries *>(series))
991 1013 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
992 1014 else if (qobject_cast<DeclarativeAreaSeries *>(series))
993 1015 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
994 1016 else if (qobject_cast<DeclarativeBarSeries *>(series))
995 1017 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
996 1018 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
997 1019 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
998 1020 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
999 1021 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1000 1022 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1001 1023 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1002 1024 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1003 1025 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1004 1026 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1005 1027 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1006 1028 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1007 1029 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1008 1030 // else: do nothing
1009 1031 }
1010 1032
1011 1033 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1012 1034 {
1013 1035 // Initialize axis X
1014 1036 if (axes->axisX())
1015 1037 axes->emitAxisXChanged();
1016 1038 else if (axes->axisXTop())
1017 1039 axes->emitAxisXTopChanged();
1018 1040 else
1019 1041 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1020 1042
1021 1043 // Initialize axis Y
1022 1044 if (axes->axisY())
1023 1045 axes->emitAxisYChanged();
1024 1046 else if (axes->axisYRight())
1025 1047 axes->emitAxisYRightChanged();
1026 1048 else
1027 1049 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1028 1050 }
1029 1051
1030 1052 #include "moc_declarativechart.cpp"
1031 1053
1032 1054 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,235 +1,240
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef DECLARATIVECHART_H
22 22 #define DECLARATIVECHART_H
23 23
24 24 #include <QtCore/QtGlobal>
25 25 #include "shared_defines.h"
26 26
27 27 #ifdef CHARTS_FOR_QUICK2
28 28 #include <QtQuick/QQuickItem>
29 29 #include <QtQuick/QQuickPaintedItem>
30 30 #include <QtWidgets/QGraphicsScene>
31 31 #include <QtCore/QMutex>
32 32 #else
33 33 #include <QtDeclarative/QDeclarativeItem>
34 34 #endif
35 35
36 36 #include "qchart.h"
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class DeclarativeMargins;
41 41 class Domain;
42 42 class DeclarativeAxes;
43 43
44 44 class DeclarativeChart : public QDECLARATIVE_PAINTED_ITEM
45 45 {
46 46 Q_OBJECT
47 47 Q_PROPERTY(Theme theme READ theme WRITE setTheme)
48 48 Q_PROPERTY(Animation animationOptions READ animationOptions WRITE setAnimationOptions)
49 49 Q_PROPERTY(QString title READ title WRITE setTitle)
50 50 Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont)
51 51 Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor NOTIFY titleColorChanged)
52 52 Q_PROPERTY(QLegend *legend READ legend CONSTANT)
53 53 Q_PROPERTY(int count READ count)
54 54 Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
55 55 Q_PROPERTY(bool dropShadowEnabled READ dropShadowEnabled WRITE setDropShadowEnabled NOTIFY dropShadowEnabledChanged)
56 56 Q_PROPERTY(qreal backgroundRoundness READ backgroundRoundness WRITE setBackgroundRoundness NOTIFY backgroundRoundnessChanged REVISION 3)
57 57 Q_PROPERTY(qreal topMargin READ topMargin)
58 58 Q_PROPERTY(qreal bottomMargin READ bottomMargin)
59 59 Q_PROPERTY(qreal leftMargin READ leftMargin)
60 60 Q_PROPERTY(qreal rightMargin READ rightMargin)
61 61 Q_PROPERTY(DeclarativeMargins *minimumMargins READ minimumMargins NOTIFY minimumMarginsChanged REVISION 1)
62 62 Q_PROPERTY(DeclarativeMargins *margins READ margins NOTIFY marginsChanged REVISION 2)
63 63 Q_PROPERTY(QRectF plotArea READ plotArea NOTIFY plotAreaChanged REVISION 1)
64 64 Q_PROPERTY(QColor plotAreaColor READ plotAreaColor WRITE setPlotAreaColor NOTIFY plotAreaColorChanged REVISION 3)
65 65 #ifdef CHARTS_FOR_QUICK2
66 66 Q_PROPERTY(QQmlListProperty<QAbstractAxis> axes READ axes REVISION 2)
67 67 #else
68 68 Q_PROPERTY(QDeclarativeListProperty<QAbstractAxis> axes READ axes REVISION 2)
69 69 #endif
70 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers NOTIFY localizeNumbersChanged REVISION 4)
70 71 Q_ENUMS(Animation)
71 72 Q_ENUMS(Theme)
72 73 Q_ENUMS(SeriesType)
73 74
74 75 public:
75 76 // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api
76 77 enum Theme {
77 78 ChartThemeLight = 0,
78 79 ChartThemeBlueCerulean,
79 80 ChartThemeDark,
80 81 ChartThemeBrownSand,
81 82 ChartThemeBlueNcs,
82 83 ChartThemeHighContrast,
83 84 ChartThemeBlueIcy,
84 85 ChartThemeQt
85 86 };
86 87
87 88 enum Animation {
88 89 NoAnimation = 0x0,
89 90 GridAxisAnimations = 0x1,
90 91 SeriesAnimations = 0x2,
91 92 AllAnimations = 0x3
92 93 };
93 94
94 95 enum SeriesType {
95 96 SeriesTypeLine,
96 97 SeriesTypeArea,
97 98 SeriesTypeBar,
98 99 SeriesTypeStackedBar,
99 100 SeriesTypePercentBar,
100 101 SeriesTypeBoxPlot,
101 102 SeriesTypePie,
102 103 SeriesTypeScatter,
103 104 SeriesTypeSpline,
104 105 SeriesTypeHorizontalBar,
105 106 SeriesTypeHorizontalStackedBar,
106 107 SeriesTypeHorizontalPercentBar
107 108 };
108 109
109 110 public:
110 111 DeclarativeChart(QDECLARATIVE_ITEM *parent = 0);
111 112 ~DeclarativeChart();
112 113
113 114 public: // From parent classes
114 115 void childEvent(QChildEvent *event);
115 116 void componentComplete();
116 117 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
117 118 #ifdef CHARTS_FOR_QUICK2
118 119 void paint(QPainter *painter);
119 120 protected:
120 121 void mousePressEvent(QMouseEvent *event);
121 122 void mouseReleaseEvent(QMouseEvent *event);
122 123 void hoverMoveEvent(QHoverEvent *event);
123 124 private Q_SLOTS:
124 125 void handleAntialiasingChanged(bool enable);
125 126 void sceneChanged(QList<QRectF> region);
126 127 void renderScene();
127 128 #endif
128 129
129 130 public:
130 131 void setTheme(DeclarativeChart::Theme theme);
131 132 DeclarativeChart::Theme theme();
132 133 void setAnimationOptions(DeclarativeChart::Animation animations);
133 134 DeclarativeChart::Animation animationOptions();
134 135 void setTitle(QString title);
135 136 QString title();
136 137 QLegend *legend();
137 138 QFont titleFont() const;
138 139 void setTitleFont(const QFont &font);
139 140 void setTitleColor(QColor color);
140 141 QColor titleColor();
141 142 void setBackgroundColor(QColor color);
142 143 QColor backgroundColor();
143 144 Q_REVISION(3) void setPlotAreaColor(QColor color);
144 145 Q_REVISION(3) QColor plotAreaColor();
146 Q_REVISION(4) void setLocalizeNumbers(bool localize);
147 Q_REVISION(4) bool localizeNumbers() const;
148
145 149 int count();
146 150 void setDropShadowEnabled(bool enabled);
147 151 bool dropShadowEnabled();
148 152 Q_REVISION(3) qreal backgroundRoundness() const;
149 153 Q_REVISION(3) void setBackgroundRoundness(qreal diameter);
150 154
151 155 // Margins & plotArea
152 156 qreal topMargin();
153 157 qreal bottomMargin();
154 158 qreal leftMargin();
155 159 qreal rightMargin();
156 160 DeclarativeMargins *minimumMargins() { return m_margins; }
157 161 Q_REVISION(2) DeclarativeMargins *margins() { return m_margins; }
158 162 QRectF plotArea() { return m_chart->plotArea(); }
159 163
160 164 // Axis handling
161 165 QAbstractAxis *defaultAxis(Qt::Orientation orientation, QAbstractSeries *series);
162 166 void initializeAxes(QAbstractSeries *series);
163 167 void doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes);
164 168 QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> axes();
165 169 static void axesAppendFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, QAbstractAxis *element);
166 170 static int axesCountFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list);
167 171 static QAbstractAxis *axesAtFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, int index);
168 172 static void axesClearFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list);
169 173
170 174 public:
171 175 Q_INVOKABLE QAbstractSeries *series(int index);
172 176 Q_INVOKABLE QAbstractSeries *series(QString seriesName);
173 177 Q_INVOKABLE QAbstractSeries *createSeries(int type, QString name = "", QAbstractAxis *axisX = 0, QAbstractAxis *axisY = 0);
174 178 Q_INVOKABLE void removeSeries(QAbstractSeries *series);
175 179 Q_INVOKABLE void removeAllSeries() { m_chart->removeAllSeries(); }
176 180 Q_INVOKABLE void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
177 181 Q_INVOKABLE void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
178 182 Q_INVOKABLE void createDefaultAxes();
179 183 Q_INVOKABLE QAbstractAxis *axisX(QAbstractSeries *series = 0);
180 184 Q_INVOKABLE QAbstractAxis *axisY(QAbstractSeries *series = 0);
181 185 Q_INVOKABLE void zoom(qreal factor);
182 186 Q_INVOKABLE void scrollLeft(qreal pixels);
183 187 Q_INVOKABLE void scrollRight(qreal pixels);
184 188 Q_INVOKABLE void scrollUp(qreal pixels);
185 189 Q_INVOKABLE void scrollDown(qreal pixels);
186 190
187 191 Q_SIGNALS:
188 192 void axisLabelsChanged();
189 193 void titleColorChanged(QColor color);
190 194 void backgroundColorChanged();
191 195 void dropShadowEnabledChanged(bool enabled);
192 196 void minimumMarginsChanged();
193 197 Q_REVISION(2) void marginsChanged();
194 198 void plotAreaChanged(QRectF plotArea);
195 199 void seriesAdded(QAbstractSeries *series);
196 200 void seriesRemoved(QAbstractSeries *series);
197 201 Q_REVISION(3) void plotAreaColorChanged();
198 202 Q_REVISION(3) void backgroundRoundnessChanged(qreal diameter);
203 Q_REVISION(4) bool localizeNumbersChanged();
199 204
200 205 private Q_SLOTS:
201 206 void changeMinimumMargins(int top, int bottom, int left, int right);
202 207 void handleAxisXSet(QAbstractAxis *axis);
203 208 void handleAxisYSet(QAbstractAxis *axis);
204 209 void handleAxisXTopSet(QAbstractAxis *axis);
205 210 void handleAxisYRightSet(QAbstractAxis *axis);
206 211 void handleSeriesAdded(QAbstractSeries *series);
207 212
208 213 protected:
209 214 explicit DeclarativeChart(QChart::ChartType type, QDECLARATIVE_ITEM *parent);
210 215
211 216 private:
212 217 void initChart(QChart::ChartType type);
213 218 // Extending QChart with DeclarativeChart is not possible because QObject does not support
214 219 // multi inheritance, so we now have a QChart as a member instead
215 220 QChart *m_chart;
216 221 #ifdef CHARTS_FOR_QUICK2
217 222 QGraphicsScene *m_scene;
218 223 QPointF m_mousePressScenePoint;
219 224 QPoint m_mousePressScreenPoint;
220 225 QPointF m_lastMouseMoveScenePoint;
221 226 QPoint m_lastMouseMoveScreenPoint;
222 227 Qt::MouseButton m_mousePressButton;
223 228 Qt::MouseButtons m_mousePressButtons;
224 229 QMutex m_sceneImageLock;
225 230 QImage *m_currentSceneImage;
226 231 bool m_updatePending;
227 232 Qt::HANDLE m_paintThreadId;
228 233 Qt::HANDLE m_guiThreadId;
229 234 #endif
230 235 DeclarativeMargins *m_margins;
231 236 };
232 237
233 238 QTCOMMERCIALCHART_END_NAMESPACE
234 239
235 240 #endif // DECLARATIVECHART_H
@@ -1,272 +1,273
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "qchart.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qvalueaxis.h"
24 24 #include "qlogvalueaxis.h"
25 25 #include "declarativecategoryaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27 #include "declarativechart.h"
28 28 #include "declarativepolarchart.h"
29 29 #include "declarativexypoint.h"
30 30 #include "declarativelineseries.h"
31 31 #include "declarativesplineseries.h"
32 32 #include "declarativeareaseries.h"
33 33 #include "declarativescatterseries.h"
34 34 #include "declarativebarseries.h"
35 35 #include "declarativeboxplotseries.h"
36 36 #include "declarativepieseries.h"
37 37 #include "declarativeaxes.h"
38 38 #include "qvxymodelmapper.h"
39 39 #include "qhxymodelmapper.h"
40 40 #include "qhpiemodelmapper.h"
41 41 #include "qvpiemodelmapper.h"
42 42 #include "qhbarmodelmapper.h"
43 43 #include "qvbarmodelmapper.h"
44 44 #include "declarativemargins.h"
45 45 #include "qarealegendmarker.h"
46 46 #include "qbarlegendmarker.h"
47 47 #include "qpielegendmarker.h"
48 48 #include "qxylegendmarker.h"
49 49 #include "qboxplotmodelmapper.h"
50 50 #include "qvboxplotmodelmapper.h"
51 51 #ifndef QT_ON_ARM
52 52 #include "qdatetimeaxis.h"
53 53 #endif
54 54 #include "shared_defines.h"
55 55 #include <QAbstractItemModel>
56 56 #ifdef CHARTS_FOR_QUICK2
57 57 #include <QtQml/QQmlExtensionPlugin>
58 58 #else
59 59 #include <QtDeclarative/qdeclarativeextensionplugin.h>
60 60 #include <QtDeclarative/qdeclarative.h>
61 61 #endif
62 62
63 63 QTCOMMERCIALCHART_USE_NAMESPACE
64 64
65 65 Q_DECLARE_METATYPE(QList<QPieSlice *>)
66 66 Q_DECLARE_METATYPE(QList<QBarSet *>)
67 67 Q_DECLARE_METATYPE(QList<QAbstractAxis *>)
68 68
69 69 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
70 70
71 71 Q_DECLARE_METATYPE(DeclarativeChart *)
72 72 Q_DECLARE_METATYPE(DeclarativePolarChart *)
73 73 Q_DECLARE_METATYPE(DeclarativeMargins *)
74 74 Q_DECLARE_METATYPE(DeclarativeAreaSeries *)
75 75 Q_DECLARE_METATYPE(DeclarativeBarSeries *)
76 76 Q_DECLARE_METATYPE(DeclarativeBarSet *)
77 77 Q_DECLARE_METATYPE(DeclarativeBoxPlotSeries *)
78 78 Q_DECLARE_METATYPE(DeclarativeBoxSet *)
79 79 Q_DECLARE_METATYPE(DeclarativeLineSeries *)
80 80 Q_DECLARE_METATYPE(DeclarativePieSeries *)
81 81 Q_DECLARE_METATYPE(DeclarativePieSlice *)
82 82 Q_DECLARE_METATYPE(DeclarativeScatterSeries *)
83 83 Q_DECLARE_METATYPE(DeclarativeSplineSeries *)
84 84
85 85 Q_DECLARE_METATYPE(QAbstractAxis *)
86 86 Q_DECLARE_METATYPE(QValueAxis *)
87 87 Q_DECLARE_METATYPE(QBarCategoryAxis *)
88 88 Q_DECLARE_METATYPE(QCategoryAxis *)
89 89 Q_DECLARE_METATYPE(QDateTimeAxis *)
90 90 Q_DECLARE_METATYPE(QLogValueAxis *)
91 91
92 92 Q_DECLARE_METATYPE(QLegend *)
93 93 Q_DECLARE_METATYPE(QLegendMarker *)
94 94 Q_DECLARE_METATYPE(QAreaLegendMarker *)
95 95 Q_DECLARE_METATYPE(QBarLegendMarker *)
96 96 Q_DECLARE_METATYPE(QPieLegendMarker *)
97 97
98 98 Q_DECLARE_METATYPE(QHPieModelMapper *)
99 99 Q_DECLARE_METATYPE(QHXYModelMapper *)
100 100 Q_DECLARE_METATYPE(QPieModelMapper *)
101 101 Q_DECLARE_METATYPE(QHBarModelMapper *)
102 102 Q_DECLARE_METATYPE(QBarModelMapper *)
103 103 Q_DECLARE_METATYPE(QVBarModelMapper *)
104 104 Q_DECLARE_METATYPE(QVPieModelMapper *)
105 105 Q_DECLARE_METATYPE(QVXYModelMapper *)
106 106 Q_DECLARE_METATYPE(QXYLegendMarker *)
107 107 Q_DECLARE_METATYPE(QXYModelMapper *)
108 108 Q_DECLARE_METATYPE(QBoxPlotModelMapper *)
109 109 Q_DECLARE_METATYPE(QVBoxPlotModelMapper *)
110 110
111 111
112 112 Q_DECLARE_METATYPE(QAbstractSeries *)
113 113 Q_DECLARE_METATYPE(QXYSeries *)
114 114 Q_DECLARE_METATYPE(QAbstractBarSeries *)
115 115 Q_DECLARE_METATYPE(QBarSeries *)
116 116 Q_DECLARE_METATYPE(QBarSet *)
117 117 Q_DECLARE_METATYPE(QAreaSeries *)
118 118 Q_DECLARE_METATYPE(QHorizontalBarSeries *)
119 119 Q_DECLARE_METATYPE(QHorizontalPercentBarSeries *)
120 120 Q_DECLARE_METATYPE(QHorizontalStackedBarSeries *)
121 121 Q_DECLARE_METATYPE(QLineSeries *)
122 122 Q_DECLARE_METATYPE(QPercentBarSeries *)
123 123 Q_DECLARE_METATYPE(QPieSeries *)
124 124 Q_DECLARE_METATYPE(QPieSlice *)
125 125 Q_DECLARE_METATYPE(QScatterSeries *)
126 126 Q_DECLARE_METATYPE(QSplineSeries *)
127 127 Q_DECLARE_METATYPE(QStackedBarSeries *)
128 128
129 129 #endif
130 130
131 131 QTCOMMERCIALCHART_BEGIN_NAMESPACE
132 132
133 133 class ChartQmlPlugin : public QDECLARATIVE_EXTENSION_PLUGIN
134 134 {
135 135 Q_OBJECT
136 136
137 137 #ifdef CHARTS_FOR_QUICK2
138 138 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
139 139 #else
140 140 # if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
141 141 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDeclarativeExtensionInterface")
142 142 # endif
143 143 #endif
144 144
145 145 public:
146 146 virtual void registerTypes(const char *uri)
147 147 {
148 148 Q_ASSERT(QLatin1String(uri) == QLatin1String("QtCommercial.Chart"));
149 149
150 150 qRegisterMetaType<QList<QPieSlice *> >();
151 151 qRegisterMetaType<QList<QBarSet *> >();
152 152 qRegisterMetaType<QList<QAbstractAxis *> >();
153 153
154 154 // QtCommercial.Chart 1.0
155 155 qmlRegisterType<DeclarativeChart>(uri, 1, 0, "ChartView");
156 156 qmlRegisterType<DeclarativeXYPoint>(uri, 1, 0, "XYPoint");
157 157 qmlRegisterType<DeclarativeScatterSeries>(uri, 1, 0, "ScatterSeries");
158 158 qmlRegisterType<DeclarativeLineSeries>(uri, 1, 0, "LineSeries");
159 159 qmlRegisterType<DeclarativeSplineSeries>(uri, 1, 0, "SplineSeries");
160 160 qmlRegisterType<DeclarativeAreaSeries>(uri, 1, 0, "AreaSeries");
161 161 qmlRegisterType<DeclarativeBarSeries>(uri, 1, 0, "BarSeries");
162 162 qmlRegisterType<DeclarativeStackedBarSeries>(uri, 1, 0, "StackedBarSeries");
163 163 qmlRegisterType<DeclarativePercentBarSeries>(uri, 1, 0, "PercentBarSeries");
164 164 qmlRegisterType<DeclarativePieSeries>(uri, 1, 0, "PieSeries");
165 165 qmlRegisterType<QPieSlice>(uri, 1, 0, "PieSlice");
166 166 qmlRegisterType<DeclarativeBarSet>(uri, 1, 0, "BarSet");
167 167 qmlRegisterType<QHXYModelMapper>(uri, 1, 0, "HXYModelMapper");
168 168 qmlRegisterType<QVXYModelMapper>(uri, 1, 0, "VXYModelMapper");
169 169 qmlRegisterType<QHPieModelMapper>(uri, 1, 0, "HPieModelMapper");
170 170 qmlRegisterType<QVPieModelMapper>(uri, 1, 0, "VPieModelMapper");
171 171 qmlRegisterType<QHBarModelMapper>(uri, 1, 0, "HBarModelMapper");
172 172 qmlRegisterType<QVBarModelMapper>(uri, 1, 0, "VBarModelMapper");
173 173
174 174 qmlRegisterType<QValueAxis>(uri, 1, 0, "ValuesAxis");
175 175 qmlRegisterType<QBarCategoryAxis>(uri, 1, 0, "BarCategoriesAxis");
176 176 qmlRegisterUncreatableType<QLegend>(uri, 1, 0, "Legend",
177 177 QLatin1String("Trying to create uncreatable: Legend."));
178 178 qmlRegisterUncreatableType<QXYSeries>(uri, 1, 0, "XYSeries",
179 179 QLatin1String("Trying to create uncreatable: XYSeries."));
180 180 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
181 181 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
182 182 qmlRegisterUncreatableType<QXYModelMapper>(uri, 1, 0, "XYModelMapper",
183 183 QLatin1String("Trying to create uncreatable: XYModelMapper."));
184 184 qmlRegisterUncreatableType<QPieModelMapper>(uri, 1, 0, "PieModelMapper",
185 185 QLatin1String("Trying to create uncreatable: PieModelMapper."));
186 186 qmlRegisterUncreatableType<QBarModelMapper>(uri, 1, 0, "BarModelMapper",
187 187 QLatin1String("Trying to create uncreatable: BarModelMapper."));
188 188 qmlRegisterUncreatableType<QAbstractSeries>(uri, 1, 0, "AbstractSeries",
189 189 QLatin1String("Trying to create uncreatable: AbstractSeries."));
190 190 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 1, 0, "AbstractBarSeries",
191 191 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
192 192 qmlRegisterUncreatableType<QAbstractAxis>(uri, 1, 0, "AbstractAxis",
193 193 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
194 194 qmlRegisterUncreatableType<QBarSet>(uri, 1, 0, "BarSetBase",
195 195 QLatin1String("Trying to create uncreatable: BarsetBase."));
196 196 qmlRegisterUncreatableType<QPieSeries>(uri, 1, 0, "QPieSeries",
197 197 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
198 198 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 1, 0, "DeclarativeAxes",
199 199 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
200 200
201 201 // QtCommercial.Chart 1.1
202 202 qmlRegisterType<DeclarativeChart, 1>(uri, 1, 1, "ChartView");
203 203 qmlRegisterType<DeclarativeScatterSeries, 1>(uri, 1, 1, "ScatterSeries");
204 204 qmlRegisterType<DeclarativeLineSeries, 1>(uri, 1, 1, "LineSeries");
205 205 qmlRegisterType<DeclarativeSplineSeries, 1>(uri, 1, 1, "SplineSeries");
206 206 qmlRegisterType<DeclarativeAreaSeries, 1>(uri, 1, 1, "AreaSeries");
207 207 qmlRegisterType<DeclarativeBarSeries, 1>(uri, 1, 1, "BarSeries");
208 208 qmlRegisterType<DeclarativeStackedBarSeries, 1>(uri, 1, 1, "StackedBarSeries");
209 209 qmlRegisterType<DeclarativePercentBarSeries, 1>(uri, 1, 1, "PercentBarSeries");
210 210 qmlRegisterType<DeclarativeHorizontalBarSeries, 1>(uri, 1, 1, "HorizontalBarSeries");
211 211 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 1>(uri, 1, 1, "HorizontalStackedBarSeries");
212 212 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 1>(uri, 1, 1, "HorizontalPercentBarSeries");
213 213 qmlRegisterType<DeclarativePieSeries>(uri, 1, 1, "PieSeries");
214 214 qmlRegisterType<DeclarativeBarSet>(uri, 1, 1, "BarSet");
215 215 qmlRegisterType<QValueAxis>(uri, 1, 1, "ValueAxis");
216 216 #ifndef QT_ON_ARM
217 217 qmlRegisterType<QDateTimeAxis>(uri, 1, 1, "DateTimeAxis");
218 218 #endif
219 219 qmlRegisterType<DeclarativeCategoryAxis>(uri, 1, 1, "CategoryAxis");
220 220 qmlRegisterType<DeclarativeCategoryRange>(uri, 1, 1, "CategoryRange");
221 221 qmlRegisterType<QBarCategoryAxis>(uri, 1, 1, "BarCategoryAxis");
222 222 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 1, 1, "Margins",
223 223 QLatin1String("Trying to create uncreatable: Margins."));
224 224
225 225 // QtCommercial.Chart 1.2
226 226 qmlRegisterType<DeclarativeChart, 2>(uri, 1, 2, "ChartView");
227 227 qmlRegisterType<DeclarativeScatterSeries, 2>(uri, 1, 2, "ScatterSeries");
228 228 qmlRegisterType<DeclarativeLineSeries, 2>(uri, 1, 2, "LineSeries");
229 229 qmlRegisterType<DeclarativeSplineSeries, 2>(uri, 1, 2, "SplineSeries");
230 230 qmlRegisterType<DeclarativeAreaSeries, 2>(uri, 1, 2, "AreaSeries");
231 231 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 1, 2, "BarSeries");
232 232 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 1, 2, "StackedBarSeries");
233 233 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 1, 2, "PercentBarSeries");
234 234 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 1, 2, "HorizontalBarSeries");
235 235 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 1, 2, "HorizontalStackedBarSeries");
236 236 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 1, 2, "HorizontalPercentBarSeries");
237 237
238 238 // QtCommercial.Chart 1.3
239 239 qmlRegisterType<DeclarativeChart, 3>(uri, 1, 3, "ChartView");
240 240 qmlRegisterType<DeclarativePolarChart, 1>(uri, 1, 3, "PolarChartView");
241 241 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 1, 3, "SplineSeries");
242 242 qmlRegisterType<DeclarativeScatterSeries, 3>(uri, 1, 3, "ScatterSeries");
243 243 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 1, 3, "LineSeries");
244 244 qmlRegisterType<DeclarativeAreaSeries, 3>(uri, 1, 3, "AreaSeries");
245 245 qmlRegisterType<QLogValueAxis>(uri, 1, 3, "LogValueAxis");
246 246 qmlRegisterType<DeclarativeBoxPlotSeries>(uri, 1, 3, "BoxPlotSeries");
247 247 qmlRegisterType<DeclarativeBoxSet>(uri, 1, 3, "BoxSet");
248 248
249 249 // QtCommercial.Chart 1.4
250 250 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 1, 4, "AreaSeries");
251 251 qmlRegisterType<DeclarativeBarSet, 2>(uri, 1, 4, "BarSet");
252 252 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 1, 4, "BoxPlotSeries");
253 253 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 1, 4, "BoxSet");
254 254 qmlRegisterType<DeclarativePieSlice>(uri, 1, 4, "PieSlice");
255 255 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 1, 4, "ScatterSeries");
256 256
257 257 // QtCommercial.Chart 2.0
258 258 qmlRegisterType<QVBoxPlotModelMapper>(uri, 2, 0, "VBoxPlotModelMapper");
259 259 qmlRegisterUncreatableType<QBoxPlotModelMapper>(uri, 2, 0, "BoxPlotModelMapper",
260 260 QLatin1String("Trying to create uncreatable: BoxPlotModelMapper."));
261 qmlRegisterType<DeclarativeChart, 4>(uri, 2, 0, "ChartView");
261 262 }
262 263 };
263 264
264 265 QTCOMMERCIALCHART_END_NAMESPACE
265 266
266 267 #include "plugin.moc"
267 268
268 269 QTCOMMERCIALCHART_USE_NAMESPACE
269 270
270 271 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
271 272 Q_EXPORT_PLUGIN2(qtcommercialchartqml, QT_PREPEND_NAMESPACE(ChartQmlPlugin))
272 273 #endif
@@ -1,258 +1,262
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "areachartitem_p.h"
22 22 #include "qareaseries.h"
23 23 #include "qareaseries_p.h"
24 24 #include "qlineseries.h"
25 25 #include "chartpresenter_p.h"
26 26 #include "abstractdomain_p.h"
27 27 #include <QPainter>
28 28 #include <QGraphicsSceneMouseEvent>
29 29 #include <QDebug>
30 30
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, QGraphicsItem* item)
35 35 : ChartItem(areaSeries->d_func(),item),
36 36 m_series(areaSeries),
37 37 m_upper(0),
38 38 m_lower(0),
39 39 m_pointsVisible(false),
40 40 m_pointLabelsVisible(false),
41 41 m_pointLabelsFormat(areaSeries->pointLabelsFormat()),
42 42 m_pointLabelsFont(areaSeries->pointLabelsFont()),
43 43 m_pointLabelsColor(areaSeries->pointLabelsColor())
44 44 {
45 45 setAcceptHoverEvents(true);
46 46 setZValue(ChartPresenter::LineChartZValue);
47 47 if (m_series->upperSeries())
48 48 m_upper = new AreaBoundItem(this, m_series->upperSeries());
49 49 if (m_series->lowerSeries())
50 50 m_lower = new AreaBoundItem(this, m_series->lowerSeries());
51 51
52 52 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
53 53 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
54 54 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
55 55 QObject::connect(this, SIGNAL(clicked(QPointF)), areaSeries, SIGNAL(clicked(QPointF)));
56 56 QObject::connect(this, SIGNAL(hovered(QPointF,bool)), areaSeries, SIGNAL(hovered(QPointF,bool)));
57 57 QObject::connect(areaSeries, SIGNAL(pointLabelsFormatChanged(QString)),
58 58 this, SLOT(handleUpdated()));
59 59 QObject::connect(areaSeries, SIGNAL(pointLabelsVisibilityChanged(bool)),
60 60 this, SLOT(handleUpdated()));
61 61 QObject::connect(areaSeries, SIGNAL(pointLabelsFontChanged(QFont)),
62 62 this, SLOT(handleUpdated()));
63 63 QObject::connect(areaSeries, SIGNAL(pointLabelsColorChanged(QColor)),
64 64 this, SLOT(handleUpdated()));
65 65
66 66 handleUpdated();
67 67 }
68 68
69 69 AreaChartItem::~AreaChartItem()
70 70 {
71 71 delete m_upper;
72 72 delete m_lower;
73 73 }
74 74
75 75 void AreaChartItem::setPresenter(ChartPresenter *presenter)
76 76 {
77 77 if (m_upper)
78 78 m_upper->setPresenter(presenter);
79 79 if (m_lower) {
80 80 m_lower->setPresenter(presenter);
81 81 }
82 82 ChartItem::setPresenter(presenter);
83 83 }
84 84
85 85 QRectF AreaChartItem::boundingRect() const
86 86 {
87 87 return m_rect;
88 88 }
89 89
90 90 QPainterPath AreaChartItem::shape() const
91 91 {
92 92 return m_path;
93 93 }
94 94
95 95 void AreaChartItem::updatePath()
96 96 {
97 97 QPainterPath path;
98 98 QRectF rect(QPointF(0,0),domain()->size());
99 99
100 100 path = m_upper->path();
101 101
102 102 if (m_lower) {
103 103 // Note: Polarcharts always draw area correctly only when both series have equal width or are
104 104 // fully displayed. If one series is partally off-chart, the connecting line between
105 105 // the series does not attach to the end of the partially hidden series but to the point
106 106 // where it intersects the axis line. The problem is especially noticeable when one of the series
107 107 // is entirely off-chart, in which case the connecting line connects two ends of the
108 108 // visible series.
109 109 // This happens because we get the paths from linechart, which omits off-chart segments.
110 110 // To properly fix, linechart would need to provide true full path, in right, left, and the rest
111 111 // portions to enable proper clipping. However, combining those to single visually unified area
112 112 // would be a nightmare, since they would have to be painted separately.
113 113 path.connectPath(m_lower->path().toReversed());
114 114 } else {
115 115 QPointF first = path.pointAtPercent(0);
116 116 QPointF last = path.pointAtPercent(1);
117 117 if (presenter()->chartType() == QChart::ChartTypeCartesian) {
118 118 path.lineTo(last.x(), rect.bottom());
119 119 path.lineTo(first.x(), rect.bottom());
120 120 } else { // polar
121 121 path.lineTo(rect.center());
122 122 }
123 123 }
124 124 path.closeSubpath();
125 125
126 126 // Only zoom in if the bounding rect of the path fits inside int limits. QWidget::update() uses
127 127 // a region that has to be compatible with QRect.
128 128 if (path.boundingRect().height() <= INT_MAX
129 129 && path.boundingRect().width() <= INT_MAX) {
130 130 prepareGeometryChange();
131 131 m_path = path;
132 132 m_rect = path.boundingRect();
133 133 update();
134 134 }
135 135 }
136 136
137 137 void AreaChartItem::handleUpdated()
138 138 {
139 139 setVisible(m_series->isVisible());
140 140 m_pointsVisible = m_series->pointsVisible();
141 141 m_linePen = m_series->pen();
142 142 m_brush = m_series->brush();
143 143 m_pointPen = m_series->pen();
144 144 m_pointPen.setWidthF(2 * m_pointPen.width());
145 145 setOpacity(m_series->opacity());
146 146 m_pointLabelsFormat = m_series->pointLabelsFormat();
147 147 m_pointLabelsVisible = m_series->pointLabelsVisible();
148 148 m_pointLabelsFont = m_series->pointLabelsFont();
149 149 m_pointLabelsColor = m_series->pointLabelsColor();
150 150 update();
151 151 }
152 152
153 153 void AreaChartItem::handleDomainUpdated()
154 154 {
155 155 if (m_upper) {
156 156 AbstractDomain* d = m_upper->domain();
157 157 d->setSize(domain()->size());
158 158 d->setRange(domain()->minX(),domain()->maxX(),domain()->minY(),domain()->maxY());
159 159 m_upper->handleDomainUpdated();
160 160 }
161 161
162 162 if (m_lower) {
163 163 AbstractDomain* d = m_lower->domain();
164 164 d->setSize(domain()->size());
165 165 d->setRange(domain()->minX(),domain()->maxX(),domain()->minY(),domain()->maxY());
166 166 m_lower->handleDomainUpdated();
167 167 }
168 168 }
169 169
170 170 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
171 171 {
172 172 Q_UNUSED(widget)
173 173 Q_UNUSED(option)
174 174 painter->save();
175 175 painter->setPen(m_linePen);
176 176 painter->setBrush(m_brush);
177 177 QRectF clipRect = QRectF(QPointF(0, 0), domain()->size());
178 178 if (presenter()->chartType() == QChart::ChartTypePolar)
179 179 painter->setClipRegion(QRegion(clipRect.toRect(), QRegion::Ellipse));
180 180 else
181 181 painter->setClipRect(clipRect);
182 182 painter->drawPath(m_path);
183 183 if (m_pointsVisible) {
184 184 painter->setPen(m_pointPen);
185 185 painter->drawPoints(m_upper->geometryPoints());
186 186 if (m_lower)
187 187 painter->drawPoints(m_lower->geometryPoints());
188 188 }
189 189
190 190 // Draw series point label
191 191 if (m_pointLabelsVisible) {
192 192 static const QString xPointTag(QLatin1String("@xPoint"));
193 193 static const QString yPointTag(QLatin1String("@yPoint"));
194 194 const int labelOffset = 2;
195 195
196 196 painter->setFont(m_pointLabelsFont);
197 197 painter->setPen(QPen(m_pointLabelsColor));
198 198 QFontMetrics fm(painter->font());
199 199
200 200 QString pointLabel = m_pointLabelsFormat;
201 201
202 202 if (m_series->upperSeries()) {
203 203 for (int i(0); i < m_series->upperSeries()->count(); i++) {
204 pointLabel.replace(xPointTag, QString::number(m_series->upperSeries()->at(i).x()));
205 pointLabel.replace(yPointTag, QString::number(m_series->upperSeries()->at(i).y()));
204 pointLabel.replace(xPointTag,
205 presenter()->numberToString(m_series->upperSeries()->at(i).x()));
206 pointLabel.replace(yPointTag,
207 presenter()->numberToString(m_series->upperSeries()->at(i).y()));
206 208
207 209 // Position text in relation to the point
208 210 int pointLabelWidth = fm.width(pointLabel);
209 211 QPointF position(m_upper->geometryPoints().at(i));
210 212 position.setX(position.x() - pointLabelWidth / 2);
211 213 position.setY(position.y() - m_series->upperSeries()->pen().width() / 2 - labelOffset);
212 214
213 215 painter->drawText(position, pointLabel);
214 216 }
215 217 }
216 218
217 219 if (m_series->lowerSeries()) {
218 220 for (int i(0); i < m_series->lowerSeries()->count(); i++) {
219 pointLabel.replace(xPointTag, QString::number(m_series->lowerSeries()->at(i).x()));
220 pointLabel.replace(yPointTag, QString::number(m_series->lowerSeries()->at(i).y()));
221 pointLabel.replace(xPointTag,
222 presenter()->numberToString(m_series->lowerSeries()->at(i).x()));
223 pointLabel.replace(yPointTag,
224 presenter()->numberToString(m_series->lowerSeries()->at(i).y()));
221 225
222 226 // Position text in relation to the point
223 227 int pointLabelWidth = fm.width(pointLabel);
224 228 QPointF position(m_lower->geometryPoints().at(i));
225 229 position.setX(position.x() - pointLabelWidth / 2);
226 230 position.setY(position.y() - m_series->lowerSeries()->pen().width() / 2 - labelOffset);
227 231
228 232 painter->drawText(position, pointLabel);
229 233 }
230 234 }
231 235 }
232 236
233 237 painter->restore();
234 238 }
235 239
236 240 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
237 241 {
238 242 emit clicked(m_upper->domain()->calculateDomainPoint(event->pos()));
239 243 ChartItem::mousePressEvent(event);
240 244 }
241 245
242 246 void AreaChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
243 247 {
244 248 emit hovered(domain()->calculateDomainPoint(event->pos()), true);
245 249 event->accept();
246 250 // QGraphicsItem::hoverEnterEvent(event);
247 251 }
248 252
249 253 void AreaChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
250 254 {
251 255 emit hovered(domain()->calculateDomainPoint(event->pos()), false);
252 256 event->accept();
253 257 // QGraphicsItem::hoverEnterEvent(event);
254 258 }
255 259
256 260 #include "moc_areachartitem_p.cpp"
257 261
258 262 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,355 +1,400
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "chartaxiselement_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "abstractchartlayout_p.h"
25 25 #include <qmath.h>
26 26 #include <QDateTime>
27 27 #include <QTextDocument>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])";
32 static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.?(\\d)*([defgEG])(.*)$";
32 33 static QRegExp *labelFormatMatcher = 0;
34 static QRegExp *labelFormatMatcherLocalized = 0;
33 35 class StaticLabelFormatMatcherDeleter
34 36 {
35 37 public:
36 38 StaticLabelFormatMatcherDeleter() {}
37 ~StaticLabelFormatMatcherDeleter() { delete labelFormatMatcher; }
39 ~StaticLabelFormatMatcherDeleter() {
40 delete labelFormatMatcher;
41 delete labelFormatMatcherLocalized;
42 }
38 43 };
39 44 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
40 45
41 46 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
42 47 : ChartElement(item),
43 48 m_axis(axis),
44 49 m_animation(0),
45 50 m_grid(new QGraphicsItemGroup(item)),
46 51 m_arrow(new QGraphicsItemGroup(item)),
47 52 m_shades(new QGraphicsItemGroup(item)),
48 53 m_labels(new QGraphicsItemGroup(item)),
49 54 m_title(new QGraphicsTextItem(item)),
50 55 m_intervalAxis(intervalAxis)
51 56
52 57 {
53 58 //initial initialization
54 59 m_arrow->setHandlesChildEvents(false);
55 60 m_arrow->setZValue(ChartPresenter::AxisZValue);
56 61 m_labels->setZValue(ChartPresenter::AxisZValue);
57 62 m_shades->setZValue(ChartPresenter::ShadesZValue);
58 63 m_grid->setZValue(ChartPresenter::GridZValue);
59 64 m_title->setZValue(ChartPresenter::GridZValue);
60 65 m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
61 66 handleVisibleChanged(axis->isVisible());
62 67 connectSlots();
63 68
64 69 setFlag(QGraphicsItem::ItemHasNoContents, true);
65 70 }
66 71
67 72 ChartAxisElement::~ChartAxisElement()
68 73 {
69 74 }
70 75
71 76 void ChartAxisElement::connectSlots()
72 77 {
73 78 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
74 79 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
75 80 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
76 81 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
77 82 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
78 83 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
79 84 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
80 85 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
81 86 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
82 87 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
83 88 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
84 89 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
85 90 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
86 91 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
87 92 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
88 93 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
89 94 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
90 95 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
91 96 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
92 97 }
93 98
94 99 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
95 100 {
96 101 m_arrow->setVisible(visible);
97 102 }
98 103
99 104 void ChartAxisElement::handleGridVisibleChanged(bool visible)
100 105 {
101 106 m_grid->setVisible(visible);
102 107 }
103 108
104 109 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
105 110 {
106 111 QGraphicsLayoutItem::updateGeometry();
107 112 presenter()->layout()->invalidate();
108 113 m_labels->setVisible(visible);
109 114 }
110 115
111 116 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
112 117 {
113 118 m_shades->setVisible(visible);
114 119 }
115 120
116 121 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
117 122 {
118 123 QGraphicsLayoutItem::updateGeometry();
119 124 presenter()->layout()->invalidate();
120 125 m_title->setVisible(visible);
121 126 }
122 127
123 128 void ChartAxisElement::handleLabelsAngleChanged(int angle)
124 129 {
125 130 foreach (QGraphicsItem *item, m_labels->childItems())
126 131 item->setRotation(angle);
127 132
128 133 QGraphicsLayoutItem::updateGeometry();
129 134 presenter()->layout()->invalidate();
130 135 }
131 136
132 137 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
133 138 {
134 139 Q_UNUSED(pen)
135 140 }
136 141
137 142 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
138 143 {
139 144 foreach (QGraphicsItem *item, m_labels->childItems())
140 145 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
141 146 }
142 147
143 148 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
144 149 {
145 150 foreach (QGraphicsItem *item, m_labels->childItems())
146 151 static_cast<QGraphicsTextItem *>(item)->setFont(font);
147 152 QGraphicsLayoutItem::updateGeometry();
148 153 presenter()->layout()->invalidate();
149 154 }
150 155
151 156 void ChartAxisElement::handleTitleTextChanged(const QString &title)
152 157 {
153 158 QGraphicsLayoutItem::updateGeometry();
154 159 presenter()->layout()->invalidate();
155 160 if (title.isEmpty() || !m_title->isVisible())
156 161 m_title->setHtml(title);
157 162 }
158 163
159 164 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
160 165 {
161 166 Q_UNUSED(pen)
162 167 }
163 168
164 169 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
165 170 {
166 171 m_title->setDefaultTextColor(brush.color());
167 172 }
168 173
169 174 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
170 175 {
171 176 if (m_title->font() != font) {
172 177 m_title->setFont(font);
173 178 QGraphicsLayoutItem::updateGeometry();
174 179 presenter()->layout()->invalidate();
175 180 }
176 181 }
177 182
178 183 void ChartAxisElement::handleVisibleChanged(bool visible)
179 184 {
180 185 setVisible(visible);
181 186 if (!visible) {
182 187 m_grid->setVisible(visible);
183 188 m_arrow->setVisible(visible);
184 189 m_shades->setVisible(visible);
185 190 m_labels->setVisible(visible);
186 191 m_title->setVisible(visible);
187 192 } else {
188 193 m_grid->setVisible(axis()->isGridLineVisible());
189 194 m_arrow->setVisible(axis()->isLineVisible());
190 195 m_shades->setVisible(axis()->shadesVisible());
191 196 m_labels->setVisible(axis()->labelsVisible());
192 197 m_title->setVisible(axis()->isTitleVisible());
193 198 }
194 199
195 200 if (presenter()) presenter()->layout()->invalidate();
196 201 }
197 202
198 203 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
199 204 {
200 205 Q_UNUSED(min);
201 206 Q_UNUSED(max);
202 207
203 208 if (!isEmpty()) {
204 209 QVector<qreal> layout = calculateLayout();
205 210 updateLayout(layout);
206 211 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
207 212 QSizeF after = sizeHint(Qt::PreferredSize);
208 213
209 214 if (before != after) {
210 215 QGraphicsLayoutItem::updateGeometry();
211 216 // We don't want to call invalidate on layout, since it will change minimum size of
212 217 // component, which we would like to avoid since it causes nasty flips when scrolling
213 218 // or zooming, instead recalculate layout and use plotArea for extra space.
214 219 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
215 220 }
216 221 }
217 222 }
218 223
219 224 bool ChartAxisElement::isEmpty()
220 225 {
221 226 return axisGeometry().isEmpty()
222 227 || gridGeometry().isEmpty()
223 228 || qFuzzyCompare(min(), max());
224 229 }
225 230
226 231 qreal ChartAxisElement::min() const
227 232 {
228 233 return m_axis->d_ptr->min();
229 234 }
230 235
231 236 qreal ChartAxisElement::max() const
232 237 {
233 238 return m_axis->d_ptr->max();
234 239 }
235 240
236 static void appendFormattedLabel(const QString &capStr, const QByteArray &array,
237 QStringList &labels, qreal value)
241 QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array,
242 qreal value, int precision, const QString &preStr,
243 const QString &postStr) const
238 244 {
239 if (capStr.isEmpty()) {
240 labels << QString();
241 } else if (capStr.at(0) == QLatin1Char('d')
242 || capStr.at(0) == QLatin1Char('i')
243 || capStr.at(0) == QLatin1Char('c')) {
244 labels << QString().sprintf(array, (qint64)value);
245 } else if (capStr.at(0) == QLatin1Char('u')
246 || capStr.at(0) == QLatin1Char('o')
247 || capStr.at(0) == QLatin1Char('x')
248 || capStr.at(0) == QLatin1Char('X')) {
249 labels << QString().sprintf(array, (quint64)value);
250 } else if (capStr.at(0) == QLatin1Char('f')
251 || capStr.at(0) == QLatin1Char('F')
252 || capStr.at(0) == QLatin1Char('e')
253 || capStr.at(0) == QLatin1Char('E')
254 || capStr.at(0) == QLatin1Char('g')
255 || capStr.at(0) == QLatin1Char('G')) {
256 labels << QString().sprintf(array, value);
257 } else {
258 labels << QString();
245 QString retVal;
246 if (!formatSpec.isEmpty()) {
247 if (formatSpec.at(0) == QLatin1Char('d')
248 || formatSpec.at(0) == QLatin1Char('i')
249 || formatSpec.at(0) == QLatin1Char('c')) {
250 if (presenter()->localizeNumbers())
251 retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr;
252 else
253 retVal = QString().sprintf(array, qint64(value));
254 } else if (formatSpec.at(0) == QLatin1Char('u')
255 || formatSpec.at(0) == QLatin1Char('o')
256 || formatSpec.at(0) == QLatin1Char('x')
257 || formatSpec.at(0) == QLatin1Char('X')) {
258 // These formats are not supported by localized numbers
259 retVal = QString().sprintf(array, quint64(value));
260 } else if (formatSpec.at(0) == QLatin1Char('f')
261 || formatSpec.at(0) == QLatin1Char('F')
262 || formatSpec.at(0) == QLatin1Char('e')
263 || formatSpec.at(0) == QLatin1Char('E')
264 || formatSpec.at(0) == QLatin1Char('g')
265 || formatSpec.at(0) == QLatin1Char('G')) {
266 if (presenter()->localizeNumbers()) {
267 retVal = preStr
268 + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(),
269 precision)
270 + postStr;
271 } else {
272 retVal = QString().sprintf(array, value);
273 }
274 }
259 275 }
276 return retVal;
260 277 }
261 278
262 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks, const QString &format)
279 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks,
280 const QString &format) const
263 281 {
264 282 QStringList labels;
265 283
266 284 if (max <= min || ticks < 1)
267 285 return labels;
268 286
269 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
270 n++;
271
272 287 if (format.isNull()) {
288 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0) + 1;
273 289 for (int i = 0; i < ticks; i++) {
274 290 qreal value = min + (i * (max - min) / (ticks - 1));
275 labels << QString::number(value, 'f', n);
291 labels << presenter()->numberToString(value, 'f', n);
276 292 }
277 293 } else {
278 294 QByteArray array = format.toLatin1();
279 QString capStr;
280 if (!labelFormatMatcher)
281 labelFormatMatcher = new QRegExp(labelFormatMatchString);
282 if (labelFormatMatcher->indexIn(format, 0) != -1)
283 capStr = labelFormatMatcher->cap(1);
295 QString formatSpec;
296 QString preStr;
297 QString postStr;
298 int precision = 0;
299 if (presenter()->localizeNumbers()) {
300 if (!labelFormatMatcherLocalized)
301 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
302 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
303 preStr = labelFormatMatcherLocalized->cap(1);
304 precision = labelFormatMatcherLocalized->cap(2).toInt();
305 formatSpec = labelFormatMatcherLocalized->cap(3);
306 postStr = labelFormatMatcherLocalized->cap(4);
307 }
308 } else {
309 if (!labelFormatMatcher)
310 labelFormatMatcher = new QRegExp(labelFormatMatchString);
311 if (labelFormatMatcher->indexIn(format, 0) != -1)
312 formatSpec = labelFormatMatcher->cap(1);
313 }
284 314 for (int i = 0; i < ticks; i++) {
285 315 qreal value = min + (i * (max - min) / (ticks - 1));
286 appendFormattedLabel(capStr, array, labels, value);
316 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
287 317 }
288 318 }
289 319
290 320 return labels;
291 321 }
292 322
293 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString &format)
323 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
324 const QString &format) const
294 325 {
295 326 QStringList labels;
296 327
297 328 if (max <= min || ticks < 1)
298 329 return labels;
299 330
300 int n = 0;
301 if (ticks > 1)
302 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
303 n++;
304
305 331 int firstTick;
306 332 if (base > 1)
307 333 firstTick = ceil(log10(min) / log10(base));
308 334 else
309 335 firstTick = ceil(log10(max) / log10(base));
310 336
311 337 if (format.isNull()) {
338 int n = 0;
339 if (ticks > 1)
340 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
341 n++;
312 342 for (int i = firstTick; i < ticks + firstTick; i++) {
313 343 qreal value = qPow(base, i);
314 labels << QString::number(value, 'f', n);
344 labels << presenter()->numberToString(value, 'f', n);
315 345 }
316 346 } else {
317 347 QByteArray array = format.toLatin1();
318 QString capStr;
319 if (!labelFormatMatcher)
320 labelFormatMatcher = new QRegExp(labelFormatMatchString);
321 if (labelFormatMatcher->indexIn(format, 0) != -1)
322 capStr = labelFormatMatcher->cap(1);
348 QString formatSpec;
349 QString preStr;
350 QString postStr;
351 int precision = 0;
352 if (presenter()->localizeNumbers()) {
353 if (!labelFormatMatcherLocalized)
354 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
355 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
356 preStr = labelFormatMatcherLocalized->cap(1);
357 precision = labelFormatMatcherLocalized->cap(2).toInt();
358 formatSpec = labelFormatMatcherLocalized->cap(3);
359 postStr = labelFormatMatcherLocalized->cap(4);
360 }
361 } else {
362 if (!labelFormatMatcher)
363 labelFormatMatcher = new QRegExp(labelFormatMatchString);
364 if (labelFormatMatcher->indexIn(format, 0) != -1)
365 formatSpec = labelFormatMatcher->cap(1);
366 }
323 367 for (int i = firstTick; i < ticks + firstTick; i++) {
324 368 qreal value = qPow(base, i);
325 appendFormattedLabel(capStr, array, labels, value);
369 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
326 370 }
327 371 }
328 372
329 373 return labels;
330 374 }
331 375
332 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,const QString &format)
376 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,
377 const QString &format) const
333 378 {
334 379 QStringList labels;
335 380
336 381 if (max <= min || ticks < 1)
337 382 return labels;
338 383
339 384 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
340 385 n++;
341 386 for (int i = 0; i < ticks; i++) {
342 387 qreal value = min + (i * (max - min) / (ticks - 1));
343 388 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
344 389 }
345 390 return labels;
346 391 }
347 392
348 393 void ChartAxisElement::axisSelected()
349 394 {
350 395 emit clicked();
351 396 }
352 397
353 398 #include "moc_chartaxiselement_p.cpp"
354 399
355 400 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,151 +1,155
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTAXISELEMENT_H
31 31 #define CHARTAXISELEMENT_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "chartelement_p.h"
35 35 #include "axisanimation_p.h"
36 36 #include <QGraphicsItem>
37 37 #include <QGraphicsLayoutItem>
38 38 #include <QFont>
39 39
40 40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 41
42 42 class ChartPresenter;
43 43 class QAbstractAxis;
44 44
45 45 class ChartAxisElement : public ChartElement, public QGraphicsLayoutItem
46 46 {
47 47 Q_OBJECT
48 48
49 49 using QGraphicsLayoutItem::setGeometry;
50 50 public:
51 51 ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis = false);
52 52 ~ChartAxisElement();
53 53
54 54 virtual QRectF gridGeometry() const = 0;
55 55 virtual void setGeometry(const QRectF &axis, const QRectF &grid) = 0;
56 56 virtual bool isEmpty() = 0;
57 57
58 58 void setAnimation(AxisAnimation *animation) { m_animation = animation; }
59 59 AxisAnimation *animation() const { return m_animation; }
60 60
61 61 QAbstractAxis *axis() const { return m_axis; }
62 62 void setLayout(QVector<qreal> &layout) { m_layout = layout; }
63 63 QVector<qreal> &layout() { return m_layout; } // Modifiable reference
64 64 inline qreal labelPadding() const { return qreal(4.0); }
65 65 inline qreal titlePadding() const { return qreal(2.0); }
66 66 void setLabels(const QStringList &labels) { m_labelsList = labels; }
67 67 QStringList labels() const { return m_labelsList; }
68 68
69 69 qreal min() const;
70 70 qreal max() const;
71 71
72 72 QRectF axisGeometry() const { return m_axisRect; }
73 73 void setAxisGeometry(const QRectF &axisGeometry) { m_axisRect = axisGeometry; }
74 74
75 75 void axisSelected();
76 76
77 77 //this flag indicates that axis is used to show intervals it means labels are in between ticks
78 78 bool intervalAxis() const { return m_intervalAxis; }
79 79
80 static QStringList createValueLabels(qreal max, qreal min, int ticks, const QString &format);
81 static QStringList createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString &format);
82 static QStringList createDateTimeLabels(qreal max, qreal min, int ticks, const QString &format);
80 QStringList createValueLabels(qreal max, qreal min, int ticks, const QString &format) const;
81 QStringList createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
82 const QString &format) const;
83 QStringList createDateTimeLabels(qreal max, qreal min, int ticks, const QString &format) const;
83 84
84 85 // from QGraphicsLayoutItem
85 86 QRectF boundingRect() const
86 87 {
87 88 return QRectF();
88 89 }
89 90
90 91 // from QGraphicsLayoutItem
91 92 void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
92 93 {
93 94 }
94 95
95 96 protected:
96 97 virtual QVector<qreal> calculateLayout() const = 0;
97 98 virtual void updateLayout(QVector<qreal> &layout) = 0;
98 99
99 100 QList<QGraphicsItem *> gridItems() { return m_grid->childItems(); }
100 101 QList<QGraphicsItem *> labelItems() { return m_labels->childItems(); }
101 102 QList<QGraphicsItem *> shadeItems() { return m_shades->childItems(); }
102 103 QList<QGraphicsItem *> arrowItems() { return m_arrow->childItems(); }
103 104 QGraphicsTextItem *titleItem() const { return m_title.data(); }
104 105 QGraphicsItemGroup *gridGroup() { return m_grid.data(); }
105 106 QGraphicsItemGroup *labelGroup() { return m_labels.data(); }
106 107 QGraphicsItemGroup *shadeGroup() { return m_shades.data(); }
107 108 QGraphicsItemGroup *arrowGroup() { return m_arrow.data(); }
108 109
109 110 public Q_SLOTS:
110 111 void handleVisibleChanged(bool visible);
111 112 void handleArrowVisibleChanged(bool visible);
112 113 void handleGridVisibleChanged(bool visible);
113 114 void handleLabelsVisibleChanged(bool visible);
114 115 void handleShadesVisibleChanged(bool visible);
115 116 void handleLabelsAngleChanged(int angle);
116 117 virtual void handleShadesBrushChanged(const QBrush &brush) = 0;
117 118 virtual void handleShadesPenChanged(const QPen &pen) = 0;
118 119 virtual void handleArrowPenChanged(const QPen &pen) = 0;
119 120 virtual void handleGridPenChanged(const QPen &pen) = 0;
120 121 void handleLabelsPenChanged(const QPen &pen);
121 122 void handleLabelsBrushChanged(const QBrush &brush);
122 123 void handleLabelsFontChanged(const QFont &font);
123 124 void handleTitlePenChanged(const QPen &pen);
124 125 void handleTitleBrushChanged(const QBrush &brush);
125 126 void handleTitleFontChanged(const QFont &font);
126 127 void handleTitleTextChanged(const QString &title);
127 128 void handleTitleVisibleChanged(bool visible);
128 129 void handleRangeChanged(qreal min, qreal max);
129 130
130 131 Q_SIGNALS:
131 132 void clicked();
132 133
133 134 private:
134 135 void connectSlots();
136 QString formatLabel(const QString &formatSpec, const QByteArray &array,
137 qreal value, int precision, const QString &preStr,
138 const QString &postStr) const;
135 139
136 140 QAbstractAxis *m_axis;
137 141 AxisAnimation *m_animation;
138 142 QVector<qreal> m_layout;
139 143 QStringList m_labelsList;
140 144 QRectF m_axisRect;
141 145 QScopedPointer<QGraphicsItemGroup> m_grid;
142 146 QScopedPointer<QGraphicsItemGroup> m_arrow;
143 147 QScopedPointer<QGraphicsItemGroup> m_shades;
144 148 QScopedPointer<QGraphicsItemGroup> m_labels;
145 149 QScopedPointer<QGraphicsTextItem> m_title;
146 150 bool m_intervalAxis;
147 151 };
148 152
149 153 QTCOMMERCIALCHART_END_NAMESPACE
150 154
151 155 #endif /* CHARTAXISELEMENT_H */
@@ -1,443 +1,451
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "qvalueaxis.h"
22 22 #include "qvalueaxis_p.h"
23 23 #include "chartvalueaxisx_p.h"
24 24 #include "chartvalueaxisy_p.h"
25 25 #include "abstractdomain_p.h"
26 26 #include "polarchartvalueaxisangular_p.h"
27 27 #include "polarchartvalueaxisradial_p.h"
28 28 #include "chartdataset_p.h"
29 29 #include "chartpresenter_p.h"
30 30 #include "charttheme_p.h"
31 31
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34 /*!
35 35 \class QValueAxis
36 36 \inmodule Qt Charts
37 37 \brief The QValueAxis class is used for manipulating chart's axis.
38 38 \mainclass
39 39
40 40 ValueAxis can be setup to show axis line with tick marks, grid lines and shades.
41 41 Values of axis are drawn to position of ticks.
42 42
43 43 Example code on how to use QValueAxis.
44 44 \code
45 45 QChartView *chartView = new QChartView;
46 46 QLineSeries *series = new QLineSeries;
47 47 // ...
48 48 chartView->chart()->addSeries(series);
49 49
50 50 QValueAxis *axisX = new QValueAxis;
51 51 axisX->setRange(10, 20.5);
52 52 axisX->setTickCount(10);
53 53 axisX->setLabelFormat("%.2f");
54 54 chartView->chart()->setAxisX(axisX, series);
55 55 \endcode
56 56 */
57 57 #ifdef QDOC_QT5
58 58 /*!
59 59 \qmltype ValueAxis
60 60 \instantiates QValueAxis
61 61 \inqmlmodule QtCommercial.Chart
62 62
63 63 \include doc/src/valueaxis.qdocinc
64 64 */
65 65 #else
66 66 /*!
67 67 \qmlclass ValueAxis QValueAxis
68 68
69 69 \include ../doc/src/valueaxis.qdocinc
70 70 */
71 71 #endif
72 72
73 73 /*!
74 74 \property QValueAxis::min
75 75 Defines the minimum value on the axis.
76 76 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
77 77 */
78 78 /*!
79 79 \qmlproperty real ValueAxis::min
80 80 Defines the minimum value on the axis.
81 81 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
82 82 */
83 83
84 84 /*!
85 85 \property QValueAxis::max
86 86 Defines the maximum value on the axis.
87 87 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
88 88 */
89 89 /*!
90 90 \qmlproperty real ValueAxis::max
91 91 Defines the maximum value on the axis.
92 92 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
93 93 */
94 94
95 95 /*!
96 96 \property QValueAxis::tickCount
97 97 Defines the number of ticks on the axis. This indicates how many grid lines are draw on the chart.
98 98 The default value is 5, and it can not be below 2.
99 99 */
100 100 /*!
101 101 \qmlproperty real ValueAxis::tickCount
102 102 Defines the number of ticks on the axis. This indicates how many grid lines are draw on the chart.
103 103 The default value is 5, and it can not be below 2.
104 104 */
105 105
106 106 /*!
107 107 \property QValueAxis::labelFormat
108 108 Defines the label format of the axis.
109 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, c
109 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c.
110 110 See QString::sprintf() for additional details.
111
112 If the QChart::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f,
113 g, and G. Also, only the precision modifier is supported. The rest of the formatting comes from
114 the default QLocale of the application.
111 115 */
112 116 /*!
113 117 \qmlproperty real ValueAxis::labelFormat
114 118 Defines the label format of the axis.
115 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, c
119 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c.
116 120 See QString::sprintf() for additional details.
121
122 If the ChartView::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f,
123 g, and G. Also, only the precision modifier is supported. The rest of the formatting comes from
124 the default QLocale of the application.
117 125 */
118 126
119 127 /*!
120 128 \fn void QValueAxis::minChanged(qreal min)
121 129 Axis emits signal when \a min of axis has changed.
122 130 */
123 131 /*!
124 132 \qmlsignal ValueAxis::onMinChanged(real min)
125 133 Axis emits signal when \a min of axis has changed.
126 134 */
127 135
128 136 /*!
129 137 \fn void QValueAxis::maxChanged(qreal max)
130 138 Axis emits signal when \a max of axis has changed.
131 139 */
132 140 /*!
133 141 \qmlsignal ValueAxis::onMaxChanged(real max)
134 142 Axis emits signal when \a max of axis has changed.
135 143 */
136 144
137 145 /*!
138 146 \fn void QValueAxis::tickCountChanged(int tickCount)
139 147 Axis emits signal when \a tickCount of axis has changed.
140 148 */
141 149 /*!
142 150 \qmlsignal ValueAxis::tickCountChanged(int tickCount)
143 151 Axis emits signal when \a tickCount of axis has changed.
144 152 */
145 153
146 154 /*!
147 155 \fn void QValueAxis::rangeChanged(qreal min, qreal max)
148 156 Axis emits signal when \a min or \a max of axis has changed.
149 157 */
150 158
151 159 /*!
152 160 \fn void QValueAxis::labelFormatChanged(const QString &format)
153 161 Axis emits signal when \a format of axis labels has changed.
154 162 */
155 163 /*!
156 164 \qmlsignal ValueAxis::labelFormatChanged(const QString &format)
157 165 Axis emits signal when \a format of axis labels has changed.
158 166 */
159 167
160 168 /*!
161 169 \property QValueAxis::niceNumbersEnabled
162 170 \obsolete
163 171 Using this function can lead to unexpected behavior. Use applyNiceNumbers() instead.
164 172 */
165 173
166 174 /*!
167 175 \qmlproperty bool ValueAxis::niceNumbersEnabled
168 176 Deprecated; Using this function can lead to unexpected behavior. Use applyNiceNumbers() instead.
169 177 */
170 178
171 179 /*!
172 180 Constructs an axis object which is a child of \a parent.
173 181 */
174 182 QValueAxis::QValueAxis(QObject *parent) :
175 183 QAbstractAxis(*new QValueAxisPrivate(this), parent)
176 184 {
177 185
178 186 }
179 187
180 188 /*!
181 189 \internal
182 190 */
183 191 QValueAxis::QValueAxis(QValueAxisPrivate &d, QObject *parent)
184 192 : QAbstractAxis(d, parent)
185 193 {
186 194
187 195 }
188 196
189 197 /*!
190 198 Destroys the object
191 199 */
192 200 QValueAxis::~QValueAxis()
193 201 {
194 202 Q_D(QValueAxis);
195 203 if (d->m_chart)
196 204 d->m_chart->removeAxis(this);
197 205 }
198 206
199 207 void QValueAxis::setMin(qreal min)
200 208 {
201 209 Q_D(QValueAxis);
202 210 setRange(min, qMax(d->m_max, min));
203 211 }
204 212
205 213 qreal QValueAxis::min() const
206 214 {
207 215 Q_D(const QValueAxis);
208 216 return d->m_min;
209 217 }
210 218
211 219 void QValueAxis::setMax(qreal max)
212 220 {
213 221 Q_D(QValueAxis);
214 222 setRange(qMin(d->m_min, max), max);
215 223 }
216 224
217 225 qreal QValueAxis::max() const
218 226 {
219 227 Q_D(const QValueAxis);
220 228 return d->m_max;
221 229 }
222 230
223 231 /*!
224 232 Sets range from \a min to \a max on the axis.
225 233 If min is greater than max then this function returns without making any changes.
226 234 */
227 235 void QValueAxis::setRange(qreal min, qreal max)
228 236 {
229 237 Q_D(QValueAxis);
230 238 d->setRange(min,max);
231 239 }
232 240
233 241 void QValueAxis::setTickCount(int count)
234 242 {
235 243 Q_D(QValueAxis);
236 244 if (d->m_tickCount != count && count >= 2) {
237 245 d->m_tickCount = count;
238 246 emit tickCountChanged(count);
239 247 }
240 248 }
241 249
242 250 int QValueAxis::tickCount() const
243 251 {
244 252 Q_D(const QValueAxis);
245 253 return d->m_tickCount;
246 254 }
247 255
248 256 void QValueAxis::setNiceNumbersEnabled(bool enable)
249 257 {
250 258 Q_D(QValueAxis);
251 259 qWarning() << "Deprecated; Using this function can lead to unexpected behavior. " \
252 260 "Use applyNiceNumbers() instead.";
253 261 if(enable) {
254 262 QObject::connect(this,SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(applyNiceNumbers()));
255 263 QObject::connect(this,SIGNAL(tickCountChanged(int)),this,SLOT(applyNiceNumbers()));
256 264 applyNiceNumbers();
257 265 }
258 266 else {
259 267 QObject::disconnect(this,SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(applyNiceNumbers()));
260 268 QObject::disconnect(this,SIGNAL(tickCountChanged(int)),this,SLOT(applyNiceNumbers()));
261 269 }
262 270 d->m_niceNumbersEnabled=enable;
263 271 }
264 272
265 273 bool QValueAxis::niceNumbersEnabled() const
266 274 {
267 275 Q_D(const QValueAxis);
268 276 qWarning() << "Deprecated; Using this function can lead to unexpected behavior. " \
269 277 "Use applyNiceNumbers() instead.";
270 278 return d->m_niceNumbersEnabled;
271 279 }
272 280
273 281 void QValueAxis::setLabelFormat(const QString &format)
274 282 {
275 283 Q_D(QValueAxis);
276 284 d->m_format = format;
277 285 emit labelFormatChanged(format);
278 286 }
279 287
280 288 QString QValueAxis::labelFormat() const
281 289 {
282 290 Q_D(const QValueAxis);
283 291 return d->m_format;
284 292 }
285 293
286 294 /*!
287 295 Returns the type of the axis
288 296 */
289 297 QAbstractAxis::AxisType QValueAxis::type() const
290 298 {
291 299 return AxisTypeValue;
292 300 }
293 301
294 302 /*!
295 303 This method modifies range and number of ticks on the axis to look "nice". Algorithm considers numbers that
296 304 can be expressed as form of 1*10^n, 2* 10^n or 5*10^n as a nice numbers. These numbers are used for spacing the ticks.
297 305 This method will modify the current range and number of ticks.
298 306 \sa setRange(), setTickCount()
299 307 */
300 308 void QValueAxis::applyNiceNumbers()
301 309 {
302 310 Q_D(QValueAxis);
303 311 if(d->m_applying) return;
304 312 qreal min = d->m_min;
305 313 qreal max = d->m_max;
306 314 int ticks = d->m_tickCount;
307 315 AbstractDomain::looseNiceNumbers(min,max,ticks);
308 316 d->m_applying=true;
309 317 d->setRange(min,max);
310 318 setTickCount(ticks);
311 319 d->m_applying=false;
312 320 }
313 321
314 322 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
315 323
316 324 QValueAxisPrivate::QValueAxisPrivate(QValueAxis *q)
317 325 : QAbstractAxisPrivate(q),
318 326 m_min(0),
319 327 m_max(0),
320 328 m_tickCount(5),
321 329 m_format(QString::null),
322 330 m_applying(false),
323 331 m_niceNumbersEnabled(false)
324 332 {
325 333
326 334 }
327 335
328 336 QValueAxisPrivate::~QValueAxisPrivate()
329 337 {
330 338
331 339 }
332 340
333 341 void QValueAxisPrivate::setMin(const QVariant &min)
334 342 {
335 343 Q_Q(QValueAxis);
336 344 bool ok;
337 345 qreal value = min.toReal(&ok);
338 346 if (ok)
339 347 q->setMin(value);
340 348 }
341 349
342 350 void QValueAxisPrivate::setMax(const QVariant &max)
343 351 {
344 352 Q_Q(QValueAxis);
345 353 bool ok;
346 354 qreal value = max.toReal(&ok);
347 355 if (ok)
348 356 q->setMax(value);
349 357 }
350 358
351 359 void QValueAxisPrivate::setRange(const QVariant &min, const QVariant &max)
352 360 {
353 361 Q_Q(QValueAxis);
354 362 bool ok1;
355 363 bool ok2;
356 364 qreal value1 = min.toReal(&ok1);
357 365 qreal value2 = max.toReal(&ok2);
358 366 if (ok1 && ok2)
359 367 q->setRange(value1, value2);
360 368 }
361 369
362 370 void QValueAxisPrivate::setRange(qreal min, qreal max)
363 371 {
364 372 Q_Q(QValueAxis);
365 373 bool changed = false;
366 374
367 375 if (min > max)
368 376 return;
369 377
370 378 bool changeMin = false;
371 379 if (m_min == 0 || min == 0)
372 380 changeMin = !qFuzzyCompare(1 + m_min, 1 + min);
373 381 else
374 382 changeMin = !qFuzzyCompare(m_min, min);
375 383
376 384 bool changeMax = false;
377 385 if (m_max == 0 || max == 0)
378 386 changeMax = !qFuzzyCompare(1 + m_max, 1 + max);
379 387 else
380 388 changeMax = !qFuzzyCompare(m_max, max);
381 389
382 390 if (changeMin) {
383 391 m_min = min;
384 392 changed = true;
385 393 emit q->minChanged(min);
386 394 }
387 395
388 396 if (changeMax) {
389 397 m_max = max;
390 398 changed = true;
391 399 emit q->maxChanged(max);
392 400 }
393 401
394 402 if (changed) {
395 403 emit rangeChanged(min,max);
396 404 emit q->rangeChanged(min, max);
397 405 }
398 406 }
399 407
400 408 void QValueAxisPrivate::initializeGraphics(QGraphicsItem *parent)
401 409 {
402 410 Q_Q(QValueAxis);
403 411 ChartAxisElement *axis(0);
404 412
405 413 if (m_chart->chartType() == QChart::ChartTypeCartesian) {
406 414 if (orientation() == Qt::Vertical)
407 415 axis = new ChartValueAxisY(q,parent);
408 416 if (orientation() == Qt::Horizontal)
409 417 axis = new ChartValueAxisX(q,parent);
410 418 }
411 419
412 420 if (m_chart->chartType() == QChart::ChartTypePolar) {
413 421 if (orientation() == Qt::Vertical)
414 422 axis = new PolarChartValueAxisRadial(q, parent);
415 423 if (orientation() == Qt::Horizontal)
416 424 axis = new PolarChartValueAxisAngular(q, parent);
417 425 }
418 426
419 427 m_item.reset(axis);
420 428 QAbstractAxisPrivate::initializeGraphics(parent);
421 429 }
422 430
423 431
424 432 void QValueAxisPrivate::initializeDomain(AbstractDomain *domain)
425 433 {
426 434 if (orientation() == Qt::Vertical) {
427 435 if (!qFuzzyIsNull(m_max - m_min))
428 436 domain->setRangeY(m_min, m_max);
429 437 else
430 438 setRange(domain->minY(), domain->maxY());
431 439 }
432 440 if (orientation() == Qt::Horizontal) {
433 441 if (!qFuzzyIsNull(m_max - m_min))
434 442 domain->setRangeX(m_min, m_max);
435 443 else
436 444 setRange(domain->minX(), domain->maxX());
437 445 }
438 446 }
439 447
440 448 #include "moc_qvalueaxis.cpp"
441 449 #include "moc_qvalueaxis_p.cpp"
442 450
443 451 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,265 +1,268
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "abstractbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "qabstractbarseries.h"
26 26 #include "qabstractbarseries_p.h"
27 27 #include "qchart.h"
28 28 #include "chartpresenter_p.h"
29 29 #include "charttheme_p.h"
30 30 #include "baranimation_p.h"
31 31 #include "chartdataset_p.h"
32 32 #include <QPainter>
33 33 #include <QTextDocument>
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
38 38 ChartItem(series->d_func(),item),
39 39 m_animation(0),
40 40 m_series(series)
41 41 {
42 42
43 43 setFlag(ItemClipsChildrenToShape);
44 44 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
45 45 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleUpdatedBars()));
46 46 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
47 47 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
48 48 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
49 49 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
50 50 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(handleUpdatedBars()));
51 51 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
52 52 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
53 53 this, SLOT(handleLabelsPositionChanged()));
54 54 setZValue(ChartPresenter::BarSeriesZValue);
55 55 handleDataStructureChanged();
56 56 handleVisibleChanged();
57 57 handleUpdatedBars();
58 58 }
59 59
60 60 AbstractBarChartItem::~AbstractBarChartItem()
61 61 {
62 62 }
63 63
64 64 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
65 65 {
66 66 Q_UNUSED(painter);
67 67 Q_UNUSED(option);
68 68 Q_UNUSED(widget);
69 69 }
70 70
71 71 QRectF AbstractBarChartItem::boundingRect() const
72 72 {
73 73 return m_rect;
74 74 }
75 75
76 76 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
77 77 {
78 78 QSizeF size = geometry().size();
79 79 if (geometry().size().isValid()) {
80 80 if (m_animation) {
81 81 if (m_layout.count() == 0 || m_oldSize != size) {
82 82 initializeLayout();
83 83 m_oldSize = size;
84 84 }
85 85 m_animation->setup(m_layout, layout);
86 86 presenter()->startAnimation(m_animation);
87 87 } else {
88 88 setLayout(layout);
89 89 update();
90 90 }
91 91 }
92 92 }
93 93
94 94 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
95 95 {
96 96 m_animation = animation;
97 97 }
98 98
99 99 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
100 100 {
101 101 if (layout.count() != m_bars.count())
102 102 return;
103 103
104 104 m_layout = layout;
105 105
106 106 for (int i = 0; i < m_bars.count(); i++)
107 107 m_bars.at(i)->setRect(layout.at(i));
108 108
109 109 positionLabels();
110 110 }
111 111 //handlers
112 112
113 113 void AbstractBarChartItem::handleDomainUpdated()
114 114 {
115 115 m_domainMinX = domain()->minX();
116 116 m_domainMaxX = domain()->maxX();
117 117 m_domainMinY = domain()->minY();
118 118 m_domainMaxY = domain()->maxY();
119 119
120 120 QRectF rect(QPointF(0,0),domain()->size());
121 121
122 122 if(m_rect != rect){
123 123 prepareGeometryChange();
124 124 m_rect = rect;
125 125 }
126 126
127 127 handleLayoutChanged();
128 128 }
129 129
130 130 void AbstractBarChartItem::handleLayoutChanged()
131 131 {
132 132 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
133 133 return; // rect size zero.
134 134 QVector<QRectF> layout = calculateLayout();
135 135 applyLayout(layout);
136 136 handleUpdatedBars();
137 137 }
138 138
139 139 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
140 140 {
141 141 foreach (QGraphicsTextItem *label, m_labels)
142 142 label->setVisible(visible);
143 143 update();
144 144 }
145 145
146 146 void AbstractBarChartItem::handleDataStructureChanged()
147 147 {
148 148 foreach (QGraphicsItem *item, childItems())
149 149 delete item;
150 150
151 151 m_bars.clear();
152 152 m_labels.clear();
153 153 m_layout.clear();
154 154
155 155 // Create new graphic items for bars
156 156 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
157 157 for (int s = 0; s < m_series->count(); s++) {
158 158 QBarSet *set = m_series->d_func()->barsetAt(s);
159 159
160 160 // Bars
161 161 Bar *bar = new Bar(set, c, this);
162 162 m_bars.append(bar);
163 163 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
164 164 connect(bar, SIGNAL(hovered(bool,QBarSet*)), m_series, SIGNAL(hovered(bool,QBarSet*)));
165 165 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), m_series, SIGNAL(hovered(bool, int, QBarSet*)));
166 166 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
167 167 connect(bar, SIGNAL(hovered(bool,QBarSet*)), set, SIGNAL(hovered(bool)));
168 168 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
169 169 // m_layout.append(QRectF(0, 0, 1, 1));
170 170
171 171 // Labels
172 172 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
173 173 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
174 174 m_labels.append(newLabel);
175 175 }
176 176 }
177 177
178 178 if(themeManager()) themeManager()->updateSeries(m_series);
179 179 handleLayoutChanged();
180 180 handleVisibleChanged();
181 181 }
182 182
183 183 void AbstractBarChartItem::handleVisibleChanged()
184 184 {
185 185 bool visible = m_series->isVisible();
186 186 if (visible)
187 187 handleLabelsVisibleChanged(m_series->isLabelsVisible());
188 188 else
189 189 handleLabelsVisibleChanged(visible);
190 190
191 191 foreach (QGraphicsItem *bar, m_bars)
192 192 bar->setVisible(visible);
193 193 }
194 194
195 195 void AbstractBarChartItem::handleOpacityChanged()
196 196 {
197 197 foreach (QGraphicsItem *item, childItems())
198 198 item->setOpacity(m_series->opacity());
199 199 }
200 200
201 201 void AbstractBarChartItem::handleUpdatedBars()
202 202 {
203 203 if (!m_series->d_func()->blockBarUpdate()) {
204 204 // Handle changes in pen, brush, labels etc.
205 205 int categoryCount = m_series->d_func()->categoryCount();
206 206 int setCount = m_series->count();
207 207 int itemIndex(0);
208 208 static const QString valueTag(QLatin1String("@value"));
209 209
210 210 for (int category = 0; category < categoryCount; category++) {
211 211 for (int set = 0; set < setCount; set++) {
212 212 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
213 213 Bar *bar = m_bars.at(itemIndex);
214 214 bar->setPen(barSet->m_pen);
215 215 bar->setBrush(barSet->m_brush);
216 216 bar->update();
217 217
218 218 QGraphicsTextItem *label = m_labels.at(itemIndex);
219 219 QString valueLabel;
220 if (m_series->labelsFormat().isEmpty()) {
221 valueLabel = QString("%1").arg(barSet->value(category));
222 } else {
223 valueLabel = m_series->labelsFormat();
224 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
220 if (presenter()) { // At startup presenter is not yet set, yet somehow update comes
221 if (m_series->labelsFormat().isEmpty()) {
222 valueLabel = presenter()->numberToString(barSet->value(category));
223 } else {
224 valueLabel = m_series->labelsFormat();
225 valueLabel.replace(valueTag,
226 presenter()->numberToString(barSet->value(category)));
227 }
225 228 }
226 229 label->setHtml(valueLabel);
227 230 label->setFont(barSet->m_labelFont);
228 231 label->setDefaultTextColor(barSet->m_labelBrush.color());
229 232 label->update();
230 233 itemIndex++;
231 234 }
232 235 }
233 236 }
234 237 }
235 238
236 239 void AbstractBarChartItem::handleLabelsPositionChanged()
237 240 {
238 241 positionLabels();
239 242 }
240 243
241 244 void AbstractBarChartItem::positionLabels()
242 245 {
243 246 for (int i = 0; i < m_layout.count(); i++) {
244 247 QGraphicsTextItem *label = m_labels.at(i);
245 248 qreal xPos = 0;
246 249 qreal yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
247 250
248 251 int offset = m_bars.at(i)->pen().width() / 2 + 2;
249 252 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
250 253 xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
251 254 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
252 255 xPos = m_layout.at(i).right() - label->boundingRect().width() - offset;
253 256 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
254 257 xPos = m_layout.at(i).left() + offset;
255 258 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
256 259 xPos = m_layout.at(i).right() + offset;
257 260
258 261 label->setPos(xPos, yPos);
259 262 label->setZValue(zValue() + 1);
260 263 }
261 264 }
262 265
263 266 #include "moc_abstractbarchartitem_p.cpp"
264 267
265 268 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,141 +1,140
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "horizontalpercentbarchartitem_p.h"
22 22 #include "qabstractbarseries_p.h"
23 23 #include "qbarset_p.h"
24 24 #include "bar_p.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
29 29 : AbstractBarChartItem(series, item)
30 30 {
31 31 }
32 32
33 33 void HorizontalPercentBarChartItem::initializeLayout()
34 34 {
35 35 qreal categoryCount = m_series->d_func()->categoryCount();
36 36 qreal setCount = m_series->count();
37 37 qreal barWidth = m_series->d_func()->barWidth();
38 38
39 39 m_layout.clear();
40 40 for(int category = 0; category < categoryCount; category++) {
41 41 for (int set = 0; set < setCount; set++) {
42 42 QRectF rect;
43 43 QPointF topLeft;
44 44 QPointF bottomRight;
45 45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
46 46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
47 47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
48 48 } else {
49 49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
50 50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
51 51 }
52 52
53 53 if (!m_validData)
54 54 return;
55 55
56 56 rect.setTopLeft(topLeft);
57 57 rect.setBottomRight(bottomRight);
58 58 m_layout.append(rect.normalized());
59 59 }
60 60 }
61 61 }
62 62
63 63 QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
64 64 {
65 65 QVector<QRectF> layout;
66 66
67 67 // Use temporary qreals for accuracy
68 68 qreal categoryCount = m_series->d_func()->categoryCount();
69 69 qreal setCount = m_series->count();
70 70 qreal barWidth = m_series->d_func()->barWidth();
71 71
72 72 for(int category = 0; category < categoryCount; category++) {
73 73 qreal sum = 0;
74 74 qreal categorySum = m_series->d_func()->categorySum(category);
75 75 for (int set = 0; set < setCount; set++) {
76 76 qreal value = m_series->barSets().at(set)->at(category);
77 77 QRectF rect;
78 78 qreal topX = 0;
79 79 if (sum > 0)
80 80 topX = 100 * sum / categorySum;
81 81 qreal bottomX = 0;
82 82 qreal newSum = value + sum;
83 83 if (newSum > 0)
84 84 bottomX = 100 * newSum / categorySum;
85 85 QPointF topLeft;
86 86 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
87 87 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : domain()->minX(), category - barWidth/2), m_validData);
88 88 else
89 89 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : 0, category - barWidth/2), m_validData);
90 90 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(bottomX, category + barWidth/2), m_validData);
91 91
92 92 rect.setTopLeft(topLeft);
93 93 rect.setBottomRight(bottomRight);
94 94 layout.append(rect.normalized());
95 95 sum = newSum;
96 96 }
97 97 }
98 98 return layout;
99 99 }
100 100
101 101 void HorizontalPercentBarChartItem::handleUpdatedBars()
102 102 {
103 103 // Handle changes in pen, brush, labels etc.
104 104 int categoryCount = m_series->d_func()->categoryCount();
105 105 int setCount = m_series->count();
106 106 int itemIndex(0);
107 107 static const QString valueTag(QLatin1String("@value"));
108 108
109 109 for (int category = 0; category < categoryCount; category++) {
110 110 for (int set = 0; set < setCount; set++) {
111 111 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
112 112 Bar *bar = m_bars.at(itemIndex);
113 113 bar->setPen(barSet->m_pen);
114 114 bar->setBrush(barSet->m_brush);
115 115 bar->update();
116 116
117 117 QGraphicsTextItem *label = m_labels.at(itemIndex);
118 int p = m_series->d_func()->percentageAt(set, category) * 100;
119 QString vString(QString::number(p));
120 vString.truncate(3);
121 vString.append("%");
118 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
119 QString vString(presenter()->numberToString(p, 'f', 0));
122 120 QString valueLabel;
123 121 if (m_series->labelsFormat().isEmpty()) {
122 vString.append("%");
124 123 valueLabel = vString;
125 124 } else {
126 125 valueLabel = m_series->labelsFormat();
127 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
126 valueLabel.replace(valueTag, vString);
128 127 }
129 128 label->setHtml(valueLabel);
130 129 label->setFont(barSet->m_labelFont);
131 130 label->setDefaultTextColor(barSet->m_labelBrush.color());
132 131 label->update();
133 132 itemIndex++;
134 133 }
135 134 }
136 135 }
137 136
138 137 #include "moc_horizontalpercentbarchartitem_p.cpp"
139 138
140 139 QTCOMMERCIALCHART_END_NAMESPACE
141 140
@@ -1,172 +1,171
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "percentbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qabstractbarseries_p.h"
24 24 #include "qbarset.h"
25 25 #include "qbarset_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 30 AbstractBarChartItem(series, item)
31 31 {
32 32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
33 33 this, SLOT(handleLabelsPositionChanged()));
34 34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
35 35 }
36 36
37 37 void PercentBarChartItem::initializeLayout()
38 38 {
39 39 qreal categoryCount = m_series->d_func()->categoryCount();
40 40 qreal setCount = m_series->count();
41 41 qreal barWidth = m_series->d_func()->barWidth();
42 42
43 43 m_layout.clear();
44 44 for(int category = 0; category < categoryCount; category++) {
45 45 for (int set = 0; set < setCount; set++) {
46 46 QRectF rect;
47 47 QPointF topLeft;
48 48 QPointF bottomRight;
49 49
50 50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
51 51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
52 52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
53 53 } else {
54 54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
55 55 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
56 56 }
57 57
58 58 if (!m_validData)
59 59 return;
60 60
61 61 rect.setTopLeft(topLeft);
62 62 rect.setBottomRight(bottomRight);
63 63 m_layout.append(rect.normalized());
64 64 }
65 65 }
66 66 }
67 67
68 68 QVector<QRectF> PercentBarChartItem::calculateLayout()
69 69 {
70 70 QVector<QRectF> layout;
71 71
72 72 // Use temporary qreals for accuracy
73 73 qreal categoryCount = m_series->d_func()->categoryCount();
74 74 qreal setCount = m_series->count();
75 75 qreal barWidth = m_series->d_func()->barWidth();
76 76
77 77 for(int category = 0; category < categoryCount; category++) {
78 78 qreal sum = 0;
79 79 qreal categorySum = m_series->d_func()->categorySum(category);
80 80 for (int set = 0; set < setCount; set++) {
81 81 qreal value = m_series->barSets().at(set)->at(category);
82 82 QRectF rect;
83 83 qreal topY = 0;
84 84 qreal newSum = value + sum;
85 85 if (newSum > 0)
86 86 topY = 100 * newSum / categorySum;
87 87 qreal bottomY = 0;
88 88 if (sum > 0)
89 89 bottomY = 100 * sum / categorySum;
90 90 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
91 91 QPointF bottomRight;
92 92 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
93 93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
94 94 else
95 95 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
96 96
97 97 rect.setTopLeft(topLeft);
98 98 rect.setBottomRight(bottomRight);
99 99 layout.append(rect.normalized());
100 100 sum = newSum;
101 101 }
102 102 }
103 103 return layout;
104 104 }
105 105
106 106 void PercentBarChartItem::handleUpdatedBars()
107 107 {
108 108 // Handle changes in pen, brush, labels etc.
109 109 int categoryCount = m_series->d_func()->categoryCount();
110 110 int setCount = m_series->count();
111 111 int itemIndex(0);
112 112 static const QString valueTag(QLatin1String("@value"));
113 113
114 114 for (int category = 0; category < categoryCount; category++) {
115 115 for (int set = 0; set < setCount; set++) {
116 116 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
117 117 Bar *bar = m_bars.at(itemIndex);
118 118 bar->setPen(barSet->m_pen);
119 119 bar->setBrush(barSet->m_brush);
120 120 bar->update();
121 121
122 122 QGraphicsTextItem *label = m_labels.at(itemIndex);
123 int p = m_series->d_func()->percentageAt(set, category) * 100;
124 QString vString(QString::number(p));
125 vString.truncate(3);
126 vString.append("%");
123 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
124 QString vString(presenter()->numberToString(p, 'f', 0));
127 125 QString valueLabel;
128 126 if (m_series->labelsFormat().isEmpty()) {
127 vString.append("%");
129 128 valueLabel = vString;
130 129 } else {
131 130 valueLabel = m_series->labelsFormat();
132 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
131 valueLabel.replace(valueTag, vString);
133 132 }
134 133 label->setHtml(valueLabel);
135 134 label->setFont(barSet->m_labelFont);
136 135 label->setDefaultTextColor(barSet->m_labelBrush.color());
137 136 label->update();
138 137 itemIndex++;
139 138 }
140 139 }
141 140 }
142 141
143 142 void PercentBarChartItem::handleLabelsPositionChanged()
144 143 {
145 144 positionLabels();
146 145 }
147 146
148 147 void PercentBarChartItem::positionLabels()
149 148 {
150 149 for (int i = 0; i < m_layout.count(); i++) {
151 150 QGraphicsTextItem *label = m_labels.at(i);
152 151 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
153 152 qreal yPos = 0;
154 153
155 154 int offset = m_bars.at(i)->pen().width() / 2 + 2;
156 155 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
157 156 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
158 157 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
159 158 yPos = m_layout.at(i).top() - offset;
160 159 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
161 160 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
162 161 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
163 162 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
164 163
165 164 label->setPos(xPos, yPos);
166 165 label->setZValue(zValue() + 1);
167 166 }
168 167 }
169 168
170 169 #include "moc_percentbarchartitem_p.cpp"
171 170
172 171 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,480 +1,501
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 #include "chartpresenter_p.h"
21 21 #include "qchart.h"
22 22 #include "chartitem_p.h"
23 23 #include "qchart_p.h"
24 24 #include "qabstractaxis.h"
25 25 #include "qabstractaxis_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "chartanimation_p.h"
28 28 #include "qabstractseries_p.h"
29 29 #include "qareaseries.h"
30 30 #include "chartaxiselement_p.h"
31 31 #include "chartbackground_p.h"
32 32 #include "cartesianchartlayout_p.h"
33 33 #include "polarchartlayout_p.h"
34 34 #include "charttitle_p.h"
35 35 #include <QTimer>
36 36 #include <QTextDocument>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
41 41 : QObject(chart),
42 42 m_chart(chart),
43 43 m_options(QChart::NoAnimation),
44 44 m_state(ShowState),
45 45 m_background(0),
46 46 m_plotAreaBackground(0),
47 m_title(0)
47 m_title(0),
48 m_localizeNumbers(false)
48 49 {
49 50 if (type == QChart::ChartTypeCartesian)
50 51 m_layout = new CartesianChartLayout(this);
51 52 else if (type == QChart::ChartTypePolar)
52 53 m_layout = new PolarChartLayout(this);
53 54 Q_ASSERT(m_layout);
54 55 }
55 56
56 57 ChartPresenter::~ChartPresenter()
57 58 {
58 59
59 60 }
60 61
61 62 void ChartPresenter::setGeometry(const QRectF rect)
62 63 {
63 64 if (m_rect != rect) {
64 65 m_rect = rect;
65 66 foreach (ChartItem *chart, m_chartItems) {
66 67 chart->domain()->setSize(rect.size());
67 68 chart->setPos(rect.topLeft());
68 69 }
69 70 }
70 71 }
71 72
72 73 QRectF ChartPresenter::geometry() const
73 74 {
74 75 return m_rect;
75 76 }
76 77
77 78 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
78 79 {
79 80 axis->d_ptr->initializeGraphics(rootItem());
80 81 axis->d_ptr->initializeAnimations(m_options);
81 82 ChartAxisElement *item = axis->d_ptr->axisItem();
82 83 item->setPresenter(this);
83 84 item->setThemeManager(m_chart->d_ptr->m_themeManager);
84 85 m_axisItems<<item;
85 86 m_axes<<axis;
86 87 m_layout->invalidate();
87 88 }
88 89
89 90 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
90 91 {
91 92 ChartAxisElement *item = axis->d_ptr->m_item.take();
92 93 item->hide();
93 94 item->disconnect();
94 95 item->deleteLater();
95 96 m_axisItems.removeAll(item);
96 97 m_axes.removeAll(axis);
97 98 m_layout->invalidate();
98 99 }
99 100
100 101
101 102 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
102 103 {
103 104 series->d_ptr->initializeGraphics(rootItem());
104 105 series->d_ptr->initializeAnimations(m_options);
106 series->d_ptr->setPresenter(this);
105 107 ChartItem *chart = series->d_ptr->chartItem();
106 108 chart->setPresenter(this);
107 109 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
108 110 chart->domain()->setSize(m_rect.size());
109 111 chart->setPos(m_rect.topLeft());
110 112 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
111 113 m_chartItems<<chart;
112 114 m_series<<series;
113 115 m_layout->invalidate();
114 116 }
115 117
116 118 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
117 119 {
118 120 ChartItem *chart = series->d_ptr->m_item.take();
119 121 chart->hide();
120 122 chart->disconnect();
121 123 chart->deleteLater();
122 124 m_chartItems.removeAll(chart);
123 125 m_series.removeAll(series);
124 126 m_layout->invalidate();
125 127 }
126 128
127 129 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
128 130 {
129 131 if (m_options != options) {
130 132 QChart::AnimationOptions oldOptions = m_options;
131 133 m_options = options;
132 134 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
133 135 foreach (QAbstractSeries *series, m_series)
134 136 series->d_ptr->initializeAnimations(m_options);
135 137 }
136 138 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
137 139 foreach (QAbstractAxis *axis, m_axes)
138 140 axis->d_ptr->initializeAnimations(m_options);
139 141 }
140 142 m_layout->invalidate(); // So that existing animations don't just stop halfway
141 143 }
142 144 }
143 145
144 146 void ChartPresenter::setState(State state,QPointF point)
145 147 {
146 148 m_state=state;
147 149 m_statePoint=point;
148 150 }
149 151
150 152 QChart::AnimationOptions ChartPresenter::animationOptions() const
151 153 {
152 154 return m_options;
153 155 }
154 156
155 157 void ChartPresenter::createBackgroundItem()
156 158 {
157 159 if (!m_background) {
158 160 m_background = new ChartBackground(rootItem());
159 161 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
160 162 m_background->setBrush(QChartPrivate::defaultBrush());
161 163 m_background->setZValue(ChartPresenter::BackgroundZValue);
162 164 }
163 165 }
164 166
165 167 void ChartPresenter::createPlotAreaBackgroundItem()
166 168 {
167 169 if (!m_plotAreaBackground) {
168 170 if (m_chart->chartType() == QChart::ChartTypeCartesian)
169 171 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
170 172 else
171 173 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
172 174 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
173 175 // antialising artifacts with axis lines for some reason.
174 176 m_plotAreaBackground->setPen(QPen(Qt::transparent));
175 177 m_plotAreaBackground->setBrush(Qt::NoBrush);
176 178 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
177 179 m_plotAreaBackground->setVisible(false);
178 180 }
179 181 }
180 182
181 183 void ChartPresenter::createTitleItem()
182 184 {
183 185 if (!m_title) {
184 186 m_title = new ChartTitle(rootItem());
185 187 m_title->setZValue(ChartPresenter::BackgroundZValue);
186 188 }
187 189 }
188 190
189 191 void ChartPresenter::startAnimation(ChartAnimation *animation)
190 192 {
191 193 animation->stop();
192 194 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
193 195 }
194 196
195 197 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
196 198 {
197 199 createBackgroundItem();
198 200 m_background->setBrush(brush);
199 201 m_layout->invalidate();
200 202 }
201 203
202 204 QBrush ChartPresenter::backgroundBrush() const
203 205 {
204 206 if (!m_background)
205 207 return QBrush();
206 208 return m_background->brush();
207 209 }
208 210
209 211 void ChartPresenter::setBackgroundPen(const QPen &pen)
210 212 {
211 213 createBackgroundItem();
212 214 m_background->setPen(pen);
213 215 m_layout->invalidate();
214 216 }
215 217
216 218 QPen ChartPresenter::backgroundPen() const
217 219 {
218 220 if (!m_background)
219 221 return QPen();
220 222 return m_background->pen();
221 223 }
222 224
223 225 void ChartPresenter::setBackgroundRoundness(qreal diameter)
224 226 {
225 227 createBackgroundItem();
226 228 m_background->setDiameter(diameter);
227 229 m_layout->invalidate();
228 230 }
229 231
230 232 qreal ChartPresenter::backgroundRoundness() const
231 233 {
232 234 if (!m_background)
233 235 return 0;
234 236 return m_background->diameter();
235 237 }
236 238
237 239 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
238 240 {
239 241 createPlotAreaBackgroundItem();
240 242 m_plotAreaBackground->setBrush(brush);
241 243 m_layout->invalidate();
242 244 }
243 245
244 246 QBrush ChartPresenter::plotAreaBackgroundBrush() const
245 247 {
246 248 if (!m_plotAreaBackground)
247 249 return QBrush();
248 250 return m_plotAreaBackground->brush();
249 251 }
250 252
251 253 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
252 254 {
253 255 createPlotAreaBackgroundItem();
254 256 m_plotAreaBackground->setPen(pen);
255 257 m_layout->invalidate();
256 258 }
257 259
258 260 QPen ChartPresenter::plotAreaBackgroundPen() const
259 261 {
260 262 if (!m_plotAreaBackground)
261 263 return QPen();
262 264 return m_plotAreaBackground->pen();
263 265 }
264 266
265 267 void ChartPresenter::setTitle(const QString &title)
266 268 {
267 269 createTitleItem();
268 270 m_title->setText(title);
269 271 m_layout->invalidate();
270 272 }
271 273
272 274 QString ChartPresenter::title() const
273 275 {
274 276 if (!m_title)
275 277 return QString();
276 278 return m_title->text();
277 279 }
278 280
279 281 void ChartPresenter::setTitleFont(const QFont &font)
280 282 {
281 283 createTitleItem();
282 284 m_title->setFont(font);
283 285 m_layout->invalidate();
284 286 }
285 287
286 288 QFont ChartPresenter::titleFont() const
287 289 {
288 290 if (!m_title)
289 291 return QFont();
290 292 return m_title->font();
291 293 }
292 294
293 295 void ChartPresenter::setTitleBrush(const QBrush &brush)
294 296 {
295 297 createTitleItem();
296 298 m_title->setDefaultTextColor(brush.color());
297 299 m_layout->invalidate();
298 300 }
299 301
300 302 QBrush ChartPresenter::titleBrush() const
301 303 {
302 304 if (!m_title)
303 305 return QBrush();
304 306 return QBrush(m_title->defaultTextColor());
305 307 }
306 308
307 309 void ChartPresenter::setBackgroundVisible(bool visible)
308 310 {
309 311 createBackgroundItem();
310 312 m_background->setVisible(visible);
311 313 }
312 314
313 315
314 316 bool ChartPresenter::isBackgroundVisible() const
315 317 {
316 318 if (!m_background)
317 319 return false;
318 320 return m_background->isVisible();
319 321 }
320 322
321 323 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
322 324 {
323 325 createPlotAreaBackgroundItem();
324 326 m_plotAreaBackground->setVisible(visible);
325 327 }
326 328
327 329 bool ChartPresenter::isPlotAreaBackgroundVisible() const
328 330 {
329 331 if (!m_plotAreaBackground)
330 332 return false;
331 333 return m_plotAreaBackground->isVisible();
332 334 }
333 335
334 336 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
335 337 {
336 338 createBackgroundItem();
337 339 m_background->setDropShadowEnabled(enabled);
338 340 }
339 341
340 342 bool ChartPresenter::isBackgroundDropShadowEnabled() const
341 343 {
342 344 if (!m_background)
343 345 return false;
344 346 return m_background->isDropShadowEnabled();
345 347 }
346 348
349 void ChartPresenter::setLocalizeNumbers(bool localize)
350 {
351 m_localizeNumbers = localize;
352 m_layout->invalidate();
353 }
354
355 bool ChartPresenter::localizeNumbers() const
356 {
357 return m_localizeNumbers;
358 }
359
347 360
348 361 AbstractChartLayout *ChartPresenter::layout()
349 362 {
350 363 return m_layout;
351 364 }
352 365
353 366 QLegend *ChartPresenter::legend()
354 367 {
355 368 return m_chart->legend();
356 369 }
357 370
358 371 void ChartPresenter::setVisible(bool visible)
359 372 {
360 373 m_chart->setVisible(visible);
361 374 }
362 375
363 376 ChartBackground *ChartPresenter::backgroundElement()
364 377 {
365 378 return m_background;
366 379 }
367 380
368 381 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
369 382 {
370 383 return m_plotAreaBackground;
371 384 }
372 385
373 386 QList<ChartAxisElement *> ChartPresenter::axisItems() const
374 387 {
375 388 return m_axisItems;
376 389 }
377 390
378 391 QList<ChartItem *> ChartPresenter::chartItems() const
379 392 {
380 393 return m_chartItems;
381 394 }
382 395
383 396 ChartTitle *ChartPresenter::titleElement()
384 397 {
385 398 return m_title;
386 399 }
387 400
388 401 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
389 402 {
390 403 static QGraphicsTextItem dummyTextItem;
391 404 static bool initMargin = true;
392 405 if (initMargin) {
393 406 dummyTextItem.document()->setDocumentMargin(textMargin());
394 407 initMargin = false;
395 408 }
396 409
397 410 dummyTextItem.setFont(font);
398 411 dummyTextItem.setHtml(text);
399 412 QRectF boundingRect = dummyTextItem.boundingRect();
400 413
401 414 // Take rotation into account
402 415 if (angle) {
403 416 QTransform transform;
404 417 transform.rotate(angle);
405 418 boundingRect = transform.mapRect(boundingRect);
406 419 }
407 420
408 421 return boundingRect;
409 422 }
410 423
411 424 // boundingRect parameter returns the rotated bounding rect of the text
412 425 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
413 426 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
414 427 {
415 428 QString truncatedString(text);
416 429 boundingRect = textBoundingRect(font, truncatedString, angle);
417 430 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
418 431 // It can be assumed that almost any amount of string manipulation is faster
419 432 // than calculating one bounding rectangle, so first prepare a list of truncated strings
420 433 // to try.
421 434 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
422 435 static QRegExp truncateMatcher(truncateMatchString);
423 436
424 437 QVector<QString> testStrings(text.length());
425 438 int count(0);
426 439 static QLatin1Char closeTag('>');
427 440 static QLatin1Char openTag('<');
428 441 static QLatin1Char semiColon(';');
429 442 static QLatin1String ellipsis("...");
430 443 while (truncatedString.length() > 1) {
431 444 int chopIndex(-1);
432 445 int chopCount(1);
433 446 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
434 447
435 448 if (lastChar == closeTag)
436 449 chopIndex = truncatedString.lastIndexOf(openTag);
437 450 else if (lastChar == semiColon)
438 451 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
439 452
440 453 if (chopIndex != -1)
441 454 chopCount = truncatedString.length() - chopIndex;
442 455 truncatedString.chop(chopCount);
443 456 testStrings[count] = truncatedString + ellipsis;
444 457 count++;
445 458 }
446 459
447 460 // Binary search for best fit
448 461 int minIndex(0);
449 462 int maxIndex(count - 1);
450 463 int bestIndex(count);
451 464 QRectF checkRect;
452 465
453 466 while (maxIndex >= minIndex) {
454 467 int mid = (maxIndex + minIndex) / 2;
455 468 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
456 469 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
457 470 // Checked index too large, all under this are also too large
458 471 minIndex = mid + 1;
459 472 } else {
460 473 // Checked index fits, all over this also fit
461 474 maxIndex = mid - 1;
462 475 bestIndex = mid;
463 476 boundingRect = checkRect;
464 477 }
465 478 }
466 479 // Default to "..." if nothing fits
467 480 if (bestIndex == count) {
468 481 boundingRect = textBoundingRect(font, ellipsis, angle);
469 482 truncatedString = ellipsis;
470 483 } else {
471 484 truncatedString = testStrings.at(bestIndex);
472 485 }
473 486 }
474 487
475 488 return truncatedString;
476 489 }
477 490
491 QString ChartPresenter::numberToString(double value, char f, int prec)
492 {
493 if (m_localizeNumbers)
494 return m_locale.toString(value, f, prec);
495 else
496 return QString::number(value, f, prec);
497 }
498
478 499 #include "moc_chartpresenter_p.cpp"
479 500
480 501 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,180 +1,190
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTPRESENTER_H
31 31 #define CHARTPRESENTER_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "qchart.h" //because of QChart::ChartThemeId
35 35 #include <QRectF>
36 36 #include <QMargins>
37 #include <QLocale>
37 38
38 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 40
40 41 class ChartItem;
41 42 class AxisItem;
42 43 class QAbstractSeries;
43 44 class ChartDataSet;
44 45 class AbstractDomain;
45 46 class ChartAxisElement;
46 47 class ChartAnimator;
47 48 class ChartBackground;
48 49 class ChartTitle;
49 50 class ChartAnimation;
50 51 class AbstractChartLayout;
51 52
52 53 class ChartPresenter: public QObject
53 54 {
54 55 Q_OBJECT
55 56 public:
56 57 enum ZValues {
57 58 BackgroundZValue = -1,
58 59 PlotAreaZValue,
59 60 ShadesZValue,
60 61 GridZValue,
61 62 AxisZValue,
62 63 SeriesZValue,
63 64 LineChartZValue = SeriesZValue,
64 65 SplineChartZValue = SeriesZValue,
65 66 BarSeriesZValue = SeriesZValue,
66 67 ScatterSeriesZValue = SeriesZValue,
67 68 PieSeriesZValue = SeriesZValue,
68 69 BoxPlotSeriesZValue = SeriesZValue,
69 70 LegendZValue,
70 71 TopMostZValue
71 72 };
72 73
73 74 enum State {
74 75 ShowState,
75 76 ScrollUpState,
76 77 ScrollDownState,
77 78 ScrollLeftState,
78 79 ScrollRightState,
79 80 ZoomInState,
80 81 ZoomOutState
81 82 };
82 83
83 84 ChartPresenter(QChart *chart, QChart::ChartType type);
84 85 virtual ~ChartPresenter();
85 86
86 87
87 88 void setGeometry(QRectF rect);
88 89 QRectF geometry() const;
89 90
90 91 QGraphicsItem *rootItem(){ return m_chart; }
91 92 ChartBackground *backgroundElement();
92 93 QAbstractGraphicsShapeItem *plotAreaElement();
93 94 ChartTitle *titleElement();
94 95 QList<ChartAxisElement *> axisItems() const;
95 96 QList<ChartItem *> chartItems() const;
96 97
97 98 QLegend *legend();
98 99
99 100 void setBackgroundBrush(const QBrush &brush);
100 101 QBrush backgroundBrush() const;
101 102
102 103 void setBackgroundPen(const QPen &pen);
103 104 QPen backgroundPen() const;
104 105
105 106 void setBackgroundRoundness(qreal diameter);
106 107 qreal backgroundRoundness() const;
107 108
108 109 void setPlotAreaBackgroundBrush(const QBrush &brush);
109 110 QBrush plotAreaBackgroundBrush() const;
110 111
111 112 void setPlotAreaBackgroundPen(const QPen &pen);
112 113 QPen plotAreaBackgroundPen() const;
113 114
114 115 void setTitle(const QString &title);
115 116 QString title() const;
116 117
117 118 void setTitleFont(const QFont &font);
118 119 QFont titleFont() const;
119 120
120 121 void setTitleBrush(const QBrush &brush);
121 122 QBrush titleBrush() const;
122 123
123 124 void setBackgroundVisible(bool visible);
124 125 bool isBackgroundVisible() const;
125 126
126 127 void setPlotAreaBackgroundVisible(bool visible);
127 128 bool isPlotAreaBackgroundVisible() const;
128 129
129 130 void setBackgroundDropShadowEnabled(bool enabled);
130 131 bool isBackgroundDropShadowEnabled() const;
131 132
133 void setLocalizeNumbers(bool localize);
134 bool localizeNumbers() const;
135
132 136 void setVisible(bool visible);
133 137
134 138 void setAnimationOptions(QChart::AnimationOptions options);
135 139 QChart::AnimationOptions animationOptions() const;
136 140
137 141 void startAnimation(ChartAnimation *animation);
138 142
139 143 void setState(State state,QPointF point);
140 144 State state() const { return m_state; }
141 145 QPointF statePoint() const { return m_statePoint; }
142 146 AbstractChartLayout *layout();
143 147
144 148 QChart::ChartType chartType() const { return m_chart->chartType(); }
145 149 QChart *chart() { return m_chart; }
146 150
147 151 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
148 152 static QString truncatedText(const QFont &font, const QString &text, qreal angle,
149 153 qreal maxWidth, qreal maxHeight, QRectF &boundingRect);
150 154 inline static qreal textMargin() { return qreal(0.5); }
155
156 QString numberToString(double value, char f = 'g', int prec = 6);
157 inline const QLocale &locale() const { return m_locale; }
158
151 159 private:
152 160 void createBackgroundItem();
153 161 void createPlotAreaBackgroundItem();
154 162 void createTitleItem();
155 163
156 164 public Q_SLOTS:
157 165 void handleSeriesAdded(QAbstractSeries *series);
158 166 void handleSeriesRemoved(QAbstractSeries *series);
159 167 void handleAxisAdded(QAbstractAxis *axis);
160 168 void handleAxisRemoved(QAbstractAxis *axis);
161 169
162 170 private:
163 171 QChart *m_chart;
164 172 QList<ChartItem *> m_chartItems;
165 173 QList<ChartAxisElement *> m_axisItems;
166 174 QList<QAbstractSeries *> m_series;
167 175 QList<QAbstractAxis *> m_axes;
168 176 QChart::AnimationOptions m_options;
169 177 State m_state;
170 178 QPointF m_statePoint;
171 179 AbstractChartLayout *m_layout;
172 180 ChartBackground *m_background;
173 181 QAbstractGraphicsShapeItem *m_plotAreaBackground;
174 182 ChartTitle *m_title;
175 183 QRectF m_rect;
184 bool m_localizeNumbers;
185 QLocale m_locale;
176 186 };
177 187
178 188 QTCOMMERCIALCHART_END_NAMESPACE
179 189
180 190 #endif /* CHARTPRESENTER_H */
@@ -1,323 +1,333
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "qabstractseries.h"
22 22 #include "qabstractseries_p.h"
23 23 #include "chartdataset_p.h"
24 24 #include "qchart.h"
25 25 #include "qchart_p.h"
26 26 #include "chartitem_p.h"
27 27 #include "xydomain_p.h"
28 28 #include "xlogydomain_p.h"
29 29 #include "logxydomain_p.h"
30 30 #include "logxlogydomain_p.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QAbstractSeries
36 36 \inmodule Qt Charts
37 37 \brief Base class for all Qt Chart series.
38 38 \mainclass
39 39
40 40 Usually you use the series type specific inherited classes instead of the base class.
41 41 \sa QXYSeries, QLineSeries, QSplineSeries, QScatterSeries, QAreaSeries, QAbstractBarSeries, QStackedBarSeries,
42 42 QPercentBarSeries, QPieSeries
43 43 */
44 44 #ifdef QDOC_QT5
45 45 /*!
46 46 \qmltype AbstractSeries
47 47 \instantiates QAbstractSeries
48 48 \inqmlmodule QtCommercial.Chart
49 49
50 50 \include doc/src/abstractseries.qdocinc
51 51 */
52 52 #else
53 53 /*!
54 54 \qmlclass AbstractSeries QAbstractSeries
55 55
56 56 \include ../doc/src/abstractseries.qdocinc
57 57 */
58 58 #endif
59 59
60 60 /*!
61 61 \enum QAbstractSeries::SeriesType
62 62
63 63 The type of the series object.
64 64
65 65 \value SeriesTypeLine
66 66 \value SeriesTypeArea
67 67 \value SeriesTypeBar
68 68 \value SeriesTypeStackedBar
69 69 \value SeriesTypePercentBar
70 70 \value SeriesTypePie
71 71 \value SeriesTypeScatter
72 72 \value SeriesTypeSpline
73 73 \value SeriesTypeHorizontalBar
74 74 \value SeriesTypeHorizontalStackedBar
75 75 \value SeriesTypeHorizontalPercentBar
76 76 \value SeriesTypeBoxPlot
77 77 */
78 78
79 79 /*!
80 80 \property QAbstractSeries::type
81 81 The type of the series.
82 82 */
83 83 /*!
84 84 \qmlproperty ChartView.SeriesType AbstractSeries::type
85 85 The type of the series.
86 86 */
87 87
88 88 /*!
89 89 \property QAbstractSeries::name
90 90 \brief name of the series property. The name is shown in legend for series and supports html formatting.
91 91 */
92 92 /*!
93 93 \qmlproperty string AbstractSeries::name
94 94 Name of the series. The name is shown in legend for series and supports html formatting.
95 95 */
96 96
97 97 /*!
98 98 \fn void QAbstractSeries::nameChanged()
99 99 This signal is emitted when the series name changes.
100 100 */
101 101 /*!
102 102 \qmlsignal AbstractSeries::onNameChanged()
103 103 This signal is emitted when the series name changes.
104 104 */
105 105
106 106 /*!
107 107 \property QAbstractSeries::visible
108 108 \brief whether the series is visible or not; true by default.
109 109 */
110 110 /*!
111 111 \qmlproperty bool AbstractSeries::visible
112 112 Visibility of the series. True by default.
113 113 */
114 114
115 115 /*!
116 116 \fn void QAbstractSeries::visibleChanged()
117 117 Emitted when the series visibility changes.
118 118 */
119 119 /*!
120 120 \qmlsignal AbstractSeries::onVisibleChanged()
121 121 Emitted when the series visibility changes.
122 122 */
123 123
124 124 /*!
125 125 \property QAbstractSeries::opacity
126 126 \brief The opacity of the series.
127 127
128 128 By default the opacity is 1.0. The valid values range from 0.0 (transparent) to 1.0 (opaque).
129 129 */
130 130 /*!
131 131 \qmlproperty real AbstractSeries::opacity
132 132 The opacity of the series. By default the opacity is 1.0.
133 133 The valid values range from 0.0 (transparent) to 1.0 (opaque).
134 134 */
135 135
136 136 /*!
137 137 \fn void QAbstractSeries::opacityChanged()
138 138 Emitted when the opacity of the series changes.
139 139 */
140 140 /*!
141 141 \qmlsignal AbstractSeries::onOpacityChanged()
142 142 Emitted when the opacity of the series changes.
143 143 */
144 144
145 145 /*!
146 146 \internal
147 147 \brief Constructs QAbstractSeries object with \a parent.
148 148 */
149 149 QAbstractSeries::QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent) :
150 150 QObject(parent),
151 151 d_ptr(&d)
152 152 {
153 153 }
154 154
155 155 /*!
156 156 \brief Virtual destructor for the chart series.
157 157 */
158 158 QAbstractSeries::~QAbstractSeries()
159 159 {
160 160 if (d_ptr->m_chart)
161 161 qFatal("Series still bound to a chart when destroyed!");
162 162 }
163 163
164 164 void QAbstractSeries::setName(const QString &name)
165 165 {
166 166 if (name != d_ptr->m_name) {
167 167 d_ptr->m_name = name;
168 168 emit nameChanged();
169 169 }
170 170 }
171 171
172 172 QString QAbstractSeries::name() const
173 173 {
174 174 return d_ptr->m_name;
175 175 }
176 176
177 177 void QAbstractSeries::setVisible(bool visible)
178 178 {
179 179 if (visible != d_ptr->m_visible) {
180 180 d_ptr->m_visible = visible;
181 181 emit visibleChanged();
182 182 }
183 183 }
184 184
185 185 bool QAbstractSeries::isVisible() const
186 186 {
187 187 return d_ptr->m_visible;
188 188 }
189 189
190 190 qreal QAbstractSeries::opacity() const
191 191 {
192 192 return d_ptr->m_opacity;
193 193 }
194 194
195 195 void QAbstractSeries::setOpacity(qreal opacity)
196 196 {
197 197 if (opacity != d_ptr->m_opacity) {
198 198 d_ptr->m_opacity = opacity;
199 199 emit opacityChanged();
200 200 }
201 201 }
202 202
203 203 /*!
204 204 \brief Returns the chart where series belongs to.
205 205
206 206 Set automatically when the series is added to the chart
207 207 and unset when the series is removed from the chart.
208 208 */
209 209 QChart *QAbstractSeries::chart() const
210 210 {
211 211 return d_ptr->m_chart;
212 212 }
213 213
214 214 /*!
215 215 \brief Sets the visibility of the series to true.
216 216
217 217 \sa setVisible(), isVisible()
218 218 */
219 219 void QAbstractSeries::show()
220 220 {
221 221 setVisible(true);
222 222 }
223 223
224 224 /*!
225 225 \brief Sets the visibility of the series to false.
226 226
227 227 \sa setVisible(), isVisible()
228 228 */
229 229 void QAbstractSeries::hide()
230 230 {
231 231 setVisible(false);
232 232 }
233 233
234 234 /*!
235 235 Attach \a axis to the series.
236 236 \return true if the axis was attached successfully, false otherwise.
237 237 \note If multiple axes of same orientation are attached to same series,
238 238 they will have same min/max ranges.
239 239 \sa QChart::addAxis(), QChart::createDefaultAxes()
240 240 */
241 241 bool QAbstractSeries::attachAxis(QAbstractAxis* axis)
242 242 {
243 243 if(d_ptr->m_chart) {
244 244 return d_ptr->m_chart->d_ptr->m_dataset->attachAxis(this, axis);
245 245 } else {
246 246 qWarning()<<"Series not in the chart. Please addSeries to chart first.";
247 247 return false;
248 248 }
249 249 }
250 250
251 251 /*!
252 252 Detach \a axis from the series.
253 253 \return true if the axis was detached successfully, false otherwise.
254 254 \sa QChart::removeAxis()
255 255 */
256 256 bool QAbstractSeries::detachAxis(QAbstractAxis* axis)
257 257 {
258 258 if(d_ptr->m_chart) {
259 259 return d_ptr->m_chart->d_ptr->m_dataset->detachAxis(this, axis);
260 260 }
261 261 else {
262 262 qWarning()<<"Series not in the chart. Please addSeries to chart first.";
263 263 return false;
264 264 }
265 265 }
266 266
267 267 /*!
268 268 Returns the list of axes attached to the series. Usually there is an x-axis and a y-axis attached to a series, except
269 269 in case of a QPieSeries, which does not have any axes attached.
270 270 \sa attachAxis(), detachAxis()
271 271 */
272 272 QList<QAbstractAxis*> QAbstractSeries::attachedAxes()
273 273 {
274 274 return d_ptr->m_axes;
275 275 }
276 276
277 277 ///////////////////////////////////////////////////////////////////////////////////////////////////
278 278
279 279 QAbstractSeriesPrivate::QAbstractSeriesPrivate(QAbstractSeries *q)
280 280 : q_ptr(q),
281 281 m_chart(0),
282 282 m_item(0),
283 283 m_domain(new XYDomain()),
284 284 m_visible(true),
285 285 m_opacity(1.0)
286 286 {
287 287 }
288 288
289 289 QAbstractSeriesPrivate::~QAbstractSeriesPrivate()
290 290 {
291 291 }
292 292
293 293 void QAbstractSeriesPrivate::setDomain(AbstractDomain* domain)
294 294 {
295 295 Q_ASSERT(domain);
296 296 if(m_domain.data()!=domain) {
297 297 if(!m_item.isNull()) QObject::disconnect(m_domain.data(), SIGNAL(updated()), m_item.data(), SLOT(handleDomainUpdated()));
298 298 m_domain.reset(domain);
299 299 if(!m_item.isNull()) {
300 300 QObject::connect(m_domain.data(), SIGNAL(updated()),m_item.data(), SLOT(handleDomainUpdated()));
301 301 m_item->handleDomainUpdated();
302 302 }
303 303 }
304 304 }
305 305
306 void QAbstractSeriesPrivate::setPresenter(ChartPresenter *presenter)
307 {
308 m_presenter = presenter;
309 }
310
311 ChartPresenter *QAbstractSeriesPrivate::presenter() const
312 {
313 return m_presenter;
314 }
315
306 316 void QAbstractSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
307 317 {
308 318 Q_ASSERT(!m_item.isNull());
309 319 Q_UNUSED(parent);
310 320 QObject::connect(m_domain.data(), SIGNAL(updated()),m_item.data(), SLOT(handleDomainUpdated()));
311 321 }
312 322
313 323 void QAbstractSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
314 324 {
315 325 Q_UNUSED(options);
316 326 }
317 327
318 328 #include "moc_qabstractseries.cpp"
319 329 #include "moc_qabstractseries_p.cpp"
320 330
321 331 QTCOMMERCIALCHART_END_NAMESPACE
322 332
323 333
@@ -1,101 +1,105
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QABSTRACTSERIES_P_H
31 31 #define QABSTRACTSERIES_P_H
32 32
33 33 #include "qabstractseries.h"
34 34 #include "qchart.h"
35 35 #include "abstractdomain_p.h"
36 36
37 37 class QGraphicsItem;
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class ChartPresenter;
42 42 class ChartElement;
43 43 class LegendMarker;
44 44 class QLegend;
45 45 class ChartDataSet;
46 46 class QAbstractAxis;
47 47 class QLegendMarker;
48 48 class ChartTheme;
49 49 class ChartAnimation;
50 50 class ChartItem;
51 51 class BoxPlotChartItem;
52 52
53 53 class QAbstractSeriesPrivate : public QObject
54 54 {
55 55 Q_OBJECT
56 56 public:
57 57 QAbstractSeriesPrivate(QAbstractSeries *q);
58 58 ~QAbstractSeriesPrivate();
59 59
60 60 virtual void initializeDomain() = 0;
61 61 virtual void initializeAxes() = 0;
62 62 virtual void initializeTheme(int index, ChartTheme* theme, bool forced = false) = 0;
63 63 virtual void initializeGraphics(QGraphicsItem* parent) = 0;
64 64 virtual void initializeAnimations(QChart::AnimationOptions options) = 0;
65 65
66 66 virtual QList<QLegendMarker*> createLegendMarkers(QLegend* legend) = 0;
67 67
68 68 virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation) const = 0;
69 69 virtual QAbstractAxis* createDefaultAxis(Qt::Orientation) const = 0;
70 70
71 71 ChartItem* chartItem() { return m_item.data(); }
72 72
73 73 virtual void setDomain(AbstractDomain* domain);
74 74 AbstractDomain* domain() { return m_domain.data(); }
75 75
76 virtual void setPresenter(ChartPresenter *presenter);
77 ChartPresenter *presenter() const;
78
76 79 QChart* chart() { return m_chart; }
77 80
78 81 Q_SIGNALS:
79 82 void countChanged();
80 83
81 84 protected:
82 85 QAbstractSeries *q_ptr;
83 86 QChart *m_chart;
84 87 QScopedPointer<ChartItem> m_item;
85 88 QList<QAbstractAxis*> m_axes;
86 89 private:
87 90 QScopedPointer<AbstractDomain> m_domain;
88 91 QString m_name;
89 92 bool m_visible;
90 93 qreal m_opacity;
94 ChartPresenter *m_presenter;
91 95
92 96 friend class QAbstractSeries;
93 97 friend class ChartDataSet;
94 98 friend class ChartPresenter;
95 99 friend class QLegendPrivate;
96 100 friend class BoxPlotChartItem;
97 101 };
98 102
99 103 QTCOMMERCIALCHART_END_NAMESPACE
100 104
101 105 #endif
@@ -1,828 +1,847
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "legendscroller_p.h"
24 24 #include "qlegend_p.h"
25 25 #include "chartbackground_p.h"
26 26 #include "qabstractaxis.h"
27 27 #include "abstractchartlayout_p.h"
28 28 #include "charttheme_p.h"
29 29 #include "chartpresenter_p.h"
30 30 #include "chartdataset_p.h"
31 31 #include <QGraphicsScene>
32 32 #include <QGraphicsSceneResizeEvent>
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 /*!
37 37 \enum QChart::ChartTheme
38 38
39 39 This enum describes the theme used by the chart.
40 40
41 41 \value ChartThemeLight The default theme
42 42 \value ChartThemeBlueCerulean
43 43 \value ChartThemeDark
44 44 \value ChartThemeBrownSand
45 45 \value ChartThemeBlueNcs
46 46 \value ChartThemeHighContrast
47 47 \value ChartThemeBlueIcy
48 48 \value ChartThemeQt
49 49 */
50 50
51 51 /*!
52 52 \enum QChart::AnimationOption
53 53
54 54 For enabling/disabling animations. Defaults to NoAnimation.
55 55
56 56 \value NoAnimation
57 57 \value GridAxisAnimations
58 58 \value SeriesAnimations
59 59 \value AllAnimations
60 60 */
61 61
62 62 /*!
63 63 \enum QChart::ChartType
64 64
65 65 This enum describes the chart type.
66 66
67 67 \value ChartTypeUndefined
68 68 \value ChartTypeCartesian
69 69 \value ChartTypePolar
70 70 */
71 71
72 72 /*!
73 73 \class QChart
74 74 \inmodule Qt Charts
75 75 \brief Main chart API for Qt Charts.
76 76
77 77 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
78 78 representation of different types of series and other chart related objects like legend and
79 79 axes. If you simply want to show a chart in a layout, you can use the
80 80 convenience class QChartView instead of QChart.
81 81 \sa QChartView, QPolarChart
82 82 */
83 83
84 84 /*!
85 85 \property QChart::animationOptions
86 86 The animation \a options for the chart. Animations are enabled/disabled based on this setting.
87 87 */
88 88
89 89 /*!
90 90 \property QChart::backgroundVisible
91 91 Specifies whether the chart background is visible or not.
92 92 \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible
93 93 */
94 94
95 95 /*!
96 96 \property QChart::dropShadowEnabled
97 97 If set to true, the background drop shadow effect is enabled. If set to false, it is disabled. Note that the drop
98 98 shadow effect depends on theme, which means the setting may be changed if you switch to another theme.
99 99 */
100 100
101 101 /*!
102 102 \property QChart::backgroundRoundness
103 103 The diameter of the rounding cirle at the corners of the chart background.
104 104 */
105 105
106 106 /*!
107 107 \property QChart::minimumMargins
108 108 Minimum margins between the plot area (axes) and the edge of the chart widget.
109 109 This property is deprecated; use margins property instead.
110 110
111 111 \sa margins
112 112 */
113 113
114 114 /*!
115 115 \property QChart::margins
116 116 Margins between the plot area (axes) and the edge of the chart widget.
117 117 */
118 118
119 119 /*!
120 120 \property QChart::theme
121 121 Theme is a built-in collection of UI style related settings applied for all visual elements of a chart, like colors,
122 122 pens, brushes, and fonts of series, axes, title, and legend. \l {Chart themes demo} shows an example with a few
123 123 different themes.
124 124 \note Changing the theme will overwrite all customizations previously applied to the series.
125 125 */
126 126
127 127 /*!
128 128 \property QChart::title
129 129 Title is the name (label) of a chart. It is shown as a headline on top of the chart. Chart title supports html formatting.
130 130 */
131 131
132 132 /*!
133 133 \property QChart::chartType
134 134 Chart type indicates if the chart is a cartesian chart or a polar chart.
135 135 This property is set internally and it is read only.
136 136 \sa QPolarChart
137 137 */
138 138
139 139 /*!
140 140 \property QChart::plotAreaBackgroundVisible
141 141 Specifies whether the chart plot area background is visible or not.
142 142 \note By default the plot area background is not visible and the plot area uses
143 143 the general chart background.
144 144 \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible
145 145 */
146 146
147 147 /*!
148 \property QChart::localizeNumbers
149 \since QtCharts 2.0
150 When \c{true}, all generated numbers appearing in various series and axis labels will be
151 localized using the default QLocale of the application, which defaults to the system locale.
152 When \c{false}, the "C" locale is always used.
153 Defaults to \c{false}.
154 */
155
156 /*!
148 157 \internal
149 158 Constructs a chart object of \a type which is a child of a \a parent.
150 159 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
151 160 This constructor is called only by subclasses.
152 161 */
153 162 QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
154 163 : QGraphicsWidget(parent, wFlags),
155 164 d_ptr(new QChartPrivate(this, type))
156 165 {
157 166 d_ptr->init();
158 167 }
159 168
160 169 /*!
161 170 Constructs a chart object which is a child of a \a parent.
162 171 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
163 172 */
164 173 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
165 174 : QGraphicsWidget(parent, wFlags),
166 175 d_ptr(new QChartPrivate(this, ChartTypeCartesian))
167 176 {
168 177 d_ptr->init();
169 178 }
170 179
171 180 /*!
172 181 Destroys the chart object and its children, like series and axis objects added to it.
173 182 */
174 183 QChart::~QChart()
175 184 {
176 185 //start by deleting dataset, it will remove all series and axes
177 186 delete d_ptr->m_dataset;
178 187 d_ptr->m_dataset = 0;
179 188 }
180 189
181 190 /*!
182 191 Adds the \a series onto the chart and takes the ownership of it.
183 192
184 193 \note A newly added series is attached to no axes by default, including any axes that were created for the chart
185 194 using createDefaultAxes() before the series was added to the chart. If no axes are attached to
186 195 the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
187 196 that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
188 197 series that have properly attached axes, so always make sure you either call createDefaultAxes() after
189 198 a series has been added or explicitly attach axes for the series.
190 199
191 200 \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
192 201 */
193 202 void QChart::addSeries(QAbstractSeries *series)
194 203 {
195 204 Q_ASSERT(series);
196 205 d_ptr->m_dataset->addSeries(series);
197 206 }
198 207
199 208 /*!
200 209 Removes the \a series from the chart.
201 210 The chart releases its ownership of the specified \a series object.
202 211
203 212 \sa addSeries(), removeAllSeries()
204 213 */
205 214 void QChart::removeSeries(QAbstractSeries *series)
206 215 {
207 216 Q_ASSERT(series);
208 217 d_ptr->m_dataset->removeSeries(series);
209 218 }
210 219
211 220 /*!
212 221 Removes and deletes all series objects that have been added to the chart.
213 222
214 223 \sa addSeries(), removeSeries()
215 224 */
216 225 void QChart::removeAllSeries()
217 226 {
218 227 foreach (QAbstractSeries *s , d_ptr->m_dataset->series()){
219 228 removeSeries(s);
220 229 delete s;
221 230 }
222 231 }
223 232
224 233 /*!
225 234 Sets the \a brush that is used for painting the background of the chart area.
226 235 */
227 236 void QChart::setBackgroundBrush(const QBrush &brush)
228 237 {
229 238 d_ptr->m_presenter->setBackgroundBrush(brush);
230 239 }
231 240
232 241 /*!
233 242 Gets the brush that is used for painting the background of the chart area.
234 243 */
235 244 QBrush QChart::backgroundBrush() const
236 245 {
237 246 return d_ptr->m_presenter->backgroundBrush();
238 247 }
239 248
240 249 /*!
241 250 Sets the \a pen that is used for painting the background of the chart area.
242 251 */
243 252 void QChart::setBackgroundPen(const QPen &pen)
244 253 {
245 254 d_ptr->m_presenter->setBackgroundPen(pen);
246 255 }
247 256
248 257 /*!
249 258 Gets the pen that is used for painting the background of the chart area.
250 259 */
251 260 QPen QChart::backgroundPen() const
252 261 {
253 262 return d_ptr->m_presenter->backgroundPen();
254 263 }
255 264
256 265 void QChart::setTitle(const QString &title)
257 266 {
258 267 d_ptr->m_presenter->setTitle(title);
259 268 }
260 269
261 270 QString QChart::title() const
262 271 {
263 272 return d_ptr->m_presenter->title();
264 273 }
265 274
266 275 /*!
267 276 Sets the \a font that is used for drawing the chart title.
268 277 */
269 278 void QChart::setTitleFont(const QFont &font)
270 279 {
271 280 d_ptr->m_presenter->setTitleFont(font);
272 281 }
273 282
274 283 /*!
275 284 Gets the font that is used for drawing the chart title.
276 285 */
277 286 QFont QChart::titleFont() const
278 287 {
279 288 return d_ptr->m_presenter->titleFont();
280 289 }
281 290
282 291 /*!
283 292 Sets the \a brush used for drawing the title text.
284 293 */
285 294 void QChart::setTitleBrush(const QBrush &brush)
286 295 {
287 296 d_ptr->m_presenter->setTitleBrush(brush);
288 297 }
289 298
290 299 /*!
291 300 Returns the brush used for drawing the title text.
292 301 */
293 302 QBrush QChart::titleBrush() const
294 303 {
295 304 return d_ptr->m_presenter->titleBrush();
296 305 }
297 306
298 307 void QChart::setTheme(QChart::ChartTheme theme)
299 308 {
300 309 d_ptr->m_themeManager->setTheme(theme);
301 310 }
302 311
303 312 QChart::ChartTheme QChart::theme() const
304 313 {
305 314 return d_ptr->m_themeManager->theme()->id();
306 315 }
307 316
308 317 /*!
309 318 Zooms in the view by a factor of two.
310 319 */
311 320 void QChart::zoomIn()
312 321 {
313 322 d_ptr->zoomIn(2.0);
314 323 }
315 324
316 325 /*!
317 326 Zooms in the view to a maximum level at which \a rect is still fully visible.
318 327 \note This is not supported for polar charts.
319 328 */
320 329 void QChart::zoomIn(const QRectF &rect)
321 330 {
322 331 if (d_ptr->m_type == QChart::ChartTypePolar)
323 332 return;
324 333 d_ptr->zoomIn(rect);
325 334 }
326 335
327 336 /*!
328 337 Zooms out the view by a factor of two.
329 338 */
330 339 void QChart::zoomOut()
331 340 {
332 341 d_ptr->zoomOut(2.0);
333 342 }
334 343
335 344 /*!
336 345 Zooms in the view by a custom \a factor.
337 346
338 347 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
339 348 */
340 349 void QChart::zoom(qreal factor)
341 350 {
342 351 if (qFuzzyCompare(factor, 0))
343 352 return;
344 353
345 354 if (qFuzzyCompare(factor, (qreal)1.0))
346 355 return;
347 356
348 357 if (factor < 0)
349 358 return;
350 359
351 360 if (factor > 1.0)
352 361 d_ptr->zoomIn(factor);
353 362 else
354 363 d_ptr->zoomOut(1.0 / factor);
355 364 }
356 365
357 366
358 367 /*!
359 368 Resets the series domains to what they were before any zoom method was called.
360 369 Note that this will also reset any scrolls and explicit axis range settings done between
361 370 the first zoom operation and calling this method. If no zoom operation has been
362 371 done, this method does nothing.
363 372 */
364 373 void QChart::zoomReset()
365 374 {
366 375 d_ptr->zoomReset();
367 376 }
368 377
369 378 /*!
370 379 Returns true if any series has a zoomed domain.
371 380 */
372 381 bool QChart::isZoomed()
373 382 {
374 383 return d_ptr->isZoomed();
375 384 }
376 385
377 386 /*!
378 387 Returns a pointer to the horizontal axis attached to the specified \a series.
379 388 If no \a series is specified, the first horizontal axis added to the chart is returned.
380 389
381 390 \sa addAxis(), QAbstractSeries::attachAxis()
382 391 */
383 392 QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
384 393 {
385 394 QList<QAbstractAxis *> axisList = axes(Qt::Horizontal, series);
386 395 if (axisList.count())
387 396 return axisList[0];
388 397 return 0;
389 398 }
390 399
391 400 /*!
392 401 Returns a pointer to the vertical axis attached to the specified \a series.
393 402 If no \a series is specified, the first vertical axis added to the chart is returned.
394 403
395 404 \sa addAxis(), QAbstractSeries::attachAxis()
396 405 */
397 406 QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
398 407 {
399 408 QList<QAbstractAxis *> axisList = axes(Qt::Vertical, series);
400 409 if (axisList.count())
401 410 return axisList[0];
402 411 return 0;
403 412 }
404 413
405 414 /*!
406 415 Returns the axes attached to the \a series with \a orientation. If no \a series is provided,
407 416 then all axes added to the chart with the specified orientation are returned.
408 417 \sa addAxis(), createDefaultAxes()
409 418 */
410 419 QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
411 420 {
412 421 QList<QAbstractAxis *> result ;
413 422
414 423 if (series) {
415 424 foreach (QAbstractAxis *axis, series->attachedAxes()){
416 425 if (orientation.testFlag(axis->orientation()))
417 426 result << axis;
418 427 }
419 428 } else {
420 429 foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){
421 430 if (orientation.testFlag(axis->orientation()) && !result.contains(axis))
422 431 result << axis;
423 432 }
424 433 }
425 434
426 435 return result;
427 436 }
428 437
429 438 /*!
430 439 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
431 440 the chart will be deleted.
432 441
433 442 \note This function has to be called after all series have been added to the chart. The axes created by this function
434 443 will NOT get automatically attached to any series added to the chart after this function has been called.
435 444 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
436 445 if there are other series with properly attached axes also present.
437 446
438 447 \table
439 448 \header
440 449 \li Series type
441 450 \li X-axis
442 451 \li Y-axis
443 452 \row
444 453 \li QXYSeries
445 454 \li QValueAxis
446 455 \li QValueAxis
447 456 \row
448 457 \li QBarSeries
449 458 \li QBarCategoryAxis
450 459 \li QValueAxis
451 460 \row
452 461 \li QPieSeries
453 462 \li None
454 463 \li None
455 464 \endtable
456 465
457 466 If there are several QXYSeries derived series added to the chart and no series of other types have been added, then only one pair of axes is created.
458 467 If there are several series of different types added to the chart, then each series gets its own axes pair.
459 468
460 469 The axes specific to the series can be later obtained from the chart by providing the series as the parameter for axes() function call.
461 470 QPieSeries does not create any axes.
462 471
463 472 \sa axisX(), axisY(), axes(), setAxisX(), setAxisY(), QAbstractSeries::attachAxis()
464 473 */
465 474 void QChart::createDefaultAxes()
466 475 {
467 476 d_ptr->m_dataset->createDefaultAxes();
468 477 }
469 478
470 479 /*!
471 480 Returns the legend object of the chart. Ownership stays with the chart.
472 481 */
473 482 QLegend *QChart::legend() const
474 483 {
475 484 return d_ptr->m_legend;
476 485 }
477 486
478 487 void QChart::setMinimumMargins(const QMargins &margins)
479 488 {
480 489 qWarning() << "QChart::setMinimumMargins is deprecated. Use QChart::setMargins instead.";
481 490 d_ptr->m_presenter->layout()->setMargins(margins);
482 491 }
483 492
484 493 QMargins QChart::minimumMargins() const
485 494 {
486 495 qWarning() << "QChart::minimumMargins is deprecated. Use QChart::margins instead.";
487 496 return d_ptr->m_presenter->layout()->margins();
488 497 }
489 498
490 499 void QChart::setMargins(const QMargins &margins)
491 500 {
492 501 d_ptr->m_presenter->layout()->setMargins(margins);
493 502 }
494 503
495 504 QMargins QChart::margins() const
496 505 {
497 506 return d_ptr->m_presenter->layout()->margins();
498 507 }
499 508
500 509 QChart::ChartType QChart::chartType() const
501 510 {
502 511 return d_ptr->m_type;
503 512 }
504 513
505 514 /*!
506 515 Returns the the rectangle within which the drawing of the chart is done.
507 516 It does not include the area defined by margins.
508 517 */
509 518 QRectF QChart::plotArea() const
510 519 {
511 520 return d_ptr->m_presenter->geometry();
512 521 }
513 522
514 523 /*!
515 524 Sets the \a brush for the background of the plot area of the chart.
516 525
517 526 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
518 527 */
519 528 void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
520 529 {
521 530 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
522 531 }
523 532
524 533 /*!
525 534 Returns the brush for the background of the plot area of the chart.
526 535
527 536 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
528 537 */
529 538 QBrush QChart::plotAreaBackgroundBrush() const
530 539 {
531 540 return d_ptr->m_presenter->plotAreaBackgroundBrush();
532 541 }
533 542
534 543 /*!
535 544 Sets the \a pen for the background of the plot area of the chart.
536 545
537 546 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
538 547 */
539 548 void QChart::setPlotAreaBackgroundPen(const QPen &pen)
540 549 {
541 550 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
542 551 }
543 552
544 553 /*!
545 554 Returns the pen for the background of the plot area of the chart.
546 555
547 556 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
548 557 */
549 558 QPen QChart::plotAreaBackgroundPen() const
550 559 {
551 560 return d_ptr->m_presenter->plotAreaBackgroundPen();
552 561 }
553 562
554 563 void QChart::setPlotAreaBackgroundVisible(bool visible)
555 564 {
556 565 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
557 566 }
558 567
559 568 bool QChart::isPlotAreaBackgroundVisible() const
560 569 {
561 570 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
562 571 }
563 572
573 void QChart::setLocalizeNumbers(bool localize)
574 {
575 d_ptr->m_presenter->setLocalizeNumbers(localize);
576 }
577
578 bool QChart::localizeNumbers() const
579 {
580 return d_ptr->m_presenter->localizeNumbers();
581 }
582
564 583 void QChart::setAnimationOptions(AnimationOptions options)
565 584 {
566 585 d_ptr->m_presenter->setAnimationOptions(options);
567 586 }
568 587
569 588 QChart::AnimationOptions QChart::animationOptions() const
570 589 {
571 590 return d_ptr->m_presenter->animationOptions();
572 591 }
573 592
574 593 /*!
575 594 Scrolls the visible area of the chart by the distance defined in the \a dx and \a dy.
576 595
577 596 For polar charts, \a dx indicates the angle along angular axis instead of distance.
578 597 */
579 598 void QChart::scroll(qreal dx, qreal dy)
580 599 {
581 600 d_ptr->scroll(dx,dy);
582 601 }
583 602
584 603 void QChart::setBackgroundVisible(bool visible)
585 604 {
586 605 d_ptr->m_presenter->setBackgroundVisible(visible);
587 606 }
588 607
589 608 bool QChart::isBackgroundVisible() const
590 609 {
591 610 return d_ptr->m_presenter->isBackgroundVisible();
592 611 }
593 612
594 613 void QChart::setDropShadowEnabled(bool enabled)
595 614 {
596 615 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
597 616 }
598 617
599 618 bool QChart::isDropShadowEnabled() const
600 619 {
601 620 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
602 621 }
603 622
604 623 void QChart::setBackgroundRoundness(qreal diameter)
605 624 {
606 625 d_ptr->m_presenter->setBackgroundRoundness(diameter);
607 626 }
608 627
609 628 qreal QChart::backgroundRoundness() const
610 629 {
611 630 return d_ptr->m_presenter->backgroundRoundness();
612 631 }
613 632
614 633 /*!
615 634 Returns all series that are added to the chart.
616 635
617 636 \sa addSeries(), removeSeries(), removeAllSeries()
618 637 */
619 638 QList<QAbstractSeries *> QChart::series() const
620 639 {
621 640 return d_ptr->m_dataset->series();
622 641 }
623 642
624 643 /*!
625 644 Adds the \a axis to the chart and attaches it to the \a series as a bottom-aligned horizontal axis.
626 645 The chart takes ownership of both the \a axis and the \a series.
627 646 Any horizontal axes previously attached to the \a series are deleted.
628 647
629 648 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
630 649 */
631 650 void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
632 651 {
633 652 QList<QAbstractAxis*> list = axes(Qt::Horizontal, series);
634 653
635 654 foreach (QAbstractAxis* a, list) {
636 655 d_ptr->m_dataset->removeAxis(a);
637 656 delete a;
638 657 }
639 658
640 659 if (!d_ptr->m_dataset->axes().contains(axis))
641 660 d_ptr->m_dataset->addAxis(axis, Qt::AlignBottom);
642 661 d_ptr->m_dataset->attachAxis(series, axis);
643 662 }
644 663
645 664 /*!
646 665 Adds the \a axis to the chart and attaches it to the \a series as a left-aligned vertical axis.
647 666 The chart takes ownership of both the \a axis and the \a series.
648 667 Any vertical axes previously attached to the \a series are deleted.
649 668
650 669 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
651 670 */
652 671 void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
653 672 {
654 673 QList<QAbstractAxis*> list = axes(Qt::Vertical, series);
655 674
656 675 foreach (QAbstractAxis* a, list) {
657 676 d_ptr->m_dataset->removeAxis(a);
658 677 delete a;
659 678 }
660 679
661 680 if (!d_ptr->m_dataset->axes().contains(axis))
662 681 d_ptr->m_dataset->addAxis(axis, Qt::AlignLeft);
663 682 d_ptr->m_dataset->attachAxis(series, axis);
664 683 }
665 684
666 685 /*!
667 686 Adds the \a axis to the chart with \a alignment. The chart takes the ownership of the axis.
668 687
669 688 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
670 689 */
671 690 void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
672 691 {
673 692 d_ptr->m_dataset->addAxis(axis, alignment);
674 693 }
675 694
676 695 /*!
677 696 Removes the \a axis from the chart.
678 697 The chart releases its ownership of the specified \a axis object.
679 698
680 699 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
681 700 */
682 701 void QChart::removeAxis(QAbstractAxis *axis)
683 702 {
684 703 d_ptr->m_dataset->removeAxis(axis);
685 704 }
686 705
687 706 /*!
688 707 Returns the value in the \a series domain that corresponds to the \a position relative to chart widget.
689 708 */
690 709 QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
691 710 {
692 711 return d_ptr->m_dataset->mapToValue(position, series);
693 712 }
694 713
695 714 /*!
696 715 Returns the position on the chart widget that corresponds to the \a value in the \a series domain.
697 716 */
698 717 QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
699 718 {
700 719 return d_ptr->m_dataset->mapToPosition(value, series);
701 720 }
702 721
703 722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
704 723
705 724 QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
706 725 q_ptr(q),
707 726 m_legend(0),
708 727 m_dataset(new ChartDataSet(q)),
709 728 m_presenter(new ChartPresenter(q, type)),
710 729 m_themeManager(new ChartThemeManager(q)),
711 730 m_type(type)
712 731 {
713 732 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
714 733 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
715 734 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
716 735 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
717 736 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
718 737 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
719 738 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
720 739 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
721 740 }
722 741
723 742 QChartPrivate::~QChartPrivate()
724 743 {
725 744 }
726 745
727 746 // Hackish solution to the problem of explicitly assigning the default pen/brush/font
728 747 // to a series or axis and having theme override it:
729 748 // Initialize pens, brushes, and fonts to something nobody is likely to ever use,
730 749 // so that default theme initialization will always set these properly.
731 750 QPen &QChartPrivate::defaultPen()
732 751 {
733 752 static QPen defaultPen(QColor(1, 2, 0), 0.93247536);
734 753 return defaultPen;
735 754 }
736 755
737 756 QBrush &QChartPrivate::defaultBrush()
738 757 {
739 758 static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern);
740 759 return defaultBrush;
741 760 }
742 761
743 762 QFont &QChartPrivate::defaultFont()
744 763 {
745 764 static bool defaultFontInitialized(false);
746 765 static QFont defaultFont;
747 766 if (!defaultFontInitialized) {
748 767 defaultFont.setPointSizeF(8.34563465);
749 768 defaultFontInitialized = true;
750 769 }
751 770 return defaultFont;
752 771 }
753 772
754 773 void QChartPrivate::init()
755 774 {
756 775 m_legend = new LegendScroller(q_ptr);
757 776 q_ptr->setTheme(QChart::ChartThemeLight);
758 777 q_ptr->setLayout(m_presenter->layout());
759 778 }
760 779
761 780 void QChartPrivate::zoomIn(qreal factor)
762 781 {
763 782 QRectF rect = m_presenter->geometry();
764 783 rect.setWidth(rect.width() / factor);
765 784 rect.setHeight(rect.height() / factor);
766 785 rect.moveCenter(m_presenter->geometry().center());
767 786 zoomIn(rect);
768 787 }
769 788
770 789 void QChartPrivate::zoomIn(const QRectF &rect)
771 790 {
772 791 if (!rect.isValid())
773 792 return;
774 793
775 794 QRectF r = rect.normalized();
776 795 const QRectF geometry = m_presenter->geometry();
777 796 r.translate(-geometry.topLeft());
778 797
779 798 if (!r.isValid())
780 799 return;
781 800
782 801 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
783 802 m_presenter->setState(ChartPresenter::ZoomInState,zoomPoint);
784 803 m_dataset->zoomInDomain(r);
785 804 m_presenter->setState(ChartPresenter::ShowState,QPointF());
786 805
787 806 }
788 807
789 808 void QChartPrivate::zoomReset()
790 809 {
791 810 m_dataset->zoomResetDomain();
792 811 }
793 812
794 813 bool QChartPrivate::isZoomed()
795 814 {
796 815 return m_dataset->isZoomedDomain();
797 816 }
798 817
799 818 void QChartPrivate::zoomOut(qreal factor)
800 819 {
801 820 const QRectF geometry = m_presenter->geometry();
802 821
803 822 QRectF r;
804 823 r.setSize(geometry.size() / factor);
805 824 r.moveCenter(QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
806 825 if (!r.isValid())
807 826 return;
808 827
809 828 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
810 829 m_presenter->setState(ChartPresenter::ZoomOutState,zoomPoint);
811 830 m_dataset->zoomOutDomain(r);
812 831 m_presenter->setState(ChartPresenter::ShowState,QPointF());
813 832 }
814 833
815 834 void QChartPrivate::scroll(qreal dx, qreal dy)
816 835 {
817 836 if (dx < 0) m_presenter->setState(ChartPresenter::ScrollLeftState,QPointF());
818 837 if (dx > 0) m_presenter->setState(ChartPresenter::ScrollRightState,QPointF());
819 838 if (dy < 0) m_presenter->setState(ChartPresenter::ScrollUpState,QPointF());
820 839 if (dy > 0) m_presenter->setState(ChartPresenter::ScrollDownState,QPointF());
821 840
822 841 m_dataset->scrollDomain(dx, dy);
823 842 m_presenter->setState(ChartPresenter::ShowState,QPointF());
824 843 }
825 844
826 845 #include "moc_qchart.cpp"
827 846
828 847 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,177 +1,180
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QCHART_H
22 22 #define QCHART_H
23 23
24 24 #include <QAbstractSeries>
25 25 #include <QLegend>
26 26 #include <QGraphicsWidget>
27 27 #include <QMargins>
28 28
29 29 class QGraphicsSceneResizeEvent;
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 class QAbstractSeries;
34 34 class QAbstractAxis;
35 35 class QLegend;
36 36 class QChartPrivate;
37 37 class QBoxPlotSeries;
38 38
39 39 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
40 40 {
41 41 Q_OBJECT
42 42 Q_PROPERTY(QChart::ChartTheme theme READ theme WRITE setTheme)
43 43 Q_PROPERTY(QString title READ title WRITE setTitle)
44 44 Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
45 45 Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled)
46 46 Q_PROPERTY(qreal backgroundRoundness READ backgroundRoundness WRITE setBackgroundRoundness)
47 47 Q_PROPERTY(QChart::AnimationOptions animationOptions READ animationOptions WRITE setAnimationOptions)
48 48 Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins)
49 49 Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
50 50 Q_PROPERTY(QChart::ChartType chartType READ chartType)
51 51 Q_PROPERTY(bool plotAreaBackgroundVisible READ isPlotAreaBackgroundVisible WRITE setPlotAreaBackgroundVisible)
52 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers)
52 53 Q_ENUMS(ChartTheme)
53 54 Q_ENUMS(AnimationOption)
54 55 Q_ENUMS(ChartType)
55 56
56 57 public:
57 58 enum ChartType {
58 59 ChartTypeUndefined = 0,
59 60 ChartTypeCartesian,
60 61 ChartTypePolar
61 62 };
62 63
63 64 enum ChartTheme {
64 65 ChartThemeLight = 0,
65 66 ChartThemeBlueCerulean,
66 67 ChartThemeDark,
67 68 ChartThemeBrownSand,
68 69 ChartThemeBlueNcs,
69 70 ChartThemeHighContrast,
70 71 ChartThemeBlueIcy,
71 72 ChartThemeQt
72 73 };
73 74
74 75 enum AnimationOption {
75 76 NoAnimation = 0x0,
76 77 GridAxisAnimations = 0x1,
77 78 SeriesAnimations = 0x2,
78 79 AllAnimations = 0x3
79 80 };
80 81
81 82 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
82 83
83 84 public:
84 85 explicit QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
85 86 ~QChart();
86 87
87 88 void addSeries(QAbstractSeries *series);
88 89 void removeSeries(QAbstractSeries *series);
89 90 void removeAllSeries();
90 91 QList<QAbstractSeries *> series() const;
91 92
92 93 // *** deprecated ***
93 94 void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
94 95 void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
95 96 QAbstractAxis *axisX(QAbstractSeries *series = 0) const;
96 97 QAbstractAxis *axisY(QAbstractSeries *series = 0) const;
97 98 // ******************
98 99
99 100 void addAxis(QAbstractAxis *axis, Qt::Alignment alignment);
100 101 void removeAxis(QAbstractAxis *axis);
101 102 QList<QAbstractAxis*> axes(Qt::Orientations orientation = Qt::Horizontal|Qt::Vertical, QAbstractSeries *series = 0) const;
102 103
103 104 void createDefaultAxes();
104 105
105 106 void setTheme(QChart::ChartTheme theme);
106 107 QChart::ChartTheme theme() const;
107 108
108 109 void setTitle(const QString &title);
109 110 QString title() const;
110 111 void setTitleFont(const QFont &font);
111 112 QFont titleFont() const;
112 113 void setTitleBrush(const QBrush &brush);
113 114 QBrush titleBrush() const;
114 115
115 116 void setBackgroundBrush(const QBrush &brush);
116 117 QBrush backgroundBrush() const;
117 118 void setBackgroundPen(const QPen &pen);
118 119 QPen backgroundPen() const;
119 120 void setBackgroundVisible(bool visible = true);
120 121 bool isBackgroundVisible() const;
121 122
122 123 void setDropShadowEnabled(bool enabled = true);
123 124 bool isDropShadowEnabled() const;
124 125 void setBackgroundRoundness(qreal diameter);
125 126 qreal backgroundRoundness() const;
126 127 void setAnimationOptions(AnimationOptions options);
127 128 AnimationOptions animationOptions() const;
128 129
129 130 void zoomIn();
130 131 void zoomOut();
131 132
132 133 void zoomIn(const QRectF &rect);
133 134 void zoom(qreal factor);
134 135 void zoomReset();
135 136 bool isZoomed();
136 137
137 138 void scroll(qreal dx, qreal dy);
138 139
139 140 QLegend *legend() const;
140 141
141 142 void setMinimumMargins(const QMargins& margins);
142 143 QMargins minimumMargins() const;
143 144
144 145 void setMargins(const QMargins &margins);
145 146 QMargins margins() const;
146 147
147 148 QRectF plotArea() const;
148 149 void setPlotAreaBackgroundBrush(const QBrush &brush);
149 150 QBrush plotAreaBackgroundBrush() const;
150 151 void setPlotAreaBackgroundPen(const QPen &pen);
151 152 QPen plotAreaBackgroundPen() const;
152 153 void setPlotAreaBackgroundVisible(bool visible = true);
153 154 bool isPlotAreaBackgroundVisible() const;
155 void setLocalizeNumbers(bool localize);
156 bool localizeNumbers() const;
154 157
155 158 QPointF mapToValue(const QPointF &position, QAbstractSeries *series = 0);
156 159 QPointF mapToPosition(const QPointF &value, QAbstractSeries *series = 0);
157 160
158 161 ChartType chartType() const;
159 162
160 163 protected:
161 164 explicit QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags);
162 165 QScopedPointer<QChartPrivate> d_ptr;
163 166 friend class QLegend;
164 167 friend class DeclarativeChart;
165 168 friend class ChartDataSet;
166 169 friend class ChartPresenter;
167 170 friend class ChartThemeManager;
168 171 friend class QAbstractSeries;
169 172 friend class QBoxPlotSeriesPrivate;
170 173 Q_DISABLE_COPY(QChart)
171 174 };
172 175
173 176 QTCOMMERCIALCHART_END_NAMESPACE
174 177
175 178 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
176 179
177 180 #endif // QCHART_H
@@ -1,804 +1,804
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 #include "charthelpers_p.h"
28 28 #include "qchart_p.h"
29 29 #include <QPainter>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \class QXYSeries
35 35 \inmodule Qt Charts
36 36 \brief The QXYSeries class is a base class for line, spline and scatter series.
37 37 */
38 38 #ifdef QDOC_QT5
39 39 /*!
40 40 \qmltype XYSeries
41 41 \instantiates QXYSeries
42 42 \inqmlmodule QtCommercial.Chart
43 43
44 44 \include doc/src/xyseries.qdocinc
45 45 */
46 46 #else
47 47 /*!
48 48 \qmlclass XYSeries QXYSeries
49 49
50 50 \include ../doc/src/xyseries.qdocinc
51 51 */
52 52 #endif
53 53
54 54 /*!
55 55 \qmlproperty AbstractAxis XYSeries::axisX
56 56 The x axis used for the series. If you leave both axisX and axisXTop undefined, a ValueAxis is created for
57 57 the series.
58 58 \sa axisXTop
59 59 */
60 60
61 61 /*!
62 62 \qmlproperty AbstractAxis XYSeries::axisY
63 63 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
64 64 the series.
65 65 \sa axisYRight
66 66 */
67 67
68 68 /*!
69 69 \qmlproperty AbstractAxis XYSeries::axisXTop
70 70 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
71 71 axisXTop, but not both.
72 72 \sa axisX
73 73 */
74 74
75 75 /*!
76 76 \qmlproperty AbstractAxis XYSeries::axisYRight
77 77 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
78 78 or axisYRight, but not both.
79 79 \sa axisY
80 80 */
81 81
82 82 /*!
83 83 \qmlproperty AbstractAxis XYSeries::axisAngular
84 84 The angular axis used for the series, drawn around the polar chart view.
85 85 \sa axisX
86 86 */
87 87
88 88 /*!
89 89 \qmlproperty AbstractAxis XYSeries::axisRadial
90 90 The radial axis used for the series, drawn inside the polar chart view.
91 91 \sa axisY
92 92 */
93 93
94 94 /*!
95 95 \property QXYSeries::pointsVisible
96 96 Controls if the data points are visible and should be drawn.
97 97 */
98 98 /*!
99 99 \qmlproperty bool XYSeries::pointsVisible
100 100 Controls if the data points are visible and should be drawn.
101 101 */
102 102
103 103 /*!
104 104 \fn QPen QXYSeries::pen() const
105 105 \brief Returns pen used to draw points for series.
106 106 \sa setPen()
107 107 */
108 108
109 109 /*!
110 110 \fn QBrush QXYSeries::brush() const
111 111 \brief Returns brush used to draw points for series.
112 112 \sa setBrush()
113 113 */
114 114
115 115 /*!
116 116 \property QXYSeries::color
117 117 The color of the series. This is line (pen) color in case of QLineSeries or QSplineSeries and
118 118 fill (brush) color in case of QScatterSeries or QAreaSeries.
119 119 \sa QXYSeries::pen(), QXYSeries::brush()
120 120 */
121 121 /*!
122 122 \qmlproperty color XYSeries::color
123 123 The color of the series. This is line (pen) color in case of LineSeries or SplineSeries and
124 124 fill (brush) color in case of ScatterSeries or AreaSeries.
125 125 */
126 126
127 127 /*!
128 128 \property QXYSeries::pointLabelsFormat
129 129 The \a format used for showing labels with series points.
130 130
131 131 QXYSeries supports the following format tags:
132 132 \table
133 133 \row
134 134 \li @xPoint \li The x value of the data point
135 135 \row
136 136 \li @yPoint \li The y value of the data point
137 137 \endtable
138 138
139 139 For example, the following usage of the format tags would produce labels that have the data
140 140 point (x, y) shown inside brackets separated by a comma:
141 141 \code
142 142 series->setPointLabelsFormat("(@xPoint, @yPoint)");
143 143 \endcode
144 144
145 145 By default, the labels format is set to '@xPoint, @yPoint'. The labels are shown on the plot
146 146 area, labels on the edge of the plot area are cut. If the points are close to each other the
147 147 labels may overlap.
148 148
149 149 \sa QXYSeries::pointLabelsVisible, QXYSeries::pointLabelsFont, QXYSeries::pointLabelsColor
150 150 */
151 151 /*!
152 152 \qmlproperty string XYSeries::pointLabelsFormat
153 153 The \a format used for showing labels with series points.
154 154
155 155 \sa QXYSeries::pointLabelsFormat, pointLabelsVisible, pointLabelsFont, pointLabelsColor
156 156 */
157 157 /*!
158 158 \fn void QXYSeries::pointLabelsFormatChanged(const QString &format)
159 159 Signal is emitted when the \a format of data point labels is changed.
160 160 */
161 161 /*!
162 162 \qmlsignal XYSeries::onPointLabelsFormatChanged(string format)
163 163 Signal is emitted when the \a format of data point labels is changed.
164 164 */
165 165
166 166 /*!
167 167 \property QXYSeries::pointLabelsVisible
168 168 Defines the visibility for data point labels. False by default.
169 169
170 170 \sa QXYSeries::pointLabelsFormat
171 171 */
172 172 /*!
173 173 \qmlproperty bool XYSeries::pointLabelsVisible
174 174 Defines the visibility for data point labels.
175 175
176 176 \sa pointLabelsFormat
177 177 */
178 178 /*!
179 179 \fn void QXYSeries::pointLabelsVisibilityChanged(bool visible)
180 180 The visibility of the data point labels is changed to \a visible.
181 181 */
182 182 /*!
183 183 \qmlsignal XYSeries::onPointLabelsVisibilityChanged(bool visible)
184 184 The visibility of the data point labels is changed to \a visible.
185 185 */
186 186
187 187 /*!
188 188 \property QXYSeries::pointLabelsFont
189 189 Defines the font used for data point labels.
190 190
191 191 \sa QXYSeries::pointLabelsFormat
192 192 */
193 193 /*!
194 194 \qmlproperty font XYSeries::pointLabelsFont
195 195 Defines the font used for data point labels.
196 196
197 197 \sa pointLabelsFormat
198 198 */
199 199 /*!
200 200 \fn void QXYSeries::pointLabelsFontChanged(const QFont &font);
201 201 The font used for data point labels is changed to \a font.
202 202 */
203 203 /*!
204 204 \qmlsignal XYSeries::onPointLabelsFontChanged(Font font)
205 205 The font used for data point labels is changed to \a font.
206 206 */
207 207
208 208 /*!
209 209 \property QXYSeries::pointLabelsColor
210 210 Defines the color used for data point labels. By default, the color is the color of the brush
211 211 defined in theme for labels.
212 212
213 213 \sa QXYSeries::pointLabelsFormat
214 214 */
215 215 /*!
216 216 \qmlproperty font XYSeries::pointLabelsColor
217 217 Defines the color used for data point labels. By default, the color is the color of the brush
218 218 defined in theme for labels.
219 219
220 220 \sa pointLabelsFormat
221 221 */
222 222 /*!
223 223 \fn void QXYSeries::pointLabelsColorChanged(const QColor &color);
224 224 The color used for data point labels is changed to \a color.
225 225 */
226 226 /*!
227 227 \qmlsignal XYSeries::onPointLabelsColorChanged(Color color)
228 228 The color used for data point labels is changed to \a color.
229 229 */
230 230
231 231 /*!
232 232 \fn void QXYSeries::clicked(const QPointF& point)
233 233 \brief Signal is emitted when user clicks the \a point on chart.
234 234 */
235 235 /*!
236 236 \qmlsignal XYSeries::onClicked(QPointF point)
237 237 Signal is emitted when user clicks the \a point on chart. For example:
238 238 \code
239 239 LineSeries {
240 240 XYPoint { x: 0; y: 0 }
241 241 XYPoint { x: 1.1; y: 2.1 }
242 242 onClicked: console.log("onClicked: " + point.x + ", " + point.y);
243 243 }
244 244 \endcode
245 245 */
246 246
247 247 /*!
248 248 \fn void QXYSeries::hovered(const QPointF &point, bool state)
249 249 This signal is emitted when user has hovered over or away from the series. \a point shows the origin (coordinate)
250 250 of the hover event. \a state is true when user has hovered over the series and false when hover has moved away from
251 251 the series.
252 252 */
253 253 /*!
254 254 \qmlsignal XYSeries::onHovered(point point, bool state)
255 255 This signal is emitted when user has hovered over or away from the series. \a point shows the origin (coordinate)
256 256 of the hover event. \a state is true when user has hovered over the series and false when hover has moved away from
257 257 the series.
258 258 */
259 259
260 260 /*!
261 261 \fn void QXYSeries::pointReplaced(int index)
262 262 Signal is emitted when a point has been replaced at \a index.
263 263 \sa replace()
264 264 */
265 265 /*!
266 266 \qmlsignal XYSeries::onPointReplaced(int index)
267 267 Signal is emitted when a point has been replaced at \a index.
268 268 */
269 269
270 270 /*!
271 271 \fn void QXYSeries::pointsReplaced()
272 272 Signal is emitted when all points have been replaced with other points.
273 273 \sa replace()
274 274 */
275 275 /*!
276 276 \qmlsignal XYSeries::onPointsReplaced()
277 277 */
278 278
279 279 /*!
280 280 \fn void QXYSeries::pointAdded(int index)
281 281 Signal is emitted when a point has been added at \a index.
282 282 \sa append(), insert()
283 283 */
284 284 /*!
285 285 \qmlsignal XYSeries::onPointAdded(int index)
286 286 Signal is emitted when a point has been added at \a index.
287 287 */
288 288
289 289 /*!
290 290 \fn void QXYSeries::pointRemoved(int index)
291 291 Signal is emitted when a point has been removed from \a index.
292 292 \sa remove()
293 293 */
294 294 /*!
295 295 \qmlsignal XYSeries::onPointRemoved(int index)
296 296 Signal is emitted when a point has been removed from \a index.
297 297 */
298 298
299 299 /*!
300 300 \fn void QXYSeries::colorChanged(QColor color)
301 301 \brief Signal is emitted when the line (pen) color has changed to \a color.
302 302 */
303 303 /*!
304 304 \qmlsignal XYSeries::onColorChanged(color color)
305 305 Signal is emitted when the line (pen) color has changed to \a color.
306 306 */
307 307
308 308 /*!
309 309 \fn void QXYSeriesPrivate::updated()
310 310 \brief \internal
311 311 */
312 312
313 313 /*!
314 314 \qmlmethod XYSeries::append(real x, real y)
315 315 Append point (\a x, \a y) to the series
316 316 */
317 317
318 318 /*!
319 319 \qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY)
320 320 Replaces point (\a oldX, \a oldY) with point (\a newX, \a newY). Does nothing, if point (oldX, oldY) does not
321 321 exist.
322 322 */
323 323
324 324 /*!
325 325 \qmlmethod XYSeries::remove(real x, real y)
326 326 Removes point (\a x, \a y) from the series. Does nothing, if point (x, y) does not exist.
327 327 */
328 328
329 329 /*!
330 330 \qmlmethod XYSeries::insert(int index, real x, real y)
331 331 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
332 332 points. If index is the same as or bigger than count, the point is appended to the list of points.
333 333 */
334 334
335 335 /*!
336 336 \qmlmethod QPointF XYSeries::at(int index)
337 337 Returns point at \a index. Returns (0, 0) if the index is not valid.
338 338 */
339 339
340 340 /*!
341 341 \internal
342 342
343 343 Constructs empty series object which is a child of \a parent.
344 344 When series object is added to QChart instance ownerships is transferred.
345 345 */
346 346 QXYSeries::QXYSeries(QXYSeriesPrivate &d, QObject *parent)
347 347 : QAbstractSeries(d, parent)
348 348 {
349 349 }
350 350
351 351 /*!
352 352 Destroys the object. Series added to QChart instances are owned by those,
353 353 and are destroyed when QChart instances are destroyed.
354 354 */
355 355 QXYSeries::~QXYSeries()
356 356 {
357 357 }
358 358
359 359 /*!
360 360 Adds data point (\a x, \a y) to the series.
361 361 */
362 362 void QXYSeries::append(qreal x, qreal y)
363 363 {
364 364 append(QPointF(x, y));
365 365 }
366 366
367 367 /*!
368 368 This is an overloaded function.
369 369 Adds data \a point to the series.
370 370 */
371 371 void QXYSeries::append(const QPointF &point)
372 372 {
373 373 Q_D(QXYSeries);
374 374
375 375 if (isValidValue(point)) {
376 376 d->m_points << point;
377 377 emit pointAdded(d->m_points.count() - 1);
378 378 }
379 379 }
380 380
381 381 /*!
382 382 This is an overloaded function.
383 383 Adds list of data \a points to the series.
384 384 */
385 385 void QXYSeries::append(const QList<QPointF> &points)
386 386 {
387 387 foreach (const QPointF &point , points)
388 388 append(point);
389 389 }
390 390
391 391 /*!
392 392 Replaces data point (\a oldX, \a oldY) with data point (\a newX, \a newY).
393 393 \sa QXYSeries::pointReplaced()
394 394 */
395 395 void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY)
396 396 {
397 397 replace(QPointF(oldX, oldY), QPointF(newX, newY));
398 398 }
399 399
400 400 /*!
401 401 Replaces \a oldPoint with \a newPoint.
402 402 \sa QXYSeries::pointReplaced()
403 403 */
404 404 void QXYSeries::replace(const QPointF &oldPoint, const QPointF &newPoint)
405 405 {
406 406 Q_D(QXYSeries);
407 407 int index = d->m_points.indexOf(oldPoint);
408 408 if (index == -1)
409 409 return;
410 410 replace(index, newPoint);
411 411 }
412 412
413 413 /*!
414 414 Replaces the point at \a index with data point (\a newX, \a newY).
415 415 \sa QXYSeries::pointReplaced()
416 416 */
417 417 void QXYSeries::replace(int index, qreal newX, qreal newY)
418 418 {
419 419 replace(index, QPointF(newX, newY));
420 420 }
421 421
422 422 /*!
423 423 Replaces the point at \a index with \a newPoint.
424 424 \sa QXYSeries::pointReplaced()
425 425 */
426 426 void QXYSeries::replace(int index, const QPointF &newPoint)
427 427 {
428 428 Q_D(QXYSeries);
429 429 if (isValidValue(newPoint)) {
430 430 d->m_points[index] = newPoint;
431 431 emit pointReplaced(index);
432 432 }
433 433 }
434 434
435 435 /*!
436 436 Replaces the current points with \a points.
437 437 \note This is much faster than replacing data points one by one,
438 438 or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced()
439 439 when the points have been replaced.
440 440 \sa QXYSeries::pointsReplaced()
441 441 */
442 442 void QXYSeries::replace(QList<QPointF> points)
443 443 {
444 444 Q_D(QXYSeries);
445 445 d->m_points = points.toVector();
446 446 emit pointsReplaced();
447 447 }
448 448
449 449 /*!
450 450 Removes the point (\a x, \a y) from the series.
451 451 */
452 452 void QXYSeries::remove(qreal x, qreal y)
453 453 {
454 454 remove(QPointF(x, y));
455 455 }
456 456
457 457 /*!
458 458 Removes the \a point from the series.
459 459 */
460 460 void QXYSeries::remove(const QPointF &point)
461 461 {
462 462 Q_D(QXYSeries);
463 463 int index = d->m_points.indexOf(point);
464 464 if (index == -1)
465 465 return;
466 466 remove(index);
467 467 }
468 468
469 469 /*!
470 470 Removes the point at \a index from the series.
471 471 */
472 472 void QXYSeries::remove(int index)
473 473 {
474 474 Q_D(QXYSeries);
475 475 d->m_points.remove(index);
476 476 emit pointRemoved(index);
477 477 }
478 478
479 479 /*!
480 480 Inserts a \a point in the series at \a index position.
481 481 */
482 482 void QXYSeries::insert(int index, const QPointF &point)
483 483 {
484 484 Q_D(QXYSeries);
485 485 if (isValidValue(point)) {
486 486 d->m_points.insert(index, point);
487 487 emit pointAdded(index);
488 488 }
489 489 }
490 490
491 491 /*!
492 492 Removes all points from the series.
493 493 */
494 494 void QXYSeries::clear()
495 495 {
496 496 Q_D(QXYSeries);
497 497 for (int i = d->m_points.size() - 1; i >= 0; i--)
498 498 remove(d->m_points.at(i));
499 499 }
500 500
501 501 /*!
502 502 Returns list of points in the series.
503 503 */
504 504 QList<QPointF> QXYSeries::points() const
505 505 {
506 506 Q_D(const QXYSeries);
507 507 return d->m_points.toList();
508 508 }
509 509
510 510 /*!
511 511 Returns point at \a index in internal points vector.
512 512 */
513 513 const QPointF &QXYSeries::at(int index) const
514 514 {
515 515 Q_D(const QXYSeries);
516 516 return d->m_points.at(index);
517 517 }
518 518
519 519 /*!
520 520 Returns number of data points within series.
521 521 */
522 522 int QXYSeries::count() const
523 523 {
524 524 Q_D(const QXYSeries);
525 525 return d->m_points.count();
526 526 }
527 527
528 528
529 529 /*!
530 530 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
531 531 pen from chart theme is used.
532 532 \sa QChart::setTheme()
533 533 */
534 534 void QXYSeries::setPen(const QPen &pen)
535 535 {
536 536 Q_D(QXYSeries);
537 537 if (d->m_pen != pen) {
538 538 bool emitColorChanged = d->m_pen.color() != pen.color();
539 539 d->m_pen = pen;
540 540 emit d->updated();
541 541 if (emitColorChanged)
542 542 emit colorChanged(pen.color());
543 543 }
544 544 }
545 545
546 546 QPen QXYSeries::pen() const
547 547 {
548 548 Q_D(const QXYSeries);
549 549 if (d->m_pen == QChartPrivate::defaultPen())
550 550 return QPen();
551 551 else
552 552 return d->m_pen;
553 553 }
554 554
555 555 /*!
556 556 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
557 557 from chart theme setting is used.
558 558 \sa QChart::setTheme()
559 559 */
560 560 void QXYSeries::setBrush(const QBrush &brush)
561 561 {
562 562 Q_D(QXYSeries);
563 563 if (d->m_brush != brush) {
564 564 d->m_brush = brush;
565 565 emit d->updated();
566 566 }
567 567 }
568 568
569 569 QBrush QXYSeries::brush() const
570 570 {
571 571 Q_D(const QXYSeries);
572 572 if (d->m_brush == QChartPrivate::defaultBrush())
573 573 return QBrush();
574 574 else
575 575 return d->m_brush;
576 576 }
577 577
578 578 void QXYSeries::setColor(const QColor &color)
579 579 {
580 580 QPen p = pen();
581 581 if (p.color() != color) {
582 582 p.setColor(color);
583 583 setPen(p);
584 584 }
585 585 }
586 586
587 587 QColor QXYSeries::color() const
588 588 {
589 589 return pen().color();
590 590 }
591 591
592 592 void QXYSeries::setPointsVisible(bool visible)
593 593 {
594 594 Q_D(QXYSeries);
595 595 if (d->m_pointsVisible != visible) {
596 596 d->m_pointsVisible = visible;
597 597 emit d->updated();
598 598 }
599 599 }
600 600
601 601 bool QXYSeries::pointsVisible() const
602 602 {
603 603 Q_D(const QXYSeries);
604 604 return d->m_pointsVisible;
605 605 }
606 606
607 607 void QXYSeries::setPointLabelsFormat(const QString &format)
608 608 {
609 609 Q_D(QXYSeries);
610 610 if (d->m_pointLabelsFormat != format) {
611 611 d->m_pointLabelsFormat = format;
612 612 emit pointLabelsFormatChanged(format);
613 613 }
614 614 }
615 615
616 616 QString QXYSeries::pointLabelsFormat() const
617 617 {
618 618 Q_D(const QXYSeries);
619 619 return d->m_pointLabelsFormat;
620 620 }
621 621
622 622 void QXYSeries::setPointLabelsVisible(bool visible)
623 623 {
624 624 Q_D(QXYSeries);
625 625 if (d->m_pointLabelsVisible != visible) {
626 626 d->m_pointLabelsVisible = visible;
627 627 emit pointLabelsVisibilityChanged(visible);
628 628 }
629 629 }
630 630
631 631 bool QXYSeries::pointLabelsVisible() const
632 632 {
633 633 Q_D(const QXYSeries);
634 634 return d->m_pointLabelsVisible;
635 635 }
636 636
637 637 void QXYSeries::setPointLabelsFont(const QFont &font)
638 638 {
639 639 Q_D(QXYSeries);
640 640 if (d->m_pointLabelsFont != font) {
641 641 d->m_pointLabelsFont = font;
642 642 emit pointLabelsFontChanged(font);
643 643 }
644 644 }
645 645
646 646 QFont QXYSeries::pointLabelsFont() const
647 647 {
648 648 Q_D(const QXYSeries);
649 649 return d->m_pointLabelsFont;
650 650 }
651 651
652 652 void QXYSeries::setPointLabelsColor(const QColor &color)
653 653 {
654 654 Q_D(QXYSeries);
655 655 if (d->m_pointLabelsColor != color) {
656 656 d->m_pointLabelsColor = color;
657 657 emit pointLabelsColorChanged(color);
658 658 }
659 659 }
660 660
661 661 QColor QXYSeries::pointLabelsColor() const
662 662 {
663 663 Q_D(const QXYSeries);
664 664 if (d->m_pointLabelsColor == QChartPrivate::defaultPen().color())
665 665 return QPen().color();
666 666 else
667 667 return d->m_pointLabelsColor;
668 668 }
669 669
670 670 /*!
671 671 Stream operator for adding a data \a point to the series.
672 672 \sa append()
673 673 */
674 674 QXYSeries &QXYSeries::operator<< (const QPointF &point)
675 675 {
676 676 append(point);
677 677 return *this;
678 678 }
679 679
680 680
681 681 /*!
682 682 Stream operator for adding a list of \a points to the series.
683 683 \sa append()
684 684 */
685 685
686 686 QXYSeries &QXYSeries::operator<< (const QList<QPointF>& points)
687 687 {
688 688 append(points);
689 689 return *this;
690 690 }
691 691
692 692 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
693 693
694 694
695 695 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q)
696 696 : QAbstractSeriesPrivate(q),
697 697 m_pen(QChartPrivate::defaultPen()),
698 698 m_brush(QChartPrivate::defaultBrush()),
699 699 m_pointsVisible(false),
700 700 m_pointLabelsFormat(QLatin1String("@xPoint, @yPoint")),
701 701 m_pointLabelsVisible(false),
702 702 m_pointLabelsFont(QChartPrivate::defaultFont()),
703 703 m_pointLabelsColor(QChartPrivate::defaultPen().color())
704 704 {
705 705 }
706 706
707 707 void QXYSeriesPrivate::initializeDomain()
708 708 {
709 709 qreal minX(0);
710 710 qreal minY(0);
711 711 qreal maxX(1);
712 712 qreal maxY(1);
713 713
714 714 Q_Q(QXYSeries);
715 715
716 716 const QList<QPointF>& points = q->points();
717 717
718 718 if (!points.isEmpty()) {
719 719 minX = points[0].x();
720 720 minY = points[0].y();
721 721 maxX = minX;
722 722 maxY = minY;
723 723
724 724 for (int i = 0; i < points.count(); i++) {
725 725 qreal x = points[i].x();
726 726 qreal y = points[i].y();
727 727 minX = qMin(minX, x);
728 728 minY = qMin(minY, y);
729 729 maxX = qMax(maxX, x);
730 730 maxY = qMax(maxY, y);
731 731 }
732 732 }
733 733
734 734 domain()->setRange(minX, maxX, minY, maxY);
735 735 }
736 736
737 737 QList<QLegendMarker*> QXYSeriesPrivate::createLegendMarkers(QLegend* legend)
738 738 {
739 739 Q_Q(QXYSeries);
740 740 QList<QLegendMarker*> list;
741 741 return list << new QXYLegendMarker(q,legend);
742 742 }
743 743
744 744 void QXYSeriesPrivate::initializeAxes()
745 745 {
746 746
747 747 }
748 748
749 749 QAbstractAxis::AxisType QXYSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
750 750 {
751 751 Q_UNUSED(orientation);
752 752 return QAbstractAxis::AxisTypeValue;
753 753 }
754 754
755 755 QAbstractAxis* QXYSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
756 756 {
757 757 Q_UNUSED(orientation);
758 758 return new QValueAxis;
759 759 }
760 760
761 761 void QXYSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
762 762 {
763 763 XYChart *item = static_cast<XYChart *>(m_item.data());
764 764 Q_ASSERT(item);
765 765 if (item->animation())
766 766 item->animation()->stopAndDestroyLater();
767 767
768 768 if (options.testFlag(QChart::SeriesAnimations))
769 769 item->setAnimation(new XYAnimation(item));
770 770 else
771 771 item->setAnimation(0);
772 772 QAbstractSeriesPrivate::initializeAnimations(options);
773 773 }
774 774
775 775 void QXYSeriesPrivate::drawSeriesPointLabels(QPainter *painter, const QVector<QPointF> &points,
776 776 const int offset)
777 777 {
778 778 static const QString xPointTag(QLatin1String("@xPoint"));
779 779 static const QString yPointTag(QLatin1String("@yPoint"));
780 780 const int labelOffset = offset + 2;
781 781
782 782 painter->setFont(m_pointLabelsFont);
783 783 painter->setPen(QPen(m_pointLabelsColor));
784 784 QFontMetrics fm(painter->font());
785 785
786 786 for (int i(0); i < m_points.size(); i++) {
787 787 QString pointLabel = m_pointLabelsFormat;
788 pointLabel.replace(xPointTag, QString::number(m_points.at(i).x()));
789 pointLabel.replace(yPointTag, QString::number(m_points.at(i).y()));
788 pointLabel.replace(xPointTag, presenter()->numberToString(m_points.at(i).x()));
789 pointLabel.replace(yPointTag, presenter()->numberToString(m_points.at(i).y()));
790 790
791 791 // Position text in relation to the point
792 792 int pointLabelWidth = fm.width(pointLabel);
793 793 QPointF position(points.at(i));
794 794 position.setX(position.x() - pointLabelWidth / 2);
795 795 position.setY(position.y() - labelOffset);
796 796
797 797 painter->drawText(position, pointLabel);
798 798 }
799 799 }
800 800
801 801 #include "moc_qxyseries.cpp"
802 802 #include "moc_qxyseries_p.cpp"
803 803
804 804 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now