##// END OF EJS Templates
Refactors animation handling for xyseries
Michal Klocek -
r1217:b0870dfe6522
parent child
Show More
@@ -31,14 +31,7 const static int ChartAnimationDuration = 1000;
31 31 class ChartAnimation: public QVariantAnimation
32 32 {
33 33 public:
34 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
35 ChartAnimation(QObject *parent = 0):QVariantAnimation(parent), m_type(MoveDownAnimation){}
36 void setAnimationType(Animation type){
37 m_type=type;
38 }
39 protected:
40 Animation m_type;
41
34 ChartAnimation(QObject *parent = 0):QVariantAnimation(parent){};
42 35 };
43 36
44 37 QTCOMMERCIALCHART_END_NAMESPACE
@@ -58,42 +58,6 void ChartAnimator::addAnimation(ChartAxis *item)
58 58 item->setAnimator(this);
59 59 }
60 60
61 void ChartAnimator::addAnimation(SplineChartItem *item)
62 {
63 ChartAnimation *animation = m_animations.value(item);
64
65 if (!animation) {
66 animation = new SplineAnimation(item);
67 m_animations.insert(item, animation);
68 }
69
70 item->setAnimator(this);
71 }
72
73 void ChartAnimator::addAnimation(ScatterChartItem *item)
74 {
75 ChartAnimation *animation = m_animations.value(item);
76
77 if (!animation) {
78 animation = new XYAnimation(item);
79 m_animations.insert(item, animation);
80 }
81
82 item->setAnimator(this);
83 }
84
85 void ChartAnimator::addAnimation(LineChartItem *item)
86 {
87 ChartAnimation *animation = m_animations.value(item);
88
89 if (!animation) {
90 animation = new XYAnimation(item);
91 m_animations.insert(item, animation);
92 }
93
94 item->setAnimator(this);
95 }
96
97 61 void ChartAnimator::addAnimation(PieChartItem *item)
98 62 {
99 63 ChartAnimation *animation = m_animations.value(item);
@@ -194,61 +158,6 void ChartAnimator::updateLayout(ChartAxis *item , QVector<qreal> &newLayout)
194 158 QTimer::singleShot(0, animation, SLOT(start()));
195 159 }
196 160
197 void ChartAnimator::updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
198 {
199 SplineAnimation *animation = static_cast<SplineAnimation *>(m_animations.value(item));
200
201 Q_ASSERT(animation);
202
203 if (newPoints.count() < 2 || newControlPoints.count() < 2)
204 return;
205
206 bool empty = oldPoints.count() == 0;
207
208
209 if (animation->state() != QAbstractAnimation::Stopped)
210 animation->stop();
211
212 animation->setDuration(ChartAnimationDuration);
213 if (!empty)
214 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
215 else
216 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
217
218 animation->setEasingCurve(QEasingCurve::OutQuart);
219 animation->setValues(oldPoints, newPoints, oldControlPoints, newControlPoints, index);
220
221 QTimer::singleShot(0, animation, SLOT(start()));
222 }
223
224
225 void ChartAnimator::updateLayout(XYChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
226 {
227 XYAnimation *animation = static_cast<XYAnimation *>(m_animations.value(item));
228
229 Q_ASSERT(animation);
230
231 if (newPoints.count() == 0)
232 return;
233
234 bool empty = oldPoints.count() == 0;
235
236
237 if (animation->state() != QAbstractAnimation::Stopped)
238 animation->stop();
239
240 animation->setDuration(ChartAnimationDuration);
241 if (!empty)
242 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
243 else
244 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
245
246 animation->setEasingCurve(QEasingCurve::OutQuart);
247 animation->setValues(oldPoints, newPoints, index);
248
249 QTimer::singleShot(0, animation, SLOT(start()));
250 }
251
252 161 void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
253 162 {
254 163 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
@@ -287,6 +196,16 void ChartAnimator::setState(State state, const QPointF &point)
287 196 m_point = point;
288 197 }
289 198
199 void ChartAnimator::startAnimation(XYAnimation* animation)
200 {
201 Q_ASSERT(animation);
202 if (animation->state() != QAbstractAnimation::Stopped)
203 animation->stop();
204 animation->setDuration(ChartAnimationDuration);
205 animation->setEasingCurve(QEasingCurve::OutQuart);
206 QTimer::singleShot(0, animation, SLOT(start()));
207 }
208
290 209 #include "moc_chartanimator_p.cpp"
291 210
292 211 QTCOMMERCIALCHART_END_NAMESPACE
@@ -36,6 +36,7 class SplineChartItem;
36 36 class ScatterChartItem;
37 37 class LineChartItem;
38 38 class XYChartItem;
39 class XYAnimation;
39 40
40 41 class ChartAnimator : public QObject
41 42 {
@@ -48,15 +49,10 public:
48 49
49 50 void addAnimation(ChartAxis *item);
50 51 void addAnimation(PieChartItem *item);
51 void addAnimation(ScatterChartItem *item);
52 void addAnimation(LineChartItem *item);
53 void addAnimation(SplineChartItem *item);
54 52 void addAnimation(BarChartItem *item);
55 53 void removeAnimation(Chart *item);
56 54
57 55 void animationStarted();
58 void updateLayout(XYChartItem *item, QVector<QPointF> &oldLayout, QVector<QPointF> &newLayout, int index);
59 void updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newContorlPoints, int index);
60 56 void updateLayout(ChartAxis *item, QVector<qreal> &layout);
61 57
62 58 void addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty);
@@ -67,6 +63,8 public:
67 63
68 64 void setState(State state,const QPointF &point = QPointF());
69 65
66 void startAnimation(XYAnimation* animation);
67
70 68 private:
71 69 QMap<Chart *, ChartAnimation *> m_animations;
72 70 State m_state;
@@ -27,7 +27,7 Q_DECLARE_METATYPE(SplineVector)
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 SplineAnimation::SplineAnimation(SplineChartItem* item):ChartAnimation(item),
30 SplineAnimation::SplineAnimation(SplineChartItem* item):XYAnimation(item),
31 31 m_item(item),
32 32 m_dirty(true)
33 33 {
@@ -82,7 +82,6 void SplineAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &n
82 82 newPair.second=newControlPoints;
83 83 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
84 84 setKeyValueAt(1.0, qVariantFromValue(newPair));
85
86 85 }
87 86 }
88 87
@@ -93,8 +92,7 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
93 92 SplineVector endPair = qVariantValue< SplineVector >(end);
94 93 SplineVector result;
95 94
96
97 switch (m_type) {
95 switch (animationType()) {
98 96
99 97 case MoveDownAnimation: {
100 98 if (startPair.first.count() != endPair.first.count())
@@ -130,7 +128,7 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
130 128 }
131 129 break;
132 130 default:
133 qWarning() << "Unknow type of animation";
131 qWarning() << "Unknown type of animation";
134 132 break;
135 133 }
136 134
@@ -142,7 +140,9 void SplineAnimation::updateCurrentValue (const QVariant &value )
142 140 if (state() != QAbstractAnimation::Stopped) { //workaround
143 141 m_dirty = true;
144 142 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
145 m_item->setLayout(pair.first, pair.second);
143 m_item->setGeometryPoints(pair.first);
144 m_item->setControlGeometryPoints(pair.second);
145 m_item->updateGeometry();
146 146 }
147 147 }
148 148
@@ -20,7 +20,7
20 20
21 21 #ifndef SPLINEANIMATION_P_H
22 22 #define SPLINEANIMATION_P_H
23 #include "chartanimation_p.h"
23 #include "xyanimation_p.h"
24 24 #include <QPointF>
25 25
26 26 typedef QPair<QVector<QPointF >, QVector<QPointF > > SplineVector;
@@ -29,10 +29,9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class SplineChartItem;
31 31
32 class SplineAnimation : public ChartAnimation
32 class SplineAnimation : public XYAnimation
33 33 {
34 34 public:
35
36 35 SplineAnimation(SplineChartItem *item);
37 36 ~SplineAnimation();
38 37 void setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldContorlPoints, QVector<QPointF> &newControlPoints, int index);
@@ -28,7 +28,8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 XYAnimation::XYAnimation(XYChartItem *item):ChartAnimation(item),
30 30 m_item(item),
31 m_dirty(false)
31 m_dirty(false),
32 m_type(MoveDownAnimation)
32 33 {
33 34 }
34 35
@@ -36,6 +37,11 XYAnimation::~XYAnimation()
36 37 {
37 38 }
38 39
40 void XYAnimation::setAnimationType(Animation type)
41 {
42 m_type=type;
43 }
44
39 45 void XYAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
40 46 {
41 47 int x = oldPoints.count();
@@ -103,7 +109,8 void XYAnimation::updateCurrentValue (const QVariant &value)
103 109 if(state()!=QAbstractAnimation::Stopped){ //workaround
104 110 m_dirty = true;
105 111 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
106 m_item->setLayout(vector);
112 m_item->setGeometryPoints(vector);
113 m_item->updateGeometry();
107 114 }
108 115 }
109 116
@@ -35,6 +35,8 public:
35 35 XYAnimation(XYChartItem *item);
36 36 ~XYAnimation();
37 37 void setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index);
38 void setAnimationType(Animation type);
39 Animation animationType() const { return m_type; };
38 40
39 41 protected:
40 42 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress ) const;
@@ -44,6 +46,7 private:
44 46 XYChartItem *m_item;
45 47 QVector<QPointF> m_oldPoints;
46 48 bool m_dirty;
49 Animation m_type;
47 50 };
48 51
49 52 QTCOMMERCIALCHART_END_NAMESPACE
@@ -43,8 +43,8 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
43 43 if (m_series->lowerSeries())
44 44 m_lower = new AreaBoundItem(this,m_series->lowerSeries());
45 45
46 connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
47 connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
46 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
47 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
48 48
49 49 handleUpdated();
50 50 }
@@ -125,9 +125,9 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt
125 125 painter->drawPath(m_path);
126 126 if (m_pointsVisible) {
127 127 painter->setPen(m_pointPen);
128 painter->drawPoints(m_upper->points());
128 painter->drawPoints(m_upper->geometryPoints());
129 129 if (m_lower)
130 painter->drawPoints(m_lower->points());
130 painter->drawPoints(m_lower->geometryPoints());
131 131 }
132 132 painter->restore();
133 133 }
@@ -78,8 +78,8 public:
78 78 AreaBoundItem(AreaChartItem *item,QLineSeries *lineSeries) : LineChartItem(lineSeries, 0), m_item(item) {}
79 79 ~AreaBoundItem() {}
80 80
81 void setLayout(QVector<QPointF> &points) {
82 LineChartItem::setLayout(points);
81 void updateGeometry() {
82 LineChartItem::updateGeometry();
83 83 m_item->updatePath();
84 84 }
85 85
@@ -284,8 +284,12 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
284 284
285 285 AreaChartItem* area = new AreaChartItem(q,presenter);
286 286 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
287 presenter->animator()->addAnimation(area->upperLineItem());
288 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
287 area->upperLineItem()->setAnimator(presenter->animator());
288 area->upperLineItem()->setAnimation(new XYAnimation(area->upperLineItem()));
289 if(q->lowerSeries()) {
290 area->lowerLineItem()->setAnimator(presenter->animator());
291 area->lowerLineItem()->setAnimation(new XYAnimation(area->lowerLineItem()));
292 }
289 293 }
290 294 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
291 295 return area;
@@ -20,14 +20,14
20 20
21 21 #include "chart_p.h"
22 22 #include "chartpresenter_p.h"
23 #include <QDebug>
23 #include "domain_p.h"
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27
28 27 Chart::Chart(ChartPresenter *presenter):QObject(presenter),
29 28 m_animator(0),
30 m_presenter(presenter)
29 m_presenter(presenter),
30 m_domain(0)
31 31 {
32 32 }
33 33
@@ -41,11 +41,27 ChartAnimator* Chart::animator() const
41 41 return m_animator;
42 42 }
43 43
44
45 void Chart::setPresenter(ChartPresenter *presenter)
46 {
47 m_presenter=presenter;
48 }
49
44 50 ChartPresenter* Chart::presenter() const
45 51 {
46 52 return m_presenter;
47 53 }
48 54
55 void Chart::setDomain(Domain *domain)
56 {
57 m_domain=domain;
58 }
59
60 Domain* Chart::domain() const
61 {
62 return m_domain;
63 }
64
49 65 void Chart::handleGeometryChanged(const QRectF& rect)
50 66 {
51 67 Q_UNUSED(rect);
@@ -61,22 +77,6 void Chart::handleDomainChanged(qreal minX,qreal maxX,qreal minY,qreal maxY)
61 77 qWarning()<<"Slot not implemented";
62 78 }
63 79
64 void Chart::rangeXChanged(qreal min, qreal max, int tickXCount)
65 {
66 Q_UNUSED(min);
67 Q_UNUSED(max);
68 Q_UNUSED(tickXCount);
69 qWarning()<<"Slot not implemented";
70 }
71
72 void Chart::rangeYChanged(qreal min, qreal max, int tickYCount)
73 {
74 Q_UNUSED(min);
75 Q_UNUSED(max);
76 Q_UNUSED(tickYCount);
77 qWarning()<<"Slot not implemented";
78 }
79
80 80 #include "moc_chart_p.cpp"
81 81
82 82 QTCOMMERCIALCHART_END_NAMESPACE
@@ -29,6 +29,8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class ChartAnimator;
31 31 class ChartPresenter;
32 class ChartAnimation;
33 class Domain;
32 34
33 35 class Chart: public QObject
34 36 {
@@ -39,16 +41,19 public:
39 41 public Q_SLOTS:
40 42 virtual void handleGeometryChanged(const QRectF& rect);
41 43 virtual void handleDomainChanged(qreal minX,qreal maxX,qreal minY,qreal maxY);
42 virtual void rangeXChanged(qreal min, qreal max, int tickXCount);
43 virtual void rangeYChanged(qreal min, qreal max, int tickYCount);
44 44
45 45 void setAnimator(ChartAnimator* animator);
46 46 ChartAnimator* animator() const;
47 void setPresenter(ChartPresenter *presenter);
47 48 ChartPresenter* presenter() const;
49 void setDomain(Domain *domain);
50 Domain* domain() const;
51 virtual ChartAnimation* animation() const { return 0; };
48 52
49 53 private:
50 54 ChartAnimator* m_animator;
51 55 ChartPresenter* m_presenter;
56 Domain* m_domain;
52 57 };
53 58
54 59 QTCOMMERCIALCHART_END_NAMESPACE
@@ -134,7 +134,7 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
134 134
135 135 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
136 136 //initialize
137 item->handleGeometryChanged(m_chartRect);
137 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
138 138 m_axisItems.insert(axis, item);
139 139 }
140 140
@@ -384,7 +384,7 void ChartPresenter::updateLayout()
384 384
385 385 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
386 386
387 if(m_chartRect!=chartRect){
387 if(m_chartRect!=chartRect && chartRect.isValid()){
388 388 m_chartRect=chartRect;
389 389 emit geometryChanged(m_chartRect);
390 390 }
@@ -48,17 +48,16 QPainterPath LineChartItem::shape() const
48 48 return m_path;
49 49 }
50 50
51 void LineChartItem::setLayout(QVector<QPointF>& points)
51 void LineChartItem::updateGeometry()
52 52 {
53 const QVector<QPointF>& points = geometryPoints();
54
53 55 if(points.size()==0)
54 56 {
55 57 m_path = QPainterPath();
56 XYChartItem::setLayout(points);
57 58 return;
58 59 }
59 60
60 QList<QGraphicsItem*> items = m_items.childItems();
61
62 61 QPainterPath linePath(points.at(0));
63 62
64 63 for(int i=1; i< points.size();i++) {
@@ -68,9 +67,6 void LineChartItem::setLayout(QVector<QPointF>& points)
68 67 prepareGeometryChange();
69 68 m_path = linePath;
70 69 m_rect = linePath.boundingRect();
71
72 XYChartItem::setLayout(points);
73
74 70 }
75 71
76 72 void LineChartItem::handleUpdated()
@@ -95,7 +91,7 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt
95 91 painter->drawPath(m_path);
96 92 if(m_pointsVisible){
97 93 painter->setPen(m_pointPen);
98 painter->drawPoints(points());
94 painter->drawPoints(geometryPoints());
99 95 }
100 96 painter->restore();
101 97 }
@@ -44,13 +44,11 public:
44 44
45 45 public Q_SLOTS:
46 46 void handleUpdated();
47
48 47 protected:
49 void setLayout(QVector<QPointF>& points);
48 void updateGeometry();
50 49
51 50 private:
52 51 QLineSeries* m_series;
53 QGraphicsItemGroup m_items;
54 52 QPainterPath m_path;
55 53 QRectF m_rect;
56 54 QPen m_linePen;
@@ -111,7 +111,8 Chart* QLineSeriesPrivate::createGraphics(ChartPresenter* presenter)
111 111 Q_Q(QLineSeries);
112 112 LineChartItem* line = new LineChartItem(q,presenter);
113 113 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
114 presenter->animator()->addAnimation(line);
114 line->setAnimator(presenter->animator());
115 line->setAnimation(new XYAnimation(line));
115 116 }
116 117 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
117 118 return line;
@@ -140,7 +140,8 Chart* QScatterSeriesPrivate::createGraphics(ChartPresenter* presenter)
140 140 Q_Q(QScatterSeries);
141 141 ScatterChartItem *scatter = new ScatterChartItem(q,presenter);
142 142 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
143 presenter->animator()->addAnimation(scatter);
143 scatter->setAnimator(presenter->animator());
144 scatter->setAnimation(new XYAnimation(scatter));
144 145 }
145 146 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
146 147 return scatter;
@@ -101,12 +101,14 void ScatterChartItem::markerSelected(Marker *marker)
101 101 emit XYChartItem::clicked(marker->point());
102 102 }
103 103
104 void ScatterChartItem::setLayout(QVector<QPointF>& points)
104 void ScatterChartItem::updateGeometry()
105 105 {
106
107 const QVector<QPointF>& points = geometryPoints();
108
106 109 if(points.size()==0)
107 110 {
108 111 deletePoints(m_items.childItems().count());
109 XYChartItem::setLayout(points);
110 112 return;
111 113 }
112 114
@@ -139,7 +141,6 void ScatterChartItem::setLayout(QVector<QPointF>& points)
139 141
140 142 prepareGeometryChange();
141 143 m_rect = clipRect();
142 XYChartItem::setLayout(points);
143 144 }
144 145
145 146
@@ -55,7 +55,7 private:
55 55 void deletePoints(int count);
56 56
57 57 protected:
58 void setLayout(QVector<QPointF> &points);
58 void updateGeometry();
59 59
60 60 private:
61 61 QScatterSeries *m_series;
@@ -254,8 +254,10 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
254 254 Q_Q(QSplineSeries);
255 255 SplineChartItem* spline = new SplineChartItem(q,presenter);
256 256 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
257 presenter->animator()->addAnimation(spline);
257 spline->setAnimator(presenter->animator());
258 spline->setAnimation(new SplineAnimation(spline));
258 259 }
260
259 261 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
260 262 return spline;
261 263 }
@@ -30,7 +30,8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
31 31 XYChartItem(series, presenter),
32 32 m_series(series),
33 m_pointsVisible(false)
33 m_pointsVisible(false),
34 m_animation(0)
34 35 {
35 36 setZValue(ChartPresenter::LineChartZValue);
36 37 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
@@ -47,11 +48,27 QPainterPath SplineChartItem::shape() const
47 48 return m_path;
48 49 }
49 50
50 void SplineChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
51 void SplineChartItem::setAnimation(SplineAnimation* animation)
52 {
53 m_animation=animation;
54 XYChartItem::setAnimation(animation);
55 }
56
57 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
58 {
59 m_controlPoints=points;
60 }
61
62 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
63 {
64 return m_controlPoints;
65 }
66
67 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
51 68 {
52 69 QVector<QPointF> controlPoints;
53 70
54 if(newPoints.count()>=2){
71 if(newPoints.count()>=2) {
55 72 controlPoints.resize(newPoints.count()*2-2);
56 73 }
57 74
@@ -61,38 +78,35 void SplineChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF>
61 78 }
62 79
63 80 if (controlPoints.count()<2) {
64 setLayout(newPoints,controlPoints);
81 setGeometryPoints(newPoints);
82 setControlGeometryPoints(controlPoints);
83 updateGeometry();
65 84 return;
66 85 }
67 86
68 if (animator()) {
69 animator()->updateLayout(this,oldPoints,newPoints,m_controlPoints,controlPoints,index);
70 } else {
71 setLayout(newPoints,controlPoints);
87 if (m_animation) {
88 m_animation->setValues(oldPoints,newPoints,m_controlPoints,controlPoints,index);
89 animator()->startAnimation(m_animation);
90 }
91 else {
92 setGeometryPoints(newPoints);
93 setControlGeometryPoints(controlPoints);
94 updateGeometry();
72 95 }
73 96 }
74 97
75 98 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
76 99 {
77 // return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
78 100 return XYChartItem::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
79 101 }
80 102
81 void SplineChartItem::setLayout(QVector<QPointF> &points)
103 void SplineChartItem::updateGeometry()
82 104 {
83 // Dummy implementation because of a bug in Clang compiler
84 if (points.size() < 2) {
85 m_path = QPainterPath();
86 }
87 XYChartItem::setLayout(points);
88 }
105 const QVector<QPointF> &points = geometryPoints();
106 const QVector<QPointF> &controlPoints = controlGeometryPoints();
89 107
90 void SplineChartItem::setLayout(QVector<QPointF> &points, QVector<QPointF> &controlPoints)
91 {
92 108 if ((points.size()<2) || (controlPoints.size()<2)) {
93 109 m_path = QPainterPath();
94 XYChartItem::setLayout(points);
95 m_controlPoints=controlPoints;
96 110 return;
97 111 }
98 112
@@ -108,9 +122,6 void SplineChartItem::setLayout(QVector<QPointF> &points, QVector<QPointF> &cont
108 122 prepareGeometryChange();
109 123 m_path = splinePath;
110 124 m_rect = splinePath.boundingRect();
111 XYChartItem::setLayout(points);
112 m_controlPoints=controlPoints;
113
114 125 }
115 126
116 127 //handlers
@@ -130,14 +141,13 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
130 141 {
131 142 Q_UNUSED(widget)
132 143 Q_UNUSED(option)
133 qDebug()<<__FUNCTION__;
134 144 painter->save();
135 145 painter->setClipRect(clipRect());
136 146 painter->setPen(m_linePen);
137 147 painter->drawPath(m_path);
138 148 if (m_pointsVisible) {
139 149 painter->setPen(m_pointPen);
140 painter->drawPoints(points());
150 painter->drawPoints(geometryPoints());
141 151 }
142 152 painter->restore();
143 153 }
@@ -23,6 +23,7
23 23
24 24 #include "qsplineseries.h"
25 25 #include "xychartitem_p.h"
26 #include "splineanimation_p.h"
26 27
27 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 29
@@ -37,13 +38,18 public:
37 38 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
38 39 QPainterPath shape() const;
39 40
41 void setControlGeometryPoints(QVector<QPointF>& points);
42 QVector<QPointF> controlGeometryPoints() const;
43
44 void setAnimation(SplineAnimation* animation);
45 ChartAnimation* animation() const { return m_animation; }
46
40 47 public Q_SLOTS:
41 48 void handleUpdated();
42 49
43 50 protected:
44 void setLayout(QVector<QPointF> &points);
45 void setLayout(QVector<QPointF> &points,QVector<QPointF> &controlPoints);
46 void updateLayout(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index);
51 void updateGeometry();
52 void updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index);
47 53
48 54 private:
49 55 QPointF calculateGeometryControlPoint(int index) const;
@@ -56,6 +62,7 private:
56 62 QPen m_pointPen;
57 63 bool m_pointsVisible;
58 64 QVector<QPointF> m_controlPoints;
65 SplineAnimation* m_animation;
59 66
60 67 friend class SplineAnimation;
61 68 };
@@ -407,6 +407,7 void QXYSeriesPrivate::scaleDomain(Domain& domain)
407 407
408 408 const QList<QPointF>& points = q->points();
409 409
410
410 411 if(points.isEmpty()){
411 412 minX=0.0;
412 413 minY=0.0;
@@ -425,18 +426,6 void QXYSeriesPrivate::scaleDomain(Domain& domain)
425 426 }
426 427
427 428 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
428
429 if (!points.isEmpty()) {
430 for (int i = 0; i < points.count(); i++) {
431 qreal x = points[i].x();
432 qreal y = points[i].y();
433 minX = qMin(minX, x);
434 minY = qMin(minY, y);
435 maxX = qMax(maxX, x);
436 maxY = qMax(maxY, y);
437 }
438 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
439 }
440 429 }
441 430
442 431 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
@@ -1,22 +1,22
1 1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20 20
21 21 #include "xychartitem_p.h"
22 22 #include "qxyseries.h"
@@ -27,26 +27,42
27 27 #include <QGraphicsSceneMouseEvent>
28 28 #include <QAbstractItemModel>
29 29 #include "qxymodelmapper.h"
30
30 #include <QDebug>
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 //TODO: optimize : remove points which are not visible
35 35
36 36 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
37 m_minX(0),
38 m_maxX(0),
39 m_minY(0),
40 m_maxY(0),
41 m_series(series)
37 m_minX(0),
38 m_maxX(0),
39 m_minY(0),
40 m_maxY(0),
41 m_series(series),
42 m_animation(0)
43 {
44 QObject::connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
45 QObject::connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
46 QObject::connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
47 QObject::connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
48 QObject::connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
49 QObject::connect(series->d_func(),SIGNAL(reinitialized()),this,SLOT(handleReinitialized()));
50 QObject::connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
51 }
52
53 void XYChartItem::setGeometryPoints(QVector<QPointF>& points)
54 {
55 m_points = points;
56 }
57
58 void XYChartItem::setClipRect(const QRectF &rect)
59 {
60 m_clipRect = rect;
61 }
62
63 void XYChartItem::setAnimation(XYAnimation* animation)
42 64 {
43 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
44 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
45 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
46 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
47 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
48 connect(series->d_func(),SIGNAL(reinitialized()),this,SLOT(handleReinitialized()));
49 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
65 m_animation=animation;
50 66 }
51 67
52 68 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
@@ -58,7 +74,6 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
58 74 return QPointF(x,y);
59 75 }
60 76
61
62 77 QPointF XYChartItem::calculateGeometryPoint(int index) const
63 78 {
64 79 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
@@ -95,21 +110,22 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
95 110 return QPointF(x,y);
96 111 }
97 112
98 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
113 void XYChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
99 114 {
100 if (animator()) {
101 animator()->updateLayout(this,oldPoints,newPoints,index);
102 } else {
103 setLayout(newPoints);
115 if (m_animation) {
116 m_animation->setValues(oldPoints, newPoints, index);
117 animator()->startAnimation(m_animation);
118 }
119 else {
120 setGeometryPoints(newPoints);
121 updateGeometry();
104 122 }
105 123 }
106 124
107 void XYChartItem::setLayout(QVector<QPointF> &points)
125 void XYChartItem::updateGeometry()
108 126 {
109 m_points = points;
110 127 update();
111 128 }
112
113 129 //handlers
114 130
115 131 void XYChartItem::handlePointAdded(int index)
@@ -118,38 +134,45 void XYChartItem::handlePointAdded(int index)
118 134 Q_ASSERT(index<m_series->count());
119 135 Q_ASSERT(index>=0);
120 136 }
137
121 138 QVector<QPointF> points = m_points;
122 139 QPointF point;
123 140 point = calculateGeometryPoint(index);
124 141 points.insert(index, point);
125 updateLayout(m_points, points, index);
126 update();
142
143 if(m_animation) {
144 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
145 }
146
147 updateChart(m_points,points,index);
127 148 }
128 149
129 150 void XYChartItem::handlePointsAdded(int start, int end)
130 {
151 {
131 152 if (m_series->model() == 0) {
132 153 for (int i = start; i <= end; i++)
133 handlePointAdded(i);
134 } else {
154 handlePointAdded(i);
155 }
156 else {
135 157 int mapFirst = m_series->modelMapper()->first();
136 158 int mapCount = m_series->modelMapper()->count();
137 159 if (mapCount != -1 && start >= mapFirst + mapCount) {
138 160 return;
139 } else {
161 }
162 else {
140 163 int addedCount = end - start + 1;
141 164 if (mapCount != -1 && addedCount > mapCount)
142 addedCount = mapCount;
143 int first = qMax(start, mapFirst); // get the index of the first item that will be added
144 int last = qMin(first + addedCount - 1, mapCount + mapFirst - 1); // get the index of the last item that will be added
165 addedCount = mapCount;
166 int first = qMax(start, mapFirst); // get the index of the first item that will be added
167 int last = qMin(first + addedCount - 1, mapCount + mapFirst - 1);// get the index of the last item that will be added
145 168 for (int i = first; i <= last; i++) {
146 169 handlePointAdded(i - mapFirst);
147 170 }
148 171 // the map is limited therefore the items that are now outside the map
149 172 // need to be removed from the drawn points
150 173 if (mapCount != -1 && m_points.size() > mapCount)
151 for (int i = m_points.size() - 1; i >= mapCount; i--)
152 handlePointRemoved(i);
174 for (int i = m_points.size() - 1; i >= mapCount; i--)
175 handlePointRemoved(i);
153 176 }
154 177 }
155 178 }
@@ -162,8 +185,12 void XYChartItem::handlePointRemoved(int index)
162 185 }
163 186 QVector<QPointF> points = m_points;
164 187 points.remove(index);
165 updateLayout(m_points, points, index);
166 update();
188
189 if(m_animation) {
190 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
191 }
192
193 updateChart(m_points,points,index);
167 194 }
168 195
169 196 void XYChartItem::handlePointsRemoved(int start, int end)
@@ -172,42 +199,45 void XYChartItem::handlePointsRemoved(int start, int end)
172 199 Q_UNUSED(end)
173 200 if (m_series->model() == 0) {
174 201 for (int i = end; i >= start; i--)
175 handlePointRemoved(i);
176 } else {
202 handlePointRemoved(i);
203 }
204 else {
177 205 // series uses model as a data source
178 206 int mapFirst = m_series->modelMapper()->first();
179 207 int mapCount = m_series->modelMapper()->count();
180 208 int removedCount = end - start + 1;
181 209 if (mapCount != -1 && start >= mapFirst + mapCount) {
182 210 return;
183 } else {
184 int toRemove = qMin(m_points.size(), removedCount); // first find how many items can actually be removed
185 int first = qMax(start, mapFirst); // get the index of the first item that will be removed.
186 int last = qMin(first + toRemove - 1, m_points.size() + mapFirst - 1); // get the index of the last item that will be removed.
211 }
212 else {
213 int toRemove = qMin(m_points.size(), removedCount); // first find how many items can actually be removed
214 int first = qMax(start, mapFirst);// get the index of the first item that will be removed.
215 int last = qMin(first + toRemove - 1, m_points.size() + mapFirst - 1);// get the index of the last item that will be removed.
187 216 if (last - first == 0) {
188 217 for (int i = last; i >= first; i--) {
189 218 handlePointRemoved(i - mapFirst);
190 219
191 220 }
192 } else {
221 }
222 else {
193 223 QVector<QPointF> points = m_points;
194 224 for (int i = last; i >= first; i--)
195 points.remove(i - mapFirst);
196 setLayout(points);
197 update();
225 points.remove(i - mapFirst);
226 setGeometryPoints(points);
227 updateGeometry();
198 228 }
199 229 if (mapCount != -1) {
200 int itemsAvailable; // check how many are available to be added
230 int itemsAvailable; // check how many are available to be added
201 231 if (m_series->modelMapper()->orientation() == Qt::Vertical)
202 itemsAvailable = m_series->model()->rowCount() - mapFirst - m_points.size();
232 itemsAvailable = m_series->model()->rowCount() - mapFirst - m_points.size();
203 233 else
204 itemsAvailable = m_series->model()->columnCount() - mapFirst - m_points.size();
205 int toBeAdded = qMin(itemsAvailable, mapCount - m_points.size()); // add not more items than there is space left to be filled.
234 itemsAvailable = m_series->model()->columnCount() - mapFirst - m_points.size();
235 int toBeAdded = qMin(itemsAvailable, mapCount - m_points.size());// add not more items than there is space left to be filled.
206 236 int currentSize = m_points.size();
207 237 if (toBeAdded > 0)
208 for (int i = m_points.size(); i < currentSize + toBeAdded; i++) {
209 handlePointAdded(i);
210 }
238 for (int i = m_points.size(); i < currentSize + toBeAdded; i++) {
239 handlePointAdded(i);
240 }
211 241 }
212 242 }
213 243 }
@@ -221,18 +251,23 void XYChartItem::handlePointReplaced(int index)
221 251 QPointF point = calculateGeometryPoint(index);
222 252 QVector<QPointF> points = m_points;
223 253 points.replace(index,point);
224 updateLayout(m_points,points,index);
225 update();
254
255 if(m_animation) {
256 m_animation->setAnimationType(XYAnimation::MoveDownAnimation);
257 }
258
259 updateChart(m_points,points,index);
226 260 }
227 261
228 262 void XYChartItem::handleReinitialized()
229 263 {
230 264 QVector<QPointF> points = calculateGeometryPoints();
231 if (points.isEmpty())
232 setLayout(points);
233 else
234 updateLayout(m_points,points);
235 update();
265
266 if(m_animation) {
267 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
268 }
269
270 updateChart(m_points,points);
236 271 }
237 272
238 273 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
@@ -243,8 +278,11 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal
243 278 m_maxY=maxY;
244 279 if (isEmpty()) return;
245 280 QVector<QPointF> points = calculateGeometryPoints();
246 updateLayout(m_points,points);
247 update();
281
282 if(m_animation) {
283 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
284 }
285 updateChart(m_points,points);
248 286 }
249 287
250 288 void XYChartItem::handleGeometryChanged(const QRectF &rect)
@@ -256,11 +294,12 void XYChartItem::handleGeometryChanged(const QRectF &rect)
256 294
257 295 if (isEmpty()) return;
258 296 QVector<QPointF> points = calculateGeometryPoints();
259 updateLayout(m_points,points);
260 update();
297 if(m_animation) {
298 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
299 }
300 updateChart(m_points,points);
261 301 }
262 302
263
264 303 bool XYChartItem::isEmpty()
265 304 {
266 305 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
@@ -23,6 +23,7
23 23
24 24 #include "qchartglobal.h"
25 25 #include "chartitem_p.h"
26 #include "xyanimation_p.h"
26 27 #include <QPen>
27 28
28 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -37,9 +38,15 public:
37 38 explicit XYChartItem(QXYSeries *series, ChartPresenter *presenter);
38 39 ~XYChartItem(){};
39 40
40 QVector<QPointF> points() const {return m_points;}
41 QRectF clipRect() const { return m_clipRect;}
41 void setGeometryPoints(QVector<QPointF>& points);
42 QVector<QPointF> geometryPoints() const { return m_points; }
42 43
44 void setClipRect(const QRectF &rect);
45 QRectF clipRect() const { return m_clipRect; }
46
47 void setAnimation(XYAnimation* animation);
48 ChartAnimation* animation() const { return m_animation; }
49 virtual void updateGeometry();
43 50
44 51 public Q_SLOTS:
45 52 void handlePointAdded(int index);
@@ -55,10 +62,7 Q_SIGNALS:
55 62 void clicked(const QPointF& point);
56 63
57 64 protected:
58
59 virtual void setLayout(QVector<QPointF> &points);
60 virtual void updateLayout(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index = 0);
61
65 virtual void updateChart(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index = 0);
62 66 QPointF calculateGeometryPoint(const QPointF &point) const;
63 67 QPointF calculateGeometryPoint(int index) const;
64 68 QPointF calculateDomainPoint(const QPointF &point) const;
@@ -77,8 +81,8 private:
77 81 QSizeF m_size;
78 82 QRectF m_clipRect;
79 83 QVector<QPointF> m_points;
84 XYAnimation* m_animation;
80 85
81 friend class XYAnimation;
82 86 friend class AreaChartItem;
83 87
84 88 };
General Comments 0
You need to be logged in to leave comments. Login now