qxyseries.cpp
471 lines
| 11.1 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r794 | /**************************************************************************** | ||
** | ||||
** Copyright (C) 2012 Digia Plc | ||||
** All rights reserved. | ||||
** For any questions to Digia, please use contact form at http://qt.digia.com | ||||
** | ||||
** This file is part of the Qt Commercial Charts Add-on. | ||||
** | ||||
** $QT_BEGIN_LICENSE$ | ||||
** Licensees holding valid Qt Commercial licenses may use this file in | ||||
** accordance with the Qt Commercial License Agreement provided with the | ||||
** Software or, alternatively, in accordance with the terms contained in | ||||
** a written agreement between you and Digia. | ||||
** | ||||
** If you have questions regarding the use of this file, please use | ||||
** contact form at http://qt.digia.com | ||||
** $QT_END_LICENSE$ | ||||
** | ||||
****************************************************************************/ | ||||
Michal Klocek
|
r466 | #include "qxyseries.h" | ||
Michal Klocek
|
r938 | #include "qxyseries_p.h" | ||
Michal Klocek
|
r943 | #include "domain_p.h" | ||
Michal Klocek
|
r950 | #include "legendmarker_p.h" | ||
Marek Rosa
|
r1805 | #include "qvalueaxis.h" | ||
Michal Klocek
|
r466 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
/*! | ||||
\class QXYSeries | ||||
Michal Klocek
|
r470 | \brief The QXYSeries class is a base class for line, spline and scatter series. | ||
Michal Klocek
|
r466 | */ | ||
Tero Ahola
|
r1491 | /*! | ||
\qmlclass XYSeries | ||||
Tero Ahola
|
r1521 | \inherits AbstractSeries | ||
The XYSeries class is a base class for line, spline and scatter series. | ||||
Tero Ahola
|
r1491 | |||
The class cannot be instantiated directly. | ||||
*/ | ||||
Michal Klocek
|
r466 | |||
Jani Honkonen
|
r1336 | /*! | ||
\property QXYSeries::pointsVisible | ||||
Tero Ahola
|
r1491 | Controls if the data points are visible and should be drawn. | ||
*/ | ||||
/*! | ||||
\qmlproperty bool XYSeries::pointsVisible | ||||
Jani Honkonen
|
r1336 | Controls if the data points are visible and should be drawn. | ||
*/ | ||||
Michal Klocek
|
r466 | /*! | ||
\fn QPen QXYSeries::pen() const | ||||
Michal Klocek
|
r480 | \brief Returns pen used to draw points for series. | ||
Michal Klocek
|
r466 | \sa setPen() | ||
*/ | ||||
Michal Klocek
|
r480 | /*! | ||
\fn QBrush QXYSeries::brush() const | ||||
\brief Returns brush used to draw points for series. | ||||
\sa setBrush() | ||||
*/ | ||||
Tero Ahola
|
r1481 | /*! | ||
\property QXYSeries::color | ||||
Tero Ahola
|
r1491 | The color of the series. This is line (pen) color in case of QLineSeries or QSplineSeries and | ||
fill (brush) color in case of QScatterSeries or QAreaSeries. | ||||
\sa QXYSeries::pen(), QXYSeries::brush() | ||||
*/ | ||||
/*! | ||||
\qmlproperty color XYSeries::color | ||||
The color of the series. This is line (pen) color in case of LineSeries or SplineSeries and | ||||
fill (brush) color in case of ScatterSeries or AreaSeries. | ||||
Tero Ahola
|
r1481 | */ | ||
Michal Klocek
|
r574 | /*! | ||
\fn void QXYSeries::clicked(const QPointF& point) | ||||
\brief Signal is emitted when user clicks the \a point on chart. | ||||
*/ | ||||
Tero Ahola
|
r1491 | /*! | ||
\qmlsignal XYSeries::onClicked(QPointF point) | ||||
Signal is emitted when user clicks the \a point on chart. For example: | ||||
\code | ||||
LineSeries { | ||||
Tero Ahola
|
r1532 | XYPoint { x: 0; y: 0 } | ||
XYPoint { x: 1.1; y: 2.1 } | ||||
Tero Ahola
|
r1491 | onClicked: console.log("onClicked: " + point.x + ", " + point.y); | ||
} | ||||
\endcode | ||||
*/ | ||||
Michal Klocek
|
r574 | |||
Michal Klocek
|
r466 | /*! | ||
Jani Honkonen
|
r1336 | \fn void QXYSeries::pointReplaced(int index) | ||
Tero Ahola
|
r1491 | Signal is emitted when a point has been replaced at \a index. | ||
Jani Honkonen
|
r1336 | \sa replace() | ||
Michal Klocek
|
r466 | */ | ||
Tero Ahola
|
r1491 | /*! | ||
Tero Ahola
|
r1531 | \qmlsignal XYSeries::onPointReplaced(int index) | ||
Tero Ahola
|
r1491 | Signal is emitted when a point has been replaced at \a index. | ||
*/ | ||||
Michal Klocek
|
r466 | |||
Tero Ahola
|
r1783 | /*! | ||
\fn void QXYSeries::pointsReplaced() | ||||
Signal is emitted when all points have been replaced with another points. | ||||
\sa replace() | ||||
*/ | ||||
/*! | ||||
\qmlsignal XYSeries::onPointsReplaced() | ||||
*/ | ||||
Michal Klocek
|
r466 | /*! | ||
Jani Honkonen
|
r1336 | \fn void QXYSeries::pointAdded(int index) | ||
Tero Ahola
|
r1491 | Signal is emitted when a point has been added at \a index. | ||
Jani Honkonen
|
r1336 | \sa append(), insert() | ||
Michal Klocek
|
r466 | */ | ||
Tero Ahola
|
r1491 | /*! | ||
Tero Ahola
|
r1531 | \qmlsignal XYSeries::onPointAdded(int index) | ||
Tero Ahola
|
r1491 | Signal is emitted when a point has been added at \a index. | ||
*/ | ||||
Michal Klocek
|
r466 | |||
/*! | ||||
Jani Honkonen
|
r1336 | \fn void QXYSeries::pointRemoved(int index) | ||
Tero Ahola
|
r1491 | Signal is emitted when a point has been removed from \a index. | ||
Jani Honkonen
|
r1336 | \sa remove() | ||
Michal Klocek
|
r466 | */ | ||
Tero Ahola
|
r1491 | /*! | ||
Tero Ahola
|
r1531 | \qmlsignal XYSeries::onPointRemoved(int index) | ||
Tero Ahola
|
r1491 | Signal is emitted when a point has been removed from \a index. | ||
*/ | ||||
Michal Klocek
|
r466 | |||
Tero Ahola
|
r1465 | /*! | ||
Tero Ahola
|
r1481 | \fn void QXYSeries::colorChanged(QColor color) | ||
\brief Signal is emitted when the line (pen) color has changed to \a color. | ||||
Tero Ahola
|
r1465 | */ | ||
Tero Ahola
|
r1491 | /*! | ||
Tero Ahola
|
r1531 | \qmlsignal XYSeries::onColorChanged(color color) | ||
Tero Ahola
|
r1491 | Signal is emitted when the line (pen) color has changed to \a color. | ||
*/ | ||||
Tero Ahola
|
r1465 | |||
Michal Klocek
|
r466 | /*! | ||
Marek Rosa
|
r940 | \fn void QXYSeriesPrivate::updated() | ||
Michal Klocek
|
r466 | \brief \internal | ||
*/ | ||||
Tero Ahola
|
r1491 | /*! | ||
Tero Ahola
|
r1521 | \qmlmethod XYSeries::append(real x, real y) | ||
Append point (\a x, \a y) to the series | ||||
*/ | ||||
/*! | ||||
\qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY) | ||||
Replaces point (\a oldX, \a oldY) with point (\a newX, \a newY). Does nothing, if point (oldX, oldY) does not | ||||
exist. | ||||
*/ | ||||
/*! | ||||
\qmlmethod XYSeries::remove(real x, real y) | ||||
Removes point (\a x, \a y) from the series. Does nothing, if point (x, y) does not exist. | ||||
*/ | ||||
/*! | ||||
\qmlmethod XYSeries::insert(int index, real x, real y) | ||||
Inserts point (\a x, \a y) to the \a index. If index is 0 or smaller than 0 the point is prepended to the list of | ||||
points. If index is the same as or bigger than count, the point is appended to the list of points. | ||||
*/ | ||||
/*! | ||||
\qmlmethod QPointF XYSeries::at(int index) | ||||
Returns point at \a index. Returns (0, 0) if the index is not valid. | ||||
Tero Ahola
|
r1491 | */ | ||
Michal Klocek
|
r466 | /*! | ||
Tero Ahola
|
r973 | \internal | ||
Michal Klocek
|
r466 | Constructs empty series object which is a child of \a parent. | ||
Michal Klocek
|
r974 | When series object is added to QChartView or QChart instance ownerships is transferred. | ||
Michal Klocek
|
r466 | */ | ||
Jani Honkonen
|
r2097 | QXYSeries::QXYSeries(QXYSeriesPrivate &d, QObject *parent) | ||
: QAbstractSeries(d, parent) | ||||
Michal Klocek
|
r938 | { | ||
Michal Klocek
|
r466 | } | ||
Tero Ahola
|
r1342 | |||
Michal Klocek
|
r466 | /*! | ||
Destroys the object. Series added to QChartView or QChart instances are owned by those, | ||||
and are deleted when mentioned object are destroyed. | ||||
*/ | ||||
QXYSeries::~QXYSeries() | ||||
{ | ||||
} | ||||
/*! | ||||
Adds data point \a x \a y to the series. Points are connected with lines on the chart. | ||||
*/ | ||||
Jani Honkonen
|
r2097 | void QXYSeries::append(qreal x, qreal y) | ||
Michal Klocek
|
r466 | { | ||
Jani Honkonen
|
r2097 | append(QPointF(x, y)); | ||
Michal Klocek
|
r466 | } | ||
/*! | ||||
This is an overloaded function. | ||||
Adds data \a point to the series. Points are connected with lines on the chart. | ||||
*/ | ||||
Jani Honkonen
|
r796 | void QXYSeries::append(const QPointF &point) | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1057 | Q_D(QXYSeries); | ||
Jani Honkonen
|
r2097 | d->m_points << point; | ||
emit pointAdded(d->m_points.count() - 1); | ||||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r481 | /*! | ||
This is an overloaded function. | ||||
Adds list of data \a points to the series. Points are connected with lines on the chart. | ||||
*/ | ||||
Michal Klocek
|
r1057 | void QXYSeries::append(const QList<QPointF> &points) | ||
Michal Klocek
|
r481 | { | ||
Jani Honkonen
|
r2097 | foreach (const QPointF &point , points) | ||
Michal Klocek
|
r1057 | append(point); | ||
Michal Klocek
|
r481 | } | ||
Jani Honkonen
|
r1336 | /*! | ||
Replaces data point \a oldX \a oldY with data point \a newX \a newY. | ||||
Tero Ahola
|
r1783 | \sa QXYSeries::pointReplaced() | ||
Jani Honkonen
|
r1336 | */ | ||
Jani Honkonen
|
r2097 | void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY) | ||
Michal Klocek
|
r466 | { | ||
Jani Honkonen
|
r2097 | replace(QPointF(oldX, oldY), QPointF(newX, newY)); | ||
Michal Klocek
|
r466 | } | ||
Jani Honkonen
|
r1336 | /*! | ||
Replaces \a oldPoint with \a newPoint. | ||||
Tero Ahola
|
r1783 | \sa QXYSeries::pointReplaced() | ||
Jani Honkonen
|
r1336 | */ | ||
Jani Honkonen
|
r2097 | void QXYSeries::replace(const QPointF &oldPoint, const QPointF &newPoint) | ||
Michal Klocek
|
r622 | { | ||
Michal Klocek
|
r938 | Q_D(QXYSeries); | ||
Michal Klocek
|
r1057 | int index = d->m_points.indexOf(oldPoint); | ||
Jani Honkonen
|
r2097 | if (index == -1) | ||
return; | ||||
Michal Klocek
|
r1057 | d->m_points[index] = newPoint; | ||
Marek Rosa
|
r1262 | emit pointReplaced(index); | ||
Michal Klocek
|
r622 | } | ||
Tero Ahola
|
r1783 | /*! | ||
Replaces the current points with \a points. This is 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 QXYSeries::pointsReplaced() | ||||
*/ | ||||
void QXYSeries::replace(QList<QPointF> points) | ||||
{ | ||||
Q_D(QXYSeries); | ||||
d->m_points = points.toVector(); | ||||
emit pointsReplaced(); | ||||
} | ||||
Michal Klocek
|
r466 | /*! | ||
Michal Klocek
|
r541 | Removes current \a x and \a y value. | ||
Michal Klocek
|
r466 | */ | ||
Jani Honkonen
|
r2097 | void QXYSeries::remove(qreal x, qreal y) | ||
Michal Klocek
|
r466 | { | ||
Jani Honkonen
|
r2097 | remove(QPointF(x, y)); | ||
Michal Klocek
|
r466 | } | ||
/*! | ||||
Jani Honkonen
|
r1336 | Removes current \a point x value. | ||
Note: point y value is ignored. | ||||
Michal Klocek
|
r466 | */ | ||
sauimone
|
r743 | void QXYSeries::remove(const QPointF &point) | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1057 | Q_D(QXYSeries); | ||
int index = d->m_points.indexOf(point); | ||||
Jani Honkonen
|
r2097 | if (index == -1) | ||
return; | ||||
Michal Klocek
|
r1057 | d->m_points.remove(index); | ||
Marek Rosa
|
r1262 | emit pointRemoved(index); | ||
Michal Klocek
|
r466 | } | ||
Jani Honkonen
|
r1336 | /*! | ||
Inserts a \a point in the series at \a index position. | ||||
*/ | ||||
Marek Rosa
|
r1256 | void QXYSeries::insert(int index, const QPointF &point) | ||
{ | ||||
Q_D(QXYSeries); | ||||
d->m_points.insert(index, point); | ||||
Marek Rosa
|
r1262 | emit pointAdded(index); | ||
Marek Rosa
|
r1256 | } | ||
Jani Honkonen
|
r1336 | /*! | ||
Removes all points from the series. | ||||
*/ | ||||
Marek Rosa
|
r1256 | void QXYSeries::clear() | ||
{ | ||||
Q_D(QXYSeries); | ||||
for (int i = d->m_points.size() - 1; i >= 0; i--) | ||||
remove(d->m_points.at(i)); | ||||
} | ||||
Michal Klocek
|
r466 | /*! | ||
sauimone
|
r1724 | Returns list of points in the series. | ||
Michal Klocek
|
r466 | */ | ||
Michal Klocek
|
r1057 | QList<QPointF> QXYSeries::points() const | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r938 | Q_D(const QXYSeries); | ||
Marek Rosa
|
r1230 | return d->m_points.toList(); | ||
Michal Klocek
|
r466 | } | ||
/*! | ||||
Returns number of data points within series. | ||||
*/ | ||||
int QXYSeries::count() const | ||||
{ | ||||
Michal Klocek
|
r938 | Q_D(const QXYSeries); | ||
Michal Klocek
|
r1057 | return d->m_points.count(); | ||
Tero Ahola
|
r491 | } | ||
Michal Klocek
|
r467 | /*! | ||
Michal Klocek
|
r481 | Sets \a pen used for drawing points on the chart. If the pen is not defined, the | ||
pen from chart theme is used. | ||||
Marek Rosa
|
r909 | \sa QChart::setTheme() | ||
Michal Klocek
|
r467 | */ | ||
sauimone
|
r743 | void QXYSeries::setPen(const QPen &pen) | ||
Michal Klocek
|
r467 | { | ||
Michal Klocek
|
r938 | Q_D(QXYSeries); | ||
Tero Ahola
|
r1537 | if (d->m_pen != pen) { | ||
bool emitColorChanged = d->m_pen.color() != pen.color(); | ||||
Michal Klocek
|
r938 | d->m_pen = pen; | ||
emit d->updated(); | ||||
Tero Ahola
|
r1537 | if (emitColorChanged) | ||
emit colorChanged(pen.color()); | ||||
Michal Klocek
|
r467 | } | ||
} | ||||
Michal Klocek
|
r938 | QPen QXYSeries::pen() const | ||
{ | ||||
Q_D(const QXYSeries); | ||||
return d->m_pen; | ||||
} | ||||
Michal Klocek
|
r467 | /*! | ||
Michal Klocek
|
r481 | Sets \a brush used for drawing points on the chart. If the brush is not defined, brush | ||
from chart theme setting is used. | ||||
Marek Rosa
|
r909 | \sa QChart::setTheme() | ||
Michal Klocek
|
r467 | */ | ||
sauimone
|
r743 | void QXYSeries::setBrush(const QBrush &brush) | ||
Michal Klocek
|
r467 | { | ||
Michal Klocek
|
r938 | Q_D(QXYSeries); | ||
Jani Honkonen
|
r2097 | if (d->m_brush != brush) { | ||
Michal Klocek
|
r938 | d->m_brush = brush; | ||
emit d->updated(); | ||||
Michal Klocek
|
r467 | } | ||
} | ||||
Michal Klocek
|
r938 | QBrush QXYSeries::brush() const | ||
{ | ||||
Q_D(const QXYSeries); | ||||
return d->m_brush; | ||||
} | ||||
Tero Ahola
|
r1481 | 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(); | ||||
} | ||||
Michal Klocek
|
r938 | |||
void QXYSeries::setPointsVisible(bool visible) | ||||
{ | ||||
Q_D(QXYSeries); | ||||
Jani Honkonen
|
r2097 | if (d->m_pointsVisible != visible) { | ||
Michal Klocek
|
r938 | d->m_pointsVisible = visible; | ||
emit d->updated(); | ||||
} | ||||
} | ||||
bool QXYSeries::pointsVisible() const | ||||
{ | ||||
Q_D(const QXYSeries); | ||||
return d->m_pointsVisible; | ||||
} | ||||
Michal Klocek
|
r467 | |||
Michal Klocek
|
r466 | /*! | ||
Stream operator for adding a data \a point to the series. | ||||
Jani Honkonen
|
r796 | \sa append() | ||
Michal Klocek
|
r466 | */ | ||
QXYSeries& QXYSeries::operator<< (const QPointF &point) | ||||
{ | ||||
Jani Honkonen
|
r796 | append(point); | ||
Michal Klocek
|
r466 | return *this; | ||
} | ||||
Michal Klocek
|
r481 | /*! | ||
Stream operator for adding a list of \a points to the series. | ||||
Jani Honkonen
|
r796 | \sa append() | ||
Michal Klocek
|
r481 | */ | ||
Michal Klocek
|
r1057 | QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points) | ||
Michal Klocek
|
r481 | { | ||
Jani Honkonen
|
r796 | append(points); | ||
Michal Klocek
|
r481 | return *this; | ||
} | ||||
Michal Klocek
|
r938 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
Marek Rosa
|
r990 | |||
Marek Rosa
|
r1230 | QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : | ||
QAbstractSeriesPrivate(q), | ||||
Tero Ahola
|
r988 | m_pointsVisible(false) | ||
Michal Klocek
|
r938 | { | ||
} | ||||
Michal Klocek
|
r943 | void QXYSeriesPrivate::scaleDomain(Domain& domain) | ||
{ | ||||
Marek Rosa
|
r1740 | qreal minX(0); | ||
qreal minY(0); | ||||
qreal maxX(1); | ||||
qreal maxY(1); | ||||
Michal Klocek
|
r943 | |||
Michal Klocek
|
r1059 | Q_Q(QXYSeries); | ||
Michal Klocek
|
r1057 | |||
Michal Klocek
|
r1059 | const QList<QPointF>& points = q->points(); | ||
Michal Klocek
|
r1070 | |||
Jani Honkonen
|
r2097 | if (!points.isEmpty()) { | ||
Marek Rosa
|
r1740 | 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); | ||||
} | ||||
Marek Rosa
|
r1205 | } | ||
Jani Honkonen
|
r2097 | domain.setRange(minX, maxX, minY, maxY); | ||
Michal Klocek
|
r943 | } | ||
Michal Klocek
|
r950 | QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend) | ||
{ | ||||
Q_Q(QXYSeries); | ||||
QList<LegendMarker*> list; | ||||
Jani Honkonen
|
r2097 | return list << new XYLegendMarker(q, legend); | ||
Michal Klocek
|
r950 | } | ||
Michal Klocek
|
r1695 | void QXYSeriesPrivate::initializeAxis(QAbstractAxis* axis) | ||
Michal Klocek
|
r1556 | { | ||
Michal Klocek
|
r1588 | Q_UNUSED(axis); | ||
Michal Klocek
|
r1556 | } | ||
Michal Klocek
|
r1695 | QAbstractAxis::AxisType QXYSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const | ||
Michal Klocek
|
r1588 | { | ||
Michal Klocek
|
r1695 | Q_UNUSED(orientation); | ||
Marek Rosa
|
r1818 | return QAbstractAxis::AxisTypeValue; | ||
Michal Klocek
|
r1556 | } | ||
Michal Klocek
|
r466 | #include "moc_qxyseries.cpp" | ||
Michal Klocek
|
r938 | #include "moc_qxyseries_p.cpp" | ||
Michal Klocek
|
r466 | |||
QTCOMMERCIALCHART_END_NAMESPACE | ||||