xychart.cpp
227 lines
| 5.8 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r794 | /**************************************************************************** | ||
Michal Klocek
|
r1217 | ** | ||
** 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$ | ||||
** | ||||
****************************************************************************/ | ||||
Jani Honkonen
|
r794 | |||
Michal Klocek
|
r1218 | #include "xychart_p.h" | ||
Michal Klocek
|
r466 | #include "qxyseries.h" | ||
Michal Klocek
|
r938 | #include "qxyseries_p.h" | ||
Michal Klocek
|
r466 | #include "chartpresenter_p.h" | ||
Michal Klocek
|
r1698 | #include "domain_p.h" | ||
Michal Klocek
|
r1735 | #include "qxymodelmapper.h" | ||
Michal Klocek
|
r466 | #include <QPainter> | ||
Marek Rosa
|
r1055 | #include <QAbstractItemModel> | ||
Michal Klocek
|
r1735 | |||
Michal Klocek
|
r466 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
//TODO: optimize : remove points which are not visible | ||||
Michal Klocek
|
r1736 | XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter):ChartElement(presenter), | ||
Michal Klocek
|
r1217 | m_minX(0), | ||
m_maxX(0), | ||||
m_minY(0), | ||||
m_maxY(0), | ||||
m_series(series), | ||||
Michal Klocek
|
r1241 | 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))); | ||||
Michal Klocek
|
r1217 | } | ||
Michal Klocek
|
r1241 | void XYChart::setGeometryPoints(const QVector<QPointF>& points) | ||
Michal Klocek
|
r1217 | { | ||
m_points = points; | ||||
} | ||||
Michal Klocek
|
r1218 | void XYChart::setClipRect(const QRectF &rect) | ||
Michal Klocek
|
r1217 | { | ||
m_clipRect = rect; | ||||
} | ||||
Michal Klocek
|
r1218 | void XYChart::setAnimation(XYAnimation* animation) | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1217 | m_animation=animation; | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1241 | void XYChart::setDirty(bool dirty) | ||
{ | ||||
m_dirty=dirty; | ||||
} | ||||
Michal Klocek
|
r1218 | QPointF XYChart::calculateGeometryPoint(const QPointF &point) const | ||
Michal Klocek
|
r466 | { | ||
const qreal deltaX = m_size.width()/(m_maxX-m_minX); | ||||
const qreal deltaY = m_size.height()/(m_maxY-m_minY); | ||||
qreal x = (point.x() - m_minX)* deltaX; | ||||
qreal y = (point.y() - m_minY)*-deltaY + m_size.height(); | ||||
return QPointF(x,y); | ||||
} | ||||
Michal Klocek
|
r1218 | QPointF XYChart::calculateGeometryPoint(int index) const | ||
Michal Klocek
|
r466 | { | ||
const qreal deltaX = m_size.width()/(m_maxX-m_minX); | ||||
const qreal deltaY = m_size.height()/(m_maxY-m_minY); | ||||
Michal Klocek
|
r1057 | const QList<QPointF>& vector = m_series->points(); | ||
qreal x = (vector[index].x() - m_minX)* deltaX; | ||||
qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height(); | ||||
Michal Klocek
|
r466 | return QPointF(x,y); | ||
} | ||||
Michal Klocek
|
r1218 | QVector<QPointF> XYChart::calculateGeometryPoints() const | ||
Michal Klocek
|
r466 | { | ||
const qreal deltaX = m_size.width()/(m_maxX-m_minX); | ||||
const qreal deltaY = m_size.height()/(m_maxY-m_minY); | ||||
Michal Klocek
|
r1057 | QVector<QPointF> result; | ||
result.resize(m_series->count()); | ||||
const QList<QPointF>& vector = m_series->points(); | ||||
Michal Klocek
|
r466 | for (int i = 0; i < m_series->count(); ++i) { | ||
Michal Klocek
|
r1057 | qreal x = (vector[i].x() - m_minX)* deltaX; | ||
qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height(); | ||||
result[i].setX(x); | ||||
result[i].setY(y); | ||||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1057 | return result; | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | QPointF XYChart::calculateDomainPoint(const QPointF &point) const | ||
Michal Klocek
|
r544 | { | ||
const qreal deltaX = m_size.width()/(m_maxX-m_minX); | ||||
const qreal deltaY = m_size.height()/(m_maxY-m_minY); | ||||
qreal x = point.x()/deltaX +m_minX; | ||||
qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY; | ||||
return QPointF(x,y); | ||||
} | ||||
Michal Klocek
|
r1218 | 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); | ||||
Michal Klocek
|
r1217 | } | ||
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 | { | ||
Marek Rosa
|
r1230 | Q_ASSERT(index<m_series->count()); | ||
Q_ASSERT(index>=0); | ||||
Michal Klocek
|
r1217 | |||
Michal Klocek
|
r1241 | QVector<QPointF> points; | ||
if(m_dirty) { | ||||
points = calculateGeometryPoints(); | ||||
} else { | ||||
points = m_points; | ||||
QPointF point = calculateGeometryPoint(index); | ||||
points.insert(index, point); | ||||
} | ||||
updateChart(m_points,points,index); | ||||
Michal Klocek
|
r466 | } | ||
Marek Rosa
|
r1054 | |||
Michal Klocek
|
r1218 | void XYChart::handlePointRemoved(int index) | ||
Michal Klocek
|
r938 | { | ||
Michal Klocek
|
r1241 | Q_ASSERT(index<=m_series->count()); | ||
Q_ASSERT(index>=0); | ||||
Michal Klocek
|
r1217 | |||
Michal Klocek
|
r1241 | QVector<QPointF> points; | ||
Michal Klocek
|
r1217 | |||
Michal Klocek
|
r1241 | if(m_dirty) { | ||
points = calculateGeometryPoints(); | ||||
} else { | ||||
points = m_points; | ||||
points.remove(index); | ||||
} | ||||
updateChart(m_points,points,index); | ||||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | void XYChart::handlePointReplaced(int index) | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1241 | Q_ASSERT(index<m_series->count()); | ||
Q_ASSERT(index>=0); | ||||
Michal Klocek
|
r1217 | |||
Michal Klocek
|
r1241 | QVector<QPointF> points; | ||
Michal Klocek
|
r1217 | |||
Michal Klocek
|
r1241 | if(m_dirty) { | ||
points = calculateGeometryPoints(); | ||||
} else { | ||||
QPointF point = calculateGeometryPoint(index); | ||||
points = m_points; | ||||
points.replace(index,point); | ||||
} | ||||
updateChart(m_points,points,index); | ||||
Michal Klocek
|
r466 | } | ||
Tero Ahola
|
r1783 | void XYChart::handlePointsReplaced() | ||
{ | ||||
// All the points were replaced -> recalculate | ||||
QVector<QPointF> points = calculateGeometryPoints(); | ||||
updateChart(m_points, points, -1); | ||||
} | ||||
Michal Klocek
|
r1698 | void XYChart::handleDomainUpdated() | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1698 | m_minX=domain()->minX(); | ||
m_maxX=domain()->maxX(); | ||||
m_minY=domain()->minY(); | ||||
m_maxY=domain()->maxY(); | ||||
sauimone
|
r743 | if (isEmpty()) return; | ||
Michal Klocek
|
r1241 | |||
Michal Klocek
|
r466 | QVector<QPointF> points = calculateGeometryPoints(); | ||
Michal Klocek
|
r1217 | |||
updateChart(m_points,points); | ||||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | void XYChart::handleGeometryChanged(const QRectF &rect) | ||
Michal Klocek
|
r466 | { | ||
Marek Rosa
|
r833 | Q_ASSERT(rect.isValid()); | ||
m_size=rect.size(); | ||||
m_clipRect=rect.translated(-rect.topLeft()); | ||||
Michal Klocek
|
r1218 | m_origin=rect.topLeft(); | ||
Michal Klocek
|
r466 | |||
sauimone
|
r743 | if (isEmpty()) return; | ||
Michal Klocek
|
r1241 | |||
Marek Rosa
|
r833 | QVector<QPointF> points = calculateGeometryPoints(); | ||
Michal Klocek
|
r1241 | |||
Michal Klocek
|
r1217 | updateChart(m_points,points); | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | bool XYChart::isEmpty() | ||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r1082 | return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty(); | ||
Michal Klocek
|
r466 | } | ||
Michal Klocek
|
r1218 | #include "moc_xychart_p.cpp" | ||
Michal Klocek
|
r466 | |||
QTCOMMERCIALCHART_END_NAMESPACE | ||||