| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2017 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the Qt Charts module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 or (at your option) any later version | 
| 20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by | 
| 21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 | 
| 22 | ** included in the packaging of this file. Please review the following | 
| 23 | ** information to ensure the GNU General Public License requirements will | 
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 25 | ** | 
| 26 | ** $QT_END_LICENSE$ | 
| 27 | ** | 
| 28 | ****************************************************************************/ | 
| 29 |  | 
| 30 | #include <QtCharts/QChart> | 
| 31 | #include <private/qchart_p.h> | 
| 32 | #include <private/legendscroller_p.h> | 
| 33 | #include <private/qlegend_p.h> | 
| 34 | #include <private/chartbackground_p.h> | 
| 35 | #include <QtCharts/QAbstractAxis> | 
| 36 | #include <private/abstractchartlayout_p.h> | 
| 37 | #include <private/charttheme_p.h> | 
| 38 | #include <private/chartpresenter_p.h> | 
| 39 | #include <private/chartdataset_p.h> | 
| 40 | #include <QtWidgets/QGraphicsScene> | 
| 41 | #include <QGraphicsSceneResizeEvent> | 
| 42 |  | 
| 43 | QT_CHARTS_BEGIN_NAMESPACE | 
| 44 |  | 
| 45 | /*! | 
| 46 |  \enum QChart::ChartTheme | 
| 47 |  | 
| 48 |  This enum describes the theme used by the chart. | 
| 49 |  | 
| 50 |  A theme is a built-in collection of UI style related settings applied to all | 
| 51 |  the visual elements of a chart, such as colors, pens, brushes, and fonts of | 
| 52 |  series, as well as axes, title, and legend. The \l {Chart themes example} | 
| 53 |  illustrates how to use themes. | 
| 54 |  | 
| 55 |  \note Changing the theme will overwrite all customizations previously applied | 
| 56 |  to the series. | 
| 57 |  | 
| 58 |  \value ChartThemeLight | 
| 59 |         The light theme, which is the default theme. | 
| 60 |  \value ChartThemeBlueCerulean | 
| 61 |         The cerulean blue theme. | 
| 62 |  \value ChartThemeDark | 
| 63 |         The dark theme. | 
| 64 |  \value ChartThemeBrownSand | 
| 65 |         The sand brown theme. | 
| 66 |  \value ChartThemeBlueNcs | 
| 67 |         The natural color system (NCS) blue theme. | 
| 68 |  \value ChartThemeHighContrast | 
| 69 |         The high contrast theme. | 
| 70 |  \value ChartThemeBlueIcy | 
| 71 |         The icy blue theme. | 
| 72 |  \value ChartThemeQt | 
| 73 |         The Qt theme. | 
| 74 |  */ | 
| 75 |  | 
| 76 | /*! | 
| 77 |  \enum QChart::AnimationOption | 
| 78 |  | 
| 79 |  This enum describes the animations enabled in the chart. | 
| 80 |  | 
| 81 |  \value NoAnimation | 
| 82 |         Animation is disabled in the chart. This is the default value. | 
| 83 |  \value GridAxisAnimations | 
| 84 |         Grid axis animation is enabled in the chart. | 
| 85 |  \value SeriesAnimations | 
| 86 |         Series animation is enabled in the chart. | 
| 87 |  \value AllAnimations | 
| 88 |         All animation types are enabled in the chart. | 
| 89 |  */ | 
| 90 |  | 
| 91 | /*! | 
| 92 |  \enum QChart::ChartType | 
| 93 |  | 
| 94 |  This enum describes the chart type. | 
| 95 |  | 
| 96 |  \value ChartTypeUndefined | 
| 97 |         The chart type is not defined. | 
| 98 |  \value ChartTypeCartesian | 
| 99 |         A cartesian chart. | 
| 100 |  \value ChartTypePolar | 
| 101 |         A polar chart. | 
| 102 |  */ | 
| 103 |  | 
| 104 | /*! | 
| 105 |  \class QChart | 
| 106 |  \inmodule QtCharts | 
| 107 |  \brief The QChart class manages the graphical representation of the chart's | 
| 108 |  series, legends, and axes. | 
| 109 |  | 
| 110 |  QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical | 
| 111 |  representation of different types of series and other chart related objects like legend and | 
| 112 |  axes. To simply show a chart in a layout, the convenience class QChartView can be used | 
| 113 |  instead of QChart. In addition, line, spline, area, and scatter series can be presented as | 
| 114 |  polar charts by using the QPolarChart class. | 
| 115 |  | 
| 116 |  \sa QChartView, QPolarChart | 
| 117 |  */ | 
| 118 |  | 
| 119 | /*! | 
| 120 |  \property QChart::animationOptions | 
| 121 |  \brief The animation options for the chart. | 
| 122 |  | 
| 123 |  Animations are enabled or disabled based on this setting. | 
| 124 |  */ | 
| 125 |  | 
| 126 | /*! | 
| 127 |  \property QChart::animationDuration | 
| 128 |  \brief The duration of the animation for the chart. | 
| 129 |  */ | 
| 130 |  | 
| 131 | /*! | 
| 132 |  \property QChart::animationEasingCurve | 
| 133 |  \brief The easing curve of the animation for the chart. | 
| 134 |  */ | 
| 135 |  | 
| 136 | /*! | 
| 137 |  \property QChart::backgroundVisible | 
| 138 |  \brief Whether the chart background is visible. | 
| 139 |  \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible | 
| 140 |  */ | 
| 141 |  | 
| 142 | /*! | 
| 143 |  \property QChart::dropShadowEnabled | 
| 144 |  \brief Whether the background drop shadow effect is enabled. | 
| 145 |  | 
| 146 |  If set to \c true, the background drop shadow effect is enabled. If set to \c false, it | 
| 147 |  is disabled. | 
| 148 |  | 
| 149 |  \note The drop shadow effect depends on the theme, and therefore the setting may | 
| 150 |  change if the theme is changed. | 
| 151 |  */ | 
| 152 |  | 
| 153 | /*! | 
| 154 |  \property QChart::backgroundRoundness | 
| 155 |  \brief The diameter of the rounding circle at the corners of the chart background. | 
| 156 |  */ | 
| 157 |  | 
| 158 | /*! | 
| 159 |  \property QChart::margins | 
| 160 |  \brief The minimum margins allowed between the edge of the chart rectangle and | 
| 161 |  the plot area. | 
| 162 |  | 
| 163 |  The margins are used for drawing the title, axes, and legend. | 
| 164 |  */ | 
| 165 |  | 
| 166 | /*! | 
| 167 |  \property QChart::theme | 
| 168 |  \brief The theme used for the chart. | 
| 169 |  */ | 
| 170 |  | 
| 171 | /*! | 
| 172 |  \property QChart::title | 
| 173 |  \brief The title of the chart. | 
| 174 |  | 
| 175 |  The title is shown as a headline on top of the chart. Chart titles support HTML formatting. | 
| 176 |  */ | 
| 177 |  | 
| 178 | /*! | 
| 179 |  \property QChart::chartType | 
| 180 |  \brief Whether the chart is a cartesian chart or a polar chart. | 
| 181 |  | 
| 182 |  This property is set internally and it is read only. | 
| 183 |  \sa QPolarChart | 
| 184 |  */ | 
| 185 |  | 
| 186 | /*! | 
| 187 |  \property QChart::plotAreaBackgroundVisible | 
| 188 |  \brief Whether the chart plot area background is visible. | 
| 189 |  | 
| 190 |  \note By default, the plot area background is invisible and the plot area uses | 
| 191 |  the general chart background. | 
| 192 |  \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible | 
| 193 |  */ | 
| 194 |  | 
| 195 | /*! | 
| 196 |   \property QChart::localizeNumbers | 
| 197 |   \brief Whether numbers are localized. | 
| 198 |  | 
| 199 |   When \c{true}, all generated numbers appearing in various series and axis labels will be | 
| 200 |   localized using the QLocale set with the \l locale property. | 
| 201 |   When \c{false}, the \e C locale is always used. | 
| 202 |   Defaults to \c{false}. | 
| 203 |  | 
| 204 |   \note This property does not affect QDateTimeAxis labels, which always use the QLocale set with | 
| 205 |   the locale property. | 
| 206 |  | 
| 207 |   \sa locale | 
| 208 | */ | 
| 209 |  | 
| 210 | /*! | 
| 211 |   \property QChart::locale | 
| 212 |   \brief The locale used to format various chart labels. | 
| 213 |  | 
| 214 |   Labels are localized only when \l localizeNumbers is \c true, except for QDateTimeAxis | 
| 215 |   labels, which always use the QLocale set with this property. | 
| 216 |  | 
| 217 |   Defaults to the application default locale at the time when the chart is constructed. | 
| 218 |  | 
| 219 |   \sa localizeNumbers | 
| 220 | */ | 
| 221 |  | 
| 222 | /*! | 
| 223 |   \property QChart::plotArea | 
| 224 |   \brief The rectangle within which the chart is drawn. | 
| 225 |  | 
| 226 |   The plot area does not include the area defined by margins. By default this will resize if inside | 
| 227 |   a QChartView. If an explicit size is set for the plot area then it will respect this, to revert | 
| 228 |   back to the default behavior, then calling \c{setPlotArea(QRectF());} will achieve this. | 
| 229 | */ | 
| 230 |  | 
| 231 | /*! | 
| 232 |  \internal | 
| 233 |  Constructs a chart object of \a type that is a child of \a parent. | 
| 234 |  The properties specified by \a wFlags are passed to the QGraphicsWidget constructor. | 
| 235 |  This constructor is called only by subclasses. | 
| 236 | */ | 
| 237 | QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags) | 
| 238 |     : QGraphicsWidget(parent, wFlags), | 
| 239 |       d_ptr(new QChartPrivate(this, type)) | 
| 240 | { | 
| 241 |     d_ptr->init(); | 
| 242 | } | 
| 243 |  | 
| 244 | /*! | 
| 245 |  Constructs a chart object that is a child of \a parent. | 
| 246 |  The properties specified by \a wFlags are passed to the QGraphicsWidget constructor. | 
| 247 |  */ | 
| 248 | QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) | 
| 249 |     : QGraphicsWidget(parent, wFlags), | 
| 250 |       d_ptr(new QChartPrivate(this, ChartTypeCartesian)) | 
| 251 | { | 
| 252 |     d_ptr->init(); | 
| 253 | } | 
| 254 |  | 
| 255 | /*! | 
| 256 |  Deletes the chart object and its children, such as the series and axis objects added to it. | 
| 257 |  */ | 
| 258 | QChart::~QChart() | 
| 259 | { | 
| 260 |     //start by deleting dataset, it will remove all series and axes | 
| 261 |     delete d_ptr->m_dataset; | 
| 262 |     d_ptr->m_dataset = 0; | 
| 263 | } | 
| 264 |  | 
| 265 | /*! | 
| 266 |  Adds the series \a series to the chart and takes ownership of it. | 
| 267 |  | 
| 268 |  \note A newly added series is not attached to any axes by default, not even those that | 
| 269 |  might have been created for the chart | 
| 270 |  using createDefaultAxes() before the series was added to the chart. If no axes are attached to | 
| 271 |  the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges | 
| 272 |  that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other | 
| 273 |  series that have properly attached axes, so always make sure you either call createDefaultAxes() after | 
| 274 |  a series has been added or explicitly attach axes for the series. | 
| 275 |  | 
| 276 |  \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis() | 
| 277 |  */ | 
| 278 | void QChart::addSeries(QAbstractSeries *series) | 
| 279 | { | 
| 280 |     Q_ASSERT(series); | 
| 281 |     d_ptr->m_dataset->addSeries(series); | 
| 282 | } | 
| 283 |  | 
| 284 | /*! | 
| 285 |  Removes the series \a series from the chart. | 
| 286 |  The chart releases the ownership of the specified \a series object. | 
| 287 |  | 
| 288 |  \sa addSeries(), removeAllSeries() | 
| 289 |  */ | 
| 290 | void QChart::removeSeries(QAbstractSeries *series) | 
| 291 | { | 
| 292 |     Q_ASSERT(series); | 
| 293 |     d_ptr->m_dataset->removeSeries(series); | 
| 294 | } | 
| 295 |  | 
| 296 | /*! | 
| 297 |  Removes and deletes all series objects that have been added to the chart. | 
| 298 |  | 
| 299 |  \sa addSeries(), removeSeries() | 
| 300 |  */ | 
| 301 | void QChart::removeAllSeries() | 
| 302 | { | 
| 303 |     foreach (QAbstractSeries *s ,  d_ptr->m_dataset->series()){ | 
| 304 |         removeSeries(series: s); | 
| 305 |         delete s; | 
| 306 |     } | 
| 307 | } | 
| 308 |  | 
| 309 | /*! | 
| 310 |  Sets the brush that is used for painting the background of the chart area to \a brush. | 
| 311 |  */ | 
| 312 | void QChart::setBackgroundBrush(const QBrush &brush) | 
| 313 | { | 
| 314 |     d_ptr->m_presenter->setBackgroundBrush(brush); | 
| 315 | } | 
| 316 |  | 
| 317 | /*! | 
| 318 |  Gets the brush that is used for painting the background of the chart area. | 
| 319 |  */ | 
| 320 | QBrush QChart::backgroundBrush() const | 
| 321 | { | 
| 322 |     return d_ptr->m_presenter->backgroundBrush(); | 
| 323 | } | 
| 324 |  | 
| 325 | /*! | 
| 326 |  Sets the pen that is used for painting the background of the chart area to \a pen. | 
| 327 |  */ | 
| 328 | void QChart::setBackgroundPen(const QPen &pen) | 
| 329 | { | 
| 330 |     d_ptr->m_presenter->setBackgroundPen(pen); | 
| 331 | } | 
| 332 |  | 
| 333 | /*! | 
| 334 |  Gets the pen that is used for painting the background of the chart area. | 
| 335 |  */ | 
| 336 | QPen QChart::backgroundPen() const | 
| 337 | { | 
| 338 |     return d_ptr->m_presenter->backgroundPen(); | 
| 339 | } | 
| 340 |  | 
| 341 | void QChart::setTitle(const QString &title) | 
| 342 | { | 
| 343 |     d_ptr->m_presenter->setTitle(title); | 
| 344 | } | 
| 345 |  | 
| 346 | QString QChart::title() const | 
| 347 | { | 
| 348 |     return d_ptr->m_presenter->title(); | 
| 349 | } | 
| 350 |  | 
| 351 | /*! | 
| 352 |  Sets the font that is used for drawing the chart title to \a font. | 
| 353 |  */ | 
| 354 | void QChart::setTitleFont(const QFont &font) | 
| 355 | { | 
| 356 |     d_ptr->m_presenter->setTitleFont(font); | 
| 357 | } | 
| 358 |  | 
| 359 | /*! | 
| 360 |  Gets the font that is used for drawing the chart title. | 
| 361 |  */ | 
| 362 | QFont QChart::titleFont() const | 
| 363 | { | 
| 364 |     return d_ptr->m_presenter->titleFont(); | 
| 365 | } | 
| 366 |  | 
| 367 | /*! | 
| 368 |  Sets the brush used for drawing the title text to \a brush. | 
| 369 |  */ | 
| 370 | void QChart::setTitleBrush(const QBrush &brush) | 
| 371 | { | 
| 372 |     d_ptr->m_presenter->setTitleBrush(brush); | 
| 373 | } | 
| 374 |  | 
| 375 | /*! | 
| 376 |  Returns the brush used for drawing the title text. | 
| 377 |  */ | 
| 378 | QBrush QChart::titleBrush() const | 
| 379 | { | 
| 380 |     return d_ptr->m_presenter->titleBrush(); | 
| 381 | } | 
| 382 |  | 
| 383 | void QChart::setTheme(QChart::ChartTheme theme) | 
| 384 | { | 
| 385 |     d_ptr->m_themeManager->setTheme(theme); | 
| 386 | } | 
| 387 |  | 
| 388 | QChart::ChartTheme QChart::theme() const | 
| 389 | { | 
| 390 |     return d_ptr->m_themeManager->theme()->id(); | 
| 391 | } | 
| 392 |  | 
| 393 | /*! | 
| 394 |  Zooms into the view by a factor of two. | 
| 395 |  */ | 
| 396 | void QChart::zoomIn() | 
| 397 | { | 
| 398 |     d_ptr->zoomIn(factor: 2.0); | 
| 399 | } | 
| 400 |  | 
| 401 | /*! | 
| 402 |  Zooms into the view to a maximum level at which the rectangle \a rect is still | 
| 403 |  fully visible. | 
| 404 |  \note Applying a zoom may modify properties of attached axes, for instance QAbstractAxis::min | 
| 405 |        and QAbstractAxis::max. | 
| 406 |  \note This is not supported for polar charts. | 
| 407 |  */ | 
| 408 | void QChart::zoomIn(const QRectF &rect) | 
| 409 | { | 
| 410 |     if (d_ptr->m_type == QChart::ChartTypePolar) | 
| 411 |         return; | 
| 412 |     d_ptr->zoomIn(rect); | 
| 413 | } | 
| 414 |  | 
| 415 | /*! | 
| 416 |  Zooms out of the view by a factor of two. | 
| 417 |  \note This will do nothing if the result would contain an invalid logarithmic axis range. | 
| 418 |  */ | 
| 419 | void QChart::zoomOut() | 
| 420 | { | 
| 421 |     d_ptr->zoomOut(factor: 2.0); | 
| 422 | } | 
| 423 |  | 
| 424 | /*! | 
| 425 |  Zooms into the view by the custom factor \a factor. | 
| 426 |  | 
| 427 |  A factor over 1.0 zooms into the view and a factor between 0.0 and 1.0 zooms | 
| 428 |  out of it. | 
| 429 |  */ | 
| 430 | void QChart::zoom(qreal factor) | 
| 431 | { | 
| 432 |     if (qFuzzyCompare(p1: factor, p2: 0)) | 
| 433 |         return; | 
| 434 |  | 
| 435 |     if (qFuzzyCompare(p1: factor, p2: (qreal)1.0)) | 
| 436 |         return; | 
| 437 |  | 
| 438 |     if (factor < 0) | 
| 439 |         return; | 
| 440 |  | 
| 441 |     if (factor > 1.0) | 
| 442 |         d_ptr->zoomIn(factor); | 
| 443 |     else | 
| 444 |         d_ptr->zoomOut(factor: 1.0 / factor); | 
| 445 | } | 
| 446 |  | 
| 447 |  | 
| 448 | /*! | 
| 449 |  Resets the series domains to what they were before any zoom method was called. | 
| 450 |  | 
| 451 |  \note This will also reset scrolling and explicit axis range settings specified between | 
| 452 |  the first zoom operation and calling this method. If no zoom operation has been | 
| 453 |  performed, this method does nothing. | 
| 454 |  */ | 
| 455 | void QChart::zoomReset() | 
| 456 | { | 
| 457 |     d_ptr->zoomReset(); | 
| 458 | } | 
| 459 |  | 
| 460 | /*! | 
| 461 |  Returns \c true if any series has a zoomed domain. | 
| 462 |  */ | 
| 463 | bool QChart::isZoomed() | 
| 464 | { | 
| 465 |    return d_ptr->isZoomed(); | 
| 466 | } | 
| 467 |  | 
| 468 | /*! | 
| 469 |  \deprecated | 
| 470 |  Use axes() instead. | 
| 471 |  | 
| 472 |  Returns a pointer to the horizontal axis attached to the specified \a series. | 
| 473 |  If no series is specified, the first horizontal axis added to the chart is returned. | 
| 474 |  | 
| 475 |  \sa addAxis(), QAbstractSeries::attachAxis() | 
| 476 |  */ | 
| 477 | QAbstractAxis *QChart::axisX(QAbstractSeries *series) const | 
| 478 | { | 
| 479 |     QList<QAbstractAxis *> axisList = axes(orientation: Qt::Horizontal, series); | 
| 480 |     if (axisList.count()) | 
| 481 |         return axisList[0]; | 
| 482 |     return 0; | 
| 483 | } | 
| 484 |  | 
| 485 | /*! | 
| 486 |  \deprecated | 
| 487 |  Use axes() instead. | 
| 488 |  | 
| 489 |  Returns a pointer to the vertical axis attached to the specified \a series. | 
| 490 |  If no series is specified, the first vertical axis added to the chart is returned. | 
| 491 |  | 
| 492 |  \sa addAxis(), QAbstractSeries::attachAxis() | 
| 493 |  */ | 
| 494 | QAbstractAxis *QChart::axisY(QAbstractSeries *series) const | 
| 495 | { | 
| 496 |     QList<QAbstractAxis *> axisList = axes(orientation: Qt::Vertical, series); | 
| 497 |     if (axisList.count()) | 
| 498 |         return axisList[0]; | 
| 499 |     return 0; | 
| 500 | } | 
| 501 |  | 
| 502 | /*! | 
| 503 |  Returns the axes attached to the series \a series with the orientation specified | 
| 504 |  by \a orientation. If no series is specified, all axes added to the chart with | 
| 505 |  the specified orientation are returned. | 
| 506 |  | 
| 507 |  \sa addAxis(), createDefaultAxes() | 
| 508 |  */ | 
| 509 | QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const | 
| 510 | { | 
| 511 |     QList<QAbstractAxis *> result ; | 
| 512 |  | 
| 513 |     if (series) { | 
| 514 |         foreach (QAbstractAxis *axis, series->attachedAxes()){ | 
| 515 |             if (orientation.testFlag(flag: axis->orientation())) | 
| 516 |                 result << axis; | 
| 517 |         } | 
| 518 |     } else { | 
| 519 |         foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){ | 
| 520 |             if (orientation.testFlag(flag: axis->orientation()) && !result.contains(t: axis)) | 
| 521 |                 result << axis; | 
| 522 |         } | 
| 523 |     } | 
| 524 |  | 
| 525 |     return result; | 
| 526 | } | 
| 527 |  | 
| 528 | /*! | 
| 529 |  Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to | 
| 530 |  the chart will be deleted. | 
| 531 |  | 
| 532 |  \note This function has to be called after all series have been added to the chart. The axes created by this function | 
| 533 |  will NOT get automatically attached to any series added to the chart after this function has been called. | 
| 534 |  A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing | 
| 535 |  if there are other series with properly attached axes also present. | 
| 536 |  | 
| 537 |  \table | 
| 538 |      \header | 
| 539 |          \li Series type | 
| 540 |          \li Horizontal axis (X) | 
| 541 |          \li Vertical axis (Y) | 
| 542 |      \row | 
| 543 |          \li QXYSeries | 
| 544 |          \li QValueAxis | 
| 545 |          \li QValueAxis | 
| 546 |      \row | 
| 547 |          \li QBarSeries | 
| 548 |          \li QBarCategoryAxis | 
| 549 |          \li QValueAxis | 
| 550 |      \row | 
| 551 |          \li QPieSeries | 
| 552 |          \li None | 
| 553 |          \li None | 
| 554 |  \endtable | 
| 555 |  | 
| 556 |  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. | 
| 557 |  If there are several series of different types added to the chart, then each series gets its own axes pair. | 
| 558 |  | 
| 559 |  The axes specific to the series can be later obtained from the chart by providing the series | 
| 560 |  as the parameter for the axes() function call. | 
| 561 |  QPieSeries does not create any axes. | 
| 562 |  | 
| 563 |  \sa axes(), QAbstractSeries::attachAxis() | 
| 564 |  */ | 
| 565 | void QChart::createDefaultAxes() | 
| 566 | { | 
| 567 |     d_ptr->m_dataset->createDefaultAxes(); | 
| 568 | } | 
| 569 |  | 
| 570 | /*! | 
| 571 |  Returns the legend object of the chart. Ownership stays with the chart. | 
| 572 |  */ | 
| 573 | QLegend *QChart::legend() const | 
| 574 | { | 
| 575 |     return d_ptr->m_legend; | 
| 576 | } | 
| 577 |  | 
| 578 | void QChart::setMargins(const QMargins &margins) | 
| 579 | { | 
| 580 |     d_ptr->m_presenter->layout()->setMargins(margins); | 
| 581 | } | 
| 582 |  | 
| 583 | QMargins QChart::margins() const | 
| 584 | { | 
| 585 |     return d_ptr->m_presenter->layout()->margins(); | 
| 586 | } | 
| 587 |  | 
| 588 | QChart::ChartType QChart::chartType() const | 
| 589 | { | 
| 590 |     return d_ptr->m_type; | 
| 591 | } | 
| 592 |  | 
| 593 | QRectF QChart::plotArea() const | 
| 594 | { | 
| 595 |     return d_ptr->m_presenter->geometry(); | 
| 596 | } | 
| 597 |  | 
| 598 | void QChart::setPlotArea(const QRectF &rect) | 
| 599 | { | 
| 600 |     d_ptr->m_presenter->setFixedGeometry(rect); | 
| 601 | } | 
| 602 |  | 
| 603 | /*! | 
| 604 |     Sets the brush used to fill the background of the plot area of the chart to \a brush. | 
| 605 |  | 
| 606 |     \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush() | 
| 607 |  */ | 
| 608 | void QChart::setPlotAreaBackgroundBrush(const QBrush &brush) | 
| 609 | { | 
| 610 |     d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush); | 
| 611 | } | 
| 612 |  | 
| 613 | /*! | 
| 614 |     Returns the brush used to fill the background of the plot area of the chart. | 
| 615 |  | 
| 616 |     \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush() | 
| 617 |  */ | 
| 618 | QBrush QChart::plotAreaBackgroundBrush() const | 
| 619 | { | 
| 620 |     return d_ptr->m_presenter->plotAreaBackgroundBrush(); | 
| 621 | } | 
| 622 |  | 
| 623 | /*! | 
| 624 |     Sets the pen used to draw the background of the plot area of the chart to \a pen. | 
| 625 |  | 
| 626 |     \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen() | 
| 627 |  */ | 
| 628 | void QChart::setPlotAreaBackgroundPen(const QPen &pen) | 
| 629 | { | 
| 630 |     d_ptr->m_presenter->setPlotAreaBackgroundPen(pen); | 
| 631 | } | 
| 632 |  | 
| 633 | /*! | 
| 634 |     Returns the pen used to draw the background of the plot area of the chart. | 
| 635 |  | 
| 636 |     \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen() | 
| 637 |  */ | 
| 638 | QPen QChart::plotAreaBackgroundPen() const | 
| 639 | { | 
| 640 |     return d_ptr->m_presenter->plotAreaBackgroundPen(); | 
| 641 | } | 
| 642 |  | 
| 643 | void QChart::setPlotAreaBackgroundVisible(bool visible) | 
| 644 | { | 
| 645 |     d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible); | 
| 646 | } | 
| 647 |  | 
| 648 | bool QChart::isPlotAreaBackgroundVisible() const | 
| 649 | { | 
| 650 |     return d_ptr->m_presenter->isPlotAreaBackgroundVisible(); | 
| 651 | } | 
| 652 |  | 
| 653 | void QChart::setLocalizeNumbers(bool localize) | 
| 654 | { | 
| 655 |     d_ptr->m_presenter->setLocalizeNumbers(localize); | 
| 656 | } | 
| 657 |  | 
| 658 | bool QChart::localizeNumbers() const | 
| 659 | { | 
| 660 |     return d_ptr->m_presenter->localizeNumbers(); | 
| 661 | } | 
| 662 |  | 
| 663 | void QChart::setLocale(const QLocale &locale) | 
| 664 | { | 
| 665 |     d_ptr->m_presenter->setLocale(locale); | 
| 666 | } | 
| 667 |  | 
| 668 | QLocale QChart::locale() const | 
| 669 | { | 
| 670 |     return d_ptr->m_presenter->locale(); | 
| 671 | } | 
| 672 |  | 
| 673 | void QChart::setAnimationOptions(AnimationOptions options) | 
| 674 | { | 
| 675 |     d_ptr->m_presenter->setAnimationOptions(options); | 
| 676 | } | 
| 677 |  | 
| 678 | QChart::AnimationOptions QChart::animationOptions() const | 
| 679 | { | 
| 680 |     return d_ptr->m_presenter->animationOptions(); | 
| 681 | } | 
| 682 |  | 
| 683 | void QChart::setAnimationDuration(int msecs) | 
| 684 | { | 
| 685 |     d_ptr->m_presenter->setAnimationDuration(msecs); | 
| 686 | } | 
| 687 |  | 
| 688 | int QChart::animationDuration() const | 
| 689 | { | 
| 690 |     return d_ptr->m_presenter->animationDuration(); | 
| 691 | } | 
| 692 |  | 
| 693 | void QChart::setAnimationEasingCurve(const QEasingCurve &curve) | 
| 694 | { | 
| 695 |     d_ptr->m_presenter->setAnimationEasingCurve(curve); | 
| 696 | } | 
| 697 |  | 
| 698 | QEasingCurve QChart::animationEasingCurve() const | 
| 699 | { | 
| 700 |     return d_ptr->m_presenter->animationEasingCurve(); | 
| 701 | } | 
| 702 |  | 
| 703 | /*! | 
| 704 |     Scrolls the visible area of the chart by the distance specified by \a dx and \a dy. | 
| 705 |  | 
| 706 |     For polar charts, \a dx indicates the angle along the angular axis instead of distance. | 
| 707 |  */ | 
| 708 | void QChart::scroll(qreal dx, qreal dy) | 
| 709 | { | 
| 710 |     d_ptr->scroll(dx,dy); | 
| 711 | } | 
| 712 |  | 
| 713 | void QChart::setBackgroundVisible(bool visible) | 
| 714 | { | 
| 715 |     d_ptr->m_presenter->setBackgroundVisible(visible); | 
| 716 | } | 
| 717 |  | 
| 718 | bool QChart::isBackgroundVisible() const | 
| 719 | { | 
| 720 |     return d_ptr->m_presenter->isBackgroundVisible(); | 
| 721 | } | 
| 722 |  | 
| 723 | void QChart::setDropShadowEnabled(bool enabled) | 
| 724 | { | 
| 725 |     d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled); | 
| 726 | } | 
| 727 |  | 
| 728 | bool QChart::isDropShadowEnabled() const | 
| 729 | { | 
| 730 |     return d_ptr->m_presenter->isBackgroundDropShadowEnabled(); | 
| 731 | } | 
| 732 |  | 
| 733 | void QChart::setBackgroundRoundness(qreal diameter) | 
| 734 | { | 
| 735 |     d_ptr->m_presenter->setBackgroundRoundness(diameter); | 
| 736 | } | 
| 737 |  | 
| 738 | qreal QChart::backgroundRoundness() const | 
| 739 | { | 
| 740 |     return d_ptr->m_presenter->backgroundRoundness(); | 
| 741 | } | 
| 742 |  | 
| 743 | /*! | 
| 744 |   Returns all series that are added to the chart. | 
| 745 |  | 
| 746 |   \sa addSeries(), removeSeries(), removeAllSeries() | 
| 747 | */ | 
| 748 | QList<QAbstractSeries *> QChart::series() const | 
| 749 | { | 
| 750 |     return d_ptr->m_dataset->series(); | 
| 751 | } | 
| 752 |  | 
| 753 | /*! | 
| 754 |   \deprecated | 
| 755 |   Use addAxis() instead. | 
| 756 |  | 
| 757 |   Adds the axis \a axis to the chart and attaches it to the series \a series as a | 
| 758 |   bottom-aligned horizontal axis. | 
| 759 |   The chart takes ownership of both the axis and the  series. | 
| 760 |   Any horizontal axes previously attached to the series are deleted. | 
| 761 |  | 
| 762 |   \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis() | 
| 763 | */ | 
| 764 | void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series) | 
| 765 | { | 
| 766 |     QList<QAbstractAxis*> list = axes(orientation: Qt::Horizontal, series); | 
| 767 |  | 
| 768 |     foreach (QAbstractAxis* a, list) { | 
| 769 |         d_ptr->m_dataset->removeAxis(axis: a); | 
| 770 |         delete a; | 
| 771 |     } | 
| 772 |  | 
| 773 |     if (!d_ptr->m_dataset->axes().contains(t: axis)) | 
| 774 |         d_ptr->m_dataset->addAxis(axis, aligment: Qt::AlignBottom); | 
| 775 |     d_ptr->m_dataset->attachAxis(series, axis); | 
| 776 | } | 
| 777 |  | 
| 778 | /*! | 
| 779 |   \deprecated | 
| 780 |   Use addAxis() instead. | 
| 781 |  | 
| 782 |   Adds the axis \a axis to the chart and attaches it to the series \a series as a | 
| 783 |   left-aligned vertical axis. | 
| 784 |   The chart takes ownership of both the axis and the series. | 
| 785 |   Any vertical axes previously attached to the series are deleted. | 
| 786 |  | 
| 787 |   \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis() | 
| 788 | */ | 
| 789 | void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series) | 
| 790 | { | 
| 791 |     QList<QAbstractAxis*> list = axes(orientation: Qt::Vertical, series); | 
| 792 |  | 
| 793 |     foreach (QAbstractAxis* a, list) { | 
| 794 |         d_ptr->m_dataset->removeAxis(axis: a); | 
| 795 |         delete a; | 
| 796 |     } | 
| 797 |  | 
| 798 |     if (!d_ptr->m_dataset->axes().contains(t: axis)) | 
| 799 |         d_ptr->m_dataset->addAxis(axis, aligment: Qt::AlignLeft); | 
| 800 |     d_ptr->m_dataset->attachAxis(series, axis); | 
| 801 | } | 
| 802 |  | 
| 803 | /*! | 
| 804 |   Adds the axis \a axis to the chart aligned as specified by \a alignment. | 
| 805 |   The chart takes the ownership of the axis. | 
| 806 |  | 
| 807 |   \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis() | 
| 808 | */ | 
| 809 | void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment) | 
| 810 | { | 
| 811 |     d_ptr->m_dataset->addAxis(axis, aligment: alignment); | 
| 812 | } | 
| 813 |  | 
| 814 | /*! | 
| 815 |   Removes the axis \a axis from the chart. | 
| 816 |   The chart releases the ownership of the specified \a axis object. | 
| 817 |  | 
| 818 |   \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis() | 
| 819 | */ | 
| 820 | void QChart::removeAxis(QAbstractAxis *axis) | 
| 821 | { | 
| 822 |     d_ptr->m_dataset->removeAxis(axis); | 
| 823 | } | 
| 824 |  | 
| 825 | /*! | 
| 826 |   Returns the value in the series specified by \a series at the position | 
| 827 |   specified by \a position in a chart. | 
| 828 | */ | 
| 829 | QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series) | 
| 830 | { | 
| 831 |     return d_ptr->m_dataset->mapToValue(position, series); | 
| 832 | } | 
| 833 |  | 
| 834 | /*! | 
| 835 |   Returns the position on the chart that corresponds to the value \a value in the | 
| 836 |   series specified by \a series. | 
| 837 | */ | 
| 838 | QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series) | 
| 839 | { | 
| 840 |     return d_ptr->m_dataset->mapToPosition(value, series); | 
| 841 | } | 
| 842 |  | 
| 843 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | 
| 844 |  | 
| 845 | QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type): | 
| 846 |     q_ptr(q), | 
| 847 |     m_legend(0), | 
| 848 |     m_dataset(new ChartDataSet(q)), | 
| 849 |     m_presenter(new ChartPresenter(q, type)), | 
| 850 |     m_themeManager(new ChartThemeManager(q)), | 
| 851 |     m_type(type) | 
| 852 | { | 
| 853 |     QObject::connect(sender: m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*))); | 
| 854 |     QObject::connect(sender: m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*))); | 
| 855 |     QObject::connect(sender: m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), receiver: m_presenter, SLOT(handleAxisAdded(QAbstractAxis*))); | 
| 856 |     QObject::connect(sender: m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), receiver: m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*))); | 
| 857 |     QObject::connect(sender: m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*))); | 
| 858 |     QObject::connect(sender: m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*))); | 
| 859 |     QObject::connect(sender: m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), receiver: m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*))); | 
| 860 |     QObject::connect(sender: m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), receiver: m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*))); | 
| 861 |     QObject::connect(sender: m_presenter, signal: &ChartPresenter::plotAreaChanged, receiver: q, slot: &QChart::plotAreaChanged); | 
| 862 | } | 
| 863 |  | 
| 864 | QChartPrivate::~QChartPrivate() | 
| 865 | { | 
| 866 |     delete m_themeManager; | 
| 867 | } | 
| 868 |  | 
| 869 | // Hackish solution to the problem of explicitly assigning the default pen/brush/font | 
| 870 | // to a series or axis and having theme override it: | 
| 871 | // Initialize pens, brushes, and fonts to something nobody is likely to ever use, | 
| 872 | // so that default theme initialization will always set these properly. | 
| 873 | QPen &QChartPrivate::defaultPen() | 
| 874 | { | 
| 875 |     static QPen defaultPen(QColor(1, 2, 0), 0.93247536); | 
| 876 |     return defaultPen; | 
| 877 | } | 
| 878 |  | 
| 879 | QBrush &QChartPrivate::defaultBrush() | 
| 880 | { | 
| 881 |     static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern); | 
| 882 |     return defaultBrush; | 
| 883 | } | 
| 884 |  | 
| 885 | QFont &QChartPrivate::defaultFont() | 
| 886 | { | 
| 887 |     static bool defaultFontInitialized(false); | 
| 888 |     static QFont defaultFont; | 
| 889 |     if (!defaultFontInitialized) { | 
| 890 |         defaultFont.setPointSizeF(8.34563465); | 
| 891 |         defaultFontInitialized = true; | 
| 892 |     } | 
| 893 |     return defaultFont; | 
| 894 | } | 
| 895 |  | 
| 896 | void QChartPrivate::init() | 
| 897 | { | 
| 898 |     m_legend = new LegendScroller(q_ptr); | 
| 899 |     q_ptr->setTheme(QChart::ChartThemeLight); | 
| 900 |     q_ptr->setLayout(m_presenter->layout()); | 
| 901 | } | 
| 902 |  | 
| 903 | void QChartPrivate::zoomIn(qreal factor) | 
| 904 | { | 
| 905 |     QRectF rect = m_presenter->geometry(); | 
| 906 |     rect.setWidth(rect.width() / factor); | 
| 907 |     rect.setHeight(rect.height() / factor); | 
| 908 |     rect.moveCenter(p: m_presenter->geometry().center()); | 
| 909 |     zoomIn(rect); | 
| 910 | } | 
| 911 |  | 
| 912 | void QChartPrivate::zoomIn(const QRectF &rect) | 
| 913 | { | 
| 914 |     if (!rect.isValid()) | 
| 915 |         return; | 
| 916 |  | 
| 917 |     QRectF r = rect.normalized(); | 
| 918 |     const QRectF geometry = m_presenter->geometry(); | 
| 919 |     r.translate(p: -geometry.topLeft()); | 
| 920 |  | 
| 921 |     if (!r.isValid()) | 
| 922 |         return; | 
| 923 |  | 
| 924 |     QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height()); | 
| 925 |     m_presenter->setState(state: ChartPresenter::ZoomInState,point: zoomPoint); | 
| 926 |     m_dataset->zoomInDomain(rect: r); | 
| 927 |     m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF()); | 
| 928 |  | 
| 929 | } | 
| 930 |  | 
| 931 | void QChartPrivate::zoomReset() | 
| 932 | { | 
| 933 |     m_dataset->zoomResetDomain(); | 
| 934 | } | 
| 935 |  | 
| 936 | bool QChartPrivate::isZoomed() | 
| 937 | { | 
| 938 |     return m_dataset->isZoomedDomain(); | 
| 939 | } | 
| 940 |  | 
| 941 | void QChartPrivate::zoomOut(qreal factor) | 
| 942 | { | 
| 943 |     const QRectF geometry = m_presenter->geometry(); | 
| 944 |  | 
| 945 |     QRectF r; | 
| 946 |     r.setSize(geometry.size() / factor); | 
| 947 |     r.moveCenter(p: QPointF(geometry.size().width()/2 ,geometry.size().height()/2)); | 
| 948 |     if (!r.isValid()) | 
| 949 |         return; | 
| 950 |  | 
| 951 |     QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height()); | 
| 952 |     m_presenter->setState(state: ChartPresenter::ZoomOutState,point: zoomPoint); | 
| 953 |     m_dataset->zoomOutDomain(rect: r); | 
| 954 |     m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF()); | 
| 955 | } | 
| 956 |  | 
| 957 | void QChartPrivate::scroll(qreal dx, qreal dy) | 
| 958 | { | 
| 959 |     if (dx < 0) m_presenter->setState(state: ChartPresenter::ScrollLeftState,point: QPointF()); | 
| 960 |     if (dx > 0) m_presenter->setState(state: ChartPresenter::ScrollRightState,point: QPointF()); | 
| 961 |     if (dy < 0) m_presenter->setState(state: ChartPresenter::ScrollUpState,point: QPointF()); | 
| 962 |     if (dy > 0) m_presenter->setState(state: ChartPresenter::ScrollDownState,point: QPointF()); | 
| 963 |  | 
| 964 |     m_dataset->scrollDomain(dx, dy); | 
| 965 |     m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF()); | 
| 966 | } | 
| 967 |  | 
| 968 | QT_CHARTS_END_NAMESPACE | 
| 969 |  | 
| 970 | #include "moc_qchart.cpp" | 
| 971 |  |