xychart.cpp
190 lines
| 5.7 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r794 | /**************************************************************************** | ||
Michal Klocek
|
r1217 | ** | ||
Titta Heikkala
|
r2776 | ** Copyright (C) 2015 The Qt Company Ltd | ||
Michal Klocek
|
r1217 | ** All rights reserved. | ||
Titta Heikkala
|
r2776 | ** For any questions to The Qt Company, please use contact form at http://qt.io | ||
Michal Klocek
|
r1217 | ** | ||
Titta Heikkala
|
r2740 | ** This file is part of the Qt Charts module. | ||
Michal Klocek
|
r1217 | ** | ||
Titta Heikkala
|
r2740 | ** Licensees holding valid commercial license for Qt may use this file in | ||
** accordance with the Qt License Agreement provided with the Software | ||||
** or, alternatively, in accordance with the terms contained in a written | ||||
Titta Heikkala
|
r2776 | ** agreement between you and The Qt Company. | ||
Michal Klocek
|
r1217 | ** | ||
** If you have questions regarding the use of this file, please use | ||||
Titta Heikkala
|
r2740 | ** contact form at http://qt.io | ||
Michal Klocek
|
r1217 | ** | ||
****************************************************************************/ | ||||
Jani Honkonen
|
r794 | |||
Titta Heikkala
|
r2714 | #include <private/xychart_p.h> | ||
#include <QtCharts/QXYSeries> | ||||
#include <private/qxyseries_p.h> | ||||
#include <private/chartpresenter_p.h> | ||||
#include <private/abstractdomain_p.h> | ||||
#include <QtCharts/QXYModelMapper> | ||||
#include <private/qabstractaxis_p.h> | ||||
#include <QtGui/QPainter> | ||||
#include <QtCore/QAbstractItemModel> | ||||
Michal Klocek
|
r1735 | |||
Michal Klocek
|
r466 | |||
Titta Heikkala
|
r2712 | QT_CHARTS_BEGIN_NAMESPACE | ||
Michal Klocek
|
r466 | |||
Miikka Heikkinen
|
r2483 | XYChart::XYChart(QXYSeries *series, QGraphicsItem *item): | ||
Michal Klocek
|
r2273 | ChartItem(series->d_func(),item), | ||
Jani Honkonen
|
r2097 | m_series(series), | ||
m_animation(0), | ||||
m_dirty(true) | ||||
Michal Klocek
|
r1217 | { | ||
Tero Ahola
|
r1782 | QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int))); | ||
Tero Ahola
|
r1783 | QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced())); | ||
Tero Ahola
|
r1782 | QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int))); | ||
QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int))); | ||||
QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF))); | ||||
Marek Rosa
|
r2255 | QObject::connect(this, SIGNAL(hovered(QPointF,bool)), series, SIGNAL(hovered(QPointF,bool))); | ||
Titta Heikkala
|
r2739 | QObject::connect(this, SIGNAL(pressed(QPointF)), series, SIGNAL(pressed(QPointF))); | ||
QObject::connect(this, SIGNAL(released(QPointF)), series, SIGNAL(released(QPointF))); | ||||
QObject::connect(this, SIGNAL(doubleClicked(QPointF)), series, SIGNAL(doubleClicked(QPointF))); | ||||
Michal Klocek
|
r1217 | } | ||
Miikka Heikkinen
|
r2483 | void XYChart::setGeometryPoints(const QVector<QPointF> &points) | ||
Michal Klocek
|
r1217 | { | ||
m_points = points; | ||||
} | ||||
Jani Honkonen
|
r2104 | void XYChart::setAnimation(XYAnimation *animation) | ||
Michal Klocek
|
r466 | { | ||
Jani Honkonen
|
r2097 | m_animation = animation; | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1241 | void XYChart::setDirty(bool dirty) | ||
{ | ||||
Jani Honkonen
|
r2097 | m_dirty = dirty; | ||
Michal Klocek
|
r1241 | } | ||
Miikka Heikkinen
|
r2483 | // Returns a vector with same size as geometryPoints vector, indicating | ||
// the off grid status of points. | ||||
QVector<bool> XYChart::offGridStatusVector() | ||||
{ | ||||
qreal minX = domain()->minX(); | ||||
qreal maxX = domain()->maxX(); | ||||
qreal minY = domain()->minY(); | ||||
qreal maxY = domain()->maxY(); | ||||
QVector<bool> returnVector; | ||||
returnVector.resize(m_points.size()); | ||||
Miikka Heikkinen
|
r2492 | // During remove animation series may have different number of points, | ||
Miikka Heikkinen
|
r2489 | // so ensure we don't go over the index. No need to check for zero points, this | ||
// will not be called in such a situation. | ||||
const int seriesLastIndex = m_series->count() - 1; | ||||
Miikka Heikkinen
|
r2483 | |||
for (int i = 0; i < m_points.size(); i++) { | ||||
Miikka Heikkinen
|
r2491 | const QPointF &seriesPoint = m_series->at(qMin(seriesLastIndex, i)); | ||
Miikka Heikkinen
|
r2483 | if (seriesPoint.x() < minX | ||
|| seriesPoint.x() > maxX | ||||
|| seriesPoint.y() < minY | ||||
|| seriesPoint.y() > maxY) { | ||||
returnVector[i] = true; | ||||
} else { | ||||
returnVector[i] = false; | ||||
} | ||||
} | ||||
return returnVector; | ||||
} | ||||
Jani Honkonen
|
r2097 | void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index) | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1271 | |||
Michal Klocek
|
r1217 | if (m_animation) { | ||
Michal Klocek
|
r1271 | m_animation->setup(oldPoints, newPoints, index); | ||
Tero Ahola
|
r1782 | m_points = newPoints; | ||
Michal Klocek
|
r1241 | setDirty(false); | ||
presenter()->startAnimation(m_animation); | ||||
Jani Honkonen
|
r2097 | } else { | ||
Tero Ahola
|
r1782 | m_points = newPoints; | ||
Michal Klocek
|
r1217 | updateGeometry(); | ||
Michal Klocek
|
r530 | } | ||
Michal Klocek
|
r466 | } | ||
//handlers | ||||
Michal Klocek
|
r1218 | void XYChart::handlePointAdded(int index) | ||
Michal Klocek
|
r466 | { | ||
Jani Honkonen
|
r2097 | Q_ASSERT(index < m_series->count()); | ||
Q_ASSERT(index >= 0); | ||||
Michal Klocek
|
r1217 | |||
Michal Klocek
|
r1241 | QVector<QPointF> points; | ||
Miikka Heikkinen
|
r2427 | if (m_dirty || m_points.isEmpty()) { | ||
Michal Klocek
|
r2273 | points = domain()->calculateGeometryPoints(m_series->points()); | ||
Jani Honkonen
|
r2097 | } else { | ||
points = m_points; | ||||
Marek Rosa
|
r2356 | QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData); | ||
Miikka Heikkinen
|
r2427 | if (!m_validData) | ||
Marek Rosa
|
r2356 | m_points.clear(); | ||
Miikka Heikkinen
|
r2427 | else | ||
points.insert(index, point); | ||||
Jani Honkonen
|
r2097 | } | ||
Michal Klocek
|
r1241 | |||
Jani Honkonen
|
r2097 | updateChart(m_points, points, index); | ||
Michal Klocek
|
r466 | } | ||
Marek Rosa
|
r1054 | |||
Michal Klocek
|
r1218 | void XYChart::handlePointRemoved(int index) | ||
Michal Klocek
|
r938 | { | ||
Jani Honkonen
|
r2097 | Q_ASSERT(index <= m_series->count()); | ||
Q_ASSERT(index >= 0); | ||||
Michal Klocek
|
r1217 | |||
Jani Honkonen
|
r2097 | QVector<QPointF> points; | ||
Michal Klocek
|
r1217 | |||
Miikka Heikkinen
|
r2427 | if (m_dirty || m_points.isEmpty()) { | ||
Michal Klocek
|
r2273 | points = domain()->calculateGeometryPoints(m_series->points()); | ||
Jani Honkonen
|
r2097 | } else { | ||
points = m_points; | ||||
points.remove(index); | ||||
} | ||||
Michal Klocek
|
r1241 | |||
Jani Honkonen
|
r2097 | updateChart(m_points, points, index); | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | void XYChart::handlePointReplaced(int index) | ||
Michal Klocek
|
r466 | { | ||
Jani Honkonen
|
r2097 | Q_ASSERT(index < m_series->count()); | ||
Q_ASSERT(index >= 0); | ||||
Michal Klocek
|
r1217 | |||
Jani Honkonen
|
r2097 | QVector<QPointF> points; | ||
Michal Klocek
|
r1217 | |||
Miikka Heikkinen
|
r2427 | if (m_dirty || m_points.isEmpty()) { | ||
Michal Klocek
|
r2273 | points = domain()->calculateGeometryPoints(m_series->points()); | ||
Jani Honkonen
|
r2097 | } else { | ||
Marek Rosa
|
r2356 | QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData); | ||
Miikka Heikkinen
|
r2427 | if (!m_validData) | ||
Marek Rosa
|
r2356 | m_points.clear(); | ||
Jani Honkonen
|
r2097 | points = m_points; | ||
Miikka Heikkinen
|
r2427 | if (m_validData) | ||
points.replace(index, point); | ||||
Jani Honkonen
|
r2097 | } | ||
Michal Klocek
|
r1241 | |||
Jani Honkonen
|
r2097 | updateChart(m_points, points, index); | ||
Michal Klocek
|
r466 | } | ||
Tero Ahola
|
r1783 | void XYChart::handlePointsReplaced() | ||
{ | ||||
// All the points were replaced -> recalculate | ||||
Michal Klocek
|
r2273 | QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points()); | ||
Tero Ahola
|
r1783 | updateChart(m_points, points, -1); | ||
} | ||||
Michal Klocek
|
r1698 | void XYChart::handleDomainUpdated() | ||
Michal Klocek
|
r466 | { | ||
sauimone
|
r743 | if (isEmpty()) return; | ||
Michal Klocek
|
r2273 | QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points()); | ||
Jani Honkonen
|
r2097 | updateChart(m_points, points); | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | bool XYChart::isEmpty() | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r2273 | return domain()->isEmpty() || m_series->points().isEmpty(); | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | #include "moc_xychart_p.cpp" | ||
Michal Klocek
|
r466 | |||
Titta Heikkala
|
r2712 | QT_CHARTS_END_NAMESPACE | ||