Revision control

++ // Copyright (C) 2017 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++
++ #include <QtCharts/QChart>
++ #include <private/qchart_p.h>
++ #include <private/legendscroller_p.h>
++ #include <private/qlegend_p.h>
++ #include <private/chartbackground_p.h>
++ #include <QtCharts/QAbstractAxis>
++ #include <private/abstractchartlayout_p.h>
++ #include <private/charttheme_p.h>
++ #include <private/chartpresenter_p.h>
++ #include <private/chartdataset_p.h>
++ #include <QtWidgets/QGraphicsScene>
++ #include <QGraphicsSceneResizeEvent>
++
++ QT_BEGIN_NAMESPACE
++
++ /*!
++ \enum QChart::ChartTheme
++
++ This enum describes the theme used by the chart.
++
++ A theme is a built-in collection of UI style related settings applied to all
++ the visual elements of a chart, such as colors, pens, brushes, and fonts of
++ series, as well as axes, title, and legend. The \l {Charts with Widgets Gallery}
++ illustrates how to use themes.
++
++ \note Changing the theme will overwrite all customizations previously applied
++ to the series.
++
++ \value ChartThemeLight
++ The light theme, which is the default theme.
++ \value ChartThemeBlueCerulean
++ The cerulean blue theme.
++ \value ChartThemeDark
++ The dark theme.
++ \value ChartThemeBrownSand
++ The sand brown theme.
++ \value ChartThemeBlueNcs
++ The natural color system (NCS) blue theme.
++ \value ChartThemeHighContrast
++ The high contrast theme.
++ \value ChartThemeBlueIcy
++ The icy blue theme.
++ \value ChartThemeQt
++ The Qt theme.
++ */
++
++ /*!
++ \enum QChart::AnimationOption
++
++ This enum describes the animations enabled in the chart.
++
++ \value NoAnimation
++ Animation is disabled in the chart. This is the default value.
++ \value GridAxisAnimations
++ Grid axis animation is enabled in the chart.
++ \value SeriesAnimations
++ Series animation is enabled in the chart.
++ \value AllAnimations
++ All animation types are enabled in the chart.
++ */
++
++ /*!
++ \enum QChart::ChartType
++
++ This enum describes the chart type.
++
++ \value ChartTypeUndefined
++ The chart type is not defined.
++ \value ChartTypeCartesian
++ A cartesian chart.
++ \value ChartTypePolar
++ A polar chart.
++ */
++
++ /*!
++ \class QChart
++ \inmodule QtCharts
++ \brief The QChart class manages the graphical representation of the chart's
++ series, legends, and axes.
++
++ QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
++ representation of different types of series and other chart related objects like legend and
++ axes. To simply show a chart in a layout, the convenience class QChartView can be used
++ instead of QChart. In addition, line, spline, area, and scatter series can be presented as
++ polar charts by using the QPolarChart class.
++
++ \sa QChartView, QPolarChart
++ */
++
++ /*!
++ \property QChart::animationOptions
++ \brief The animation options for the chart.
++
++ Animations are enabled or disabled based on this setting.
++ */
++
++ /*!
++ \property QChart::animationDuration
++ \brief The duration of the animation for the chart.
++ */
++
++ /*!
++ \property QChart::animationEasingCurve
++ \brief The easing curve of the animation for the chart.
++ */
++
++ /*!
++ \property QChart::backgroundVisible
++ \brief Whether the chart background is visible.
++ \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible
++ */
++
++ /*!
++ \property QChart::dropShadowEnabled
++ \brief Whether the background drop shadow effect is enabled.
++
++ If set to \c true, the background drop shadow effect is enabled. If set to \c false, it
++ is disabled.
++
++ \note The drop shadow effect depends on the theme, and therefore the setting may
++ change if the theme is changed.
++ */
++
++ /*!
++ \property QChart::backgroundRoundness
++ \brief The diameter of the rounding circle at the corners of the chart background.
++ */
++
++ /*!
++ \property QChart::margins
++ \brief The minimum margins allowed between the edge of the chart rectangle and
++ the plot area.
++
++ The margins are used for drawing the title, axes, and legend.
++ */
++
++ /*!
++ \property QChart::theme
++ \brief The theme used for the chart.
++ */
++
++ /*!
++ \property QChart::title
++ \brief The title of the chart.
++
++ The title is shown as a headline on top of the chart. Chart titles support HTML formatting.
++ */
++
++ /*!
++ \property QChart::chartType
++ \brief Whether the chart is a cartesian chart or a polar chart.
++
++ This property is set internally and it is read only.
++ \sa QPolarChart
++ */
++
++ /*!
++ \property QChart::plotAreaBackgroundVisible
++ \brief Whether the chart plot area background is visible.
++
++ \note By default, the plot area background is invisible and the plot area uses
++ the general chart background.
++ \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible
++ */
++
++ /*!
++ \property QChart::localizeNumbers
++ \brief Whether numbers are localized.
++
++ When \c{true}, all generated numbers appearing in various series and axis labels will be
++ localized using the QLocale set with the \l locale property.
++ When \c{false}, the \e C locale is always used.
++ Defaults to \c{false}.
++
++ \note This property does not affect QDateTimeAxis labels, which always use the QLocale set with
++ the locale property.
++
++ \sa locale
++ */
++
++ /*!
++ \property QChart::locale
++ \brief The locale used to format various chart labels.
++
++ Labels are localized only when \l localizeNumbers is \c true, except for QDateTimeAxis
++ labels, which always use the QLocale set with this property.
++
++ Defaults to the application default locale at the time when the chart is constructed.
++
++ \sa localizeNumbers
++ */
++
++ /*!
++ \property QChart::plotArea
++ \brief The rectangle within which the chart is drawn.
++
++ The plot area does not include the area defined by margins. By default this will resize if inside
++ a QChartView. If an explicit size is set for the plot area then it will respect this, to revert
++ back to the default behavior, then calling \c{setPlotArea(QRectF());} will achieve this.
++ */
++
++ /*!
++ \internal
++ Constructs a chart object of \a type that is a child of \a parent.
++ The properties specified by \a wFlags are passed to the QGraphicsWidget constructor.
++ This constructor is called only by subclasses.
++ */
++ QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
++ : QGraphicsWidget(parent, wFlags),
++ d_ptr(new QChartPrivate(this, type))
++ {
++ d_ptr->init();
++ }
++
++ /*!
++ Constructs a chart object that is a child of \a parent.
++ The properties specified by \a wFlags are passed to the QGraphicsWidget constructor.
++ */
++ QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
++ : QGraphicsWidget(parent, wFlags),
++ d_ptr(new QChartPrivate(this, ChartTypeCartesian))
++ {
++ d_ptr->init();
++ }
++
++ /*!
++ Deletes the chart object and its children, such as the series and axis objects added to it.
++ */
++ QChart::~QChart()
++ {
++ //start by deleting dataset, it will remove all series and axes
++ delete d_ptr->m_dataset;
++ d_ptr->m_dataset = 0;
++ }
++
++ /*!
++ Adds the series \a series to the chart and takes ownership of it.
++
++ \note A newly added series is not attached to any axes by default, not even those that
++ might have been created for the chart
++ using createDefaultAxes() before the series was added to the chart. If no axes are attached to
++ the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
++ that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
++ series that have properly attached axes, so always make sure you either call createDefaultAxes() after
++ a series has been added or explicitly attach axes for the series.
++
++ \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
++ */
++ void QChart::addSeries(QAbstractSeries *series)
++ {
++ Q_ASSERT(series);
++ d_ptr->m_dataset->addSeries(series);
++ }
++
++ /*!
++ Removes the series \a series from the chart.
++ The chart releases the ownership of the specified \a series object.
++
++ \sa addSeries(), removeAllSeries()
++ */
++ void QChart::removeSeries(QAbstractSeries *series)
++ {
++ Q_ASSERT(series);
++ d_ptr->m_dataset->removeSeries(series);
++ }
++
++ /*!
++ Removes and deletes all series objects that have been added to the chart.
++
++ \sa addSeries(), removeSeries()
++ */
++ void QChart::removeAllSeries()
++ {
++ const auto series = d_ptr->m_dataset->series();
++ for (QAbstractSeries *s : series) {
++ removeSeries(s);
++ delete s;
++ }
++ }
++
++ /*!
++ Sets the brush that is used for painting the background of the chart area to \a brush.
++ */
++ void QChart::setBackgroundBrush(const QBrush &brush)
++ {
++ d_ptr->m_presenter->setBackgroundBrush(brush);
++ }
++
++ /*!
++ Gets the brush that is used for painting the background of the chart area.
++ */
++ QBrush QChart::backgroundBrush() const
++ {
++ return d_ptr->m_presenter->backgroundBrush();
++ }
++
++ /*!
++ Sets the pen that is used for painting the background of the chart area to \a pen.
++ */
++ void QChart::setBackgroundPen(const QPen &pen)
++ {
++ d_ptr->m_presenter->setBackgroundPen(pen);
++ }
++
++ /*!
++ Gets the pen that is used for painting the background of the chart area.
++ */
++ QPen QChart::backgroundPen() const
++ {
++ return d_ptr->m_presenter->backgroundPen();
++ }
++
++ void QChart::setTitle(const QString &title)
++ {
++ d_ptr->m_presenter->setTitle(title);
++ }
++
++ QString QChart::title() const
++ {
++ return d_ptr->m_presenter->title();
++ }
++
++ /*!
++ Sets the font that is used for drawing the chart title to \a font.
++ */
++ void QChart::setTitleFont(const QFont &font)
++ {
++ d_ptr->m_presenter->setTitleFont(font);
++ }
++
++ /*!
++ Gets the font that is used for drawing the chart title.
++ */
++ QFont QChart::titleFont() const
++ {
++ return d_ptr->m_presenter->titleFont();
++ }
++
++ /*!
++ Sets the brush used for drawing the title text to \a brush.
++ */
++ void QChart::setTitleBrush(const QBrush &brush)
++ {
++ d_ptr->m_presenter->setTitleBrush(brush);
++ }
++
++ /*!
++ Returns the brush used for drawing the title text.
++ */
++ QBrush QChart::titleBrush() const
++ {
++ return d_ptr->m_presenter->titleBrush();
++ }
++
++ void QChart::setTheme(QChart::ChartTheme theme)
++ {
++ d_ptr->m_themeManager->setTheme(theme);
++ }
++
++ QChart::ChartTheme QChart::theme() const
++ {
++ return d_ptr->m_themeManager->theme()->id();
++ }
++
++ /*!
++ Zooms into the view by a factor of two.
++ */
++ void QChart::zoomIn()
++ {
++ d_ptr->zoomIn(2.0);
++ }
++
++ /*!
++ Zooms into the view to a maximum level at which the rectangle \a rect is still
++ fully visible.
++ \note Applying a zoom may modify properties of attached axes, for instance QAbstractAxis::min
++ and QAbstractAxis::max.
++ \note This is not supported for polar charts.
++ */
++ void QChart::zoomIn(const QRectF &rect)
++ {
++ if (d_ptr->m_type == QChart::ChartTypePolar)
++ return;
++ d_ptr->zoomIn(rect);
++ }
++
++ /*!
++ Zooms out of the view by a factor of two.
++ \note This will do nothing if the result would contain an invalid logarithmic axis range.
++ */
++ void QChart::zoomOut()
++ {
++ d_ptr->zoomOut(2.0);
++ }
++
++ /*!
++ Zooms into the view by the custom factor \a factor.
++
++ A factor over 1.0 zooms into the view and a factor between 0.0 and 1.0 zooms
++ out of it.
++ */
++ void QChart::zoom(qreal factor)
++ {
++ if (qFuzzyCompare(factor, 0))
++ return;
++
++ if (qFuzzyCompare(factor, (qreal)1.0))
++ return;
++
++ if (factor < 0)
++ return;
++
++ if (factor > 1.0)
++ d_ptr->zoomIn(factor);
++ else
++ d_ptr->zoomOut(1.0 / factor);
++ }
++
++
++ /*!
++ Resets the series domains to what they were before any zoom method was called.
++
++ \note This will also reset scrolling and explicit axis range settings specified between
++ the first zoom operation and calling this method. If no zoom operation has been
++ performed, this method does nothing.
++ */
++ void QChart::zoomReset()
++ {
++ d_ptr->zoomReset();
++ }
++
++ /*!
++ Returns \c true if any series has a zoomed domain.
++ */
++ bool QChart::isZoomed()
++ {
++ return d_ptr->isZoomed();
++ }
++
++ /*!
++ \deprecated
++ Use axes() instead.
++
++ Returns a pointer to the horizontal axis attached to the specified \a series.
++ If no series is specified, the first horizontal axis added to the chart is returned.
++
++ \sa addAxis(), QAbstractSeries::attachAxis()
++ */
++ QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
++ {
++ QList<QAbstractAxis *> axisList = axes(Qt::Horizontal, series);
++ if (axisList.size())
++ return axisList[0];
++ return 0;
++ }
++
++ /*!
++ \deprecated
++ Use axes() instead.
++
++ Returns a pointer to the vertical axis attached to the specified \a series.
++ If no series is specified, the first vertical axis added to the chart is returned.
++
++ \sa addAxis(), QAbstractSeries::attachAxis()
++ */
++ QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
++ {
++ QList<QAbstractAxis *> axisList = axes(Qt::Vertical, series);
++ if (axisList.size())
++ return axisList[0];
++ return 0;
++ }
++
++ /*!
++ Returns the axes attached to the series \a series with the orientation specified
++ by \a orientation. If no series is specified, all axes added to the chart with
++ the specified orientation are returned.
++
++ \sa addAxis(), createDefaultAxes()
++ */
++ QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
++ {
++ QList<QAbstractAxis *> result ;
++
++ if (series) {
++ const auto axes = series->attachedAxes();
++ for (QAbstractAxis *axis : axes) {
++ if (orientation.testFlag(axis->orientation()))
++ result << axis;
++ }
++ } else {
++ const auto axes = d_ptr->m_dataset->axes();
++ for (QAbstractAxis *axis : axes) {
++ if (orientation.testFlag(axis->orientation()) && !result.contains(axis))
++ result << axis;
++ }
++ }
++
++ return result;
++ }
++
++ /*!
++ Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
++ the chart will be deleted.
++
++ \note This function has to be called after all series have been added to the chart. The axes created by this function
++ will NOT get automatically attached to any series added to the chart after this function has been called.
++ A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
++ if there are other series with properly attached axes also present.
++
++ \table
++ \header
++ \li Series type
++ \li Horizontal axis (X)
++ \li Vertical axis (Y)
++ \row
++ \li QXYSeries
++ \li QValueAxis
++ \li QValueAxis
++ \row
++ \li QBarSeries
++ \li QBarCategoryAxis
++ \li QValueAxis
++ \row
++ \li QPieSeries
++ \li None
++ \li None
++ \endtable
++
++ 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.
++ If there are several series of different types added to the chart, then each series gets its own axes pair.
++
++ The axes specific to the series can be later obtained from the chart by providing the series
++ as the parameter for the axes() function call.
++ QPieSeries does not create any axes.
++
++ \sa axes(), QAbstractSeries::attachAxis()
++ */
++ void QChart::createDefaultAxes()
++ {
++ d_ptr->m_dataset->createDefaultAxes();
++ }
++
++ /*!
++ Returns the legend object of the chart. Ownership stays with the chart.
++ */
++ QLegend *QChart::legend() const
++ {
++ return d_ptr->m_legend;
++ }
++
++ void QChart::setMargins(const QMargins &margins)
++ {
++ d_ptr->m_presenter->layout()->setMargins(margins);
++ }
++
++ QMargins QChart::margins() const
++ {
++ return d_ptr->m_presenter->layout()->margins();
++ }
++
++ QChart::ChartType QChart::chartType() const
++ {
++ return d_ptr->m_type;
++ }
++
++ QRectF QChart::plotArea() const
++ {
++ return d_ptr->m_presenter->geometry();
++ }
++
++ void QChart::setPlotArea(const QRectF &rect)
++ {
++ d_ptr->m_presenter->setFixedGeometry(rect);
++ }
++
++ /*!
++ Sets the brush used to fill the background of the plot area of the chart to \a brush.
++
++ \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
++ */
++ void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
++ {
++ d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
++ }
++
++ /*!
++ Returns the brush used to fill the background of the plot area of the chart.
++
++ \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
++ */
++ QBrush QChart::plotAreaBackgroundBrush() const
++ {
++ return d_ptr->m_presenter->plotAreaBackgroundBrush();
++ }
++
++ /*!
++ Sets the pen used to draw the background of the plot area of the chart to \a pen.
++
++ \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
++ */
++ void QChart::setPlotAreaBackgroundPen(const QPen &pen)
++ {
++ d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
++ }
++
++ /*!
++ Returns the pen used to draw the background of the plot area of the chart.
++
++ \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
++ */
++ QPen QChart::plotAreaBackgroundPen() const
++ {
++ return d_ptr->m_presenter->plotAreaBackgroundPen();
++ }
++
++ void QChart::setPlotAreaBackgroundVisible(bool visible)
++ {
++ d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
++ }
++
++ bool QChart::isPlotAreaBackgroundVisible() const
++ {
++ return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
++ }
++
++ void QChart::setLocalizeNumbers(bool localize)
++ {
++ d_ptr->m_presenter->setLocalizeNumbers(localize);
++ }
++
++ bool QChart::localizeNumbers() const
++ {
++ return d_ptr->m_presenter->localizeNumbers();
++ }
++
++ void QChart::setLocale(const QLocale &locale)
++ {
++ d_ptr->m_presenter->setLocale(locale);
++ }
++
++ QLocale QChart::locale() const
++ {
++ return d_ptr->m_presenter->locale();
++ }
++
++ void QChart::setAnimationOptions(AnimationOptions options)
++ {
++ d_ptr->m_presenter->setAnimationOptions(options);
++ }
++
++ QChart::AnimationOptions QChart::animationOptions() const
++ {
++ return d_ptr->m_presenter->animationOptions();
++ }
++
++ void QChart::setAnimationDuration(int msecs)
++ {
++ d_ptr->m_presenter->setAnimationDuration(msecs);
++ }
++
++ int QChart::animationDuration() const
++ {
++ return d_ptr->m_presenter->animationDuration();
++ }
++
++ void QChart::setAnimationEasingCurve(const QEasingCurve &curve)
++ {
++ d_ptr->m_presenter->setAnimationEasingCurve(curve);
++ }
++
++ QEasingCurve QChart::animationEasingCurve() const
++ {
++ return d_ptr->m_presenter->animationEasingCurve();
++ }
++
++ /*!
++ Scrolls the visible area of the chart by the distance specified by \a dx and \a dy.
++
++ For polar charts, \a dx indicates the angle along the angular axis instead of distance.
++ */
++ void QChart::scroll(qreal dx, qreal dy)
++ {
++ d_ptr->scroll(dx,dy);
++ }
++
++ void QChart::setBackgroundVisible(bool visible)
++ {
++ d_ptr->m_presenter->setBackgroundVisible(visible);
++ }
++
++ bool QChart::isBackgroundVisible() const
++ {
++ return d_ptr->m_presenter->isBackgroundVisible();
++ }
++
++ void QChart::setDropShadowEnabled(bool enabled)
++ {
++ d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
++ }
++
++ bool QChart::isDropShadowEnabled() const
++ {
++ return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
++ }
++
++ void QChart::setBackgroundRoundness(qreal diameter)
++ {
++ d_ptr->m_presenter->setBackgroundRoundness(diameter);
++ }
++
++ qreal QChart::backgroundRoundness() const
++ {
++ return d_ptr->m_presenter->backgroundRoundness();
++ }
++
++ /*!
++ Returns all series that are added to the chart.
++
++ \sa addSeries(), removeSeries(), removeAllSeries()
++ */
++ QList<QAbstractSeries *> QChart::series() const
++ {
++ return d_ptr->m_dataset->series();
++ }
++
++ /*!
++ \deprecated
++ Use addAxis() instead.
++
++ Adds the axis \a axis to the chart and attaches it to the series \a series as a
++ bottom-aligned horizontal axis.
++ The chart takes ownership of both the axis and the series.
++ Any horizontal axes previously attached to the series are deleted.
++
++ \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
++ */
++ void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
++ {
++ const QList<QAbstractAxis*> list = axes(Qt::Horizontal, series);
++
++ for (QAbstractAxis *a : list) {
++ d_ptr->m_dataset->removeAxis(a);
++ delete a;
++ }
++
++ if (!d_ptr->m_dataset->axes().contains(axis))
++ d_ptr->m_dataset->addAxis(axis, Qt::AlignBottom);
++ d_ptr->m_dataset->attachAxis(series, axis);
++ }
++
++ /*!
++ \deprecated
++ Use addAxis() instead.
++
++ Adds the axis \a axis to the chart and attaches it to the series \a series as a
++ left-aligned vertical axis.
++ The chart takes ownership of both the axis and the series.
++ Any vertical axes previously attached to the series are deleted.
++
++ \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
++ */
++ void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
++ {
++ const QList<QAbstractAxis*> list = axes(Qt::Vertical, series);
++
++ for (QAbstractAxis *a : list) {
++ d_ptr->m_dataset->removeAxis(a);
++ delete a;
++ }
++
++ if (!d_ptr->m_dataset->axes().contains(axis))
++ d_ptr->m_dataset->addAxis(axis, Qt::AlignLeft);
++ d_ptr->m_dataset->attachAxis(series, axis);
++ }
++
++ /*!
++ Adds the axis \a axis to the chart aligned as specified by \a alignment.
++ The chart takes the ownership of the axis.
++
++ \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
++ */
++ void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
++ {
++ d_ptr->m_dataset->addAxis(axis, alignment);
++ }
++
++ /*!
++ Removes the axis \a axis from the chart.
++ The chart releases the ownership of the specified \a axis object.
++
++ \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
++ */
++ void QChart::removeAxis(QAbstractAxis *axis)
++ {
++ d_ptr->m_dataset->removeAxis(axis);
++ }
++
++ /*!
++ Returns the value in the series specified by \a series at the position
++ specified by \a position in a chart.
++ */
++ QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
++ {
++ return d_ptr->m_dataset->mapToValue(position, series);
++ }
++
++ /*!
++ Returns the position on the chart that corresponds to the value \a value in the
++ series specified by \a series.
++ */
++ QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
++ {
++ return d_ptr->m_dataset->mapToPosition(value, series);
++ }
++
++ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++ QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
++ q_ptr(q),
++ m_legend(0),
++ m_dataset(new ChartDataSet(q)),
++ m_presenter(new ChartPresenter(q, type)),
++ m_themeManager(new ChartThemeManager(q)),
++ m_type(type)
++ {
++ QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
++ QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
++ QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
++ QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
++ QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
++ QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
++ QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
++ QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
++ QObject::connect(m_presenter, &ChartPresenter::plotAreaChanged, q, &QChart::plotAreaChanged);
++ }
++
++ QChartPrivate::~QChartPrivate()
++ {
++ delete m_themeManager;
++ }
++
++ // Hackish solution to the problem of explicitly assigning the default pen/brush/font
++ // to a series or axis and having theme override it:
++ // Initialize pens, brushes, and fonts to something nobody is likely to ever use,
++ // so that default theme initialization will always set these properly.
++ QPen &QChartPrivate::defaultPen()
++ {
++ static QPen defaultPen(QColor(1, 2, 0), 0.93247536);
++ return defaultPen;
++ }
++
++ QBrush &QChartPrivate::defaultBrush()
++ {
++ static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern);
++ return defaultBrush;
++ }
++
++ QFont &QChartPrivate::defaultFont()
++ {
++ static bool defaultFontInitialized(false);
++ static QFont defaultFont;
++ if (!defaultFontInitialized) {
++ defaultFont.setPointSizeF(8.34563465);
++ defaultFontInitialized = true;
++ }
++ return defaultFont;
++ }
++
++ void QChartPrivate::init()
++ {
++ m_legend = new LegendScroller(q_ptr);
++ q_ptr->setTheme(QChart::ChartThemeLight);
++ q_ptr->setLayout(m_presenter->layout());
++ }
++
++ void QChartPrivate::zoomIn(qreal factor)
++ {
++ QRectF rect = m_presenter->geometry();
++ rect.setWidth(rect.width() / factor);
++ rect.setHeight(rect.height() / factor);
++ rect.moveCenter(m_presenter->geometry().center());
++ zoomIn(rect);
++ }
++
++ void QChartPrivate::zoomIn(const QRectF &rect)
++ {
++ if (!rect.isValid())
++ return;
++
++ QRectF r = rect.normalized();
++ const QRectF geometry = m_presenter->geometry();
++ r.translate(-geometry.topLeft());
++
++ if (!r.isValid())
++ return;
++
++ QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
++ m_presenter->setState(ChartPresenter::ZoomInState,zoomPoint);
++ m_dataset->zoomInDomain(r);
++ m_presenter->setState(ChartPresenter::ShowState,QPointF());
++
++ }
++
++ void QChartPrivate::zoomReset()
++ {
++ m_dataset->zoomResetDomain();
++ }
++
++ bool QChartPrivate::isZoomed()
++ {
++ return m_dataset->isZoomedDomain();
++ }
++
++ void QChartPrivate::zoomOut(qreal factor)
++ {
++ const QRectF geometry = m_presenter->geometry();
++
++ QRectF r;
++ r.setSize(geometry.size() / factor);
++ r.moveCenter(QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
++ if (!r.isValid())
++ return;
++
++ QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
++ m_presenter->setState(ChartPresenter::ZoomOutState,zoomPoint);
++ m_dataset->zoomOutDomain(r);
++ m_presenter->setState(ChartPresenter::ShowState,QPointF());
++ }
++
++ void QChartPrivate::scroll(qreal dx, qreal dy)
++ {
++ if (dx < 0) m_presenter->setState(ChartPresenter::ScrollLeftState,QPointF());
++ if (dx > 0) m_presenter->setState(ChartPresenter::ScrollRightState,QPointF());
++ if (dy < 0) m_presenter->setState(ChartPresenter::ScrollUpState,QPointF());
++ if (dy > 0) m_presenter->setState(ChartPresenter::ScrollDownState,QPointF());
++
++ m_dataset->scrollDomain(dx, dy);
++ m_presenter->setState(ChartPresenter::ShowState,QPointF());
++ }
++
++ QT_END_NAMESPACE
++
++ #include "moc_qchart.cpp"