From 7f683774d508b60a2a9720a8599a738efd85e5f8 2012-03-06 07:51:31 From: Michal Klocek Date: 2012-03-06 07:51:31 Subject: [PATCH] Refactor line spline to common xyline * create xyline base class * encapsulate common stuff * TODO scatter (next commit) --- diff --git a/example/example.pro b/example/example.pro index dc13dc2..738ee74 100644 --- a/example/example.pro +++ b/example/example.pro @@ -16,6 +16,6 @@ SUBDIRS += linechart \ presenterchart \ chartview \ scatterinteractions \ - #splinechart \ + splinechart \ areachart \ stackedbarchartdrilldown diff --git a/src/linechart/linechartanimationitem.cpp b/src/linechart/linechartanimationitem.cpp index 858c428..e55e39a 100644 --- a/src/linechart/linechartanimationitem.cpp +++ b/src/linechart/linechartanimationitem.cpp @@ -20,11 +20,10 @@ LineChartAnimationItem::~LineChartAnimationItem() { } -void LineChartAnimationItem::updateAllPoints() +void LineChartAnimationItem::updatePoints(QVector& newPoints) { QVector oldPoints = points(); - LineChartItem::updateAllPoints(); - QVector newPoints = points(); + LineChartItem::updatePoints(newPoints); if(newPoints.count()==0) return; oldPoints.resize(newPoints.size()); diff --git a/src/linechart/linechartanimationitem_p.h b/src/linechart/linechartanimationitem_p.h index 1128a8c..17ccfc0 100644 --- a/src/linechart/linechartanimationitem_p.h +++ b/src/linechart/linechartanimationitem_p.h @@ -19,7 +19,7 @@ public: virtual ~LineChartAnimationItem(); protected: - virtual void updateAllPoints(); + virtual void updatePoints(QVector& newPoints); virtual void updatePoint(int index,QPointF& newPoint); private slots: diff --git a/src/linechart/linechartitem.cpp b/src/linechart/linechartitem.cpp index 9a0963f..07c6752 100644 --- a/src/linechart/linechartitem.cpp +++ b/src/linechart/linechartitem.cpp @@ -8,20 +8,12 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE //TODO: optimize : remove points which are not visible -LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):ChartItem(parent), -m_minX(0), -m_maxX(0), -m_minY(0), -m_maxY(0), +LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent), m_series(series), m_items(this) { //m_items.setZValue(ChartPresenter::LineChartZValue); setZValue(ChartPresenter::LineChartZValue); - - QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int))); - QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int))); - QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int))); QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated())); handleUpdated(); @@ -45,7 +37,7 @@ void LineChartItem::createPoints(int count) } } -void LineChartItem::clearPoints(int count) +void LineChartItem::deletePoints(int count) { QList items = m_items.childItems(); @@ -54,99 +46,51 @@ void LineChartItem::clearPoints(int count) } } -QPointF LineChartItem::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 LineChartItem::calculateGeometryPoints() const -{ - const qreal deltaX = m_size.width()/(m_maxX-m_minX); - const qreal deltaY = m_size.height()/(m_maxY-m_minY); - - QVector points; - points.reserve(m_series->count()); - for (int i = 0; i < m_series->count(); ++i) { - 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); - } - return points; -} - -void LineChartItem::updateAllPoints() +void LineChartItem::setGeometry(QVector& points) { - QVector points = calculateGeometryPoints(); + if(points.size()==0) return; - int diff = m_points.size() - points.size(); + int diff = XYChartItem::points().size() - points.size(); if(diff>0) { - clearPoints(diff); + deletePoints(diff); } else if(diff<0) { createPoints(-diff); } - setGeometry(points); -} - -void LineChartItem::updatePoints(QVector& points) -{ - int diff = m_points.size() - points.size(); + QList items = m_items.childItems(); - if(diff>0) { - clearPoints(diff); - } - else if(diff<0) { - createPoints(-diff); - } + QPainterPath path; + const QPointF& point = points.at(0); + path.moveTo(point); + QGraphicsItem* item = items.at(0); + item->setPos(point.x()-1,point.y()-1); + if(!clipRect().contains(point)) { + item->setVisible(false); + } + else { + item->setVisible(true); + } - setGeometry(points); -} + for(int i=1; i< points.size();i++) { + QGraphicsItem* item = items.at(i); + const QPointF& point = points.at(i); + item->setPos(point.x()-1,point.y()-1); + if(!clipRect().contains(point)) { + item->setVisible(false); + } + else { + item->setVisible(true); + } + path.lineTo(point); + } -void LineChartItem::updatePoint(int index,QPointF& newPoint) -{ - m_points.replace(index,newPoint); - setGeometry(m_points); -} + prepareGeometryChange(); + m_path = path; + m_rect = path.boundingRect(); -void LineChartItem::setGeometry(QVector& points) -{ - if(points.size()==0) return; - - QList items = m_items.childItems(); - - QPainterPath path; - const QPointF& point = points.at(0); - path.moveTo(point); - QGraphicsItem* item = items.at(0); - item->setPos(point.x()-1,point.y()-1); - if(!m_clipRect.contains(point)) { - item->setVisible(false); - }else{ - item->setVisible(true); - } - - for(int i=1 ; i< points.size();i++) { - QGraphicsItem* item = items.at(i); - const QPointF& point = points.at(i); - item->setPos(point.x()-1,point.y()-1); - if(!m_clipRect.contains(point)) { - item->setVisible(false); - }else{ - item->setVisible(true); - } - path.lineTo(point); - } - - prepareGeometryChange(); - m_path = path; - m_rect = path.boundingRect(); - m_points = points; + XYChartItem::setGeometry(points); } void LineChartItem::setPen(const QPen& pen) @@ -154,66 +98,6 @@ void LineChartItem::setPen(const QPen& pen) m_pen = pen; } -//handlers - -void LineChartItem::handlePointAdded(int index) -{ - Q_ASSERT(indexcount()); - Q_ASSERT(index>=0); - - QPointF point = calculateGeometryPoint(index); - createPoints(1); - QVector points = m_points; - points.insert(index,point); - - updatePoints(points); - update(); -} -void LineChartItem::handlePointRemoved(int index) -{ - Q_ASSERT(indexcount()); - Q_ASSERT(index>=0); - - QPointF point = calculateGeometryPoint(index); - clearPoints(1); - QVector points = m_points; - points.remove(index); - updatePoints(points); - update(); -} - -void LineChartItem::handlePointReplaced(int index) -{ - Q_ASSERT(indexcount()); - Q_ASSERT(index>=0); - QPointF point = calculateGeometryPoint(index); - updatePoint(index,point); - update(); -} - -void LineChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY) -{ - m_minX=minX; - m_maxX=maxX; - m_minY=minY; - m_maxY=maxY; - - if(isEmpty()) return; - updateAllPoints(); - update(); -} - -void LineChartItem::handleGeometryChanged(const QRectF& rect) -{ - Q_ASSERT(rect.isValid()); - m_size=rect.size(); - m_clipRect=rect.translated(-rect.topLeft()); - setPos(rect.topLeft()); - - if(isEmpty()) return; - updateAllPoints(); - update(); -} void LineChartItem::handleUpdated() { @@ -230,16 +114,11 @@ void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt Q_UNUSED(option); painter->save(); painter->setPen(m_pen); - painter->setClipRect(m_clipRect); + painter->setClipRect(clipRect()); painter->drawPath(m_path); painter->restore(); } -bool LineChartItem::isEmpty() -{ - return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ; -} - #include "moc_linechartitem_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/linechart/linechartitem_p.h b/src/linechart/linechartitem_p.h index d874e4c..70d07a7 100644 --- a/src/linechart/linechartitem_p.h +++ b/src/linechart/linechartitem_p.h @@ -2,7 +2,7 @@ #define LINECHARTITEM_H #include "qchartglobal.h" -#include "chartitem_p.h" +#include "xychartitem_p.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -10,7 +10,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class ChartPresenter; class QLineSeries; -class LineChartItem : public QObject , public ChartItem +class LineChartItem : public XYChartItem { Q_OBJECT public: @@ -25,39 +25,20 @@ public: void setPen(const QPen& pen); void setPointsVisible(bool visible); + void createPoints(int count); + void deletePoints(int count); + public slots: - void handlePointAdded(int index); - void handlePointRemoved(int index); - void handlePointReplaced(int index); void handleUpdated(); - void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY); - void handleGeometryChanged(const QRectF& size); protected: - virtual void updateAllPoints(); - virtual void updatePoints(QVector& points); - virtual void updatePoint(int index,QPointF& newPoint); virtual void setGeometry(QVector& points); - QVector points() {return m_points;} - void createPoints(int count); - void clearPoints(int count); - QPointF calculateGeometryPoint(int index) const; - QVector calculateGeometryPoints() const; - inline bool isEmpty(); - -protected: - qreal m_minX; - qreal m_maxX; - qreal m_minY; - qreal m_maxY; - QPainterPath m_path; - QRectF m_rect; +private: QLineSeries* m_series; - QSizeF m_size; - QRectF m_clipRect; QGraphicsItemGroup m_items; - QVector m_points; + QPainterPath m_path; + QRectF m_rect; QPen m_pen; friend class LineChartAnimatator; diff --git a/src/linechart/qlineseries.cpp b/src/linechart/qlineseries.cpp index 2d0ed6f..4c02713 100644 --- a/src/linechart/qlineseries.cpp +++ b/src/linechart/qlineseries.cpp @@ -66,7 +66,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE Constructs empty series object which is a child of \a parent. When series object is added to QChartView or QChart instance ownerships is transfered. */ -QLineSeries::QLineSeries(QObject* parent):QSeries(parent), +QLineSeries::QLineSeries(QObject* parent):QXYSeries(parent), m_pointsVisible(false) { } @@ -79,101 +79,6 @@ QLineSeries::~QLineSeries() } /*! - Adds data point \a x \a y to the series. Points are connected with lines on the chart. - */ -void QLineSeries::add(qreal x,qreal y) -{ - Q_ASSERT(m_x.size() == m_y.size()); - m_x< #include #include QTCOMMERCIALCHART_BEGIN_NAMESPACE -class QTCOMMERCIALCHART_EXPORT QLineSeries : public QSeries +class QTCOMMERCIALCHART_EXPORT QLineSeries : public QXYSeries { Q_OBJECT public: @@ -18,38 +18,13 @@ public: public: // from QChartSeries virtual QSeriesType type() const {return QSeries::SeriesTypeLine;} - void add(qreal x, qreal y); - void add(const QPointF& point); - void replace(qreal x,qreal y); - void replace(const QPointF& point); - void remove(qreal x); - void remove(const QPointF& point); - void clear(); - void setPen(const QPen& pen); QPen pen() const {return m_pen;} void setPointsVisible(bool visible); bool pointsVisible() const {return m_pointsVisible;} - int count() const; - qreal x(int pos) const; - qreal y(int pos) const; - - QLineSeries& operator << (const QPointF &point); - friend QDebug operator<< (QDebug d, const QLineSeries series); - -signals: - void updated(); - void pointReplaced(int index); - void pointRemoved(int index); - void pointAdded(int index); - - -protected: - QVector m_x; - QVector m_y; - + friend QDebug operator<< (QDebug d, const QLineSeries series); private: QPen m_pen; bool m_pointsVisible; diff --git a/src/splinechart/splinechartitem.cpp b/src/splinechart/splinechartitem.cpp index 01541c6..0a6a5dd 100644 --- a/src/splinechart/splinechartitem.cpp +++ b/src/splinechart/splinechartitem.cpp @@ -4,21 +4,24 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE SplineChartItem::SplineChartItem(QSplineSeries* series, QGraphicsObject *parent) : - LineChartItem(series, parent)//,m_boundingRect() +XYChartItem(series, parent), +m_series(series) { - // } +QRectF SplineChartItem::boundingRect() const +{ + return m_rect; +} +QPainterPath SplineChartItem::shape() const +{ + return m_path; +} QPointF SplineChartItem::calculateGeometryControlPoint(int index) const { - QSplineSeries* splineSeries = qobject_cast(m_series); - const qreal deltaX = m_size.width()/(m_maxX-m_minX); - const qreal deltaY = m_size.height()/(m_maxY-m_minY); - qreal x = (splineSeries->controlPoint(index).x() - m_minX)* deltaX; - qreal y = (splineSeries->controlPoint(index).y() - m_minY)*-deltaY + m_size.height(); - return QPointF(x,y); + return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index)); } void SplineChartItem::setGeometry(QVector& points) @@ -29,7 +32,6 @@ void SplineChartItem::setGeometry(QVector& points) const QPointF& point = points.at(0); splinePath.moveTo(point); -// QSplineSeries* splineSeries = qobject_cast(m_series); for (int i = 0; i < points.size() - 1; i++) { const QPointF& point = points.at(i + 1); @@ -39,22 +41,29 @@ void SplineChartItem::setGeometry(QVector& points) prepareGeometryChange(); m_path = splinePath; m_rect = splinePath.boundingRect(); + XYChartItem::setGeometry(points); +} + +void SplineChartItem::setPen(const QPen& pen) +{ + m_pen = pen; } + void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget); Q_UNUSED(option); painter->save(); - painter->setPen(m_pen); - painter->setClipRect(m_clipRect); + painter->setClipRect(clipRect()); painter->drawPath(m_path); - QSplineSeries* splineSeries = qobject_cast(m_series); - for (int i = 0; i < m_points.size() - 1; i++) + const QVector points = XYChartItem::points(); + + for (int i = 0; i < points.size() - 1; i++) { painter->setPen(Qt::red); - painter->drawEllipse(m_points[i], 2, 2); + painter->drawEllipse(points[i], 2, 2); painter->setPen(Qt::blue); // painter->drawLine(m_series->at(i), m_series->controlPoint(2 * i)); @@ -62,10 +71,10 @@ void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o // painter->drawEllipse(calculateGeometryControlPoint(2 * i), 4, 4); // painter->drawEllipse(calculateGeometryControlPoint(2 * i + 1), 4, 4); } - if (m_points.count() > 0) + if (points.count() > 0) { painter->setPen(Qt::red); - painter->drawEllipse(m_points[m_points.count() - 1], 2, 2); + painter->drawEllipse(points[points.count() - 1], 2, 2); } painter->restore(); } diff --git a/src/splinechart/splinechartitem_p.h b/src/splinechart/splinechartitem_p.h index ac3209d..0890e82 100644 --- a/src/splinechart/splinechartitem_p.h +++ b/src/splinechart/splinechartitem_p.h @@ -4,23 +4,35 @@ #include "chartitem_p.h" #include #include "qsplineseries.h" -#include "linechartitem_p.h" +#include "xychartitem_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE -class SplineChartItem : public LineChartItem +class SplineChartItem : public XYChartItem { Q_OBJECT public: SplineChartItem(QSplineSeries* series, QGraphicsObject *parent = 0); - void updateGeometry(); + //from QGraphicsItem + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QPainterPath shape() const; + void setPen(const QPen& pen); + void setPointsVisible(bool visible); + +protected: void setGeometry(QVector& points); +private: QPointF calculateGeometryControlPoint(int index) const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); +private: + QSplineSeries* m_series; + QPainterPath m_path; + QRectF m_rect; + QPen m_pen; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/src.pro b/src/src.pro index 6b47c62..7c53520 100644 --- a/src/src.pro +++ b/src/src.pro @@ -30,6 +30,7 @@ PUBLIC_HEADERS += qchart.h \ qchartglobal.h \ qseries.h \ qchartview.h +include(xychart/xychart.pri) include(linechart/linechart.pri) include(areachart/areachart.pri) include(barchart/barchart.pri)