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