blob: a290f6d4d2f8ec2e477633e2a769035226777a01 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCharts/QXYSeries>
#include <private/qxyseries_p.h>
#include <private/abstractdomain_p.h>
#include <QtCharts/QValueAxis>
#include <private/xychart_p.h>
#include <QtCharts/QXYLegendMarker>
#include <private/charthelpers_p.h>
#include <private/qchart_p.h>
#include <QtGui/QPainter>
QT_CHARTS_BEGIN_NAMESPACE
/*!
\class QXYSeries
\inmodule QtCharts
\brief The QXYSeries class is a base class for line, spline, and scatter
series.
*/
/*!
\qmltype XYSeries
\instantiates QXYSeries
\inqmlmodule QtCharts
\inherits AbstractSeries
\brief A base type for line, spline, and scatter series.
*/
/*!
\qmlproperty AbstractAxis XYSeries::axisX
The x-axis used for the series. If you leave both axisX and axisXTop
undefined, a value axis is created for the series.
\sa axisXTop, ValueAxis
*/
/*!
\qmlproperty AbstractAxis XYSeries::axisY
The y-axis used for the series. If you leave both axisY and axisYRight
undefined, a value axis is created for the series.
\sa axisYRight, ValueAxis
*/
/*!
\qmlproperty AbstractAxis XYSeries::axisXTop
The x-axis used for the series, drawn on top of the chart view.
\note You can only provide either axisX or axisXTop, not both.
\sa axisX
*/
/*!
\qmlproperty AbstractAxis XYSeries::axisYRight
The y-axis used for the series, drawn to the right on the chart view.
\note You can only provide either axisY or axisYRight, not both.
\sa axisY
*/
/*!
\qmlproperty AbstractAxis XYSeries::axisAngular
The angular axis used for the series, drawn around the polar chart view.
\sa axisX
*/
/*!
\qmlproperty AbstractAxis XYSeries::axisRadial
The radial axis used for the series, drawn inside the polar chart view.
\sa axisY
*/
/*!
\property QXYSeries::pointsVisible
\brief Whether the data points are visible and should be drawn.
*/
/*!
\qmlproperty bool XYSeries::pointsVisible
Whether the data points are visible and should be drawn.
*/
/*!
\fn QPen QXYSeries::pen() const
Returns the pen used to draw the outline of the data points for the series.
\sa setPen()
*/
/*!
\fn QBrush QXYSeries::brush() const
Returns the brush used to fill the data points for the series.
\sa setBrush()
*/
/*!
\property QXYSeries::color
\brief The color of the series.
This is the line (pen) color in case of QLineSeries or QSplineSeries and the
fill (brush) color in case of QScatterSeries or QAreaSeries.
\sa pen(), brush()
*/
/*!
\qmlproperty color XYSeries::color
The color of the series. This is the line (pen) color in case of LineSeries
or SplineSeries and the fill (brush) color in case of ScatterSeries or
AreaSeries.
*/
/*!
\property QXYSeries::pointLabelsFormat
\brief The format used for showing labels with data points.
QXYSeries supports the following format tags:
\table
\row
\li @xPoint \li The x-coordinate of the data point.
\row
\li @yPoint \li The y-coordinate of the data point.
\endtable
For example, the following usage of the format tags would produce labels
that display the data point shown inside brackets separated by a comma
(x, y):
\code
series->setPointLabelsFormat("(@xPoint, @yPoint)");
\endcode
By default, the labels' format is set to \c {@xPoint, @yPoint}. The labels
are shown on the plot area, and the labels on the edge of the plot area are
cut. If the points are close to each other, the labels may overlap.
\sa pointLabelsVisible, pointLabelsFont, pointLabelsColor
*/
/*!
\qmlproperty string XYSeries::pointLabelsFormat
The format used for showing labels with data points.
\sa pointLabelsVisible, pointLabelsFont, pointLabelsColor
*/
/*!
\fn void QXYSeries::pointLabelsFormatChanged(const QString &format)
This signal is emitted when the format of data point labels changes to
\a format.
*/
/*!
\property QXYSeries::pointLabelsVisible
\brief The visibility of data point labels.
This property is \c false by default.
\sa pointLabelsFormat, pointLabelsClipping
*/
/*!
\qmlproperty bool XYSeries::pointLabelsVisible
The visibility of data point labels. This property is \c false by default.
\sa pointLabelsFormat, pointLabelsClipping
*/
/*!
\fn void QXYSeries::pointLabelsVisibilityChanged(bool visible)
This signal is emitted when the visibility of the data point labels
changes to \a visible.
*/
/*!
\property QXYSeries::pointLabelsFont
\brief The font used for data point labels.
\sa pointLabelsFormat
*/
/*!
\qmlproperty font XYSeries::pointLabelsFont
The font used for data point labels.
\sa pointLabelsFormat
*/
/*!
\fn void QXYSeries::pointLabelsFontChanged(const QFont &font);
This signal is emitted when the font used for data point labels changes to
\a font.
*/
/*!
\property QXYSeries::pointLabelsColor
\brief The color used for data point labels. By default, the color is the color of the brush
defined in theme for labels.
\sa pointLabelsFormat
*/
/*!
\qmlproperty font XYSeries::pointLabelsColor
The color used for data point labels. By default, the color is the color of the brush
defined in theme for labels.
\sa pointLabelsFormat
*/
/*!
\fn void QXYSeries::pointLabelsColorChanged(const QColor &color);
This signal is emitted when the color used for data point labels changes to
\a color.
*/
/*!
\property QXYSeries::pointLabelsClipping
\brief The clipping for data point labels.
This property is \c true by default. The labels on the edge of the plot area
are cut when clipping is enabled.
\sa pointLabelsVisible
*/
/*!
\qmlproperty bool XYSeries::pointLabelsClipping
The clipping for data point labels. This property is \c true by default. The
labels on the edge of the plot area are cut when clipping is enabled.
\sa pointLabelsVisible
*/
/*!
\fn void QXYSeries::pointLabelsClippingChanged(bool clipping)
This signal is emitted when the clipping of the data point labels changes to
\a clipping.
*/
/*!
\fn void QXYSeries::clicked(const QPointF& point)
This signal is emitted when the user triggers a mouse event by
clicking the point \a point in the chart.
\sa pressed(), released(), doubleClicked()
*/
/*!
\qmlsignal XYSeries::clicked(point point)
This signal is emitted when the user triggers a mouse event by clicking the
point \a point in the chart. For example:
\code
LineSeries {
XYPoint { x: 0; y: 0 }
XYPoint { x: 1.1; y: 2.1 }
onClicked: console.log("onClicked: " + point.x + ", " + point.y);
}
\endcode
The corresponding signal handler is \c onClicked().
\sa pressed(), released(), doubleClicked()
*/
/*!
\fn void QXYSeries::hovered(const QPointF &point, bool state)
This signal is emitted when a mouse is hovered over the point \a point in
the chart. When the mouse moves over the point, \a state turns \c true,
and when the mouse moves away again, it turns \c false.
*/
/*!
\qmlsignal XYSeries::hovered(point point, bool state)
This signal is emitted when a mouse is hovered over the point \a point in
the chart. When the mouse moves over the point, \a state turns \c true,
and when the mouse moves away again, it turns \c false.
The corresponding signal handler is \c onHovered().
*/
/*!
\fn void QXYSeries::pressed(const QPointF& point)
This signal is emitted when the user presses the data point \a point in the
chart and holds down the mouse button.
\sa clicked(), released(), doubleClicked()
*/
/*!
\qmlsignal XYSeries::pressed(point point)
This signal is emitted when the user presses the data point \a point in the
chart and holds down the mouse button. For example:
\code
LineSeries {
XYPoint { x: 0; y: 0 }
XYPoint { x: 1.1; y: 2.1 }
onPressed: console.log("onPressed: " + point.x + ", " + point.y);
}
\endcode
The corresponding signal handler is \c onPressed().
\sa clicked(), released(), doubleClicked()
*/
/*!
\fn void QXYSeries::released(const QPointF& point)
This signal is emitted when the user releases the mouse press on the data
point specified by \a point.
\sa pressed(), clicked(), doubleClicked()
*/
/*!
\qmlsignal XYSeries::released(point point)
This signal is emitted when the user releases the mouse press on the data
point specified by \a point.
For example:
\code
LineSeries {
XYPoint { x: 0; y: 0 }
XYPoint { x: 1.1; y: 2.1 }
onReleased: console.log("onReleased: " + point.x + ", " + point.y);
}
\endcode
The corresponding signal handler is \c onReleased().
\sa pressed(), clicked(), doubleClicked()
*/
/*!
\fn void QXYSeries::doubleClicked(const QPointF& point)
This signal is emitted when the user double-clicks the data point \a point
in the chart. The \a point is the point where the first press was triggered.
\sa pressed(), released(), clicked()
*/
/*!
\qmlsignal XYSeries::doubleClicked(point point)
This signal is emitted when the user double-clicks the data point \a point
in the chart. The \a point is the point where the first press was triggered.
For example:
\code
LineSeries {
XYPoint { x: 0; y: 0 }
XYPoint { x: 1.1; y: 2.1 }
onDoubleClicked: console.log("onDoubleClicked: " + point.x + ", " + point.y);
}
\endcode
The corresponding signal handler is \c onDoubleClicked().
\sa pressed(), released(), clicked()
*/
/*!
\fn void QXYSeries::pointReplaced(int index)
This signal is emitted when a point is replaced at the position specified by
\a index.
\sa replace()
*/
/*!
\qmlsignal XYSeries::pointReplaced(int index)
This signal is emitted when a point is replaced at the position specified by
\a index.
The corresponding signal handler is \c onPointReplaced().
*/
/*!
\fn void QXYSeries::pointsReplaced()
This signal is emitted when all points are replaced with other points.
\sa replace()
*/
/*!
\qmlsignal XYSeries::pointsReplaced()
This signal is emitted when all points are replaced with other points.
The corresponding signal handler is \c onPointsReplaced().
*/
/*!
\fn void QXYSeries::pointAdded(int index)
This signal is emitted when a point is added at the position specified by
\a index.
\sa append(), insert()
*/
/*!
\qmlsignal XYSeries::pointAdded(int index)
This signal is emitted when a point is added at the position specified by
\a index.
The corresponding signal handler is \c onPointAdded().
*/
/*!
\fn void QXYSeries::pointRemoved(int index)
This signal is emitted when a point is removed from the position specified
by \a index.
\sa remove()
*/
/*!
\qmlsignal XYSeries::pointRemoved(int index)
This signal is emitted when a point is removed from the position specified
by \a index.
The corresponding signal handler is \c onPointRemoved().
*/
/*!
\fn void QXYSeries::pointsRemoved(int index, int count)
This signal is emitted when the number of points specified by \a count
is removed starting at the position specified by \a index.
\sa removePoints(), clear()
*/
/*!
\qmlsignal XYSeries::pointsRemoved(int index, int count)
This signal is emitted when the number of points specified by \a count
is removed starting at the position specified by \a index.
The corresponding signal handler is \c onPointRemoved().
*/
/*!
\fn void QXYSeries::colorChanged(QColor color)
This signal is emitted when the line (pen) color changes to \a color.
*/
/*!
\fn void QXYSeries::penChanged(const QPen &pen)
This signal is emitted when the pen changes to \a pen.
*/
/*!
\fn void QXYSeriesPrivate::updated()
\internal
*/
/*!
\qmlmethod XYSeries::append(real x, real y)
Appends a point with the coordinates \a x and \a y to the series.
*/
/*!
\qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY)
Replaces the point with the coordinates \a oldX and \a oldY with the point
with the coordinates \a newX and \a newY. Does nothing if the old point does
not exist.
*/
/*!
\qmlmethod XYSeries::remove(real x, real y)
Removes the point with the coordinates \a x and \a y from the series. Does
nothing if the point does not exist.
*/
/*!
\qmlmethod XYSeries::remove(int index)
Removes the point at the position specified by \a index from the series.
*/
/*!
\qmlmethod XYSeries::removePoints(int index, int count)
Removes the number of points specified by \a count from the series starting
at the position specified by \a index.
*/
/*!
\qmlmethod XYSeries::insert(int index, real x, real y)
Inserts a point with the coordinates \a x and \a y to the position specified
by \a index in the series. If the index is 0 or less than 0, the point is
prepended to the list of points. If the index is equal to or greater than
than the number of points in the series, the point is appended to the
list of points.
*/
/*!
\qmlmethod QPointF XYSeries::at(int index)
Returns the point at the position specified by \a index. Returns (0, 0) if
the index is not valid.
*/
/*!
\internal
Constructs an empty series object that is a child of \a parent.
When the series object is added to QChart, instance ownerships is transferred.
*/
QXYSeries::QXYSeries(QXYSeriesPrivate &d, QObject *parent)
: QAbstractSeries(d, parent)
{
}
/*!
Deletes the series. Series added to QChart instances are owned by them,
and are deleted when the QChart instances are deleted.
*/
QXYSeries::~QXYSeries()
{
}
/*!
Adds the data point with the coordinates \a x and \a y to the series.
*/
void QXYSeries::append(qreal x, qreal y)
{
append(QPointF(x, y));
}
/*!
\overload
Adds the data point \a point to the series.
*/
void QXYSeries::append(const QPointF &point)
{
Q_D(QXYSeries);
if (isValidValue(point)) {
d->m_points << point;
emit pointAdded(d->m_points.count() - 1);
}
}
/*!
\overload
Adds the list of data points specified by \a points to the series.
*/
void QXYSeries::append(const QList<QPointF> &points)
{
foreach (const QPointF &point , points)
append(point);
}
/*!
Replaces the point with the coordinates \a oldX and \a oldY with the point
with the coordinates \a newX and \a newY. Does nothing if the old point does
not exist.
\sa pointReplaced()
*/
void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY)
{
replace(QPointF(oldX, oldY), QPointF(newX, newY));
}
/*!
Replaces the point specified by \a oldPoint with the one specified by
\a newPoint.
\sa pointReplaced()
*/
void QXYSeries::replace(const QPointF &oldPoint, const QPointF &newPoint)
{
Q_D(QXYSeries);
int index = d->m_points.indexOf(oldPoint);
if (index == -1)
return;
replace(index, newPoint);
}
/*!
Replaces the point at the position specified by \a index with the point that
has the coordinates \a newX and \a newY.
\sa pointReplaced()
*/
void QXYSeries::replace(int index, qreal newX, qreal newY)
{
replace(index, QPointF(newX, newY));
}
/*!
Replaces the point at the position specified by \a index with the point
specified by \a newPoint.
\sa pointReplaced()
*/
void QXYSeries::replace(int index, const QPointF &newPoint)
{
Q_D(QXYSeries);
if (isValidValue(newPoint)) {
d->m_points[index] = newPoint;
emit pointReplaced(index);
}
}
/*!
Replaces the current points with the points specified by \a points.
\note This is much faster than replacing data points one by one,
or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced()
when the points have been replaced. However, note that using the overload that takes
\c{QVector<QPointF>} as parameter is faster than using this overload.
\sa pointsReplaced()
*/
void QXYSeries::replace(QList<QPointF> points)
{
replace(points.toVector());
}
/*!
Replaces the current points with the points specified by \a points.
\note This is much faster than replacing data points one by one,
or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced()
when the points have been replaced.
\sa pointsReplaced()
*/
void QXYSeries::replace(QVector<QPointF> points)
{
Q_D(QXYSeries);
d->m_points = points;
emit pointsReplaced();
}
/*!
Removes the point that has the coordinates \a x and \a y from the series.
\sa pointRemoved()
*/
void QXYSeries::remove(qreal x, qreal y)
{
remove(QPointF(x, y));
}
/*!
Removes the data point \a point from the series.
\sa pointRemoved()
*/
void QXYSeries::remove(const QPointF &point)
{
Q_D(QXYSeries);
int index = d->m_points.indexOf(point);
if (index == -1)
return;
remove(index);
}
/*!
Removes the point at the position specified by \a index from the series.
\sa pointRemoved()
*/
void QXYSeries::remove(int index)
{
Q_D(QXYSeries);
d->m_points.remove(index);
emit pointRemoved(index);
}
/*!
Removes the number of points specified by \a count from the series starting at
the position specified by \a index.
\sa pointsRemoved()
*/
void QXYSeries::removePoints(int index, int count)
{
// This function doesn't overload remove as there is chance for it to get mixed up with
// remove(qreal, qreal) overload in some implicit casting cases.
Q_D(QXYSeries);
if (count > 0) {
d->m_points.remove(index, count);
emit pointsRemoved(index, count);
}
}
/*!
Inserts the data point \a point in the series at the position specified by
\a index.
\sa pointAdded()
*/
void QXYSeries::insert(int index, const QPointF &point)
{
Q_D(QXYSeries);
if (isValidValue(point)) {
index = qMax(0, qMin(index, d->m_points.size()));
d->m_points.insert(index, point);
emit pointAdded(index);
}
}
/*!
Removes all points from the series.
\sa pointsRemoved()
*/
void QXYSeries::clear()
{
Q_D(QXYSeries);
removePoints(0, d->m_points.size());
}
/*!
Returns the points in the series as a list.
Use pointsVector() for better performance.
*/
QList<QPointF> QXYSeries::points() const
{
Q_D(const QXYSeries);
return d->m_points.toList();
}
/*!
Returns the points in the series as a vector.
This is more efficient than calling points().
*/
QVector<QPointF> QXYSeries::pointsVector() const
{
Q_D(const QXYSeries);
return d->m_points;
}
/*!
Returns the data point at the position specified by \a index in the internal
points vector.
*/
const QPointF &QXYSeries::at(int index) const
{
Q_D(const QXYSeries);
return d->m_points.at(index);
}
/*!
Returns the number of data points in a series.
*/
int QXYSeries::count() const
{
Q_D(const QXYSeries);
return d->m_points.count();
}
/*!
Sets the pen used for drawing points on the chart to \a pen. If the pen is
not defined, the pen from the chart theme is used.
\sa QChart::setTheme()
*/
void QXYSeries::setPen(const QPen &pen)
{
Q_D(QXYSeries);
if (d->m_pen != pen) {
bool emitColorChanged = d->m_pen.color() != pen.color();
d->m_pen = pen;
emit d->updated();
if (emitColorChanged)
emit colorChanged(pen.color());
emit penChanged(pen);
}
}
QPen QXYSeries::pen() const
{
Q_D(const QXYSeries);
if (d->m_pen == QChartPrivate::defaultPen())
return QPen();
else
return d->m_pen;
}
/*!
Sets the brush used for drawing points on the chart to \a brush. If the
brush is not defined, the brush from the chart theme setting is used.
\sa QChart::setTheme()
*/
void QXYSeries::setBrush(const QBrush &brush)
{
Q_D(QXYSeries);
if (d->m_brush != brush) {
d->m_brush = brush;
emit d->updated();
}
}
QBrush QXYSeries::brush() const
{
Q_D(const QXYSeries);
if (d->m_brush == QChartPrivate::defaultBrush())
return QBrush();
else
return d->m_brush;
}
void QXYSeries::setColor(const QColor &color)
{
QPen p = pen();
if (p.color() != color) {
p.setColor(color);
setPen(p);
}
}
QColor QXYSeries::color() const
{
return pen().color();
}
void QXYSeries::setPointsVisible(bool visible)
{
Q_D(QXYSeries);
if (d->m_pointsVisible != visible) {
d->m_pointsVisible = visible;
emit d->updated();
}
}
bool QXYSeries::pointsVisible() const
{
Q_D(const QXYSeries);
return d->m_pointsVisible;
}
void QXYSeries::setPointLabelsFormat(const QString &format)
{
Q_D(QXYSeries);
if (d->m_pointLabelsFormat != format) {
d->m_pointLabelsFormat = format;
emit pointLabelsFormatChanged(format);
}
}
QString QXYSeries::pointLabelsFormat() const
{
Q_D(const QXYSeries);
return d->m_pointLabelsFormat;
}
void QXYSeries::setPointLabelsVisible(bool visible)
{
Q_D(QXYSeries);
if (d->m_pointLabelsVisible != visible) {
d->m_pointLabelsVisible = visible;
emit pointLabelsVisibilityChanged(visible);
}
}
bool QXYSeries::pointLabelsVisible() const
{
Q_D(const QXYSeries);
return d->m_pointLabelsVisible;
}
void QXYSeries::setPointLabelsFont(const QFont &font)
{
Q_D(QXYSeries);
if (d->m_pointLabelsFont != font) {
d->m_pointLabelsFont = font;
emit pointLabelsFontChanged(font);
}
}
QFont QXYSeries::pointLabelsFont() const
{
Q_D(const QXYSeries);
return d->m_pointLabelsFont;
}
void QXYSeries::setPointLabelsColor(const QColor &color)
{
Q_D(QXYSeries);
if (d->m_pointLabelsColor != color) {
d->m_pointLabelsColor = color;
emit pointLabelsColorChanged(color);
}
}
QColor QXYSeries::pointLabelsColor() const
{
Q_D(const QXYSeries);
if (d->m_pointLabelsColor == QChartPrivate::defaultPen().color())
return QPen().color();
else
return d->m_pointLabelsColor;
}
void QXYSeries::setPointLabelsClipping(bool enabled)
{
Q_D(QXYSeries);
if (d->m_pointLabelsClipping != enabled) {
d->m_pointLabelsClipping = enabled;
emit pointLabelsClippingChanged(enabled);
}
}
bool QXYSeries::pointLabelsClipping() const
{
Q_D(const QXYSeries);
return d->m_pointLabelsClipping;
}
/*!
Stream operator for adding the data point \a point to the series.
\sa append()
*/
QXYSeries &QXYSeries::operator<< (const QPointF &point)
{
append(point);
return *this;
}
/*!
Stream operator for adding the list of data points specified by \a points
to the series.
\sa append()
*/
QXYSeries &QXYSeries::operator<< (const QList<QPointF>& points)
{
append(points);
return *this;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q)
: QAbstractSeriesPrivate(q),
m_pen(QChartPrivate::defaultPen()),
m_brush(QChartPrivate::defaultBrush()),
m_pointsVisible(false),
m_pointLabelsFormat(QLatin1String("@xPoint, @yPoint")),
m_pointLabelsVisible(false),
m_pointLabelsFont(QChartPrivate::defaultFont()),
m_pointLabelsColor(QChartPrivate::defaultPen().color()),
m_pointLabelsClipping(true)
{
}
void QXYSeriesPrivate::initializeDomain()
{
qreal minX(0);
qreal minY(0);
qreal maxX(1);
qreal maxY(1);
Q_Q(QXYSeries);
const QVector<QPointF> &points = q->pointsVector();
if (!points.isEmpty()) {
minX = points[0].x();
minY = points[0].y();
maxX = minX;
maxY = minY;
for (int i = 0; i < points.count(); i++) {
qreal x = points[i].x();
qreal y = points[i].y();
minX = qMin(minX, x);
minY = qMin(minY, y);
maxX = qMax(maxX, x);
maxY = qMax(maxY, y);
}
}
domain()->setRange(minX, maxX, minY, maxY);
}
QList<QLegendMarker*> QXYSeriesPrivate::createLegendMarkers(QLegend* legend)
{
Q_Q(QXYSeries);
QList<QLegendMarker*> list;
return list << new QXYLegendMarker(q,legend);
}
void QXYSeriesPrivate::initializeAxes()
{
}
QAbstractAxis::AxisType QXYSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
{
Q_UNUSED(orientation);
return QAbstractAxis::AxisTypeValue;
}
QAbstractAxis* QXYSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
{
Q_UNUSED(orientation);
return new QValueAxis;
}
void QXYSeriesPrivate::initializeAnimations(QtCharts::QChart::AnimationOptions options,
int duration, QEasingCurve &curve)
{
XYChart *item = static_cast<XYChart *>(m_item.data());
Q_ASSERT(item);
if (item->animation())
item->animation()->stopAndDestroyLater();
if (options.testFlag(QChart::SeriesAnimations))
item->setAnimation(new XYAnimation(item, duration, curve));
else
item->setAnimation(0);
QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
}
void QXYSeriesPrivate::drawSeriesPointLabels(QPainter *painter, const QVector<QPointF> &points,
const int offset)
{
if (points.size() == 0)
return;
static const QString xPointTag(QLatin1String("@xPoint"));
static const QString yPointTag(QLatin1String("@yPoint"));
const int labelOffset = offset + 2;
QFont f(m_pointLabelsFont);
f.setPixelSize(QFontInfo(m_pointLabelsFont).pixelSize());
painter->setFont(f);
painter->setPen(QPen(m_pointLabelsColor));
QFontMetrics fm(painter->font());
// m_points is used for the label here as it has the series point information
// points variable passed is used for positioning because it has the coordinates
const int pointCount = qMin(points.size(), m_points.size());
for (int i(0); i < pointCount; i++) {
QString pointLabel = m_pointLabelsFormat;
pointLabel.replace(xPointTag, presenter()->numberToString(m_points.at(i).x()));
pointLabel.replace(yPointTag, presenter()->numberToString(m_points.at(i).y()));
// Position text in relation to the point
int pointLabelWidth = fm.horizontalAdvance(pointLabel);
QPointF position(points.at(i));
position.setX(position.x() - pointLabelWidth / 2);
position.setY(position.y() - labelOffset);
painter->drawText(position, pointLabel);
}
}
QT_CHARTS_END_NAMESPACE
#include "moc_qxyseries.cpp"
#include "moc_qxyseries_p.cpp"