##// END OF EJS Templates
pie: implement hiding the series
Jani Honkonen -
r1456:0ba1c6e91aeb
parent child
Show More
@@ -1,209 +1,215
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "piechartitem_p.h"
21 #include "piechartitem_p.h"
22 #include "piesliceitem_p.h"
22 #include "piesliceitem_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "qpieslice_p.h"
24 #include "qpieslice_p.h"
25 #include "qpieseries.h"
25 #include "qpieseries.h"
26 #include "qpieseries_p.h"
26 #include "qpieseries_p.h"
27 #include "chartpresenter_p.h"
27 #include "chartpresenter_p.h"
28 #include "chartdataset_p.h"
28 #include "chartdataset_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30 #include <QPainter>
30 #include <QPainter>
31 #include <QTimer>
31 #include <QTimer>
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
34
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
36 :ChartItem(presenter),
36 :ChartItem(presenter),
37 m_series(series)
37 m_series(series)
38 {
38 {
39 Q_ASSERT(series);
39 Q_ASSERT(series);
40
40
41 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
41 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
42 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
42 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
43 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
43 connect(series, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
44 connect(series, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
44 connect(series, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
45 connect(series, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
45 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
46 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
46 connect(QPieSeriesPrivate::fromSeries(series), SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
47 connect(QPieSeriesPrivate::fromSeries(series), SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
47
48
48 // Note: the following does not affect as long as the item does not have anything to paint
49 // Note: the following does not affect as long as the item does not have anything to paint
49 setZValue(ChartPresenter::PieSeriesZValue);
50 setZValue(ChartPresenter::PieSeriesZValue);
50
51
51 // Note: will not create slice items until we have a proper rectangle to draw on.
52 // Note: will not create slice items until we have a proper rectangle to draw on.
52 }
53 }
53
54
54 PieChartItem::~PieChartItem()
55 PieChartItem::~PieChartItem()
55 {
56 {
56 // slices deleted automatically through QGraphicsItem
57 // slices deleted automatically through QGraphicsItem
57 }
58 }
58
59
59 void PieChartItem::handleGeometryChanged(const QRectF& rect)
60 void PieChartItem::handleGeometryChanged(const QRectF& rect)
60 {
61 {
61 prepareGeometryChange();
62 prepareGeometryChange();
62 m_rect = rect;
63 m_rect = rect;
63 updateLayout();
64 updateLayout();
64
65
65 // This is for delayed initialization of the slice items during startup.
66 // This is for delayed initialization of the slice items during startup.
66 // It ensures that startup animation originates from the correct position.
67 // It ensures that startup animation originates from the correct position.
67 if (m_sliceItems.isEmpty())
68 if (m_sliceItems.isEmpty())
68 handleSlicesAdded(m_series->slices());
69 handleSlicesAdded(m_series->slices());
69 }
70 }
70
71
71 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
72 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
72 {
73 {
73 Q_UNUSED(minX);
74 Q_UNUSED(minX);
74 Q_UNUSED(maxX);
75 Q_UNUSED(maxX);
75 Q_UNUSED(minY);
76 Q_UNUSED(minY);
76 Q_UNUSED(maxY);
77 Q_UNUSED(maxY);
77 // does not apply to pie
78 // does not apply to pie
78 }
79 }
79
80
80 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
81 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
81 {
82 {
82 Q_UNUSED(min);
83 Q_UNUSED(min);
83 Q_UNUSED(max);
84 Q_UNUSED(max);
84 Q_UNUSED(tickXCount);
85 Q_UNUSED(tickXCount);
85 // does not apply to pie
86 // does not apply to pie
86 }
87 }
87
88
88 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
89 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
89 {
90 {
90 Q_UNUSED(min);
91 Q_UNUSED(min);
91 Q_UNUSED(max);
92 Q_UNUSED(max);
92 Q_UNUSED(tickYCount);
93 Q_UNUSED(tickYCount);
93 // does not apply to pie
94 // does not apply to pie
94 }
95 }
95
96
96 void PieChartItem::updateLayout()
97 void PieChartItem::updateLayout()
97 {
98 {
98 // find pie center coordinates
99 // find pie center coordinates
99 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
100 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
100 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
101 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
101
102
102 // find maximum radius for pie
103 // find maximum radius for pie
103 m_pieRadius = m_rect.height() / 2;
104 m_pieRadius = m_rect.height() / 2;
104 if (m_rect.width() < m_rect.height())
105 if (m_rect.width() < m_rect.height())
105 m_pieRadius = m_rect.width() / 2;
106 m_pieRadius = m_rect.width() / 2;
106
107
107 // apply size factor
108 // apply size factor
108 m_pieRadius *= m_series->pieSize();
109 m_pieRadius *= m_series->pieSize();
109
110
110 // set layouts for existing slice items
111 // set layouts for existing slice items
111 foreach (QPieSlice* slice, m_series->slices()) {
112 foreach (QPieSlice* slice, m_series->slices()) {
112 PieSliceItem *sliceItem = m_sliceItems.value(slice);
113 PieSliceItem *sliceItem = m_sliceItems.value(slice);
113 if (sliceItem) {
114 if (sliceItem) {
114 PieSliceData sliceData = updateSliceGeometry(slice);
115 PieSliceData sliceData = updateSliceGeometry(slice);
115 if (animator())
116 if (animator())
116 animator()->updateAnimation(this, sliceItem, sliceData);
117 animator()->updateAnimation(this, sliceItem, sliceData);
117 else
118 else
118 sliceItem->setLayout(sliceData);
119 sliceItem->setLayout(sliceData);
119 }
120 }
120 }
121 }
121
122
122 update();
123 update();
123 }
124 }
124
125
125 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
126 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
126 {
127 {
127 // delay creating slice items until there is a proper rectangle
128 // delay creating slice items until there is a proper rectangle
128 if (!m_rect.isValid() && m_sliceItems.isEmpty())
129 if (!m_rect.isValid() && m_sliceItems.isEmpty())
129 return;
130 return;
130
131
131 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
132 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
132
133
133 bool startupAnimation = m_sliceItems.isEmpty();
134 bool startupAnimation = m_sliceItems.isEmpty();
134
135
135 foreach (QPieSlice *slice, slices) {
136 foreach (QPieSlice *slice, slices) {
136 PieSliceItem* sliceItem = new PieSliceItem(this);
137 PieSliceItem* sliceItem = new PieSliceItem(this);
137 m_sliceItems.insert(slice, sliceItem);
138 m_sliceItems.insert(slice, sliceItem);
138
139
139 // Note: do need to connect to slice valueChanged() etc.
140 // Note: do need to connect to slice valueChanged() etc.
140 // This is handled through calculatedDataChanged signal.
141 // This is handled through calculatedDataChanged signal.
141 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
142 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
142 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
143 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
143 connect(slice, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
144 connect(slice, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
144 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
145 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
145 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
146 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
146 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
147 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
147 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
148 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
148 connect(slice, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
149 connect(slice, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
149 connect(slice, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
150 connect(slice, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
150 connect(slice, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
151 connect(slice, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
151
152
152 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
153 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
153 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
154 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
154
155
155 PieSliceData sliceData = updateSliceGeometry(slice);
156 PieSliceData sliceData = updateSliceGeometry(slice);
156 if (animator())
157 if (animator())
157 animator()->addAnimation(this, sliceItem, sliceData, startupAnimation);
158 animator()->addAnimation(this, sliceItem, sliceData, startupAnimation);
158 else
159 else
159 sliceItem->setLayout(sliceData);
160 sliceItem->setLayout(sliceData);
160 }
161 }
161 }
162 }
162
163
163 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
164 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
164 {
165 {
165 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
166 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
166
167
167 foreach (QPieSlice *slice, slices) {
168 foreach (QPieSlice *slice, slices) {
168
169
169 PieSliceItem *sliceItem = m_sliceItems.value(slice);
170 PieSliceItem *sliceItem = m_sliceItems.value(slice);
170
171
171 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
172 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
172 if (!sliceItem)
173 if (!sliceItem)
173 continue;
174 continue;
174
175
175 m_sliceItems.remove(slice);
176 m_sliceItems.remove(slice);
176
177
177 if (animator())
178 if (animator())
178 animator()->removeAnimation(this, sliceItem); // animator deletes the PieSliceItem
179 animator()->removeAnimation(this, sliceItem); // animator deletes the PieSliceItem
179 else
180 else
180 delete sliceItem;
181 delete sliceItem;
181 }
182 }
182 }
183 }
183
184
184 void PieChartItem::handleSliceChanged()
185 void PieChartItem::handleSliceChanged()
185 {
186 {
186 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
187 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
187 Q_ASSERT(m_sliceItems.contains(slice));
188 Q_ASSERT(m_sliceItems.contains(slice));
188
189
189 PieSliceItem *sliceItem = m_sliceItems.value(slice);
190 PieSliceItem *sliceItem = m_sliceItems.value(slice);
190 PieSliceData sliceData = updateSliceGeometry(slice);
191 PieSliceData sliceData = updateSliceGeometry(slice);
191 if (animator())
192 if (animator())
192 animator()->updateAnimation(this, sliceItem, sliceData);
193 animator()->updateAnimation(this, sliceItem, sliceData);
193 else
194 else
194 sliceItem->setLayout(sliceData);
195 sliceItem->setLayout(sliceData);
195
196
196 update();
197 update();
197 }
198 }
198
199
200 void PieChartItem::handleSeriesVisibleChanged()
201 {
202 setVisible(m_series->isVisible());
203 }
204
199 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
205 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
200 {
206 {
201 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
207 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
202 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
208 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
203 sliceData.m_radius = m_pieRadius;
209 sliceData.m_radius = m_pieRadius;
204 return sliceData;
210 return sliceData;
205 }
211 }
206
212
207 #include "moc_piechartitem_p.cpp"
213 #include "moc_piechartitem_p.cpp"
208
214
209 QTCOMMERCIALCHART_END_NAMESPACE
215 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,79 +1,80
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef PIECHARTITEM_H
30 #ifndef PIECHARTITEM_H
31 #define PIECHARTITEM_H
31 #define PIECHARTITEM_H
32
32
33 #include "qpieseries.h"
33 #include "qpieseries.h"
34 #include "chartitem_p.h"
34 #include "chartitem_p.h"
35 #include "piesliceitem_p.h"
35 #include "piesliceitem_p.h"
36
36
37 class QGraphicsItem;
37 class QGraphicsItem;
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 class QPieSlice;
39 class QPieSlice;
40 class ChartPresenter;
40 class ChartPresenter;
41
41
42 class PieChartItem : public ChartItem
42 class PieChartItem : public ChartItem
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45
45
46 public:
46 public:
47 explicit PieChartItem(QPieSeries *series, ChartPresenter *presenter);
47 explicit PieChartItem(QPieSeries *series, ChartPresenter *presenter);
48 ~PieChartItem();
48 ~PieChartItem();
49
49
50 // from QGraphicsItem
50 // from QGraphicsItem
51 QRectF boundingRect() const { return m_rect; }
51 QRectF boundingRect() const { return m_rect; }
52 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
52 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
53
53
54 public Q_SLOTS:
54 public Q_SLOTS:
55 // from Chart
55 // from Chart
56 virtual void handleGeometryChanged(const QRectF &rect);
56 virtual void handleGeometryChanged(const QRectF &rect);
57 virtual void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
57 virtual void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
58 virtual void rangeXChanged(qreal min, qreal max, int tickXCount);
58 virtual void rangeXChanged(qreal min, qreal max, int tickXCount);
59 virtual void rangeYChanged(qreal min, qreal max, int tickYCount);
59 virtual void rangeYChanged(qreal min, qreal max, int tickYCount);
60
60
61 void updateLayout();
61 void updateLayout();
62 void handleSlicesAdded(QList<QPieSlice*> slices);
62 void handleSlicesAdded(QList<QPieSlice*> slices);
63 void handleSlicesRemoved(QList<QPieSlice*> slices);
63 void handleSlicesRemoved(QList<QPieSlice*> slices);
64 void handleSliceChanged();
64 void handleSliceChanged();
65 void handleSeriesVisibleChanged();
65
66
66 private:
67 private:
67 PieSliceData updateSliceGeometry(QPieSlice *slice);
68 PieSliceData updateSliceGeometry(QPieSlice *slice);
68
69
69 private:
70 private:
70 QHash<QPieSlice*, PieSliceItem*> m_sliceItems;
71 QHash<QPieSlice*, PieSliceItem*> m_sliceItems;
71 QPieSeries *m_series;
72 QPieSeries *m_series;
72 QRectF m_rect;
73 QRectF m_rect;
73 QPointF m_pieCenter;
74 QPointF m_pieCenter;
74 qreal m_pieRadius;
75 qreal m_pieRadius;
75 };
76 };
76
77
77 QTCOMMERCIALCHART_END_NAMESPACE
78 QTCOMMERCIALCHART_END_NAMESPACE
78
79
79 #endif // PIECHARTITEM_H
80 #endif // PIECHARTITEM_H
General Comments 0
You need to be logged in to leave comments. Login now