##// END OF EJS Templates
Added QChart::locale property...
Miikka Heikkinen -
r2708:b421e87aa00a
parent child
Show More
@@ -1,1054 +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 178 \qmlproperty bool ChartView::localizeNumbers
179 179 \since QtCharts 2.0
180 180 When \c{true}, all generated numbers appearing in various series and axis labels will be
181 181 localized using the default QLocale of the application, which defaults to the system locale.
182 182 When \c{false}, the "C" locale is always used.
183 Defaults to \c{false}.
183 Defaults to \c{true}.
184 184 */
185 185
186 186 /*!
187 187 \qmlmethod AbstractSeries ChartView::series(int index)
188 188 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
189 189 the count property of the chart.
190 190 */
191 191
192 192 /*!
193 193 \qmlmethod AbstractSeries ChartView::series(string name)
194 194 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
195 195 */
196 196
197 197 /*!
198 198 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
199 199 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
200 200 optional axis \a axisY. For example:
201 201 \code
202 202 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
203 203 var myAxisX = chartView.axisX(lineSeries);
204 204 var myAxisY = chartView.axisY(lineSeries);
205 205 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
206 206 \endcode
207 207 */
208 208
209 209 /*!
210 210 \qmlmethod ChartView::removeSeries(AbstractSeries series)
211 211 Removes the \a series from the chart. The series object is also destroyed.
212 212 */
213 213
214 214 /*!
215 215 \qmlmethod ChartView::removeAllSeries()
216 216 Removes all series from the chart. All the series objects are also destroyed.
217 217 */
218 218
219 219 /*!
220 220 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
221 221 The x-axis of the series.
222 222 */
223 223
224 224 /*!
225 225 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
226 226 The y-axis of the series.
227 227 */
228 228
229 229 /*!
230 230 \qmlmethod ChartView::zoomY(real factor)
231 231 Zooms in by \a factor on the center of the chart.
232 232 */
233 233
234 234 /*!
235 235 \qmlmethod ChartView::scrollLeft(real pixels)
236 236 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
237 237 */
238 238
239 239 /*!
240 240 \qmlmethod ChartView::scrollRight(real pixels)
241 241 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
242 242 */
243 243
244 244 /*!
245 245 \qmlmethod ChartView::scrollUp(real pixels)
246 246 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
247 247 */
248 248
249 249 /*!
250 250 \qmlmethod ChartView::scrollDown(real pixels)
251 251 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
252 252 */
253 253
254 254 /*!
255 255 \qmlsignal ChartView::onPlotAreaChanged(rect plotArea)
256 256 The plot area of the chart has changed. This may happen for example, if you modify minimumMargins
257 257 or if you resize the chart, or if you modify font size related properties of the legend or chart
258 258 title.
259 259 */
260 260
261 261 /*!
262 262 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
263 263 The \a series has been added to the chart.
264 264 */
265 265
266 266 /*!
267 267 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
268 268 The \a series has been removed from the chart. Please note that \a series is no longer a valid
269 269 object after the signal handler has completed.
270 270 */
271 271
272 272 DeclarativeChart::DeclarativeChart(QDECLARATIVE_ITEM *parent)
273 273 : QDECLARATIVE_PAINTED_ITEM(parent)
274 274 {
275 275 initChart(QChart::ChartTypeCartesian);
276 276 }
277 277
278 278 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QDECLARATIVE_ITEM *parent)
279 279 : QDECLARATIVE_PAINTED_ITEM(parent)
280 280 {
281 281 initChart(type);
282 282 }
283 283
284 284 void DeclarativeChart::initChart(QChart::ChartType type)
285 285 {
286 286 #ifdef CHARTS_FOR_QUICK2
287 287 m_currentSceneImage = 0;
288 288 m_guiThreadId = QThread::currentThreadId();
289 289 m_paintThreadId = 0;
290 290 m_updatePending = false;
291 291
292 292 if (type == QChart::ChartTypePolar)
293 293 m_chart = new QPolarChart();
294 294 else
295 295 m_chart = new QChart();
296 296
297 297 m_scene = new QGraphicsScene(this);
298 298 m_scene->addItem(m_chart);
299 299
300 300 setAntialiasing(QQuickItem::antialiasing());
301 301 connect(m_scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(sceneChanged(QList<QRectF>)));
302 302 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
303 303
304 304 setAcceptedMouseButtons(Qt::AllButtons);
305 305 setAcceptHoverEvents(true);
306 306 #else
307 307 if (type == QChart::ChartTypePolar)
308 308 m_chart = new QPolarChart(this);
309 309 else
310 310 m_chart = new QChart(this);
311 311
312 312 setFlag(QGraphicsItem::ItemHasNoContents, false);
313 313 #endif
314 314
315 315 m_margins = new DeclarativeMargins(this);
316 316 m_margins->setTop(m_chart->margins().top());
317 317 m_margins->setLeft(m_chart->margins().left());
318 318 m_margins->setRight(m_chart->margins().right());
319 319 m_margins->setBottom(m_chart->margins().bottom());
320 320 connect(m_margins, SIGNAL(topChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
321 321 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
322 322 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
323 323 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
324 324 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
325 325 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
326 326 }
327 327
328 328 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
329 329 {
330 330 emit seriesAdded(series);
331 331 }
332 332
333 333 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
334 334 {
335 335 m_chart->setMargins(QMargins(left, top, right, bottom));
336 336 emit minimumMarginsChanged();
337 337 emit plotAreaChanged(m_chart->plotArea());
338 338 }
339 339
340 340 DeclarativeChart::~DeclarativeChart()
341 341 {
342 342 delete m_chart;
343 343 #ifdef CHARTS_FOR_QUICK2
344 344 m_sceneImageLock.lock();
345 345 delete m_currentSceneImage;
346 346 m_currentSceneImage = 0;
347 347 m_sceneImageLock.unlock();
348 348 #endif
349 349 }
350 350
351 351 void DeclarativeChart::childEvent(QChildEvent *event)
352 352 {
353 353 if (event->type() == QEvent::ChildAdded) {
354 354 if (qobject_cast<QAbstractSeries *>(event->child())) {
355 355 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
356 356 }
357 357 }
358 358 }
359 359
360 360 void DeclarativeChart::componentComplete()
361 361 {
362 362 foreach (QObject *child, children()) {
363 363 if (qobject_cast<QAbstractSeries *>(child)) {
364 364 // Add series to the chart
365 365 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
366 366 m_chart->addSeries(series);
367 367
368 368 // Connect to axis changed signals (unless this is a pie series)
369 369 if (!qobject_cast<DeclarativePieSeries *>(series)) {
370 370 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
371 371 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
372 372 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
373 373 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
374 374 }
375 375
376 376 initializeAxes(series);
377 377 }
378 378 }
379 379
380 380 QDECLARATIVE_ITEM::componentComplete();
381 381 }
382 382
383 383 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
384 384 {
385 385 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
386 386 if (axis && s) {
387 387 if (!m_chart->axes(Qt::Horizontal).contains(axis))
388 388 m_chart->setAxisX(axis, s);
389 389 if (!s->attachedAxes().contains(axis))
390 390 s->attachAxis(axis);
391 391 } else {
392 392 qWarning() << "Trying to set axisX to null.";
393 393 }
394 394 }
395 395
396 396 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
397 397 {
398 398 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
399 399 if (axis && s) {
400 400 if (!m_chart->axes(Qt::Horizontal).contains(axis)) {
401 401 QList<QAbstractAxis *> oldAxes = m_chart->axes(Qt::Horizontal, s);
402 402 foreach (QAbstractAxis* a, oldAxes) {
403 403 m_chart->removeAxis(a);
404 404 delete a;
405 405 }
406 406 m_chart->addAxis(axis, Qt::AlignTop);
407 407 }
408 408 if (!s->attachedAxes().contains(axis))
409 409 s->attachAxis(axis);
410 410 } else {
411 411 qWarning() << "Trying to set axisXTop to null.";
412 412 }
413 413 }
414 414
415 415 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
416 416 {
417 417 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
418 418 if (axis && s) {
419 419 if (!m_chart->axes(Qt::Vertical).contains(axis))
420 420 m_chart->setAxisY(axis, s);
421 421 if (!s->attachedAxes().contains(axis))
422 422 s->attachAxis(axis);
423 423 } else {
424 424 qWarning() << "Trying to set axisY to null.";
425 425 }
426 426 }
427 427
428 428 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
429 429 {
430 430 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
431 431 if (axis && s) {
432 432 if (!m_chart->axes(Qt::Vertical).contains(axis)) {
433 433 QList<QAbstractAxis *> oldAxes = m_chart->axes((Qt::Vertical), s);
434 434 foreach (QAbstractAxis* a, oldAxes) {
435 435 m_chart->removeAxis(a);
436 436 delete a;
437 437 }
438 438 m_chart->addAxis(axis, Qt::AlignRight);
439 439 }
440 440 if (!s->attachedAxes().contains(axis))
441 441 s->attachAxis(axis);
442 442 } else {
443 443 qWarning() << "Trying to set axisYRight to null.";
444 444 }
445 445 }
446 446
447 447 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
448 448 {
449 449 if (newGeometry.isValid()) {
450 450 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
451 451 m_chart->resize(newGeometry.width(), newGeometry.height());
452 452 }
453 453 }
454 454 QDECLARATIVE_ITEM::geometryChanged(newGeometry, oldGeometry);
455 455
456 456 // It would be better to trigger the plotAreaChanged signal from QChart::plotAreaChanged or
457 457 // similar. Since that kind of a signal is not clearly needed in the C++ API the work-around is
458 458 // to implement it here for the QML API purposes.
459 459 emit plotAreaChanged(m_chart->plotArea());
460 460 }
461 461
462 462 #ifdef CHARTS_FOR_QUICK2
463 463 void DeclarativeChart::sceneChanged(QList<QRectF> region)
464 464 {
465 465 Q_UNUSED(region);
466 466
467 467 if (m_guiThreadId == m_paintThreadId) {
468 468 // Rendering in gui thread, no need for shenannigans, just update
469 469 update();
470 470 } else {
471 471 // Multi-threaded rendering, need to ensure scene is actually rendered in gui thread
472 472 if (!m_updatePending) {
473 473 m_updatePending = true;
474 474 // Do async render to avoid some unnecessary renders.
475 475 QTimer::singleShot(0, this, SLOT(renderScene()));
476 476 }
477 477 }
478 478 }
479 479
480 480 void DeclarativeChart::renderScene()
481 481 {
482 482 m_updatePending = false;
483 483 m_sceneImageLock.lock();
484 484 delete m_currentSceneImage;
485 485 m_currentSceneImage = new QImage(m_chart->size().toSize(), QImage::Format_ARGB32);
486 486 m_currentSceneImage->fill(Qt::transparent);
487 487 QPainter painter(m_currentSceneImage);
488 488 if (antialiasing())
489 489 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
490 490 QRect renderRect(QPoint(0, 0), m_chart->size().toSize());
491 491 m_scene->render(&painter, renderRect, renderRect);
492 492 m_sceneImageLock.unlock();
493 493
494 494 update();
495 495 }
496 496
497 497 void DeclarativeChart::paint(QPainter *painter)
498 498 {
499 499 if (!m_paintThreadId) {
500 500 m_paintThreadId = QThread::currentThreadId();
501 501 if (m_guiThreadId == m_paintThreadId) {
502 502 // No need for scene image in single threaded rendering, so delete
503 503 // the one that got made by default before the rendering type was
504 504 // detected.
505 505 delete m_currentSceneImage;
506 506 m_currentSceneImage = 0;
507 507 }
508 508 }
509 509
510 510 if (m_guiThreadId == m_paintThreadId) {
511 511 QRectF renderRect(QPointF(0, 0), m_chart->size());
512 512 m_scene->render(painter, renderRect, renderRect);
513 513 } else {
514 514 m_sceneImageLock.lock();
515 515 if (m_currentSceneImage) {
516 516 QRect imageRect(QPoint(0, 0), m_currentSceneImage->size());
517 517 QRect itemRect(QPoint(0, 0), QSize(width(), height()));
518 518 painter->drawImage(itemRect, *m_currentSceneImage, imageRect);
519 519 }
520 520 m_sceneImageLock.unlock();
521 521 }
522 522 }
523 523
524 524 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
525 525 {
526 526 m_mousePressScenePoint = event->pos();
527 527 m_mousePressScreenPoint = event->globalPos();
528 528 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
529 529 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
530 530 m_mousePressButton = event->button();
531 531 m_mousePressButtons = event->buttons();
532 532
533 533 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
534 534 mouseEvent.setWidget(0);
535 535 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
536 536 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
537 537 mouseEvent.setScenePos(m_mousePressScenePoint);
538 538 mouseEvent.setScreenPos(m_mousePressScreenPoint);
539 539 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
540 540 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
541 541 mouseEvent.setButtons(m_mousePressButtons);
542 542 mouseEvent.setButton(m_mousePressButton);
543 543 mouseEvent.setModifiers(event->modifiers());
544 544 mouseEvent.setAccepted(false);
545 545
546 546 QApplication::sendEvent(m_scene, &mouseEvent);
547 547 }
548 548
549 549 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
550 550 {
551 551 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
552 552 mouseEvent.setWidget(0);
553 553 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
554 554 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
555 555 mouseEvent.setScenePos(event->pos());
556 556 mouseEvent.setScreenPos(event->globalPos());
557 557 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
558 558 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
559 559 mouseEvent.setButtons(event->buttons());
560 560 mouseEvent.setButton(event->button());
561 561 mouseEvent.setModifiers(event->modifiers());
562 562 mouseEvent.setAccepted(false);
563 563
564 564 QApplication::sendEvent(m_scene, &mouseEvent);
565 565
566 566 m_mousePressButtons = event->buttons();
567 567 m_mousePressButton = Qt::NoButton;
568 568 }
569 569
570 570 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
571 571 {
572 572 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
573 573 // QGraphicsScene generates hover events from mouse move events, so we don't need
574 574 // to pass hover events there.
575 575 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
576 576 mouseEvent.setWidget(0);
577 577 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
578 578 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
579 579 mouseEvent.setScenePos(event->pos());
580 580 // Hover events do not have global pos in them, and the screen position doesn't seem to
581 581 // matter anyway in this use case, so just pass event pos instead of trying to
582 582 // calculate the real screen position.
583 583 mouseEvent.setScreenPos(event->pos());
584 584 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
585 585 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
586 586 mouseEvent.setButtons(m_mousePressButtons);
587 587 mouseEvent.setButton(m_mousePressButton);
588 588 mouseEvent.setModifiers(event->modifiers());
589 589 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
590 590 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
591 591 mouseEvent.setAccepted(false);
592 592
593 593 QApplication::sendEvent(m_scene, &mouseEvent);
594 594 }
595 595
596 596 void DeclarativeChart::handleAntialiasingChanged(bool enable)
597 597 {
598 598 setAntialiasing(enable);
599 599 }
600 600 #endif
601 601
602 602 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
603 603 {
604 604 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
605 605 if (chartTheme != m_chart->theme())
606 606 m_chart->setTheme(chartTheme);
607 607 }
608 608
609 609 DeclarativeChart::Theme DeclarativeChart::theme()
610 610 {
611 611 return (DeclarativeChart::Theme) m_chart->theme();
612 612 }
613 613
614 614 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
615 615 {
616 616 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
617 617 if (animationOptions != m_chart->animationOptions())
618 618 m_chart->setAnimationOptions(animationOptions);
619 619 }
620 620
621 621 DeclarativeChart::Animation DeclarativeChart::animationOptions()
622 622 {
623 623 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
624 624 return DeclarativeChart::AllAnimations;
625 625 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
626 626 return DeclarativeChart::GridAxisAnimations;
627 627 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
628 628 return DeclarativeChart::SeriesAnimations;
629 629 else
630 630 return DeclarativeChart::NoAnimation;
631 631 }
632 632
633 633 void DeclarativeChart::setTitle(QString title)
634 634 {
635 635 if (title != m_chart->title())
636 636 m_chart->setTitle(title);
637 637 }
638 638 QString DeclarativeChart::title()
639 639 {
640 640 return m_chart->title();
641 641 }
642 642
643 643 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
644 644 {
645 645 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
646 646 if (axes.count())
647 647 return axes[0];
648 648 return 0;
649 649 }
650 650
651 651 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
652 652 {
653 653 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
654 654 if (axes.count())
655 655 return axes[0];
656 656 return 0;
657 657 }
658 658
659 659 QLegend *DeclarativeChart::legend()
660 660 {
661 661 return m_chart->legend();
662 662 }
663 663
664 664 void DeclarativeChart::setTitleColor(QColor color)
665 665 {
666 666 QBrush b = m_chart->titleBrush();
667 667 if (color != b.color()) {
668 668 b.setColor(color);
669 669 m_chart->setTitleBrush(b);
670 670 emit titleColorChanged(color);
671 671 }
672 672 }
673 673
674 674 QFont DeclarativeChart::titleFont() const
675 675 {
676 676 return m_chart->titleFont();
677 677 }
678 678
679 679 void DeclarativeChart::setTitleFont(const QFont &font)
680 680 {
681 681 m_chart->setTitleFont(font);
682 682 }
683 683
684 684 QColor DeclarativeChart::titleColor()
685 685 {
686 686 return m_chart->titleBrush().color();
687 687 }
688 688
689 689 void DeclarativeChart::setBackgroundColor(QColor color)
690 690 {
691 691 QBrush b = m_chart->backgroundBrush();
692 692 if (b.style() != Qt::SolidPattern || color != b.color()) {
693 693 b.setStyle(Qt::SolidPattern);
694 694 b.setColor(color);
695 695 m_chart->setBackgroundBrush(b);
696 696 emit backgroundColorChanged();
697 697 }
698 698 }
699 699
700 700 QColor DeclarativeChart::backgroundColor()
701 701 {
702 702 return m_chart->backgroundBrush().color();
703 703 }
704 704
705 705 void QtCommercialChart::DeclarativeChart::setPlotAreaColor(QColor color)
706 706 {
707 707 QBrush b = m_chart->plotAreaBackgroundBrush();
708 708 if (b.style() != Qt::SolidPattern || color != b.color()) {
709 709 b.setStyle(Qt::SolidPattern);
710 710 b.setColor(color);
711 711 m_chart->setPlotAreaBackgroundBrush(b);
712 712 m_chart->setPlotAreaBackgroundVisible(true);
713 713 emit plotAreaColorChanged();
714 714 }
715 715 }
716 716
717 717 QColor QtCommercialChart::DeclarativeChart::plotAreaColor()
718 718 {
719 719 return m_chart->plotAreaBackgroundBrush().color();
720 720 }
721 721
722 722 void DeclarativeChart::setLocalizeNumbers(bool localize)
723 723 {
724 724 if (m_chart->localizeNumbers() != localize) {
725 725 m_chart->setLocalizeNumbers(localize);
726 726 emit localizeNumbersChanged();
727 727 }
728 728 }
729 729
730 730 bool DeclarativeChart::localizeNumbers() const
731 731 {
732 732 return m_chart->localizeNumbers();
733 733 }
734 734
735 735 int DeclarativeChart::count()
736 736 {
737 737 return m_chart->series().count();
738 738 }
739 739
740 740 void DeclarativeChart::setDropShadowEnabled(bool enabled)
741 741 {
742 742 if (enabled != m_chart->isDropShadowEnabled()) {
743 743 m_chart->setDropShadowEnabled(enabled);
744 744 dropShadowEnabledChanged(enabled);
745 745 }
746 746 }
747 747
748 748 bool DeclarativeChart::dropShadowEnabled()
749 749 {
750 750 return m_chart->isDropShadowEnabled();
751 751 }
752 752
753 753 qreal DeclarativeChart::backgroundRoundness() const
754 754 {
755 755 return m_chart->backgroundRoundness();
756 756 }
757 757
758 758 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
759 759 {
760 760 if (m_chart->backgroundRoundness() != diameter) {
761 761 m_chart->setBackgroundRoundness(diameter);
762 762 emit backgroundRoundnessChanged(diameter);
763 763 }
764 764 }
765 765
766 766 qreal DeclarativeChart::topMargin()
767 767 {
768 768 qWarning() << "ChartView.topMargin is deprecated. Use margins instead.";
769 769 return m_chart->margins().top();
770 770 }
771 771
772 772 qreal DeclarativeChart::bottomMargin()
773 773 {
774 774 qWarning() << "ChartView.bottomMargin is deprecated. Use margins instead.";
775 775 return m_chart->margins().bottom();
776 776 }
777 777
778 778 qreal DeclarativeChart::leftMargin()
779 779 {
780 780 qWarning() << "ChartView.leftMargin is deprecated. Use margins instead.";
781 781 return m_chart->margins().left();
782 782 }
783 783
784 784 qreal DeclarativeChart::rightMargin()
785 785 {
786 786 qWarning() << "ChartView.rightMargin is deprecated. Use margins instead.";
787 787 return m_chart->margins().right();
788 788 }
789 789
790 790 void DeclarativeChart::zoom(qreal factor)
791 791 {
792 792 m_chart->zoom(factor);
793 793 }
794 794
795 795 void DeclarativeChart::scrollLeft(qreal pixels)
796 796 {
797 797 m_chart->scroll(-pixels, 0);
798 798 }
799 799
800 800 void DeclarativeChart::scrollRight(qreal pixels)
801 801 {
802 802 m_chart->scroll(pixels, 0);
803 803 }
804 804
805 805 void DeclarativeChart::scrollUp(qreal pixels)
806 806 {
807 807 m_chart->scroll(0, pixels);
808 808 }
809 809
810 810 void DeclarativeChart::scrollDown(qreal pixels)
811 811 {
812 812 m_chart->scroll(0, -pixels);
813 813 }
814 814
815 815 QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> DeclarativeChart::axes()
816 816 {
817 817 return QDECLARATIVE_LIST_PROPERTY<QAbstractAxis>(this, 0,
818 818 &DeclarativeChart::axesAppendFunc,
819 819 &DeclarativeChart::axesCountFunc,
820 820 #ifdef CHARTS_FOR_QUICK2
821 821 &DeclarativeChart::axesAtFunc,
822 822 &DeclarativeChart::axesClearFunc);
823 823 #else
824 824 &DeclarativeChart::axesAtFunc);
825 825 #endif
826 826 }
827 827
828 828 void DeclarativeChart::axesAppendFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, QAbstractAxis *element)
829 829 {
830 830 // Empty implementation
831 831 Q_UNUSED(list);
832 832 Q_UNUSED(element);
833 833 }
834 834
835 835 int DeclarativeChart::axesCountFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list)
836 836 {
837 837 if (qobject_cast<DeclarativeChart *>(list->object)) {
838 838 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
839 839 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
840 840 }
841 841 return 0;
842 842 }
843 843
844 844 QAbstractAxis *DeclarativeChart::axesAtFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, int index)
845 845 {
846 846 if (qobject_cast<DeclarativeChart *>(list->object)) {
847 847 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
848 848 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
849 849 return axes.at(index);
850 850 }
851 851 return 0;
852 852 }
853 853
854 854 void DeclarativeChart::axesClearFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list)
855 855 {
856 856 // Empty implementation
857 857 Q_UNUSED(list);
858 858 }
859 859
860 860
861 861 QAbstractSeries *DeclarativeChart::series(int index)
862 862 {
863 863 if (index < m_chart->series().count()) {
864 864 return m_chart->series().at(index);
865 865 }
866 866 return 0;
867 867 }
868 868
869 869 QAbstractSeries *DeclarativeChart::series(QString seriesName)
870 870 {
871 871 foreach (QAbstractSeries *series, m_chart->series()) {
872 872 if (series->name() == seriesName)
873 873 return series;
874 874 }
875 875 return 0;
876 876 }
877 877
878 878 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
879 879 {
880 880 QAbstractSeries *series = 0;
881 881
882 882 switch (type) {
883 883 case DeclarativeChart::SeriesTypeLine:
884 884 series = new DeclarativeLineSeries();
885 885 break;
886 886 case DeclarativeChart::SeriesTypeArea: {
887 887 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
888 888 area->setUpperSeries(new DeclarativeLineSeries());
889 889 series = area;
890 890 break;
891 891 }
892 892 case DeclarativeChart::SeriesTypeStackedBar:
893 893 series = new DeclarativeStackedBarSeries();
894 894 break;
895 895 case DeclarativeChart::SeriesTypePercentBar:
896 896 series = new DeclarativePercentBarSeries();
897 897 break;
898 898 case DeclarativeChart::SeriesTypeBar:
899 899 series = new DeclarativeBarSeries();
900 900 break;
901 901 case DeclarativeChart::SeriesTypeHorizontalBar:
902 902 series = new DeclarativeHorizontalBarSeries();
903 903 break;
904 904 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
905 905 series = new DeclarativeHorizontalPercentBarSeries();
906 906 break;
907 907 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
908 908 series = new DeclarativeHorizontalStackedBarSeries();
909 909 break;
910 910 case DeclarativeChart::SeriesTypeBoxPlot:
911 911 series = new DeclarativeBoxPlotSeries();
912 912 break;
913 913 case DeclarativeChart::SeriesTypePie:
914 914 series = new DeclarativePieSeries();
915 915 break;
916 916 case DeclarativeChart::SeriesTypeScatter:
917 917 series = new DeclarativeScatterSeries();
918 918 break;
919 919 case DeclarativeChart::SeriesTypeSpline:
920 920 series = new DeclarativeSplineSeries();
921 921 break;
922 922 default:
923 923 qWarning() << "Illegal series type";
924 924 }
925 925
926 926 if (series) {
927 927 // Connect to axis changed signals (unless this is a pie series)
928 928 if (!qobject_cast<DeclarativePieSeries *>(series)) {
929 929 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
930 930 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
931 931 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
932 932 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
933 933 }
934 934
935 935 series->setName(name);
936 936 m_chart->addSeries(series);
937 937
938 938 if (axisX)
939 939 setAxisX(axisX, series);
940 940 if (axisY)
941 941 setAxisY(axisY, series);
942 942
943 943 if (series->attachedAxes().count() < 2)
944 944 initializeAxes(series);
945 945 }
946 946
947 947 return series;
948 948 }
949 949
950 950 void DeclarativeChart::removeSeries(QAbstractSeries *series)
951 951 {
952 952 if (series)
953 953 m_chart->removeSeries(series);
954 954 else
955 955 qWarning("removeSeries: cannot remove null");
956 956 }
957 957
958 958 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
959 959 {
960 960 if (axis)
961 961 m_chart->setAxisX(axis, series);
962 962 }
963 963
964 964 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
965 965 {
966 966 if (axis)
967 967 m_chart->setAxisY(axis, series);
968 968 }
969 969
970 970 void DeclarativeChart::createDefaultAxes()
971 971 {
972 972 qWarning() << "ChartView.createDefaultAxes() is deprecated. Axes are created automatically.";
973 973 }
974 974
975 975 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
976 976 {
977 977 if (!series) {
978 978 qWarning() << "No axis type defined for null series";
979 979 return 0;
980 980 }
981 981
982 982 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
983 983 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
984 984 return existingAxis;
985 985 }
986 986
987 987 switch (series->d_ptr->defaultAxisType(orientation)) {
988 988 case QAbstractAxis::AxisTypeValue:
989 989 return new QValueAxis(this);
990 990 case QAbstractAxis::AxisTypeBarCategory:
991 991 return new QBarCategoryAxis(this);
992 992 case QAbstractAxis::AxisTypeCategory:
993 993 return new QCategoryAxis(this);
994 994 #ifndef QT_ON_ARM
995 995 case QAbstractAxis::AxisTypeDateTime:
996 996 return new QDateTimeAxis(this);
997 997 #endif
998 998 case QAbstractAxis::AxisTypeLogValue:
999 999 return new QLogValueAxis(this);
1000 1000 default:
1001 1001 // assume AxisTypeNoAxis
1002 1002 return 0;
1003 1003 }
1004 1004 }
1005 1005
1006 1006 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1007 1007 {
1008 1008 if (qobject_cast<DeclarativeLineSeries *>(series))
1009 1009 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1010 1010 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1011 1011 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1012 1012 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1013 1013 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1014 1014 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1015 1015 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1016 1016 else if (qobject_cast<DeclarativeBarSeries *>(series))
1017 1017 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1018 1018 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1019 1019 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1020 1020 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1021 1021 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1022 1022 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1023 1023 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1024 1024 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1025 1025 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1026 1026 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1027 1027 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1028 1028 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1029 1029 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1030 1030 // else: do nothing
1031 1031 }
1032 1032
1033 1033 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1034 1034 {
1035 1035 // Initialize axis X
1036 1036 if (axes->axisX())
1037 1037 axes->emitAxisXChanged();
1038 1038 else if (axes->axisXTop())
1039 1039 axes->emitAxisXTopChanged();
1040 1040 else
1041 1041 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1042 1042
1043 1043 // Initialize axis Y
1044 1044 if (axes->axisY())
1045 1045 axes->emitAxisYChanged();
1046 1046 else if (axes->axisYRight())
1047 1047 axes->emitAxisYRightChanged();
1048 1048 else
1049 1049 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1050 1050 }
1051 1051
1052 1052 #include "moc_declarativechart.cpp"
1053 1053
1054 1054 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,240 +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 70 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers NOTIFY localizeNumbersChanged REVISION 4)
71 71 Q_ENUMS(Animation)
72 72 Q_ENUMS(Theme)
73 73 Q_ENUMS(SeriesType)
74 74
75 75 public:
76 76 // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api
77 77 enum Theme {
78 78 ChartThemeLight = 0,
79 79 ChartThemeBlueCerulean,
80 80 ChartThemeDark,
81 81 ChartThemeBrownSand,
82 82 ChartThemeBlueNcs,
83 83 ChartThemeHighContrast,
84 84 ChartThemeBlueIcy,
85 85 ChartThemeQt
86 86 };
87 87
88 88 enum Animation {
89 89 NoAnimation = 0x0,
90 90 GridAxisAnimations = 0x1,
91 91 SeriesAnimations = 0x2,
92 92 AllAnimations = 0x3
93 93 };
94 94
95 95 enum SeriesType {
96 96 SeriesTypeLine,
97 97 SeriesTypeArea,
98 98 SeriesTypeBar,
99 99 SeriesTypeStackedBar,
100 100 SeriesTypePercentBar,
101 101 SeriesTypeBoxPlot,
102 102 SeriesTypePie,
103 103 SeriesTypeScatter,
104 104 SeriesTypeSpline,
105 105 SeriesTypeHorizontalBar,
106 106 SeriesTypeHorizontalStackedBar,
107 107 SeriesTypeHorizontalPercentBar
108 108 };
109 109
110 110 public:
111 111 DeclarativeChart(QDECLARATIVE_ITEM *parent = 0);
112 112 ~DeclarativeChart();
113 113
114 114 public: // From parent classes
115 115 void childEvent(QChildEvent *event);
116 116 void componentComplete();
117 117 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
118 118 #ifdef CHARTS_FOR_QUICK2
119 119 void paint(QPainter *painter);
120 120 protected:
121 121 void mousePressEvent(QMouseEvent *event);
122 122 void mouseReleaseEvent(QMouseEvent *event);
123 123 void hoverMoveEvent(QHoverEvent *event);
124 124 private Q_SLOTS:
125 125 void handleAntialiasingChanged(bool enable);
126 126 void sceneChanged(QList<QRectF> region);
127 127 void renderScene();
128 128 #endif
129 129
130 130 public:
131 131 void setTheme(DeclarativeChart::Theme theme);
132 132 DeclarativeChart::Theme theme();
133 133 void setAnimationOptions(DeclarativeChart::Animation animations);
134 134 DeclarativeChart::Animation animationOptions();
135 135 void setTitle(QString title);
136 136 QString title();
137 137 QLegend *legend();
138 138 QFont titleFont() const;
139 139 void setTitleFont(const QFont &font);
140 140 void setTitleColor(QColor color);
141 141 QColor titleColor();
142 142 void setBackgroundColor(QColor color);
143 143 QColor backgroundColor();
144 144 Q_REVISION(3) void setPlotAreaColor(QColor color);
145 145 Q_REVISION(3) QColor plotAreaColor();
146 146 Q_REVISION(4) void setLocalizeNumbers(bool localize);
147 147 Q_REVISION(4) bool localizeNumbers() const;
148 148
149 149 int count();
150 150 void setDropShadowEnabled(bool enabled);
151 151 bool dropShadowEnabled();
152 152 Q_REVISION(3) qreal backgroundRoundness() const;
153 153 Q_REVISION(3) void setBackgroundRoundness(qreal diameter);
154 154
155 155 // Margins & plotArea
156 156 qreal topMargin();
157 157 qreal bottomMargin();
158 158 qreal leftMargin();
159 159 qreal rightMargin();
160 160 DeclarativeMargins *minimumMargins() { return m_margins; }
161 161 Q_REVISION(2) DeclarativeMargins *margins() { return m_margins; }
162 162 QRectF plotArea() { return m_chart->plotArea(); }
163 163
164 164 // Axis handling
165 165 QAbstractAxis *defaultAxis(Qt::Orientation orientation, QAbstractSeries *series);
166 166 void initializeAxes(QAbstractSeries *series);
167 167 void doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes);
168 168 QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> axes();
169 169 static void axesAppendFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, QAbstractAxis *element);
170 170 static int axesCountFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list);
171 171 static QAbstractAxis *axesAtFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, int index);
172 172 static void axesClearFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list);
173 173
174 174 public:
175 175 Q_INVOKABLE QAbstractSeries *series(int index);
176 176 Q_INVOKABLE QAbstractSeries *series(QString seriesName);
177 177 Q_INVOKABLE QAbstractSeries *createSeries(int type, QString name = "", QAbstractAxis *axisX = 0, QAbstractAxis *axisY = 0);
178 178 Q_INVOKABLE void removeSeries(QAbstractSeries *series);
179 179 Q_INVOKABLE void removeAllSeries() { m_chart->removeAllSeries(); }
180 180 Q_INVOKABLE void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
181 181 Q_INVOKABLE void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
182 182 Q_INVOKABLE void createDefaultAxes();
183 183 Q_INVOKABLE QAbstractAxis *axisX(QAbstractSeries *series = 0);
184 184 Q_INVOKABLE QAbstractAxis *axisY(QAbstractSeries *series = 0);
185 185 Q_INVOKABLE void zoom(qreal factor);
186 186 Q_INVOKABLE void scrollLeft(qreal pixels);
187 187 Q_INVOKABLE void scrollRight(qreal pixels);
188 188 Q_INVOKABLE void scrollUp(qreal pixels);
189 189 Q_INVOKABLE void scrollDown(qreal pixels);
190 190
191 191 Q_SIGNALS:
192 192 void axisLabelsChanged();
193 193 void titleColorChanged(QColor color);
194 194 void backgroundColorChanged();
195 195 void dropShadowEnabledChanged(bool enabled);
196 196 void minimumMarginsChanged();
197 197 Q_REVISION(2) void marginsChanged();
198 198 void plotAreaChanged(QRectF plotArea);
199 199 void seriesAdded(QAbstractSeries *series);
200 200 void seriesRemoved(QAbstractSeries *series);
201 201 Q_REVISION(3) void plotAreaColorChanged();
202 202 Q_REVISION(3) void backgroundRoundnessChanged(qreal diameter);
203 Q_REVISION(4) bool localizeNumbersChanged();
203 Q_REVISION(4) void localizeNumbersChanged();
204 204
205 205 private Q_SLOTS:
206 206 void changeMinimumMargins(int top, int bottom, int left, int right);
207 207 void handleAxisXSet(QAbstractAxis *axis);
208 208 void handleAxisYSet(QAbstractAxis *axis);
209 209 void handleAxisXTopSet(QAbstractAxis *axis);
210 210 void handleAxisYRightSet(QAbstractAxis *axis);
211 211 void handleSeriesAdded(QAbstractSeries *series);
212 212
213 213 protected:
214 214 explicit DeclarativeChart(QChart::ChartType type, QDECLARATIVE_ITEM *parent);
215 215
216 216 private:
217 217 void initChart(QChart::ChartType type);
218 218 // Extending QChart with DeclarativeChart is not possible because QObject does not support
219 219 // multi inheritance, so we now have a QChart as a member instead
220 220 QChart *m_chart;
221 221 #ifdef CHARTS_FOR_QUICK2
222 222 QGraphicsScene *m_scene;
223 223 QPointF m_mousePressScenePoint;
224 224 QPoint m_mousePressScreenPoint;
225 225 QPointF m_lastMouseMoveScenePoint;
226 226 QPoint m_lastMouseMoveScreenPoint;
227 227 Qt::MouseButton m_mousePressButton;
228 228 Qt::MouseButtons m_mousePressButtons;
229 229 QMutex m_sceneImageLock;
230 230 QImage *m_currentSceneImage;
231 231 bool m_updatePending;
232 232 Qt::HANDLE m_paintThreadId;
233 233 Qt::HANDLE m_guiThreadId;
234 234 #endif
235 235 DeclarativeMargins *m_margins;
236 236 };
237 237
238 238 QTCOMMERCIALCHART_END_NAMESPACE
239 239
240 240 #endif // DECLARATIVECHART_H
@@ -1,400 +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 32 static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.?(\\d)*([defgEG])(.*)$";
33 33 static QRegExp *labelFormatMatcher = 0;
34 34 static QRegExp *labelFormatMatcherLocalized = 0;
35 35 class StaticLabelFormatMatcherDeleter
36 36 {
37 37 public:
38 38 StaticLabelFormatMatcherDeleter() {}
39 39 ~StaticLabelFormatMatcherDeleter() {
40 40 delete labelFormatMatcher;
41 41 delete labelFormatMatcherLocalized;
42 42 }
43 43 };
44 44 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
45 45
46 46 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
47 47 : ChartElement(item),
48 48 m_axis(axis),
49 49 m_animation(0),
50 50 m_grid(new QGraphicsItemGroup(item)),
51 51 m_arrow(new QGraphicsItemGroup(item)),
52 52 m_shades(new QGraphicsItemGroup(item)),
53 53 m_labels(new QGraphicsItemGroup(item)),
54 54 m_title(new QGraphicsTextItem(item)),
55 55 m_intervalAxis(intervalAxis)
56 56
57 57 {
58 58 //initial initialization
59 59 m_arrow->setHandlesChildEvents(false);
60 60 m_arrow->setZValue(ChartPresenter::AxisZValue);
61 61 m_labels->setZValue(ChartPresenter::AxisZValue);
62 62 m_shades->setZValue(ChartPresenter::ShadesZValue);
63 63 m_grid->setZValue(ChartPresenter::GridZValue);
64 64 m_title->setZValue(ChartPresenter::GridZValue);
65 65 m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
66 66 handleVisibleChanged(axis->isVisible());
67 67 connectSlots();
68 68
69 69 setFlag(QGraphicsItem::ItemHasNoContents, true);
70 70 }
71 71
72 72 ChartAxisElement::~ChartAxisElement()
73 73 {
74 74 }
75 75
76 76 void ChartAxisElement::connectSlots()
77 77 {
78 78 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
79 79 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
80 80 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
81 81 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
82 82 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
83 83 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
84 84 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
85 85 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
86 86 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
87 87 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
88 88 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
89 89 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
90 90 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
91 91 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
92 92 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
93 93 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
94 94 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
95 95 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
96 96 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
97 97 }
98 98
99 99 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
100 100 {
101 101 m_arrow->setVisible(visible);
102 102 }
103 103
104 104 void ChartAxisElement::handleGridVisibleChanged(bool visible)
105 105 {
106 106 m_grid->setVisible(visible);
107 107 }
108 108
109 109 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
110 110 {
111 111 QGraphicsLayoutItem::updateGeometry();
112 112 presenter()->layout()->invalidate();
113 113 m_labels->setVisible(visible);
114 114 }
115 115
116 116 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
117 117 {
118 118 m_shades->setVisible(visible);
119 119 }
120 120
121 121 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
122 122 {
123 123 QGraphicsLayoutItem::updateGeometry();
124 124 presenter()->layout()->invalidate();
125 125 m_title->setVisible(visible);
126 126 }
127 127
128 128 void ChartAxisElement::handleLabelsAngleChanged(int angle)
129 129 {
130 130 foreach (QGraphicsItem *item, m_labels->childItems())
131 131 item->setRotation(angle);
132 132
133 133 QGraphicsLayoutItem::updateGeometry();
134 134 presenter()->layout()->invalidate();
135 135 }
136 136
137 137 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
138 138 {
139 139 Q_UNUSED(pen)
140 140 }
141 141
142 142 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
143 143 {
144 144 foreach (QGraphicsItem *item, m_labels->childItems())
145 145 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
146 146 }
147 147
148 148 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
149 149 {
150 150 foreach (QGraphicsItem *item, m_labels->childItems())
151 151 static_cast<QGraphicsTextItem *>(item)->setFont(font);
152 152 QGraphicsLayoutItem::updateGeometry();
153 153 presenter()->layout()->invalidate();
154 154 }
155 155
156 156 void ChartAxisElement::handleTitleTextChanged(const QString &title)
157 157 {
158 158 QGraphicsLayoutItem::updateGeometry();
159 159 presenter()->layout()->invalidate();
160 160 if (title.isEmpty() || !m_title->isVisible())
161 161 m_title->setHtml(title);
162 162 }
163 163
164 164 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
165 165 {
166 166 Q_UNUSED(pen)
167 167 }
168 168
169 169 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
170 170 {
171 171 m_title->setDefaultTextColor(brush.color());
172 172 }
173 173
174 174 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
175 175 {
176 176 if (m_title->font() != font) {
177 177 m_title->setFont(font);
178 178 QGraphicsLayoutItem::updateGeometry();
179 179 presenter()->layout()->invalidate();
180 180 }
181 181 }
182 182
183 183 void ChartAxisElement::handleVisibleChanged(bool visible)
184 184 {
185 185 setVisible(visible);
186 186 if (!visible) {
187 187 m_grid->setVisible(visible);
188 188 m_arrow->setVisible(visible);
189 189 m_shades->setVisible(visible);
190 190 m_labels->setVisible(visible);
191 191 m_title->setVisible(visible);
192 192 } else {
193 193 m_grid->setVisible(axis()->isGridLineVisible());
194 194 m_arrow->setVisible(axis()->isLineVisible());
195 195 m_shades->setVisible(axis()->shadesVisible());
196 196 m_labels->setVisible(axis()->labelsVisible());
197 197 m_title->setVisible(axis()->isTitleVisible());
198 198 }
199 199
200 200 if (presenter()) presenter()->layout()->invalidate();
201 201 }
202 202
203 203 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
204 204 {
205 205 Q_UNUSED(min);
206 206 Q_UNUSED(max);
207 207
208 208 if (!isEmpty()) {
209 209 QVector<qreal> layout = calculateLayout();
210 210 updateLayout(layout);
211 211 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
212 212 QSizeF after = sizeHint(Qt::PreferredSize);
213 213
214 214 if (before != after) {
215 215 QGraphicsLayoutItem::updateGeometry();
216 216 // We don't want to call invalidate on layout, since it will change minimum size of
217 217 // component, which we would like to avoid since it causes nasty flips when scrolling
218 218 // or zooming, instead recalculate layout and use plotArea for extra space.
219 219 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
220 220 }
221 221 }
222 222 }
223 223
224 224 bool ChartAxisElement::isEmpty()
225 225 {
226 226 return axisGeometry().isEmpty()
227 227 || gridGeometry().isEmpty()
228 228 || qFuzzyCompare(min(), max());
229 229 }
230 230
231 231 qreal ChartAxisElement::min() const
232 232 {
233 233 return m_axis->d_ptr->min();
234 234 }
235 235
236 236 qreal ChartAxisElement::max() const
237 237 {
238 238 return m_axis->d_ptr->max();
239 239 }
240 240
241 241 QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array,
242 242 qreal value, int precision, const QString &preStr,
243 243 const QString &postStr) const
244 244 {
245 245 QString retVal;
246 246 if (!formatSpec.isEmpty()) {
247 247 if (formatSpec.at(0) == QLatin1Char('d')
248 248 || formatSpec.at(0) == QLatin1Char('i')
249 249 || formatSpec.at(0) == QLatin1Char('c')) {
250 250 if (presenter()->localizeNumbers())
251 251 retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr;
252 252 else
253 253 retVal = QString().sprintf(array, qint64(value));
254 254 } else if (formatSpec.at(0) == QLatin1Char('u')
255 255 || formatSpec.at(0) == QLatin1Char('o')
256 256 || formatSpec.at(0) == QLatin1Char('x')
257 257 || formatSpec.at(0) == QLatin1Char('X')) {
258 258 // These formats are not supported by localized numbers
259 259 retVal = QString().sprintf(array, quint64(value));
260 260 } else if (formatSpec.at(0) == QLatin1Char('f')
261 261 || formatSpec.at(0) == QLatin1Char('F')
262 262 || formatSpec.at(0) == QLatin1Char('e')
263 263 || formatSpec.at(0) == QLatin1Char('E')
264 264 || formatSpec.at(0) == QLatin1Char('g')
265 265 || formatSpec.at(0) == QLatin1Char('G')) {
266 266 if (presenter()->localizeNumbers()) {
267 267 retVal = preStr
268 268 + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(),
269 269 precision)
270 270 + postStr;
271 271 } else {
272 272 retVal = QString().sprintf(array, value);
273 273 }
274 274 }
275 275 }
276 276 return retVal;
277 277 }
278 278
279 279 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks,
280 280 const QString &format) const
281 281 {
282 282 QStringList labels;
283 283
284 284 if (max <= min || ticks < 1)
285 285 return labels;
286 286
287 287 if (format.isNull()) {
288 288 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0) + 1;
289 289 for (int i = 0; i < ticks; i++) {
290 290 qreal value = min + (i * (max - min) / (ticks - 1));
291 291 labels << presenter()->numberToString(value, 'f', n);
292 292 }
293 293 } else {
294 294 QByteArray array = format.toLatin1();
295 295 QString formatSpec;
296 296 QString preStr;
297 297 QString postStr;
298 298 int precision = 0;
299 299 if (presenter()->localizeNumbers()) {
300 300 if (!labelFormatMatcherLocalized)
301 301 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
302 302 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
303 303 preStr = labelFormatMatcherLocalized->cap(1);
304 304 precision = labelFormatMatcherLocalized->cap(2).toInt();
305 305 formatSpec = labelFormatMatcherLocalized->cap(3);
306 306 postStr = labelFormatMatcherLocalized->cap(4);
307 307 }
308 308 } else {
309 309 if (!labelFormatMatcher)
310 310 labelFormatMatcher = new QRegExp(labelFormatMatchString);
311 311 if (labelFormatMatcher->indexIn(format, 0) != -1)
312 312 formatSpec = labelFormatMatcher->cap(1);
313 313 }
314 314 for (int i = 0; i < ticks; i++) {
315 315 qreal value = min + (i * (max - min) / (ticks - 1));
316 316 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
317 317 }
318 318 }
319 319
320 320 return labels;
321 321 }
322 322
323 323 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
324 324 const QString &format) const
325 325 {
326 326 QStringList labels;
327 327
328 328 if (max <= min || ticks < 1)
329 329 return labels;
330 330
331 331 int firstTick;
332 332 if (base > 1)
333 333 firstTick = ceil(log10(min) / log10(base));
334 334 else
335 335 firstTick = ceil(log10(max) / log10(base));
336 336
337 337 if (format.isNull()) {
338 338 int n = 0;
339 339 if (ticks > 1)
340 340 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
341 341 n++;
342 342 for (int i = firstTick; i < ticks + firstTick; i++) {
343 343 qreal value = qPow(base, i);
344 344 labels << presenter()->numberToString(value, 'f', n);
345 345 }
346 346 } else {
347 347 QByteArray array = format.toLatin1();
348 348 QString formatSpec;
349 349 QString preStr;
350 350 QString postStr;
351 351 int precision = 0;
352 352 if (presenter()->localizeNumbers()) {
353 353 if (!labelFormatMatcherLocalized)
354 354 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
355 355 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
356 356 preStr = labelFormatMatcherLocalized->cap(1);
357 357 precision = labelFormatMatcherLocalized->cap(2).toInt();
358 358 formatSpec = labelFormatMatcherLocalized->cap(3);
359 359 postStr = labelFormatMatcherLocalized->cap(4);
360 360 }
361 361 } else {
362 362 if (!labelFormatMatcher)
363 363 labelFormatMatcher = new QRegExp(labelFormatMatchString);
364 364 if (labelFormatMatcher->indexIn(format, 0) != -1)
365 365 formatSpec = labelFormatMatcher->cap(1);
366 366 }
367 367 for (int i = firstTick; i < ticks + firstTick; i++) {
368 368 qreal value = qPow(base, i);
369 369 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
370 370 }
371 371 }
372 372
373 373 return labels;
374 374 }
375 375
376 376 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,
377 377 const QString &format) const
378 378 {
379 379 QStringList labels;
380 380
381 381 if (max <= min || ticks < 1)
382 382 return labels;
383 383
384 384 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
385 385 n++;
386 386 for (int i = 0; i < ticks; i++) {
387 387 qreal value = min + (i * (max - min) / (ticks - 1));
388 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
388 labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format);
389 389 }
390 390 return labels;
391 391 }
392 392
393 393 void ChartAxisElement::axisSelected()
394 394 {
395 395 emit clicked();
396 396 }
397 397
398 398 #include "moc_chartaxiselement_p.cpp"
399 399
400 400 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,391 +1,393
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 "qdatetimeaxis.h"
22 22 #include "qdatetimeaxis_p.h"
23 23 #include "chartdatetimeaxisx_p.h"
24 24 #include "chartdatetimeaxisy_p.h"
25 25 #include "polarchartdatetimeaxisangular_p.h"
26 26 #include "polarchartdatetimeaxisradial_p.h"
27 27 #include "abstractdomain_p.h"
28 28 #include "qchart.h"
29 29 #include <float.h>
30 30 #include <cmath>
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33 /*!
34 34 \class QDateTimeAxis
35 35 \inmodule Qt Charts
36 36 \brief The QDateTimeAxis class is used for manipulating chart's axis.
37 37 \mainclass
38 38
39 39 The labels can be configured by setting an appropriate DateTime format.
40 40 QDateTimeAxis works correctly with dates from 4714 BCE to 287396 CE.
41 41 There are also other limitiation related to QDateTime. Please refer to QDateTime documentation.
42 42 QDateTimeAxis can be setup to show axis line with tick marks, grid lines and shades.
43 43
44 44 Note: QDateTimeAxis is disabled on ARM architecture.
45 45
46 46 \image api_datatime_axis.png
47 47
48 48 QDateTimeAxis can be used with any QXYSeries.
49 49 To add a data point to the series QDateTime::toMSecsSinceEpoch() is used.
50 50 \code
51 51 QLineSeries *series = new QLineSeries;
52 52
53 53 QDateTime xValue;
54 54 xValue.setDate(QDate(2012, 1 , 18));
55 55 xValue.setTime(QTime(9, 34));
56 56 qreal yValue = 12;
57 57 series->append(xValue.toMSecsSinceEpoch(), yValue);
58 58
59 59 xValue.setDate(QDate(2013, 5 , 11));
60 60 xValue.setTime(QTime(11, 14));
61 61 qreal yValue = 22;
62 62 series->append(xValue.toMSecsSinceEpoch(), yValue);
63 63 \endcode
64 64
65 65 Adding the series to the chart and setting up the QDateTimeAxis.
66 66 \code
67 67 QChartView *chartView = new QChartView;
68 68 chartView->chart()->addSeries(series);
69 69
70 70 // ...
71 71 QDateTimeAxis *axisX = new QDateTimeAxis;
72 72 axisX->setFormat("dd-MM-yyyy h:mm");
73 73 chartView->chart()->setAxisX(axisX, series);
74 74 \endcode
75 75 */
76 76
77 77 #ifdef QDOC_QT5
78 78 /*!
79 79 \qmltype DateTimeAxis
80 80 \instantiates QDateTimeAxis
81 81 \inqmlmodule QtCommercial.Chart
82 82
83 83 \include doc/src/datetimeaxis.qdocinc
84 84 */
85 85 #else
86 86 /*!
87 87 \qmlclass DateTimeAxis QDateTimeAxis
88 88
89 89 \include ../doc/src/datetimeaxis.qdocinc
90 90 */
91 91 #endif
92 92
93 93 /*!
94 94 \property QDateTimeAxis::min
95 95 Defines the minimum value on the axis.
96 96 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
97 97 */
98 98 /*!
99 99 \qmlproperty datetime DateTimeAxis::min
100 100 Defines the minimum value on the axis.
101 101 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
102 102 */
103 103
104 104 /*!
105 105 \property QDateTimeAxis::max
106 106 Defines the maximum value on the axis.
107 107 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
108 108 */
109 109 /*!
110 110 \qmlproperty datetime DateTimeAxis::max
111 111 Defines the maximum value on the axis.
112 112 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
113 113 */
114 114
115 115 /*!
116 116 \fn void QDateTimeAxis::minChanged(QDateTime min)
117 117 Axis emits signal when \a min of axis has changed.
118 118 */
119 119 /*!
120 120 \qmlsignal DateTimeAxis::onMinChanged(datetime min)
121 121 Axis emits signal when \a min of axis has changed.
122 122 */
123 123
124 124 /*!
125 125 \fn void QDateTimeAxis::maxChanged(QDateTime max)
126 126 Axis emits signal when \a max of axis has changed.
127 127 */
128 128 /*!
129 129 \qmlsignal DateTimeAxis::onMaxChanged(datetime max)
130 130 Axis emits signal when \a max of axis has changed.
131 131 */
132 132
133 133 /*!
134 134 \fn void QDateTimeAxis::rangeChanged(QDateTime min, QDateTime max)
135 135 Axis emits signal when \a min or \a max of axis has changed.
136 136 */
137 137
138 138 /*!
139 139 \property QDateTimeAxis::tickCount
140 140 The number of tick marks for the axis.
141 141 */
142 142
143 143 /*!
144 144 \qmlproperty int DateTimeAxis::tickCount
145 145 The number of tick marks for the axis.
146 146 */
147 147
148 148 /*!
149 149 \property QDateTimeAxis::format
150 150 The format string that is used when creating label for the axis out of a QDateTime object.
151 151 Check QDateTime documentation for information on how the string should be defined.
152
153 \sa QChart::locale
152 154 */
153 155 /*!
154 156 \qmlproperty string DateTimeAxis::format
155 157 The format string that is used when creating label for the axis out of a QDateTime object.
156 158 Check QDateTime documentation for information on how the string should be defined.
157 159 */
158 160
159 161 /*!
160 162 \fn void QDateTimeAxis::tickCountChanged(int tickCount)
161 163 Axis emits signal when \a tickCount number on axis have changed.
162 164 */
163 165 /*!
164 166 \qmlsignal DateTimeAxis::tickCountChanged(int tickCount)
165 167 Axis emits signal when \a tickCount number on axis have changed.
166 168 */
167 169
168 170 /*!
169 171 \fn void QDateTimeAxis::formatChanged(QString format)
170 172 Axis emits signal when \a format of the axis has changed.
171 173 */
172 174 /*!
173 175 \qmlsignal DateTimeAxis::onFormatChanged(string format)
174 176 Axis emits signal when \a format of the axis has changed.
175 177 */
176 178
177 179 /*!
178 180 Constructs an axis object which is a child of \a parent.
179 181 */
180 182 QDateTimeAxis::QDateTimeAxis(QObject *parent) :
181 183 QAbstractAxis(*new QDateTimeAxisPrivate(this), parent)
182 184 {
183 185
184 186 }
185 187
186 188 /*!
187 189 \internal
188 190 */
189 191 QDateTimeAxis::QDateTimeAxis(QDateTimeAxisPrivate &d, QObject *parent) : QAbstractAxis(d, parent)
190 192 {
191 193
192 194 }
193 195
194 196 /*!
195 197 Destroys the object.
196 198 */
197 199 QDateTimeAxis::~QDateTimeAxis()
198 200 {
199 201 Q_D(QDateTimeAxis);
200 202 if (d->m_chart)
201 203 d->m_chart->removeAxis(this);
202 204 }
203 205
204 206 void QDateTimeAxis::setMin(QDateTime min)
205 207 {
206 208 Q_D(QDateTimeAxis);
207 209 if (min.isValid())
208 210 d->setRange(min.toMSecsSinceEpoch(), qMax(d->m_max, qreal(min.toMSecsSinceEpoch())));
209 211 }
210 212
211 213 QDateTime QDateTimeAxis::min() const
212 214 {
213 215 Q_D(const QDateTimeAxis);
214 216 return QDateTime::fromMSecsSinceEpoch(d->m_min);
215 217 }
216 218
217 219 void QDateTimeAxis::setMax(QDateTime max)
218 220 {
219 221 Q_D(QDateTimeAxis);
220 222 if (max.isValid())
221 223 d->setRange(qMin(d->m_min, qreal(max.toMSecsSinceEpoch())), max.toMSecsSinceEpoch());
222 224 }
223 225
224 226 QDateTime QDateTimeAxis::max() const
225 227 {
226 228 Q_D(const QDateTimeAxis);
227 229 return QDateTime::fromMSecsSinceEpoch(d->m_max);
228 230 }
229 231
230 232 /*!
231 233 Sets range from \a min to \a max on the axis.
232 234 If min is greater than max then this function returns without making any changes.
233 235 */
234 236 void QDateTimeAxis::setRange(QDateTime min, QDateTime max)
235 237 {
236 238 Q_D(QDateTimeAxis);
237 239 if (!min.isValid() || !max.isValid() || min > max)
238 240 return;
239 241
240 242 d->setRange(min.toMSecsSinceEpoch(),max.toMSecsSinceEpoch());
241 243 }
242 244
243 245 void QDateTimeAxis::setFormat(QString format)
244 246 {
245 247 Q_D(QDateTimeAxis);
246 248 if (d->m_format != format) {
247 249 d->m_format = format;
248 250 emit formatChanged(format);
249 251 }
250 252 }
251 253
252 254 QString QDateTimeAxis::format() const
253 255 {
254 256 Q_D(const QDateTimeAxis);
255 257 return d->m_format;
256 258 }
257 259
258 260 /*!
259 261 Sets \a count for ticks on the axis.
260 262 */
261 263 void QDateTimeAxis::setTickCount(int count)
262 264 {
263 265 Q_D(QDateTimeAxis);
264 266 if (d->m_tickCount != count && count >= 2) {
265 267 d->m_tickCount = count;
266 268 emit tickCountChanged(count);
267 269 }
268 270 }
269 271
270 272 /*!
271 273 \fn int QDateTimeAxis::tickCount() const
272 274 Return number of ticks on the axis.
273 275 */
274 276 int QDateTimeAxis::tickCount() const
275 277 {
276 278 Q_D(const QDateTimeAxis);
277 279 return d->m_tickCount;
278 280 }
279 281
280 282 /*!
281 283 Returns the type of the axis.
282 284 */
283 285 QAbstractAxis::AxisType QDateTimeAxis::type() const
284 286 {
285 287 return AxisTypeDateTime;
286 288 }
287 289
288 290 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
289 291
290 292 QDateTimeAxisPrivate::QDateTimeAxisPrivate(QDateTimeAxis *q)
291 293 : QAbstractAxisPrivate(q),
292 294 m_min(0),
293 295 m_max(0),
294 296 m_tickCount(5)
295 297 {
296 298 m_format = "dd-MM-yyyy\nh:mm";
297 299 }
298 300
299 301 QDateTimeAxisPrivate::~QDateTimeAxisPrivate()
300 302 {
301 303
302 304 }
303 305
304 306 void QDateTimeAxisPrivate::setRange(qreal min,qreal max)
305 307 {
306 308 Q_Q(QDateTimeAxis);
307 309
308 310 bool changed = false;
309 311
310 312 if (m_min != min) {
311 313 m_min = min;
312 314 changed = true;
313 315 emit q->minChanged(QDateTime::fromMSecsSinceEpoch(min));
314 316 }
315 317
316 318 if (m_max != max) {
317 319 m_max = max;
318 320 changed = true;
319 321 emit q->maxChanged(QDateTime::fromMSecsSinceEpoch(max));
320 322 }
321 323
322 324 if (changed) {
323 325 emit q->rangeChanged(QDateTime::fromMSecsSinceEpoch(min), QDateTime::fromMSecsSinceEpoch(max));
324 326 emit rangeChanged(m_min,m_max);
325 327 }
326 328 }
327 329
328 330
329 331 void QDateTimeAxisPrivate::setMin(const QVariant &min)
330 332 {
331 333 Q_Q(QDateTimeAxis);
332 334 if (min.canConvert(QVariant::DateTime))
333 335 q->setMin(min.toDateTime());
334 336 }
335 337
336 338 void QDateTimeAxisPrivate::setMax(const QVariant &max)
337 339 {
338 340
339 341 Q_Q(QDateTimeAxis);
340 342 if (max.canConvert(QVariant::DateTime))
341 343 q->setMax(max.toDateTime());
342 344 }
343 345
344 346 void QDateTimeAxisPrivate::setRange(const QVariant &min, const QVariant &max)
345 347 {
346 348 Q_Q(QDateTimeAxis);
347 349 if (min.canConvert(QVariant::DateTime) && max.canConvert(QVariant::DateTime))
348 350 q->setRange(min.toDateTime(), max.toDateTime());
349 351 }
350 352
351 353 void QDateTimeAxisPrivate::initializeGraphics(QGraphicsItem* parent)
352 354 {
353 355 Q_Q(QDateTimeAxis);
354 356 ChartAxisElement *axis(0);
355 357 if (m_chart->chartType() == QChart::ChartTypeCartesian) {
356 358 if (orientation() == Qt::Vertical)
357 359 axis = new ChartDateTimeAxisY(q,parent);
358 360 if (orientation() == Qt::Horizontal)
359 361 axis = new ChartDateTimeAxisX(q,parent);
360 362 }
361 363
362 364 if (m_chart->chartType() == QChart::ChartTypePolar) {
363 365 if (orientation() == Qt::Vertical)
364 366 axis = new PolarChartDateTimeAxisRadial(q, parent);
365 367 if (orientation() == Qt::Horizontal)
366 368 axis = new PolarChartDateTimeAxisAngular(q, parent);
367 369 }
368 370
369 371 m_item.reset(axis);
370 372 QAbstractAxisPrivate::initializeGraphics(parent);
371 373 }
372 374
373 375 void QDateTimeAxisPrivate::initializeDomain(AbstractDomain *domain)
374 376 {
375 377 if (m_max == m_min) {
376 378 if (orientation() == Qt::Vertical)
377 379 setRange(domain->minY(), domain->maxY());
378 380 else
379 381 setRange(domain->minX(), domain->maxX());
380 382 } else {
381 383 if (orientation() == Qt::Vertical)
382 384 domain->setRangeY(m_min, m_max);
383 385 else
384 386 domain->setRangeX(m_min, m_max);
385 387 }
386 388 }
387 389
388 390 #include "moc_qdatetimeaxis.cpp"
389 391 #include "moc_qdatetimeaxis_p.cpp"
390 392
391 393 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,501 +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 47 m_title(0),
48 m_localizeNumbers(false)
48 m_localizeNumbers(true)
49 49 {
50 50 if (type == QChart::ChartTypeCartesian)
51 51 m_layout = new CartesianChartLayout(this);
52 52 else if (type == QChart::ChartTypePolar)
53 53 m_layout = new PolarChartLayout(this);
54 54 Q_ASSERT(m_layout);
55 55 }
56 56
57 57 ChartPresenter::~ChartPresenter()
58 58 {
59 59
60 60 }
61 61
62 62 void ChartPresenter::setGeometry(const QRectF rect)
63 63 {
64 64 if (m_rect != rect) {
65 65 m_rect = rect;
66 66 foreach (ChartItem *chart, m_chartItems) {
67 67 chart->domain()->setSize(rect.size());
68 68 chart->setPos(rect.topLeft());
69 69 }
70 70 }
71 71 }
72 72
73 73 QRectF ChartPresenter::geometry() const
74 74 {
75 75 return m_rect;
76 76 }
77 77
78 78 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
79 79 {
80 80 axis->d_ptr->initializeGraphics(rootItem());
81 81 axis->d_ptr->initializeAnimations(m_options);
82 82 ChartAxisElement *item = axis->d_ptr->axisItem();
83 83 item->setPresenter(this);
84 84 item->setThemeManager(m_chart->d_ptr->m_themeManager);
85 85 m_axisItems<<item;
86 86 m_axes<<axis;
87 87 m_layout->invalidate();
88 88 }
89 89
90 90 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
91 91 {
92 92 ChartAxisElement *item = axis->d_ptr->m_item.take();
93 93 item->hide();
94 94 item->disconnect();
95 95 item->deleteLater();
96 96 m_axisItems.removeAll(item);
97 97 m_axes.removeAll(axis);
98 98 m_layout->invalidate();
99 99 }
100 100
101 101
102 102 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
103 103 {
104 104 series->d_ptr->initializeGraphics(rootItem());
105 105 series->d_ptr->initializeAnimations(m_options);
106 106 series->d_ptr->setPresenter(this);
107 107 ChartItem *chart = series->d_ptr->chartItem();
108 108 chart->setPresenter(this);
109 109 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
110 110 chart->domain()->setSize(m_rect.size());
111 111 chart->setPos(m_rect.topLeft());
112 112 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
113 113 m_chartItems<<chart;
114 114 m_series<<series;
115 115 m_layout->invalidate();
116 116 }
117 117
118 118 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
119 119 {
120 120 ChartItem *chart = series->d_ptr->m_item.take();
121 121 chart->hide();
122 122 chart->disconnect();
123 123 chart->deleteLater();
124 124 m_chartItems.removeAll(chart);
125 125 m_series.removeAll(series);
126 126 m_layout->invalidate();
127 127 }
128 128
129 129 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
130 130 {
131 131 if (m_options != options) {
132 132 QChart::AnimationOptions oldOptions = m_options;
133 133 m_options = options;
134 134 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
135 135 foreach (QAbstractSeries *series, m_series)
136 136 series->d_ptr->initializeAnimations(m_options);
137 137 }
138 138 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
139 139 foreach (QAbstractAxis *axis, m_axes)
140 140 axis->d_ptr->initializeAnimations(m_options);
141 141 }
142 142 m_layout->invalidate(); // So that existing animations don't just stop halfway
143 143 }
144 144 }
145 145
146 146 void ChartPresenter::setState(State state,QPointF point)
147 147 {
148 148 m_state=state;
149 149 m_statePoint=point;
150 150 }
151 151
152 152 QChart::AnimationOptions ChartPresenter::animationOptions() const
153 153 {
154 154 return m_options;
155 155 }
156 156
157 157 void ChartPresenter::createBackgroundItem()
158 158 {
159 159 if (!m_background) {
160 160 m_background = new ChartBackground(rootItem());
161 161 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
162 162 m_background->setBrush(QChartPrivate::defaultBrush());
163 163 m_background->setZValue(ChartPresenter::BackgroundZValue);
164 164 }
165 165 }
166 166
167 167 void ChartPresenter::createPlotAreaBackgroundItem()
168 168 {
169 169 if (!m_plotAreaBackground) {
170 170 if (m_chart->chartType() == QChart::ChartTypeCartesian)
171 171 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
172 172 else
173 173 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
174 174 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
175 175 // antialising artifacts with axis lines for some reason.
176 176 m_plotAreaBackground->setPen(QPen(Qt::transparent));
177 177 m_plotAreaBackground->setBrush(Qt::NoBrush);
178 178 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
179 179 m_plotAreaBackground->setVisible(false);
180 180 }
181 181 }
182 182
183 183 void ChartPresenter::createTitleItem()
184 184 {
185 185 if (!m_title) {
186 186 m_title = new ChartTitle(rootItem());
187 187 m_title->setZValue(ChartPresenter::BackgroundZValue);
188 188 }
189 189 }
190 190
191 191 void ChartPresenter::startAnimation(ChartAnimation *animation)
192 192 {
193 193 animation->stop();
194 194 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
195 195 }
196 196
197 197 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
198 198 {
199 199 createBackgroundItem();
200 200 m_background->setBrush(brush);
201 201 m_layout->invalidate();
202 202 }
203 203
204 204 QBrush ChartPresenter::backgroundBrush() const
205 205 {
206 206 if (!m_background)
207 207 return QBrush();
208 208 return m_background->brush();
209 209 }
210 210
211 211 void ChartPresenter::setBackgroundPen(const QPen &pen)
212 212 {
213 213 createBackgroundItem();
214 214 m_background->setPen(pen);
215 215 m_layout->invalidate();
216 216 }
217 217
218 218 QPen ChartPresenter::backgroundPen() const
219 219 {
220 220 if (!m_background)
221 221 return QPen();
222 222 return m_background->pen();
223 223 }
224 224
225 225 void ChartPresenter::setBackgroundRoundness(qreal diameter)
226 226 {
227 227 createBackgroundItem();
228 228 m_background->setDiameter(diameter);
229 229 m_layout->invalidate();
230 230 }
231 231
232 232 qreal ChartPresenter::backgroundRoundness() const
233 233 {
234 234 if (!m_background)
235 235 return 0;
236 236 return m_background->diameter();
237 237 }
238 238
239 239 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
240 240 {
241 241 createPlotAreaBackgroundItem();
242 242 m_plotAreaBackground->setBrush(brush);
243 243 m_layout->invalidate();
244 244 }
245 245
246 246 QBrush ChartPresenter::plotAreaBackgroundBrush() const
247 247 {
248 248 if (!m_plotAreaBackground)
249 249 return QBrush();
250 250 return m_plotAreaBackground->brush();
251 251 }
252 252
253 253 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
254 254 {
255 255 createPlotAreaBackgroundItem();
256 256 m_plotAreaBackground->setPen(pen);
257 257 m_layout->invalidate();
258 258 }
259 259
260 260 QPen ChartPresenter::plotAreaBackgroundPen() const
261 261 {
262 262 if (!m_plotAreaBackground)
263 263 return QPen();
264 264 return m_plotAreaBackground->pen();
265 265 }
266 266
267 267 void ChartPresenter::setTitle(const QString &title)
268 268 {
269 269 createTitleItem();
270 270 m_title->setText(title);
271 271 m_layout->invalidate();
272 272 }
273 273
274 274 QString ChartPresenter::title() const
275 275 {
276 276 if (!m_title)
277 277 return QString();
278 278 return m_title->text();
279 279 }
280 280
281 281 void ChartPresenter::setTitleFont(const QFont &font)
282 282 {
283 283 createTitleItem();
284 284 m_title->setFont(font);
285 285 m_layout->invalidate();
286 286 }
287 287
288 288 QFont ChartPresenter::titleFont() const
289 289 {
290 290 if (!m_title)
291 291 return QFont();
292 292 return m_title->font();
293 293 }
294 294
295 295 void ChartPresenter::setTitleBrush(const QBrush &brush)
296 296 {
297 297 createTitleItem();
298 298 m_title->setDefaultTextColor(brush.color());
299 299 m_layout->invalidate();
300 300 }
301 301
302 302 QBrush ChartPresenter::titleBrush() const
303 303 {
304 304 if (!m_title)
305 305 return QBrush();
306 306 return QBrush(m_title->defaultTextColor());
307 307 }
308 308
309 309 void ChartPresenter::setBackgroundVisible(bool visible)
310 310 {
311 311 createBackgroundItem();
312 312 m_background->setVisible(visible);
313 313 }
314 314
315 315
316 316 bool ChartPresenter::isBackgroundVisible() const
317 317 {
318 318 if (!m_background)
319 319 return false;
320 320 return m_background->isVisible();
321 321 }
322 322
323 323 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
324 324 {
325 325 createPlotAreaBackgroundItem();
326 326 m_plotAreaBackground->setVisible(visible);
327 327 }
328 328
329 329 bool ChartPresenter::isPlotAreaBackgroundVisible() const
330 330 {
331 331 if (!m_plotAreaBackground)
332 332 return false;
333 333 return m_plotAreaBackground->isVisible();
334 334 }
335 335
336 336 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
337 337 {
338 338 createBackgroundItem();
339 339 m_background->setDropShadowEnabled(enabled);
340 340 }
341 341
342 342 bool ChartPresenter::isBackgroundDropShadowEnabled() const
343 343 {
344 344 if (!m_background)
345 345 return false;
346 346 return m_background->isDropShadowEnabled();
347 347 }
348 348
349 349 void ChartPresenter::setLocalizeNumbers(bool localize)
350 350 {
351 351 m_localizeNumbers = localize;
352 352 m_layout->invalidate();
353 353 }
354 354
355 bool ChartPresenter::localizeNumbers() const
355 void ChartPresenter::setLocale(const QLocale &locale)
356 356 {
357 return m_localizeNumbers;
357 m_locale = locale;
358 m_layout->invalidate();
358 359 }
359 360
360
361 361 AbstractChartLayout *ChartPresenter::layout()
362 362 {
363 363 return m_layout;
364 364 }
365 365
366 366 QLegend *ChartPresenter::legend()
367 367 {
368 368 return m_chart->legend();
369 369 }
370 370
371 371 void ChartPresenter::setVisible(bool visible)
372 372 {
373 373 m_chart->setVisible(visible);
374 374 }
375 375
376 376 ChartBackground *ChartPresenter::backgroundElement()
377 377 {
378 378 return m_background;
379 379 }
380 380
381 381 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
382 382 {
383 383 return m_plotAreaBackground;
384 384 }
385 385
386 386 QList<ChartAxisElement *> ChartPresenter::axisItems() const
387 387 {
388 388 return m_axisItems;
389 389 }
390 390
391 391 QList<ChartItem *> ChartPresenter::chartItems() const
392 392 {
393 393 return m_chartItems;
394 394 }
395 395
396 396 ChartTitle *ChartPresenter::titleElement()
397 397 {
398 398 return m_title;
399 399 }
400 400
401 401 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
402 402 {
403 403 static QGraphicsTextItem dummyTextItem;
404 404 static bool initMargin = true;
405 405 if (initMargin) {
406 406 dummyTextItem.document()->setDocumentMargin(textMargin());
407 407 initMargin = false;
408 408 }
409 409
410 410 dummyTextItem.setFont(font);
411 411 dummyTextItem.setHtml(text);
412 412 QRectF boundingRect = dummyTextItem.boundingRect();
413 413
414 414 // Take rotation into account
415 415 if (angle) {
416 416 QTransform transform;
417 417 transform.rotate(angle);
418 418 boundingRect = transform.mapRect(boundingRect);
419 419 }
420 420
421 421 return boundingRect;
422 422 }
423 423
424 424 // boundingRect parameter returns the rotated bounding rect of the text
425 425 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
426 426 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
427 427 {
428 428 QString truncatedString(text);
429 429 boundingRect = textBoundingRect(font, truncatedString, angle);
430 430 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
431 431 // It can be assumed that almost any amount of string manipulation is faster
432 432 // than calculating one bounding rectangle, so first prepare a list of truncated strings
433 433 // to try.
434 434 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
435 435 static QRegExp truncateMatcher(truncateMatchString);
436 436
437 437 QVector<QString> testStrings(text.length());
438 438 int count(0);
439 439 static QLatin1Char closeTag('>');
440 440 static QLatin1Char openTag('<');
441 441 static QLatin1Char semiColon(';');
442 442 static QLatin1String ellipsis("...");
443 443 while (truncatedString.length() > 1) {
444 444 int chopIndex(-1);
445 445 int chopCount(1);
446 446 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
447 447
448 448 if (lastChar == closeTag)
449 449 chopIndex = truncatedString.lastIndexOf(openTag);
450 450 else if (lastChar == semiColon)
451 451 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
452 452
453 453 if (chopIndex != -1)
454 454 chopCount = truncatedString.length() - chopIndex;
455 455 truncatedString.chop(chopCount);
456 456 testStrings[count] = truncatedString + ellipsis;
457 457 count++;
458 458 }
459 459
460 460 // Binary search for best fit
461 461 int minIndex(0);
462 462 int maxIndex(count - 1);
463 463 int bestIndex(count);
464 464 QRectF checkRect;
465 465
466 466 while (maxIndex >= minIndex) {
467 467 int mid = (maxIndex + minIndex) / 2;
468 468 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
469 469 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
470 470 // Checked index too large, all under this are also too large
471 471 minIndex = mid + 1;
472 472 } else {
473 473 // Checked index fits, all over this also fit
474 474 maxIndex = mid - 1;
475 475 bestIndex = mid;
476 476 boundingRect = checkRect;
477 477 }
478 478 }
479 479 // Default to "..." if nothing fits
480 480 if (bestIndex == count) {
481 481 boundingRect = textBoundingRect(font, ellipsis, angle);
482 482 truncatedString = ellipsis;
483 483 } else {
484 484 truncatedString = testStrings.at(bestIndex);
485 485 }
486 486 }
487 487
488 488 return truncatedString;
489 489 }
490 490
491 491 QString ChartPresenter::numberToString(double value, char f, int prec)
492 492 {
493 493 if (m_localizeNumbers)
494 494 return m_locale.toString(value, f, prec);
495 495 else
496 496 return QString::number(value, f, prec);
497 497 }
498 498
499 499 #include "moc_chartpresenter_p.cpp"
500 500
501 501 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,190 +1,191
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 37 #include <QLocale>
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class ChartItem;
42 42 class AxisItem;
43 43 class QAbstractSeries;
44 44 class ChartDataSet;
45 45 class AbstractDomain;
46 46 class ChartAxisElement;
47 47 class ChartAnimator;
48 48 class ChartBackground;
49 49 class ChartTitle;
50 50 class ChartAnimation;
51 51 class AbstractChartLayout;
52 52
53 53 class ChartPresenter: public QObject
54 54 {
55 55 Q_OBJECT
56 56 public:
57 57 enum ZValues {
58 58 BackgroundZValue = -1,
59 59 PlotAreaZValue,
60 60 ShadesZValue,
61 61 GridZValue,
62 62 AxisZValue,
63 63 SeriesZValue,
64 64 LineChartZValue = SeriesZValue,
65 65 SplineChartZValue = SeriesZValue,
66 66 BarSeriesZValue = SeriesZValue,
67 67 ScatterSeriesZValue = SeriesZValue,
68 68 PieSeriesZValue = SeriesZValue,
69 69 BoxPlotSeriesZValue = SeriesZValue,
70 70 LegendZValue,
71 71 TopMostZValue
72 72 };
73 73
74 74 enum State {
75 75 ShowState,
76 76 ScrollUpState,
77 77 ScrollDownState,
78 78 ScrollLeftState,
79 79 ScrollRightState,
80 80 ZoomInState,
81 81 ZoomOutState
82 82 };
83 83
84 84 ChartPresenter(QChart *chart, QChart::ChartType type);
85 85 virtual ~ChartPresenter();
86 86
87 87
88 88 void setGeometry(QRectF rect);
89 89 QRectF geometry() const;
90 90
91 91 QGraphicsItem *rootItem(){ return m_chart; }
92 92 ChartBackground *backgroundElement();
93 93 QAbstractGraphicsShapeItem *plotAreaElement();
94 94 ChartTitle *titleElement();
95 95 QList<ChartAxisElement *> axisItems() const;
96 96 QList<ChartItem *> chartItems() const;
97 97
98 98 QLegend *legend();
99 99
100 100 void setBackgroundBrush(const QBrush &brush);
101 101 QBrush backgroundBrush() const;
102 102
103 103 void setBackgroundPen(const QPen &pen);
104 104 QPen backgroundPen() const;
105 105
106 106 void setBackgroundRoundness(qreal diameter);
107 107 qreal backgroundRoundness() const;
108 108
109 109 void setPlotAreaBackgroundBrush(const QBrush &brush);
110 110 QBrush plotAreaBackgroundBrush() const;
111 111
112 112 void setPlotAreaBackgroundPen(const QPen &pen);
113 113 QPen plotAreaBackgroundPen() const;
114 114
115 115 void setTitle(const QString &title);
116 116 QString title() const;
117 117
118 118 void setTitleFont(const QFont &font);
119 119 QFont titleFont() const;
120 120
121 121 void setTitleBrush(const QBrush &brush);
122 122 QBrush titleBrush() const;
123 123
124 124 void setBackgroundVisible(bool visible);
125 125 bool isBackgroundVisible() const;
126 126
127 127 void setPlotAreaBackgroundVisible(bool visible);
128 128 bool isPlotAreaBackgroundVisible() const;
129 129
130 130 void setBackgroundDropShadowEnabled(bool enabled);
131 131 bool isBackgroundDropShadowEnabled() const;
132 132
133 133 void setLocalizeNumbers(bool localize);
134 bool localizeNumbers() const;
134 inline bool localizeNumbers() const { return m_localizeNumbers; }
135 void setLocale(const QLocale &locale);
136 inline const QLocale &locale() const { return m_locale; }
135 137
136 138 void setVisible(bool visible);
137 139
138 140 void setAnimationOptions(QChart::AnimationOptions options);
139 141 QChart::AnimationOptions animationOptions() const;
140 142
141 143 void startAnimation(ChartAnimation *animation);
142 144
143 145 void setState(State state,QPointF point);
144 146 State state() const { return m_state; }
145 147 QPointF statePoint() const { return m_statePoint; }
146 148 AbstractChartLayout *layout();
147 149
148 150 QChart::ChartType chartType() const { return m_chart->chartType(); }
149 151 QChart *chart() { return m_chart; }
150 152
151 153 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
152 154 static QString truncatedText(const QFont &font, const QString &text, qreal angle,
153 155 qreal maxWidth, qreal maxHeight, QRectF &boundingRect);
154 156 inline static qreal textMargin() { return qreal(0.5); }
155 157
156 158 QString numberToString(double value, char f = 'g', int prec = 6);
157 inline const QLocale &locale() const { return m_locale; }
158 159
159 160 private:
160 161 void createBackgroundItem();
161 162 void createPlotAreaBackgroundItem();
162 163 void createTitleItem();
163 164
164 165 public Q_SLOTS:
165 166 void handleSeriesAdded(QAbstractSeries *series);
166 167 void handleSeriesRemoved(QAbstractSeries *series);
167 168 void handleAxisAdded(QAbstractAxis *axis);
168 169 void handleAxisRemoved(QAbstractAxis *axis);
169 170
170 171 private:
171 172 QChart *m_chart;
172 173 QList<ChartItem *> m_chartItems;
173 174 QList<ChartAxisElement *> m_axisItems;
174 175 QList<QAbstractSeries *> m_series;
175 176 QList<QAbstractAxis *> m_axes;
176 177 QChart::AnimationOptions m_options;
177 178 State m_state;
178 179 QPointF m_statePoint;
179 180 AbstractChartLayout *m_layout;
180 181 ChartBackground *m_background;
181 182 QAbstractGraphicsShapeItem *m_plotAreaBackground;
182 183 ChartTitle *m_title;
183 184 QRectF m_rect;
184 185 bool m_localizeNumbers;
185 186 QLocale m_locale;
186 187 };
187 188
188 189 QTCOMMERCIALCHART_END_NAMESPACE
189 190
190 191 #endif /* CHARTPRESENTER_H */
@@ -1,847 +1,872
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 148 \property QChart::localizeNumbers
149 149 \since QtCharts 2.0
150 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.
151 localized using the QLocale set with the locale property.
152 152 When \c{false}, the "C" locale is always used.
153 Defaults to \c{false}.
153 Defaults to \c{true}.
154 \note This property doesn't affect QDateTimeAxis labels, which always use the QLocale set with
155 the locale property.
156
157 \sa locale
158 */
159
160 /*!
161 \property QChart::locale
162 \since QtCharts 2.0
163 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
164 This also determines the locale used to format QDateTimeAxis labels regardless of
165 localizeNumbers property.
166 Defaults to application default locale at the time the chart is constructed.
167
168 \sa localizeNumbers
154 169 */
155 170
156 171 /*!
157 172 \internal
158 173 Constructs a chart object of \a type which is a child of a \a parent.
159 174 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
160 175 This constructor is called only by subclasses.
161 176 */
162 177 QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
163 178 : QGraphicsWidget(parent, wFlags),
164 179 d_ptr(new QChartPrivate(this, type))
165 180 {
166 181 d_ptr->init();
167 182 }
168 183
169 184 /*!
170 185 Constructs a chart object which is a child of a \a parent.
171 186 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
172 187 */
173 188 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
174 189 : QGraphicsWidget(parent, wFlags),
175 190 d_ptr(new QChartPrivate(this, ChartTypeCartesian))
176 191 {
177 192 d_ptr->init();
178 193 }
179 194
180 195 /*!
181 196 Destroys the chart object and its children, like series and axis objects added to it.
182 197 */
183 198 QChart::~QChart()
184 199 {
185 200 //start by deleting dataset, it will remove all series and axes
186 201 delete d_ptr->m_dataset;
187 202 d_ptr->m_dataset = 0;
188 203 }
189 204
190 205 /*!
191 206 Adds the \a series onto the chart and takes the ownership of it.
192 207
193 208 \note A newly added series is attached to no axes by default, including any axes that were created for the chart
194 209 using createDefaultAxes() before the series was added to the chart. If no axes are attached to
195 210 the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
196 211 that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
197 212 series that have properly attached axes, so always make sure you either call createDefaultAxes() after
198 213 a series has been added or explicitly attach axes for the series.
199 214
200 215 \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
201 216 */
202 217 void QChart::addSeries(QAbstractSeries *series)
203 218 {
204 219 Q_ASSERT(series);
205 220 d_ptr->m_dataset->addSeries(series);
206 221 }
207 222
208 223 /*!
209 224 Removes the \a series from the chart.
210 225 The chart releases its ownership of the specified \a series object.
211 226
212 227 \sa addSeries(), removeAllSeries()
213 228 */
214 229 void QChart::removeSeries(QAbstractSeries *series)
215 230 {
216 231 Q_ASSERT(series);
217 232 d_ptr->m_dataset->removeSeries(series);
218 233 }
219 234
220 235 /*!
221 236 Removes and deletes all series objects that have been added to the chart.
222 237
223 238 \sa addSeries(), removeSeries()
224 239 */
225 240 void QChart::removeAllSeries()
226 241 {
227 242 foreach (QAbstractSeries *s , d_ptr->m_dataset->series()){
228 243 removeSeries(s);
229 244 delete s;
230 245 }
231 246 }
232 247
233 248 /*!
234 249 Sets the \a brush that is used for painting the background of the chart area.
235 250 */
236 251 void QChart::setBackgroundBrush(const QBrush &brush)
237 252 {
238 253 d_ptr->m_presenter->setBackgroundBrush(brush);
239 254 }
240 255
241 256 /*!
242 257 Gets the brush that is used for painting the background of the chart area.
243 258 */
244 259 QBrush QChart::backgroundBrush() const
245 260 {
246 261 return d_ptr->m_presenter->backgroundBrush();
247 262 }
248 263
249 264 /*!
250 265 Sets the \a pen that is used for painting the background of the chart area.
251 266 */
252 267 void QChart::setBackgroundPen(const QPen &pen)
253 268 {
254 269 d_ptr->m_presenter->setBackgroundPen(pen);
255 270 }
256 271
257 272 /*!
258 273 Gets the pen that is used for painting the background of the chart area.
259 274 */
260 275 QPen QChart::backgroundPen() const
261 276 {
262 277 return d_ptr->m_presenter->backgroundPen();
263 278 }
264 279
265 280 void QChart::setTitle(const QString &title)
266 281 {
267 282 d_ptr->m_presenter->setTitle(title);
268 283 }
269 284
270 285 QString QChart::title() const
271 286 {
272 287 return d_ptr->m_presenter->title();
273 288 }
274 289
275 290 /*!
276 291 Sets the \a font that is used for drawing the chart title.
277 292 */
278 293 void QChart::setTitleFont(const QFont &font)
279 294 {
280 295 d_ptr->m_presenter->setTitleFont(font);
281 296 }
282 297
283 298 /*!
284 299 Gets the font that is used for drawing the chart title.
285 300 */
286 301 QFont QChart::titleFont() const
287 302 {
288 303 return d_ptr->m_presenter->titleFont();
289 304 }
290 305
291 306 /*!
292 307 Sets the \a brush used for drawing the title text.
293 308 */
294 309 void QChart::setTitleBrush(const QBrush &brush)
295 310 {
296 311 d_ptr->m_presenter->setTitleBrush(brush);
297 312 }
298 313
299 314 /*!
300 315 Returns the brush used for drawing the title text.
301 316 */
302 317 QBrush QChart::titleBrush() const
303 318 {
304 319 return d_ptr->m_presenter->titleBrush();
305 320 }
306 321
307 322 void QChart::setTheme(QChart::ChartTheme theme)
308 323 {
309 324 d_ptr->m_themeManager->setTheme(theme);
310 325 }
311 326
312 327 QChart::ChartTheme QChart::theme() const
313 328 {
314 329 return d_ptr->m_themeManager->theme()->id();
315 330 }
316 331
317 332 /*!
318 333 Zooms in the view by a factor of two.
319 334 */
320 335 void QChart::zoomIn()
321 336 {
322 337 d_ptr->zoomIn(2.0);
323 338 }
324 339
325 340 /*!
326 341 Zooms in the view to a maximum level at which \a rect is still fully visible.
327 342 \note This is not supported for polar charts.
328 343 */
329 344 void QChart::zoomIn(const QRectF &rect)
330 345 {
331 346 if (d_ptr->m_type == QChart::ChartTypePolar)
332 347 return;
333 348 d_ptr->zoomIn(rect);
334 349 }
335 350
336 351 /*!
337 352 Zooms out the view by a factor of two.
338 353 */
339 354 void QChart::zoomOut()
340 355 {
341 356 d_ptr->zoomOut(2.0);
342 357 }
343 358
344 359 /*!
345 360 Zooms in the view by a custom \a factor.
346 361
347 362 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
348 363 */
349 364 void QChart::zoom(qreal factor)
350 365 {
351 366 if (qFuzzyCompare(factor, 0))
352 367 return;
353 368
354 369 if (qFuzzyCompare(factor, (qreal)1.0))
355 370 return;
356 371
357 372 if (factor < 0)
358 373 return;
359 374
360 375 if (factor > 1.0)
361 376 d_ptr->zoomIn(factor);
362 377 else
363 378 d_ptr->zoomOut(1.0 / factor);
364 379 }
365 380
366 381
367 382 /*!
368 383 Resets the series domains to what they were before any zoom method was called.
369 384 Note that this will also reset any scrolls and explicit axis range settings done between
370 385 the first zoom operation and calling this method. If no zoom operation has been
371 386 done, this method does nothing.
372 387 */
373 388 void QChart::zoomReset()
374 389 {
375 390 d_ptr->zoomReset();
376 391 }
377 392
378 393 /*!
379 394 Returns true if any series has a zoomed domain.
380 395 */
381 396 bool QChart::isZoomed()
382 397 {
383 398 return d_ptr->isZoomed();
384 399 }
385 400
386 401 /*!
387 402 Returns a pointer to the horizontal axis attached to the specified \a series.
388 403 If no \a series is specified, the first horizontal axis added to the chart is returned.
389 404
390 405 \sa addAxis(), QAbstractSeries::attachAxis()
391 406 */
392 407 QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
393 408 {
394 409 QList<QAbstractAxis *> axisList = axes(Qt::Horizontal, series);
395 410 if (axisList.count())
396 411 return axisList[0];
397 412 return 0;
398 413 }
399 414
400 415 /*!
401 416 Returns a pointer to the vertical axis attached to the specified \a series.
402 417 If no \a series is specified, the first vertical axis added to the chart is returned.
403 418
404 419 \sa addAxis(), QAbstractSeries::attachAxis()
405 420 */
406 421 QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
407 422 {
408 423 QList<QAbstractAxis *> axisList = axes(Qt::Vertical, series);
409 424 if (axisList.count())
410 425 return axisList[0];
411 426 return 0;
412 427 }
413 428
414 429 /*!
415 430 Returns the axes attached to the \a series with \a orientation. If no \a series is provided,
416 431 then all axes added to the chart with the specified orientation are returned.
417 432 \sa addAxis(), createDefaultAxes()
418 433 */
419 434 QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
420 435 {
421 436 QList<QAbstractAxis *> result ;
422 437
423 438 if (series) {
424 439 foreach (QAbstractAxis *axis, series->attachedAxes()){
425 440 if (orientation.testFlag(axis->orientation()))
426 441 result << axis;
427 442 }
428 443 } else {
429 444 foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){
430 445 if (orientation.testFlag(axis->orientation()) && !result.contains(axis))
431 446 result << axis;
432 447 }
433 448 }
434 449
435 450 return result;
436 451 }
437 452
438 453 /*!
439 454 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
440 455 the chart will be deleted.
441 456
442 457 \note This function has to be called after all series have been added to the chart. The axes created by this function
443 458 will NOT get automatically attached to any series added to the chart after this function has been called.
444 459 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
445 460 if there are other series with properly attached axes also present.
446 461
447 462 \table
448 463 \header
449 464 \li Series type
450 465 \li X-axis
451 466 \li Y-axis
452 467 \row
453 468 \li QXYSeries
454 469 \li QValueAxis
455 470 \li QValueAxis
456 471 \row
457 472 \li QBarSeries
458 473 \li QBarCategoryAxis
459 474 \li QValueAxis
460 475 \row
461 476 \li QPieSeries
462 477 \li None
463 478 \li None
464 479 \endtable
465 480
466 481 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.
467 482 If there are several series of different types added to the chart, then each series gets its own axes pair.
468 483
469 484 The axes specific to the series can be later obtained from the chart by providing the series as the parameter for axes() function call.
470 485 QPieSeries does not create any axes.
471 486
472 487 \sa axisX(), axisY(), axes(), setAxisX(), setAxisY(), QAbstractSeries::attachAxis()
473 488 */
474 489 void QChart::createDefaultAxes()
475 490 {
476 491 d_ptr->m_dataset->createDefaultAxes();
477 492 }
478 493
479 494 /*!
480 495 Returns the legend object of the chart. Ownership stays with the chart.
481 496 */
482 497 QLegend *QChart::legend() const
483 498 {
484 499 return d_ptr->m_legend;
485 500 }
486 501
487 502 void QChart::setMinimumMargins(const QMargins &margins)
488 503 {
489 504 qWarning() << "QChart::setMinimumMargins is deprecated. Use QChart::setMargins instead.";
490 505 d_ptr->m_presenter->layout()->setMargins(margins);
491 506 }
492 507
493 508 QMargins QChart::minimumMargins() const
494 509 {
495 510 qWarning() << "QChart::minimumMargins is deprecated. Use QChart::margins instead.";
496 511 return d_ptr->m_presenter->layout()->margins();
497 512 }
498 513
499 514 void QChart::setMargins(const QMargins &margins)
500 515 {
501 516 d_ptr->m_presenter->layout()->setMargins(margins);
502 517 }
503 518
504 519 QMargins QChart::margins() const
505 520 {
506 521 return d_ptr->m_presenter->layout()->margins();
507 522 }
508 523
509 524 QChart::ChartType QChart::chartType() const
510 525 {
511 526 return d_ptr->m_type;
512 527 }
513 528
514 529 /*!
515 530 Returns the the rectangle within which the drawing of the chart is done.
516 531 It does not include the area defined by margins.
517 532 */
518 533 QRectF QChart::plotArea() const
519 534 {
520 535 return d_ptr->m_presenter->geometry();
521 536 }
522 537
523 538 /*!
524 539 Sets the \a brush for the background of the plot area of the chart.
525 540
526 541 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
527 542 */
528 543 void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
529 544 {
530 545 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
531 546 }
532 547
533 548 /*!
534 549 Returns the brush for the background of the plot area of the chart.
535 550
536 551 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
537 552 */
538 553 QBrush QChart::plotAreaBackgroundBrush() const
539 554 {
540 555 return d_ptr->m_presenter->plotAreaBackgroundBrush();
541 556 }
542 557
543 558 /*!
544 559 Sets the \a pen for the background of the plot area of the chart.
545 560
546 561 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
547 562 */
548 563 void QChart::setPlotAreaBackgroundPen(const QPen &pen)
549 564 {
550 565 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
551 566 }
552 567
553 568 /*!
554 569 Returns the pen for the background of the plot area of the chart.
555 570
556 571 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
557 572 */
558 573 QPen QChart::plotAreaBackgroundPen() const
559 574 {
560 575 return d_ptr->m_presenter->plotAreaBackgroundPen();
561 576 }
562 577
563 578 void QChart::setPlotAreaBackgroundVisible(bool visible)
564 579 {
565 580 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
566 581 }
567 582
568 583 bool QChart::isPlotAreaBackgroundVisible() const
569 584 {
570 585 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
571 586 }
572 587
573 588 void QChart::setLocalizeNumbers(bool localize)
574 589 {
575 590 d_ptr->m_presenter->setLocalizeNumbers(localize);
576 591 }
577 592
578 593 bool QChart::localizeNumbers() const
579 594 {
580 595 return d_ptr->m_presenter->localizeNumbers();
581 596 }
582 597
598 void QChart::setLocale(const QLocale &locale)
599 {
600 d_ptr->m_presenter->setLocale(locale);
601 }
602
603 QLocale QChart::locale() const
604 {
605 return d_ptr->m_presenter->locale();
606 }
607
583 608 void QChart::setAnimationOptions(AnimationOptions options)
584 609 {
585 610 d_ptr->m_presenter->setAnimationOptions(options);
586 611 }
587 612
588 613 QChart::AnimationOptions QChart::animationOptions() const
589 614 {
590 615 return d_ptr->m_presenter->animationOptions();
591 616 }
592 617
593 618 /*!
594 619 Scrolls the visible area of the chart by the distance defined in the \a dx and \a dy.
595 620
596 621 For polar charts, \a dx indicates the angle along angular axis instead of distance.
597 622 */
598 623 void QChart::scroll(qreal dx, qreal dy)
599 624 {
600 625 d_ptr->scroll(dx,dy);
601 626 }
602 627
603 628 void QChart::setBackgroundVisible(bool visible)
604 629 {
605 630 d_ptr->m_presenter->setBackgroundVisible(visible);
606 631 }
607 632
608 633 bool QChart::isBackgroundVisible() const
609 634 {
610 635 return d_ptr->m_presenter->isBackgroundVisible();
611 636 }
612 637
613 638 void QChart::setDropShadowEnabled(bool enabled)
614 639 {
615 640 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
616 641 }
617 642
618 643 bool QChart::isDropShadowEnabled() const
619 644 {
620 645 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
621 646 }
622 647
623 648 void QChart::setBackgroundRoundness(qreal diameter)
624 649 {
625 650 d_ptr->m_presenter->setBackgroundRoundness(diameter);
626 651 }
627 652
628 653 qreal QChart::backgroundRoundness() const
629 654 {
630 655 return d_ptr->m_presenter->backgroundRoundness();
631 656 }
632 657
633 658 /*!
634 659 Returns all series that are added to the chart.
635 660
636 661 \sa addSeries(), removeSeries(), removeAllSeries()
637 662 */
638 663 QList<QAbstractSeries *> QChart::series() const
639 664 {
640 665 return d_ptr->m_dataset->series();
641 666 }
642 667
643 668 /*!
644 669 Adds the \a axis to the chart and attaches it to the \a series as a bottom-aligned horizontal axis.
645 670 The chart takes ownership of both the \a axis and the \a series.
646 671 Any horizontal axes previously attached to the \a series are deleted.
647 672
648 673 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
649 674 */
650 675 void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
651 676 {
652 677 QList<QAbstractAxis*> list = axes(Qt::Horizontal, series);
653 678
654 679 foreach (QAbstractAxis* a, list) {
655 680 d_ptr->m_dataset->removeAxis(a);
656 681 delete a;
657 682 }
658 683
659 684 if (!d_ptr->m_dataset->axes().contains(axis))
660 685 d_ptr->m_dataset->addAxis(axis, Qt::AlignBottom);
661 686 d_ptr->m_dataset->attachAxis(series, axis);
662 687 }
663 688
664 689 /*!
665 690 Adds the \a axis to the chart and attaches it to the \a series as a left-aligned vertical axis.
666 691 The chart takes ownership of both the \a axis and the \a series.
667 692 Any vertical axes previously attached to the \a series are deleted.
668 693
669 694 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
670 695 */
671 696 void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
672 697 {
673 698 QList<QAbstractAxis*> list = axes(Qt::Vertical, series);
674 699
675 700 foreach (QAbstractAxis* a, list) {
676 701 d_ptr->m_dataset->removeAxis(a);
677 702 delete a;
678 703 }
679 704
680 705 if (!d_ptr->m_dataset->axes().contains(axis))
681 706 d_ptr->m_dataset->addAxis(axis, Qt::AlignLeft);
682 707 d_ptr->m_dataset->attachAxis(series, axis);
683 708 }
684 709
685 710 /*!
686 711 Adds the \a axis to the chart with \a alignment. The chart takes the ownership of the axis.
687 712
688 713 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
689 714 */
690 715 void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
691 716 {
692 717 d_ptr->m_dataset->addAxis(axis, alignment);
693 718 }
694 719
695 720 /*!
696 721 Removes the \a axis from the chart.
697 722 The chart releases its ownership of the specified \a axis object.
698 723
699 724 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
700 725 */
701 726 void QChart::removeAxis(QAbstractAxis *axis)
702 727 {
703 728 d_ptr->m_dataset->removeAxis(axis);
704 729 }
705 730
706 731 /*!
707 732 Returns the value in the \a series domain that corresponds to the \a position relative to chart widget.
708 733 */
709 734 QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
710 735 {
711 736 return d_ptr->m_dataset->mapToValue(position, series);
712 737 }
713 738
714 739 /*!
715 740 Returns the position on the chart widget that corresponds to the \a value in the \a series domain.
716 741 */
717 742 QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
718 743 {
719 744 return d_ptr->m_dataset->mapToPosition(value, series);
720 745 }
721 746
722 747 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
723 748
724 749 QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
725 750 q_ptr(q),
726 751 m_legend(0),
727 752 m_dataset(new ChartDataSet(q)),
728 753 m_presenter(new ChartPresenter(q, type)),
729 754 m_themeManager(new ChartThemeManager(q)),
730 755 m_type(type)
731 756 {
732 757 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
733 758 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
734 759 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
735 760 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
736 761 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
737 762 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
738 763 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
739 764 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
740 765 }
741 766
742 767 QChartPrivate::~QChartPrivate()
743 768 {
744 769 }
745 770
746 771 // Hackish solution to the problem of explicitly assigning the default pen/brush/font
747 772 // to a series or axis and having theme override it:
748 773 // Initialize pens, brushes, and fonts to something nobody is likely to ever use,
749 774 // so that default theme initialization will always set these properly.
750 775 QPen &QChartPrivate::defaultPen()
751 776 {
752 777 static QPen defaultPen(QColor(1, 2, 0), 0.93247536);
753 778 return defaultPen;
754 779 }
755 780
756 781 QBrush &QChartPrivate::defaultBrush()
757 782 {
758 783 static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern);
759 784 return defaultBrush;
760 785 }
761 786
762 787 QFont &QChartPrivate::defaultFont()
763 788 {
764 789 static bool defaultFontInitialized(false);
765 790 static QFont defaultFont;
766 791 if (!defaultFontInitialized) {
767 792 defaultFont.setPointSizeF(8.34563465);
768 793 defaultFontInitialized = true;
769 794 }
770 795 return defaultFont;
771 796 }
772 797
773 798 void QChartPrivate::init()
774 799 {
775 800 m_legend = new LegendScroller(q_ptr);
776 801 q_ptr->setTheme(QChart::ChartThemeLight);
777 802 q_ptr->setLayout(m_presenter->layout());
778 803 }
779 804
780 805 void QChartPrivate::zoomIn(qreal factor)
781 806 {
782 807 QRectF rect = m_presenter->geometry();
783 808 rect.setWidth(rect.width() / factor);
784 809 rect.setHeight(rect.height() / factor);
785 810 rect.moveCenter(m_presenter->geometry().center());
786 811 zoomIn(rect);
787 812 }
788 813
789 814 void QChartPrivate::zoomIn(const QRectF &rect)
790 815 {
791 816 if (!rect.isValid())
792 817 return;
793 818
794 819 QRectF r = rect.normalized();
795 820 const QRectF geometry = m_presenter->geometry();
796 821 r.translate(-geometry.topLeft());
797 822
798 823 if (!r.isValid())
799 824 return;
800 825
801 826 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
802 827 m_presenter->setState(ChartPresenter::ZoomInState,zoomPoint);
803 828 m_dataset->zoomInDomain(r);
804 829 m_presenter->setState(ChartPresenter::ShowState,QPointF());
805 830
806 831 }
807 832
808 833 void QChartPrivate::zoomReset()
809 834 {
810 835 m_dataset->zoomResetDomain();
811 836 }
812 837
813 838 bool QChartPrivate::isZoomed()
814 839 {
815 840 return m_dataset->isZoomedDomain();
816 841 }
817 842
818 843 void QChartPrivate::zoomOut(qreal factor)
819 844 {
820 845 const QRectF geometry = m_presenter->geometry();
821 846
822 847 QRectF r;
823 848 r.setSize(geometry.size() / factor);
824 849 r.moveCenter(QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
825 850 if (!r.isValid())
826 851 return;
827 852
828 853 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
829 854 m_presenter->setState(ChartPresenter::ZoomOutState,zoomPoint);
830 855 m_dataset->zoomOutDomain(r);
831 856 m_presenter->setState(ChartPresenter::ShowState,QPointF());
832 857 }
833 858
834 859 void QChartPrivate::scroll(qreal dx, qreal dy)
835 860 {
836 861 if (dx < 0) m_presenter->setState(ChartPresenter::ScrollLeftState,QPointF());
837 862 if (dx > 0) m_presenter->setState(ChartPresenter::ScrollRightState,QPointF());
838 863 if (dy < 0) m_presenter->setState(ChartPresenter::ScrollUpState,QPointF());
839 864 if (dy > 0) m_presenter->setState(ChartPresenter::ScrollDownState,QPointF());
840 865
841 866 m_dataset->scrollDomain(dx, dy);
842 867 m_presenter->setState(ChartPresenter::ShowState,QPointF());
843 868 }
844 869
845 870 #include "moc_qchart.cpp"
846 871
847 872 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,180 +1,183
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 52 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers)
53 Q_PROPERTY(QLocale locale READ locale WRITE setLocale)
53 54 Q_ENUMS(ChartTheme)
54 55 Q_ENUMS(AnimationOption)
55 56 Q_ENUMS(ChartType)
56 57
57 58 public:
58 59 enum ChartType {
59 60 ChartTypeUndefined = 0,
60 61 ChartTypeCartesian,
61 62 ChartTypePolar
62 63 };
63 64
64 65 enum ChartTheme {
65 66 ChartThemeLight = 0,
66 67 ChartThemeBlueCerulean,
67 68 ChartThemeDark,
68 69 ChartThemeBrownSand,
69 70 ChartThemeBlueNcs,
70 71 ChartThemeHighContrast,
71 72 ChartThemeBlueIcy,
72 73 ChartThemeQt
73 74 };
74 75
75 76 enum AnimationOption {
76 77 NoAnimation = 0x0,
77 78 GridAxisAnimations = 0x1,
78 79 SeriesAnimations = 0x2,
79 80 AllAnimations = 0x3
80 81 };
81 82
82 83 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
83 84
84 85 public:
85 86 explicit QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
86 87 ~QChart();
87 88
88 89 void addSeries(QAbstractSeries *series);
89 90 void removeSeries(QAbstractSeries *series);
90 91 void removeAllSeries();
91 92 QList<QAbstractSeries *> series() const;
92 93
93 94 // *** deprecated ***
94 95 void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
95 96 void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
96 97 QAbstractAxis *axisX(QAbstractSeries *series = 0) const;
97 98 QAbstractAxis *axisY(QAbstractSeries *series = 0) const;
98 99 // ******************
99 100
100 101 void addAxis(QAbstractAxis *axis, Qt::Alignment alignment);
101 102 void removeAxis(QAbstractAxis *axis);
102 103 QList<QAbstractAxis*> axes(Qt::Orientations orientation = Qt::Horizontal|Qt::Vertical, QAbstractSeries *series = 0) const;
103 104
104 105 void createDefaultAxes();
105 106
106 107 void setTheme(QChart::ChartTheme theme);
107 108 QChart::ChartTheme theme() const;
108 109
109 110 void setTitle(const QString &title);
110 111 QString title() const;
111 112 void setTitleFont(const QFont &font);
112 113 QFont titleFont() const;
113 114 void setTitleBrush(const QBrush &brush);
114 115 QBrush titleBrush() const;
115 116
116 117 void setBackgroundBrush(const QBrush &brush);
117 118 QBrush backgroundBrush() const;
118 119 void setBackgroundPen(const QPen &pen);
119 120 QPen backgroundPen() const;
120 121 void setBackgroundVisible(bool visible = true);
121 122 bool isBackgroundVisible() const;
122 123
123 124 void setDropShadowEnabled(bool enabled = true);
124 125 bool isDropShadowEnabled() const;
125 126 void setBackgroundRoundness(qreal diameter);
126 127 qreal backgroundRoundness() const;
127 128 void setAnimationOptions(AnimationOptions options);
128 129 AnimationOptions animationOptions() const;
129 130
130 131 void zoomIn();
131 132 void zoomOut();
132 133
133 134 void zoomIn(const QRectF &rect);
134 135 void zoom(qreal factor);
135 136 void zoomReset();
136 137 bool isZoomed();
137 138
138 139 void scroll(qreal dx, qreal dy);
139 140
140 141 QLegend *legend() const;
141 142
142 143 void setMinimumMargins(const QMargins& margins);
143 144 QMargins minimumMargins() const;
144 145
145 146 void setMargins(const QMargins &margins);
146 147 QMargins margins() const;
147 148
148 149 QRectF plotArea() const;
149 150 void setPlotAreaBackgroundBrush(const QBrush &brush);
150 151 QBrush plotAreaBackgroundBrush() const;
151 152 void setPlotAreaBackgroundPen(const QPen &pen);
152 153 QPen plotAreaBackgroundPen() const;
153 154 void setPlotAreaBackgroundVisible(bool visible = true);
154 155 bool isPlotAreaBackgroundVisible() const;
155 156 void setLocalizeNumbers(bool localize);
156 157 bool localizeNumbers() const;
158 void setLocale(const QLocale &locale);
159 QLocale locale() const;
157 160
158 161 QPointF mapToValue(const QPointF &position, QAbstractSeries *series = 0);
159 162 QPointF mapToPosition(const QPointF &value, QAbstractSeries *series = 0);
160 163
161 164 ChartType chartType() const;
162 165
163 166 protected:
164 167 explicit QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags);
165 168 QScopedPointer<QChartPrivate> d_ptr;
166 169 friend class QLegend;
167 170 friend class DeclarativeChart;
168 171 friend class ChartDataSet;
169 172 friend class ChartPresenter;
170 173 friend class ChartThemeManager;
171 174 friend class QAbstractSeries;
172 175 friend class QBoxPlotSeriesPrivate;
173 176 Q_DISABLE_COPY(QChart)
174 177 };
175 178
176 179 QTCOMMERCIALCHART_END_NAMESPACE
177 180
178 181 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
179 182
180 183 #endif // QCHART_H
General Comments 0
You need to be logged in to leave comments. Login now