xychartitem.cpp
196 lines
| 5.7 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 "xychartitem_p.h" | ||
#include "qxyseries.h" | ||||
Michal Klocek
|
r938 | #include "qxyseries_p.h" | ||
Michal Klocek
|
r466 | #include "chartpresenter_p.h" | ||
Michal Klocek
|
r530 | #include "chartanimator_p.h" | ||
Michal Klocek
|
r466 | #include <QPainter> | ||
Michal Klocek
|
r571 | #include <QGraphicsSceneMouseEvent> | ||
Michal Klocek
|
r466 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
//TODO: optimize : remove points which are not visible | ||||
sauimone
|
r743 | XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter), | ||
m_minX(0), | ||||
m_maxX(0), | ||||
m_minY(0), | ||||
m_maxY(0), | ||||
m_series(series) | ||||
Michal Klocek
|
r466 | { | ||
Michal Klocek
|
r938 | connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int))); | ||
connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int))); | ||||
connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int))); | ||||
sauimone
|
r743 | connect(this,SIGNAL(clicked(const QPointF&)),series,SIGNAL(clicked(const QPointF&))); | ||
Michal Klocek
|
r466 | } | ||
sauimone
|
r743 | QPointF XYChartItem::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); | ||||
} | ||||
QPointF XYChartItem::calculateGeometryPoint(int index) const | ||||
{ | ||||
const qreal deltaX = m_size.width()/(m_maxX-m_minX); | ||||
const qreal deltaY = m_size.height()/(m_maxY-m_minY); | ||||
qreal x = (m_series->x(index) - m_minX)* deltaX; | ||||
qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height(); | ||||
return QPointF(x,y); | ||||
} | ||||
QVector<QPointF> XYChartItem::calculateGeometryPoints() const | ||||
{ | ||||
const qreal deltaX = m_size.width()/(m_maxX-m_minX); | ||||
const qreal deltaY = m_size.height()/(m_maxY-m_minY); | ||||
QVector<QPointF> points; | ||||
points.reserve(m_series->count()); | ||||
for (int i = 0; i < m_series->count(); ++i) { | ||||
sauimone
|
r743 | qreal x = (m_series->x(i) - m_minX)* deltaX; | ||
qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height(); | ||||
points << QPointF(x,y); | ||||
Michal Klocek
|
r466 | } | ||
return points; | ||||
} | ||||
sauimone
|
r743 | QPointF XYChartItem::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); | ||||
} | ||||
sauimone
|
r743 | void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index) | ||
Michal Klocek
|
r466 | { | ||
sauimone
|
r743 | if (animator()) { | ||
animator()->updateLayout(this,oldPoints,newPoints,index); | ||||
} else { | ||||
Michal Klocek
|
r622 | setLayout(newPoints); | ||
Michal Klocek
|
r530 | } | ||
Michal Klocek
|
r466 | } | ||
sauimone
|
r743 | void XYChartItem::setLayout(QVector<QPointF> &points) | ||
Michal Klocek
|
r466 | { | ||
m_points = points; | ||||
Michal Klocek
|
r622 | update(); | ||
Michal Klocek
|
r466 | } | ||
//handlers | ||||
void XYChartItem::handlePointAdded(int index) | ||||
{ | ||||
QVector<QPointF> points = m_points; | ||||
Marek Rosa
|
r833 | QPointF point; | ||
if (m_series->model()) { | ||||
point = calculateGeometryPoint(index - m_series->mapFirst()); | ||||
points.insert(index - m_series->mapFirst(), point); | ||||
updateLayout(m_points, points, index - m_series->mapFirst()); | ||||
} | ||||
else { | ||||
// this checks do not work correctly if model is set | ||||
Q_ASSERT(index<m_series->count()); | ||||
Q_ASSERT(index>=0); | ||||
point = calculateGeometryPoint(index); | ||||
points.insert(index, point); | ||||
updateLayout(m_points, points, index); | ||||
} | ||||
Michal Klocek
|
r466 | update(); | ||
} | ||||
void XYChartItem::handlePointRemoved(int index) | ||||
Michal Klocek
|
r938 | { | ||
Michal Klocek
|
r466 | QVector<QPointF> points = m_points; | ||
Marek Rosa
|
r833 | if (m_series->model()) { | ||
if (index < m_series->mapFirst()) | ||||
points.remove(0); | ||||
else | ||||
points.remove(index - m_series->mapFirst()); | ||||
updateLayout(m_points, points, index - m_series->mapFirst()); | ||||
} | ||||
else { | ||||
// this checks do not work correctly if model is set | ||||
Q_ASSERT(index<m_series->count() + 1); | ||||
Q_ASSERT(index>=0); | ||||
points.remove(index); | ||||
updateLayout(m_points, points, index); | ||||
} | ||||
Michal Klocek
|
r466 | update(); | ||
} | ||||
void XYChartItem::handlePointReplaced(int index) | ||||
{ | ||||
Q_ASSERT(index<m_series->count()); | ||||
Q_ASSERT(index>=0); | ||||
QPointF point = calculateGeometryPoint(index); | ||||
Michal Klocek
|
r476 | QVector<QPointF> points = m_points; | ||
Marek Rosa
|
r527 | points.replace(index,point); | ||
Michal Klocek
|
r622 | updateLayout(m_points,points,index); | ||
Michal Klocek
|
r466 | update(); | ||
} | ||||
void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY) | ||||
{ | ||||
m_minX=minX; | ||||
m_maxX=maxX; | ||||
m_minY=minY; | ||||
m_maxY=maxY; | ||||
sauimone
|
r743 | if (isEmpty()) return; | ||
Michal Klocek
|
r466 | QVector<QPointF> points = calculateGeometryPoints(); | ||
Michal Klocek
|
r622 | updateLayout(m_points,points); | ||
Michal Klocek
|
r466 | update(); | ||
} | ||||
sauimone
|
r743 | void XYChartItem::handleGeometryChanged(const QRectF &rect) | ||
Michal Klocek
|
r466 | { | ||
Marek Rosa
|
r833 | Q_ASSERT(rect.isValid()); | ||
m_size=rect.size(); | ||||
m_clipRect=rect.translated(-rect.topLeft()); | ||||
setPos(rect.topLeft()); | ||||
Michal Klocek
|
r466 | |||
sauimone
|
r743 | if (isEmpty()) return; | ||
Marek Rosa
|
r833 | QVector<QPointF> points = calculateGeometryPoints(); | ||
updateLayout(m_points,points); | ||||
update(); | ||||
Michal Klocek
|
r466 | } | ||
bool XYChartItem::isEmpty() | ||||
{ | ||||
Marek Rosa
|
r833 | return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY); | ||
Michal Klocek
|
r466 | } | ||
sauimone
|
r743 | void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event) | ||
Michal Klocek
|
r571 | { | ||
emit clicked(calculateDomainPoint(event->pos())); | ||||
} | ||||
Michal Klocek
|
r466 | #include "moc_xychartitem_p.cpp" | ||
QTCOMMERCIALCHART_END_NAMESPACE | ||||