##// END OF EJS Templates
Nicer animation for adding a pie initially.
Jani Honkonen -
r634:5a177f3a506b
parent child
Show More
@@ -1,261 +1,261
1 #include "chartanimator_p.h"
1 #include "chartanimator_p.h"
2 #include "axisanimation_p.h"
2 #include "axisanimation_p.h"
3 #include "xyanimation_p.h"
3 #include "xyanimation_p.h"
4 #include "splineanimation_p.h"
4 #include "splineanimation_p.h"
5 #include "xychartitem_p.h"
5 #include "xychartitem_p.h"
6 #include "pieanimation_p.h"
6 #include "pieanimation_p.h"
7 #include "areachartitem_p.h"
7 #include "areachartitem_p.h"
8 #include "splinechartitem_p.h"
8 #include "splinechartitem_p.h"
9 #include "scatterchartitem_p.h"
9 #include "scatterchartitem_p.h"
10 #include <QTimer>
10 #include <QTimer>
11
11
12 Q_DECLARE_METATYPE(QVector<QPointF>)
12 Q_DECLARE_METATYPE(QVector<QPointF>)
13 Q_DECLARE_METATYPE(QVector<qreal>)
13 Q_DECLARE_METATYPE(QVector<qreal>)
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16
16
17 const static int duration = 1000;
17 const static int duration = 1000;
18
18
19 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
19 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
20 {
20 {
21 }
21 }
22
22
23 ChartAnimator::~ChartAnimator()
23 ChartAnimator::~ChartAnimator()
24 {
24 {
25 }
25 }
26
26
27 void ChartAnimator::addAnimation(AxisItem* item)
27 void ChartAnimator::addAnimation(AxisItem* item)
28 {
28 {
29 ChartAnimation* animation = m_animations.value(item);
29 ChartAnimation* animation = m_animations.value(item);
30
30
31 if(!animation) {
31 if(!animation) {
32 animation = new AxisAnimation(item);
32 animation = new AxisAnimation(item);
33 m_animations.insert(item,animation);
33 m_animations.insert(item,animation);
34 }
34 }
35
35
36 item->setAnimator(this);
36 item->setAnimator(this);
37 }
37 }
38
38
39 void ChartAnimator::addAnimation(SplineChartItem* item)
39 void ChartAnimator::addAnimation(SplineChartItem* item)
40 {
40 {
41 ChartAnimation* animation = m_animations.value(item);
41 ChartAnimation* animation = m_animations.value(item);
42
42
43 if(!animation) {
43 if(!animation) {
44 animation = new SplineAnimation(item);
44 animation = new SplineAnimation(item);
45 m_animations.insert(item,animation);
45 m_animations.insert(item,animation);
46 }
46 }
47
47
48 item->setAnimator(this);
48 item->setAnimator(this);
49 }
49 }
50
50
51 void ChartAnimator::addAnimation(ScatterChartItem* item)
51 void ChartAnimator::addAnimation(ScatterChartItem* item)
52 {
52 {
53 ChartAnimation* animation = m_animations.value(item);
53 ChartAnimation* animation = m_animations.value(item);
54
54
55 if(!animation) {
55 if(!animation) {
56 animation = new XYAnimation(item);
56 animation = new XYAnimation(item);
57 m_animations.insert(item,animation);
57 m_animations.insert(item,animation);
58 }
58 }
59
59
60 item->setAnimator(this);
60 item->setAnimator(this);
61 }
61 }
62
62
63 void ChartAnimator::addAnimation(LineChartItem* item)
63 void ChartAnimator::addAnimation(LineChartItem* item)
64 {
64 {
65 ChartAnimation* animation = m_animations.value(item);
65 ChartAnimation* animation = m_animations.value(item);
66
66
67 if(!animation) {
67 if(!animation) {
68 animation = new XYAnimation(item);
68 animation = new XYAnimation(item);
69 m_animations.insert(item,animation);
69 m_animations.insert(item,animation);
70 }
70 }
71
71
72 item->setAnimator(this);
72 item->setAnimator(this);
73 }
73 }
74
74
75 void ChartAnimator::addAnimation(PieChartItem* item)
75 void ChartAnimator::addAnimation(PieChartItem* item)
76 {
76 {
77 ChartAnimation* animation = m_animations.value(item);
77 ChartAnimation* animation = m_animations.value(item);
78
78
79 if(!animation) {
79 if(!animation) {
80 animation = new PieAnimation(item);
80 animation = new PieAnimation(item);
81 m_animations.insert(item,animation);
81 m_animations.insert(item,animation);
82 }
82 }
83
83
84 item->setAnimator(this);
84 item->setAnimator(this);
85 }
85 }
86
86
87 void ChartAnimator::removeAnimation(ChartItem* item)
87 void ChartAnimator::removeAnimation(ChartItem* item)
88 {
88 {
89 item->setAnimator(0);
89 item->setAnimator(0);
90 m_animations.remove(item);
90 m_animations.remove(item);
91 }
91 }
92
92
93 void ChartAnimator::applyLayout(AxisItem* item , QVector<qreal>& newLayout)
93 void ChartAnimator::applyLayout(AxisItem* item , QVector<qreal>& newLayout)
94 {
94 {
95 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
95 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
96
96
97 Q_ASSERT(animation);
97 Q_ASSERT(animation);
98
98
99 QVector<qreal> oldLayout = item->layout();
99 QVector<qreal> oldLayout = item->layout();
100
100
101 if(newLayout.count()==0) return;
101 if(newLayout.count()==0) return;
102
102
103 switch(m_state)
103 switch(m_state)
104 {
104 {
105 case ZoomOutState: {
105 case ZoomOutState: {
106 QRectF rect = item->geometry();
106 QRectF rect = item->geometry();
107 oldLayout.resize(newLayout.count());
107 oldLayout.resize(newLayout.count());
108
108
109 for(int i=0,j=oldLayout.count()-1;i<(oldLayout.count()+1)/2;i++,j--)
109 for(int i=0,j=oldLayout.count()-1;i<(oldLayout.count()+1)/2;i++,j--)
110 {
110 {
111 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
111 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
112 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
112 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
113 }
113 }
114 }
114 }
115 break;
115 break;
116 case ZoomInState: {
116 case ZoomInState: {
117 int index = qMin(oldLayout.count()*(item->axisType()==AxisItem::X_AXIS?m_point.x():(1 -m_point.y())),newLayout.count()-1.0);
117 int index = qMin(oldLayout.count()*(item->axisType()==AxisItem::X_AXIS?m_point.x():(1 -m_point.y())),newLayout.count()-1.0);
118 oldLayout.resize(newLayout.count());
118 oldLayout.resize(newLayout.count());
119
119
120 for(int i=0;i<oldLayout.count();i++)
120 for(int i=0;i<oldLayout.count();i++)
121 {
121 {
122 oldLayout[i]= oldLayout[index];
122 oldLayout[i]= oldLayout[index];
123 }
123 }
124 }
124 }
125 break;
125 break;
126 case ScrollDownState:
126 case ScrollDownState:
127 case ScrollRightState: {
127 case ScrollRightState: {
128 oldLayout.resize(newLayout.count());
128 oldLayout.resize(newLayout.count());
129
129
130 for(int i=0, j=i+1;i<oldLayout.count()-1;i++,j++)
130 for(int i=0, j=i+1;i<oldLayout.count()-1;i++,j++)
131 {
131 {
132 oldLayout[i]= oldLayout[j];
132 oldLayout[i]= oldLayout[j];
133 }
133 }
134 }
134 }
135 break;
135 break;
136 case ScrollUpState:
136 case ScrollUpState:
137 case ScrollLeftState: {
137 case ScrollLeftState: {
138 oldLayout.resize(newLayout.count());
138 oldLayout.resize(newLayout.count());
139
139
140 for(int i=oldLayout.count()-1, j=i-1;i>0;i--,j--)
140 for(int i=oldLayout.count()-1, j=i-1;i>0;i--,j--)
141 {
141 {
142 oldLayout[i]= oldLayout[j];
142 oldLayout[i]= oldLayout[j];
143 }
143 }
144 }
144 }
145 break;
145 break;
146 default: {
146 default: {
147 oldLayout.resize(newLayout.count());
147 oldLayout.resize(newLayout.count());
148 QRectF rect = item->geometry();
148 QRectF rect = item->geometry();
149 for(int i=0, j=oldLayout.count()-1;i<oldLayout.count();i++,j--)
149 for(int i=0, j=oldLayout.count()-1;i<oldLayout.count();i++,j--)
150 {
150 {
151 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.top();
151 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.top();
152 }
152 }
153 }
153 }
154 break;
154 break;
155 }
155 }
156
156
157
157
158 if(animation->state()!=QAbstractAnimation::Stopped) {
158 if(animation->state()!=QAbstractAnimation::Stopped) {
159 animation->stop();
159 animation->stop();
160 }
160 }
161
161
162 animation->setDuration(duration);
162 animation->setDuration(duration);
163 animation->setEasingCurve(QEasingCurve::OutQuart);
163 animation->setEasingCurve(QEasingCurve::OutQuart);
164 QVariantAnimation::KeyValues value;
164 QVariantAnimation::KeyValues value;
165 animation->setKeyValues(value); //workaround for wrong interpolation call
165 animation->setKeyValues(value); //workaround for wrong interpolation call
166 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
166 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
167 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
167 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
168
168
169 QTimer::singleShot(0,animation,SLOT(start()));
169 QTimer::singleShot(0,animation,SLOT(start()));
170 }
170 }
171
171
172 void ChartAnimator::updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints ,QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newControlPoints,int index)
172 void ChartAnimator::updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints ,QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newControlPoints,int index)
173 {
173 {
174 SplineAnimation* animation = static_cast<SplineAnimation*>(m_animations.value(item));
174 SplineAnimation* animation = static_cast<SplineAnimation*>(m_animations.value(item));
175
175
176 Q_ASSERT(animation);
176 Q_ASSERT(animation);
177
177
178 if(newPoints.count()<2 || newControlPoints.count()<2) return;
178 if(newPoints.count()<2 || newControlPoints.count()<2) return;
179
179
180 bool empty = oldPoints.count()==0;
180 bool empty = oldPoints.count()==0;
181
181
182
182
183 if(animation->state()!=QAbstractAnimation::Stopped) {
183 if(animation->state()!=QAbstractAnimation::Stopped) {
184 animation->stop();
184 animation->stop();
185 }
185 }
186
186
187 animation->setDuration(duration);
187 animation->setDuration(duration);
188 if(!empty)
188 if(!empty)
189 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
189 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
190 else
190 else
191 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
191 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
192
192
193 animation->setEasingCurve(QEasingCurve::OutQuart);
193 animation->setEasingCurve(QEasingCurve::OutQuart);
194 animation->setValues(oldPoints,newPoints,oldControlPoints,newControlPoints,index);
194 animation->setValues(oldPoints,newPoints,oldControlPoints,newControlPoints,index);
195
195
196 QTimer::singleShot(0,animation,SLOT(start()));
196 QTimer::singleShot(0,animation,SLOT(start()));
197 }
197 }
198
198
199
199
200 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, int index)
200 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, int index)
201 {
201 {
202 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
202 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
203
203
204 Q_ASSERT(animation);
204 Q_ASSERT(animation);
205
205
206 if(newPoints.count()==0) return;
206 if(newPoints.count()==0) return;
207
207
208 bool empty = oldPoints.count()==0;
208 bool empty = oldPoints.count()==0;
209
209
210
210
211 if(animation->state()!=QAbstractAnimation::Stopped) {
211 if(animation->state()!=QAbstractAnimation::Stopped) {
212 animation->stop();
212 animation->stop();
213 }
213 }
214
214
215 animation->setDuration(duration);
215 animation->setDuration(duration);
216 if(!empty)
216 if(!empty)
217 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
217 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
218 else
218 else
219 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
219 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
220
220
221 animation->setEasingCurve(QEasingCurve::OutQuart);
221 animation->setEasingCurve(QEasingCurve::OutQuart);
222 animation->setValues(oldPoints,newPoints,index);
222 animation->setValues(oldPoints,newPoints,index);
223
223
224 QTimer::singleShot(0,animation,SLOT(start()));
224 QTimer::singleShot(0,animation,SLOT(start()));
225 }
225 }
226
226
227 void ChartAnimator::addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout)
227 void ChartAnimator::addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout, bool isEmpty)
228 {
228 {
229 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
229 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
230 Q_ASSERT(animation);
230 Q_ASSERT(animation);
231 animation->addSlice(slice, layout);
231 animation->addSlice(slice, layout, isEmpty);
232 }
232 }
233
233
234 void ChartAnimator::removeAnimation(PieChartItem* item, QPieSlice *slice)
234 void ChartAnimator::removeAnimation(PieChartItem* item, QPieSlice *slice)
235 {
235 {
236 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
236 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
237 Q_ASSERT(animation);
237 Q_ASSERT(animation);
238 animation->removeSlice(slice);
238 animation->removeSlice(slice);
239 }
239 }
240
240
241 void ChartAnimator::updateLayout(PieChartItem* item, const PieLayout &layout)
241 void ChartAnimator::updateLayout(PieChartItem* item, const PieLayout &layout)
242 {
242 {
243 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
243 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
244 Q_ASSERT(animation);
244 Q_ASSERT(animation);
245 animation->updateValues(layout);
245 animation->updateValues(layout);
246 }
246 }
247
247
248 void ChartAnimator::updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout)
248 void ChartAnimator::updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout)
249 {
249 {
250 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
250 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
251 Q_ASSERT(animation);
251 Q_ASSERT(animation);
252 animation->updateValue(slice, layout);
252 animation->updateValue(slice, layout);
253 }
253 }
254
254
255 void ChartAnimator::setState(State state,const QPointF& point)
255 void ChartAnimator::setState(State state,const QPointF& point)
256 {
256 {
257 m_state=state;
257 m_state=state;
258 m_point=point;
258 m_point=point;
259 }
259 }
260
260
261 QTCOMMERCIALCHART_END_NAMESPACE
261 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,53 +1,53
1 #ifndef CHARTANIMATOR_P_H_
1 #ifndef CHARTANIMATOR_P_H_
2 #define CHARTANIMATOR_P_H_
2 #define CHARTANIMATOR_P_H_
3 #include "qchartglobal.h"
3 #include "qchartglobal.h"
4 #include "chartanimation_p.h"
4 #include "chartanimation_p.h"
5 #include "piechartitem_p.h"
5 #include "piechartitem_p.h"
6 #include <QPointF>
6 #include <QPointF>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class ChartItem;
10 class ChartItem;
11 class AxisItem;
11 class AxisItem;
12 class AreaChartItem;
12 class AreaChartItem;
13 class SplineChartItem;
13 class SplineChartItem;
14 class ScatterChartItem;
14 class ScatterChartItem;
15 class LineChartItem;
15 class LineChartItem;
16 class XYChartItem;
16 class XYChartItem;
17
17
18 class ChartAnimator : public QObject {
18 class ChartAnimator : public QObject {
19
19
20 public:
20 public:
21 //TODO: this should be flags in case of two state at the time
21 //TODO: this should be flags in case of two state at the time
22 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState,ScrollRightState,ZoomInState,ZoomOutState};
22 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState,ScrollRightState,ZoomInState,ZoomOutState};
23 ChartAnimator(QObject *parent = 0);
23 ChartAnimator(QObject *parent = 0);
24 virtual ~ChartAnimator();
24 virtual ~ChartAnimator();
25
25
26 void addAnimation(AxisItem* item);
26 void addAnimation(AxisItem* item);
27 void addAnimation(PieChartItem* item);
27 void addAnimation(PieChartItem* item);
28 void addAnimation(ScatterChartItem* item);
28 void addAnimation(ScatterChartItem* item);
29 void addAnimation(LineChartItem* item);
29 void addAnimation(LineChartItem* item);
30 void addAnimation(SplineChartItem* item);
30 void addAnimation(SplineChartItem* item);
31 void removeAnimation(ChartItem* item);
31 void removeAnimation(ChartItem* item);
32
32
33 void animationStarted();
33 void animationStarted();
34 void updateLayout(XYChartItem* item, QVector<QPointF>& oldLayout,QVector<QPointF>& newLayout,int index);
34 void updateLayout(XYChartItem* item, QVector<QPointF>& oldLayout,QVector<QPointF>& newLayout,int index);
35 void updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newContorlPoints,int index);
35 void updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newContorlPoints,int index);
36 void applyLayout(AxisItem* item, QVector<qreal>& layout);
36 void applyLayout(AxisItem* item, QVector<qreal>& layout);
37
37
38 void addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout);
38 void addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout, bool isEmpty);
39 void removeAnimation(PieChartItem* item, QPieSlice *slice);
39 void removeAnimation(PieChartItem* item, QPieSlice *slice);
40 void updateLayout(PieChartItem* item, const PieLayout &layout);
40 void updateLayout(PieChartItem* item, const PieLayout &layout);
41 void updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout);
41 void updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout);
42
42
43 void setState(State state,const QPointF& point = QPointF());
43 void setState(State state,const QPointF& point = QPointF());
44
44
45 private:
45 private:
46 QMap<ChartItem*,ChartAnimation*> m_animations;
46 QMap<ChartItem*,ChartAnimation*> m_animations;
47 State m_state;
47 State m_state;
48 QPointF m_point;
48 QPointF m_point;
49 };
49 };
50
50
51 QTCOMMERCIALCHART_END_NAMESPACE
51 QTCOMMERCIALCHART_END_NAMESPACE
52
52
53 #endif
53 #endif
@@ -1,89 +1,92
1 #include "pieanimation_p.h"
1 #include "pieanimation_p.h"
2 #include "piesliceanimation_p.h"
2 #include "piesliceanimation_p.h"
3 #include "piechartitem_p.h"
3 #include "piechartitem_p.h"
4 #include <QParallelAnimationGroup>
4 #include <QParallelAnimationGroup>
5 #include <QTimer>
5 #include <QTimer>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 PieAnimation::PieAnimation(PieChartItem *item)
9 PieAnimation::PieAnimation(PieChartItem *item)
10 :ChartAnimation(item),
10 :ChartAnimation(item),
11 m_item(item)
11 m_item(item)
12 {
12 {
13 }
13 }
14
14
15 PieAnimation::~PieAnimation()
15 PieAnimation::~PieAnimation()
16 {
16 {
17 }
17 }
18
18
19 void PieAnimation::updateValues(const PieLayout &newValues)
19 void PieAnimation::updateValues(const PieLayout &newValues)
20 {
20 {
21 foreach (QPieSlice* s, newValues.keys())
21 foreach (QPieSlice* s, newValues.keys())
22 updateValue(s, newValues.value(s));
22 updateValue(s, newValues.value(s));
23 }
23 }
24
24
25 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceLayout &endLayout)
25 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceLayout &endLayout)
26 {
26 {
27 PieSliceAnimation *animation = m_animations.value(slice);
27 PieSliceAnimation *animation = m_animations.value(slice);
28 Q_ASSERT(animation);
28 Q_ASSERT(animation);
29 animation->stop();
29 animation->stop();
30
30
31 animation->updateValue(endLayout);
31 animation->updateValue(endLayout);
32 animation->setDuration(1000);
32 animation->setDuration(1000);
33 animation->setEasingCurve(QEasingCurve::OutQuart);
33 animation->setEasingCurve(QEasingCurve::OutQuart);
34
34
35 QTimer::singleShot(0, animation, SLOT(start()));
35 QTimer::singleShot(0, animation, SLOT(start()));
36 }
36 }
37
37
38 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceLayout &endLayout)
38 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceLayout &endLayout, bool isEmpty)
39 {
39 {
40 PieSliceAnimation *animation = new PieSliceAnimation(m_item, slice);
40 PieSliceAnimation *animation = new PieSliceAnimation(m_item, slice);
41 m_animations.insert(slice, animation);
41 m_animations.insert(slice, animation);
42
42
43 PieSliceLayout startLayout = endLayout;
43 PieSliceLayout startLayout = endLayout;
44 startLayout.m_radius = 0;
44 startLayout.m_radius = 0;
45 startLayout.m_startAngle = endLayout.m_startAngle + (endLayout.m_angleSpan/2);
45 if (isEmpty)
46 startLayout.m_startAngle = 0;
47 else
48 startLayout.m_startAngle = endLayout.m_startAngle + (endLayout.m_angleSpan/2);
46 startLayout.m_angleSpan = 0;
49 startLayout.m_angleSpan = 0;
47 animation->setValue(startLayout, endLayout);
50 animation->setValue(startLayout, endLayout);
48
51
49 animation->setDuration(1000);
52 animation->setDuration(1000);
50 animation->setEasingCurve(QEasingCurve::OutQuart);
53 animation->setEasingCurve(QEasingCurve::OutQuart);
51 QTimer::singleShot(0, animation, SLOT(start()));
54 QTimer::singleShot(0, animation, SLOT(start()));
52 }
55 }
53
56
54 void PieAnimation::removeSlice(QPieSlice *slice)
57 void PieAnimation::removeSlice(QPieSlice *slice)
55 {
58 {
56 PieSliceAnimation *animation = m_animations.value(slice);
59 PieSliceAnimation *animation = m_animations.value(slice);
57 Q_ASSERT(animation);
60 Q_ASSERT(animation);
58 animation->stop();
61 animation->stop();
59
62
60 PieSliceLayout endLayout = animation->currentSliceValue();
63 PieSliceLayout endLayout = animation->currentSliceValue();
61 endLayout.m_radius = 0;
64 endLayout.m_radius = 0;
62 // TODO: find the actual angle where this slice disappears
65 // TODO: find the actual angle where this slice disappears
63 endLayout.m_startAngle = endLayout.m_startAngle + endLayout.m_angleSpan;
66 endLayout.m_startAngle = endLayout.m_startAngle + endLayout.m_angleSpan;
64 endLayout.m_angleSpan = 0;
67 endLayout.m_angleSpan = 0;
65
68
66 animation->updateValue(endLayout);
69 animation->updateValue(endLayout);
67 animation->setDuration(1000);
70 animation->setDuration(1000);
68 animation->setEasingCurve(QEasingCurve::OutQuart);
71 animation->setEasingCurve(QEasingCurve::OutQuart);
69
72
70 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
73 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
71 QTimer::singleShot(0, animation, SLOT(start()));
74 QTimer::singleShot(0, animation, SLOT(start()));
72 }
75 }
73
76
74 void PieAnimation::updateCurrentValue(const QVariant &)
77 void PieAnimation::updateCurrentValue(const QVariant &)
75 {
78 {
76 // nothing to do...
79 // nothing to do...
77 }
80 }
78
81
79 void PieAnimation::destroySliceAnimationComplete()
82 void PieAnimation::destroySliceAnimationComplete()
80 {
83 {
81 PieSliceAnimation *animation = static_cast<PieSliceAnimation*>(sender());
84 PieSliceAnimation *animation = static_cast<PieSliceAnimation*>(sender());
82 QPieSlice *slice = m_animations.key(animation);
85 QPieSlice *slice = m_animations.key(animation);
83 m_item->destroySlice(slice);
86 m_item->destroySlice(slice);
84 delete m_animations.take(slice);
87 delete m_animations.take(slice);
85 }
88 }
86
89
87 #include "moc_pieanimation_p.cpp"
90 #include "moc_pieanimation_p.cpp"
88
91
89 QTCOMMERCIALCHART_END_NAMESPACE
92 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,37 +1,37
1 #ifndef PIEANIMATION_P_H_
1 #ifndef PIEANIMATION_P_H_
2 #define PIEANIMATION_P_H_
2 #define PIEANIMATION_P_H_
3
3
4 #include "chartanimation_p.h"
4 #include "chartanimation_p.h"
5 #include "piechartitem_p.h"
5 #include "piechartitem_p.h"
6 #include "piesliceanimation_p.h"
6 #include "piesliceanimation_p.h"
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class PieChartItem;
10 class PieChartItem;
11
11
12 class PieAnimation : public ChartAnimation
12 class PieAnimation : public ChartAnimation
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15
15
16 public:
16 public:
17 PieAnimation(PieChartItem *item);
17 PieAnimation(PieChartItem *item);
18 ~PieAnimation();
18 ~PieAnimation();
19 void updateValues(const PieLayout &newValues);
19 void updateValues(const PieLayout &newValues);
20 void updateValue(QPieSlice *slice, const PieSliceLayout &newValue);
20 void updateValue(QPieSlice *slice, const PieSliceLayout &newValue);
21 void addSlice(QPieSlice *slice, const PieSliceLayout &endLayout);
21 void addSlice(QPieSlice *slice, const PieSliceLayout &endLayout, bool isEmpty);
22 void removeSlice(QPieSlice *slice);
22 void removeSlice(QPieSlice *slice);
23
23
24 public: // from QVariantAnimation
24 public: // from QVariantAnimation
25 void updateCurrentValue(const QVariant &value);
25 void updateCurrentValue(const QVariant &value);
26
26
27 public Q_SLOTS:
27 public Q_SLOTS:
28 void destroySliceAnimationComplete();
28 void destroySliceAnimationComplete();
29
29
30 private:
30 private:
31 PieChartItem *m_item;
31 PieChartItem *m_item;
32 QHash<QPieSlice*, PieSliceAnimation*> m_animations;
32 QHash<QPieSlice*, PieSliceAnimation*> m_animations;
33 };
33 };
34
34
35 QTCOMMERCIALCHART_END_NAMESPACE
35 QTCOMMERCIALCHART_END_NAMESPACE
36
36
37 #endif
37 #endif
@@ -1,188 +1,190
1 #include "piechartitem_p.h"
1 #include "piechartitem_p.h"
2 #include "pieslice_p.h"
2 #include "pieslice_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include "chartanimator_p.h"
6 #include "chartanimator_p.h"
7 #include <QDebug>
7 #include <QDebug>
8 #include <QPainter>
8 #include <QPainter>
9 #include <QTimer>
9 #include <QTimer>
10
10
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
12
13 PieChartItem::PieChartItem(QGraphicsItem *parent, QPieSeries *series)
13 PieChartItem::PieChartItem(QGraphicsItem *parent, QPieSeries *series)
14 :ChartItem(parent),
14 :ChartItem(parent),
15 m_series(series)
15 m_series(series)
16 {
16 {
17 Q_ASSERT(series);
17 Q_ASSERT(series);
18 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
18 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
19 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
19 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
20 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
20 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
21 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
21 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
22
22
23 QTimer::singleShot(0, this, SLOT(initialize()));
23 QTimer::singleShot(0, this, SLOT(initialize()));
24
24
25 // Note: the following does not affect as long as the item does not have anything to paint
25 // Note: the following does not affect as long as the item does not have anything to paint
26 setZValue(ChartPresenter::PieSeriesZValue);
26 setZValue(ChartPresenter::PieSeriesZValue);
27 }
27 }
28
28
29 PieChartItem::~PieChartItem()
29 PieChartItem::~PieChartItem()
30 {
30 {
31 // slices deleted automatically through QGraphicsItem
31 // slices deleted automatically through QGraphicsItem
32 }
32 }
33
33
34 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
34 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
35 {
35 {
36 Q_UNUSED(painter)
36 Q_UNUSED(painter)
37 // TODO: paint shadows for all components
37 // TODO: paint shadows for all components
38 // - get paths from items & merge & offset and draw with shadow color?
38 // - get paths from items & merge & offset and draw with shadow color?
39 //painter->setBrush(QBrush(Qt::red));
39 //painter->setBrush(QBrush(Qt::red));
40 //painter->drawRect(m_debugRect);
40 //painter->drawRect(m_debugRect);
41 }
41 }
42
42
43 void PieChartItem::initialize()
43 void PieChartItem::initialize()
44 {
44 {
45 handleSlicesAdded(m_series->m_slices);
45 handleSlicesAdded(m_series->m_slices);
46 }
46 }
47
47
48 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
48 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
49 {
49 {
50 bool isEmpty = m_slices.isEmpty();
51
50 foreach (QPieSlice *s, slices) {
52 foreach (QPieSlice *s, slices) {
51 PieSlice* slice = new PieSlice(this);
53 PieSlice* slice = new PieSlice(this);
52 m_slices.insert(s, slice);
54 m_slices.insert(s, slice);
53 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
55 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
54 connect(slice, SIGNAL(clicked()), s, SIGNAL(clicked()));
56 connect(slice, SIGNAL(clicked()), s, SIGNAL(clicked()));
55 connect(slice, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
57 connect(slice, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
56 connect(slice, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
58 connect(slice, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
57
59
58 PieSliceLayout layout = calculateSliceLayout(s);
60 PieSliceLayout layout = calculateSliceLayout(s);
59
61
60 if (m_animator)
62 if (m_animator)
61 m_animator->addAnimation(this, s, layout);
63 m_animator->addAnimation(this, s, layout, isEmpty);
62 else
64 else
63 setLayout(s, layout);
65 setLayout(s, layout);
64 }
66 }
65 }
67 }
66
68
67 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
69 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
68 {
70 {
69 foreach (QPieSlice *s, slices) {
71 foreach (QPieSlice *s, slices) {
70 if (m_animator)
72 if (m_animator)
71 m_animator->removeAnimation(this, s);
73 m_animator->removeAnimation(this, s);
72 else
74 else
73 destroySlice(s);
75 destroySlice(s);
74 }
76 }
75 }
77 }
76
78
77 void PieChartItem::handlePieLayoutChanged()
79 void PieChartItem::handlePieLayoutChanged()
78 {
80 {
79 PieLayout layout = calculateLayout();
81 PieLayout layout = calculateLayout();
80 applyLayout(layout);
82 applyLayout(layout);
81 update();
83 update();
82 }
84 }
83
85
84 void PieChartItem::handleSliceChanged()
86 void PieChartItem::handleSliceChanged()
85 {
87 {
86 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
88 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
87 Q_ASSERT(m_slices.contains(slice));
89 Q_ASSERT(m_slices.contains(slice));
88 PieSliceLayout layout = calculateSliceLayout(slice);
90 PieSliceLayout layout = calculateSliceLayout(slice);
89 updateLayout(slice, layout);
91 updateLayout(slice, layout);
90 update();
92 update();
91 }
93 }
92
94
93 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
95 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
94 {
96 {
95 // TODO
97 // TODO
96 }
98 }
97
99
98 void PieChartItem::handleGeometryChanged(const QRectF& rect)
100 void PieChartItem::handleGeometryChanged(const QRectF& rect)
99 {
101 {
100 prepareGeometryChange();
102 prepareGeometryChange();
101 m_rect = rect;
103 m_rect = rect;
102 handlePieLayoutChanged();
104 handlePieLayoutChanged();
103 }
105 }
104
106
105 void PieChartItem::calculatePieLayout()
107 void PieChartItem::calculatePieLayout()
106 {
108 {
107 // find pie center coordinates
109 // find pie center coordinates
108 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
110 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
109 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
111 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
110
112
111 // find maximum radius for pie
113 // find maximum radius for pie
112 m_pieRadius = m_rect.height() / 2;
114 m_pieRadius = m_rect.height() / 2;
113 if (m_rect.width() < m_rect.height())
115 if (m_rect.width() < m_rect.height())
114 m_pieRadius = m_rect.width() / 2;
116 m_pieRadius = m_rect.width() / 2;
115
117
116 // apply size factor
118 // apply size factor
117 m_pieRadius *= m_series->pieSize();
119 m_pieRadius *= m_series->pieSize();
118 }
120 }
119
121
120 PieSliceLayout PieChartItem::calculateSliceLayout(QPieSlice *slice)
122 PieSliceLayout PieChartItem::calculateSliceLayout(QPieSlice *slice)
121 {
123 {
122 PieSliceLayout sliceLayout;
124 PieSliceLayout sliceLayout;
123 sliceLayout.m_center = PieSlice::sliceCenter(m_pieCenter, m_pieRadius, slice);
125 sliceLayout.m_center = PieSlice::sliceCenter(m_pieCenter, m_pieRadius, slice);
124 sliceLayout.m_radius = m_pieRadius;
126 sliceLayout.m_radius = m_pieRadius;
125 sliceLayout.m_startAngle = slice->startAngle();
127 sliceLayout.m_startAngle = slice->startAngle();
126 sliceLayout.m_angleSpan = slice->m_angleSpan;
128 sliceLayout.m_angleSpan = slice->m_angleSpan;
127 return sliceLayout;
129 return sliceLayout;
128 }
130 }
129
131
130 PieLayout PieChartItem::calculateLayout()
132 PieLayout PieChartItem::calculateLayout()
131 {
133 {
132 calculatePieLayout();
134 calculatePieLayout();
133 PieLayout layout;
135 PieLayout layout;
134 foreach (QPieSlice* s, m_series->slices()) {
136 foreach (QPieSlice* s, m_series->slices()) {
135 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
137 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
136 layout.insert(s, calculateSliceLayout(s));
138 layout.insert(s, calculateSliceLayout(s));
137 }
139 }
138 return layout;
140 return layout;
139 }
141 }
140
142
141 void PieChartItem::applyLayout(const PieLayout &layout)
143 void PieChartItem::applyLayout(const PieLayout &layout)
142 {
144 {
143 if (m_animator)
145 if (m_animator)
144 m_animator->updateLayout(this, layout);
146 m_animator->updateLayout(this, layout);
145 else
147 else
146 setLayout(layout);
148 setLayout(layout);
147 }
149 }
148
150
149 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceLayout &layout)
151 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceLayout &layout)
150 {
152 {
151 if (m_animator)
153 if (m_animator)
152 m_animator->updateLayout(this, slice, layout);
154 m_animator->updateLayout(this, slice, layout);
153 else
155 else
154 setLayout(slice, layout);
156 setLayout(slice, layout);
155 }
157 }
156
158
157 void PieChartItem::setLayout(const PieLayout &layout)
159 void PieChartItem::setLayout(const PieLayout &layout)
158 {
160 {
159 foreach (QPieSlice *slice, layout.keys()) {
161 foreach (QPieSlice *slice, layout.keys()) {
160 PieSlice *s = m_slices.value(slice);
162 PieSlice *s = m_slices.value(slice);
161 Q_ASSERT(s);
163 Q_ASSERT(s);
162 s->setLayout(layout.value(slice));
164 s->setLayout(layout.value(slice));
163 s->updateData(slice);
165 s->updateData(slice);
164 s->updateGeometry();
166 s->updateGeometry();
165 s->update();
167 s->update();
166 }
168 }
167 }
169 }
168
170
169 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceLayout &layout)
171 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceLayout &layout)
170 {
172 {
171 // find slice
173 // find slice
172 PieSlice *s = m_slices.value(slice);
174 PieSlice *s = m_slices.value(slice);
173 Q_ASSERT(s);
175 Q_ASSERT(s);
174 s->setLayout(layout);
176 s->setLayout(layout);
175 if (m_series->m_slices.contains(slice)) // Slice has been deleted if not found. Animations ongoing...
177 if (m_series->m_slices.contains(slice)) // Slice has been deleted if not found. Animations ongoing...
176 s->updateData(slice);
178 s->updateData(slice);
177 s->updateGeometry();
179 s->updateGeometry();
178 s->update();
180 s->update();
179 }
181 }
180
182
181 void PieChartItem::destroySlice(QPieSlice *slice)
183 void PieChartItem::destroySlice(QPieSlice *slice)
182 {
184 {
183 delete m_slices.take(slice);
185 delete m_slices.take(slice);
184 }
186 }
185
187
186 #include "moc_piechartitem_p.cpp"
188 #include "moc_piechartitem_p.cpp"
187
189
188 QTCOMMERCIALCHART_END_NAMESPACE
190 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now