##// END OF EJS Templates
Add mousebuttons to pie clicked signals
Jani Honkonen -
r707:0529e02041c3
parent child
Show More
@@ -1,608 +1,610
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
4 #include <qchartview.h>
5 #include <qpieseries.h>
5 #include <qpieseries.h>
6 #include <qpieslice.h>
6 #include <qpieslice.h>
7 #include <QGridLayout>
7 #include <QGridLayout>
8 #include <QFormLayout>
8 #include <QFormLayout>
9 #include <QComboBox>
9 #include <QComboBox>
10 #include <QSpinBox>
10 #include <QSpinBox>
11 #include <QCheckBox>
11 #include <QCheckBox>
12 #include <QGroupBox>
12 #include <QGroupBox>
13 #include <QLabel>
13 #include <QLabel>
14 #include <QPushButton>
14 #include <QPushButton>
15 #include <QColorDialog>
15 #include <QColorDialog>
16 #include <QFontDialog>
16 #include <QFontDialog>
17
17
18 QTCOMMERCIALCHART_USE_NAMESPACE
18 QTCOMMERCIALCHART_USE_NAMESPACE
19
19
20 class PenTool : public QWidget
20 class PenTool : public QWidget
21 {
21 {
22 Q_OBJECT
22 Q_OBJECT
23
23
24 public:
24 public:
25 explicit PenTool(QString title, QWidget *parent = 0)
25 explicit PenTool(QString title, QWidget *parent = 0)
26 :QWidget(parent)
26 :QWidget(parent)
27 {
27 {
28 setWindowTitle(title);
28 setWindowTitle(title);
29 setWindowFlags(Qt::Tool);
29 setWindowFlags(Qt::Tool);
30
30
31 m_colorButton = new QPushButton();
31 m_colorButton = new QPushButton();
32
32
33 m_widthSpinBox = new QDoubleSpinBox();
33 m_widthSpinBox = new QDoubleSpinBox();
34
34
35 m_styleCombo = new QComboBox();
35 m_styleCombo = new QComboBox();
36 m_styleCombo->addItem("NoPen");
36 m_styleCombo->addItem("NoPen");
37 m_styleCombo->addItem("SolidLine");
37 m_styleCombo->addItem("SolidLine");
38 m_styleCombo->addItem("DashLine");
38 m_styleCombo->addItem("DashLine");
39 m_styleCombo->addItem("DotLine");
39 m_styleCombo->addItem("DotLine");
40 m_styleCombo->addItem("DashDotLine");
40 m_styleCombo->addItem("DashDotLine");
41 m_styleCombo->addItem("DashDotDotLine");
41 m_styleCombo->addItem("DashDotDotLine");
42
42
43 m_capStyleCombo = new QComboBox();
43 m_capStyleCombo = new QComboBox();
44 m_capStyleCombo->addItem("FlatCap", Qt::FlatCap);
44 m_capStyleCombo->addItem("FlatCap", Qt::FlatCap);
45 m_capStyleCombo->addItem("SquareCap", Qt::SquareCap);
45 m_capStyleCombo->addItem("SquareCap", Qt::SquareCap);
46 m_capStyleCombo->addItem("RoundCap", Qt::RoundCap);
46 m_capStyleCombo->addItem("RoundCap", Qt::RoundCap);
47
47
48 m_joinStyleCombo = new QComboBox();
48 m_joinStyleCombo = new QComboBox();
49 m_joinStyleCombo->addItem("MiterJoin", Qt::MiterJoin);
49 m_joinStyleCombo->addItem("MiterJoin", Qt::MiterJoin);
50 m_joinStyleCombo->addItem("BevelJoin", Qt::BevelJoin);
50 m_joinStyleCombo->addItem("BevelJoin", Qt::BevelJoin);
51 m_joinStyleCombo->addItem("RoundJoin", Qt::RoundJoin);
51 m_joinStyleCombo->addItem("RoundJoin", Qt::RoundJoin);
52 m_joinStyleCombo->addItem("SvgMiterJoin", Qt::SvgMiterJoin);
52 m_joinStyleCombo->addItem("SvgMiterJoin", Qt::SvgMiterJoin);
53
53
54 QFormLayout *layout = new QFormLayout();
54 QFormLayout *layout = new QFormLayout();
55 layout->addRow("Color", m_colorButton);
55 layout->addRow("Color", m_colorButton);
56 layout->addRow("Width", m_widthSpinBox);
56 layout->addRow("Width", m_widthSpinBox);
57 layout->addRow("Style", m_styleCombo);
57 layout->addRow("Style", m_styleCombo);
58 layout->addRow("Cap style", m_capStyleCombo);
58 layout->addRow("Cap style", m_capStyleCombo);
59 layout->addRow("Join style", m_joinStyleCombo);
59 layout->addRow("Join style", m_joinStyleCombo);
60 setLayout(layout);
60 setLayout(layout);
61
61
62 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
62 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
63 connect(m_widthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateWidth(double)));
63 connect(m_widthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateWidth(double)));
64 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle(int)));
64 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle(int)));
65 connect(m_capStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCapStyle(int)));
65 connect(m_capStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCapStyle(int)));
66 connect(m_joinStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateJoinStyle(int)));
66 connect(m_joinStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateJoinStyle(int)));
67 }
67 }
68
68
69 void setPen(QPen pen)
69 void setPen(QPen pen)
70 {
70 {
71 m_pen = pen;
71 m_pen = pen;
72 m_colorButton->setText(m_pen.color().name());
72 m_colorButton->setText(m_pen.color().name());
73 m_widthSpinBox->setValue(m_pen.widthF());
73 m_widthSpinBox->setValue(m_pen.widthF());
74 m_styleCombo->setCurrentIndex(m_pen.style()); // index matches the enum
74 m_styleCombo->setCurrentIndex(m_pen.style()); // index matches the enum
75 m_capStyleCombo->setCurrentIndex(m_capStyleCombo->findData(m_pen.capStyle()));
75 m_capStyleCombo->setCurrentIndex(m_capStyleCombo->findData(m_pen.capStyle()));
76 m_joinStyleCombo->setCurrentIndex(m_joinStyleCombo->findData(m_pen.joinStyle()));
76 m_joinStyleCombo->setCurrentIndex(m_joinStyleCombo->findData(m_pen.joinStyle()));
77 }
77 }
78
78
79 QPen pen() const
79 QPen pen() const
80 {
80 {
81 return m_pen;
81 return m_pen;
82 }
82 }
83
83
84 QString name()
84 QString name()
85 {
85 {
86 return name(m_pen);
86 return name(m_pen);
87 }
87 }
88
88
89 static QString name(const QPen &pen)
89 static QString name(const QPen &pen)
90 {
90 {
91 return pen.color().name() + ":" + QString::number(pen.widthF());
91 return pen.color().name() + ":" + QString::number(pen.widthF());
92 }
92 }
93
93
94 Q_SIGNALS:
94 Q_SIGNALS:
95 void changed();
95 void changed();
96
96
97 public Q_SLOTS:
97 public Q_SLOTS:
98
98
99 void showColorDialog()
99 void showColorDialog()
100 {
100 {
101 QColorDialog dialog(m_pen.color());
101 QColorDialog dialog(m_pen.color());
102 dialog.show();
102 dialog.show();
103 dialog.exec();
103 dialog.exec();
104 m_pen.setColor(dialog.selectedColor());
104 m_pen.setColor(dialog.selectedColor());
105 m_colorButton->setText(m_pen.color().name());
105 m_colorButton->setText(m_pen.color().name());
106 emit changed();
106 emit changed();
107 }
107 }
108
108
109 void updateWidth(double width)
109 void updateWidth(double width)
110 {
110 {
111 if (width != m_pen.widthF()) {
111 if (width != m_pen.widthF()) {
112 m_pen.setWidthF(width);
112 m_pen.setWidthF(width);
113 emit changed();
113 emit changed();
114 }
114 }
115 }
115 }
116
116
117 void updateStyle(int style)
117 void updateStyle(int style)
118 {
118 {
119 if (m_pen.style() != style) {
119 if (m_pen.style() != style) {
120 m_pen.setStyle((Qt::PenStyle) style);
120 m_pen.setStyle((Qt::PenStyle) style);
121 emit changed();
121 emit changed();
122 }
122 }
123 }
123 }
124
124
125 void updateCapStyle(int index)
125 void updateCapStyle(int index)
126 {
126 {
127 Qt::PenCapStyle capStyle = (Qt::PenCapStyle) m_capStyleCombo->itemData(index).toInt();
127 Qt::PenCapStyle capStyle = (Qt::PenCapStyle) m_capStyleCombo->itemData(index).toInt();
128 if (m_pen.capStyle() != capStyle) {
128 if (m_pen.capStyle() != capStyle) {
129 m_pen.setCapStyle(capStyle);
129 m_pen.setCapStyle(capStyle);
130 emit changed();
130 emit changed();
131 }
131 }
132 }
132 }
133
133
134 void updateJoinStyle(int index)
134 void updateJoinStyle(int index)
135 {
135 {
136 Qt::PenJoinStyle joinStyle = (Qt::PenJoinStyle) m_joinStyleCombo->itemData(index).toInt();
136 Qt::PenJoinStyle joinStyle = (Qt::PenJoinStyle) m_joinStyleCombo->itemData(index).toInt();
137 if (m_pen.joinStyle() != joinStyle) {
137 if (m_pen.joinStyle() != joinStyle) {
138 m_pen.setJoinStyle(joinStyle);
138 m_pen.setJoinStyle(joinStyle);
139 emit changed();
139 emit changed();
140 }
140 }
141 }
141 }
142
142
143 private:
143 private:
144 QPen m_pen;
144 QPen m_pen;
145 QPushButton *m_colorButton;
145 QPushButton *m_colorButton;
146 QDoubleSpinBox *m_widthSpinBox;
146 QDoubleSpinBox *m_widthSpinBox;
147 QComboBox *m_styleCombo;
147 QComboBox *m_styleCombo;
148 QComboBox *m_capStyleCombo;
148 QComboBox *m_capStyleCombo;
149 QComboBox *m_joinStyleCombo;
149 QComboBox *m_joinStyleCombo;
150 };
150 };
151
151
152 class BrushTool : public QWidget
152 class BrushTool : public QWidget
153 {
153 {
154 Q_OBJECT
154 Q_OBJECT
155
155
156 public:
156 public:
157 explicit BrushTool(QString title, QWidget *parent = 0)
157 explicit BrushTool(QString title, QWidget *parent = 0)
158 :QWidget(parent)
158 :QWidget(parent)
159 {
159 {
160 setWindowTitle(title);
160 setWindowTitle(title);
161 setWindowFlags(Qt::Tool);
161 setWindowFlags(Qt::Tool);
162
162
163 m_colorButton = new QPushButton();
163 m_colorButton = new QPushButton();
164 m_styleCombo = new QComboBox();
164 m_styleCombo = new QComboBox();
165 m_styleCombo->addItem("Nobrush", Qt::NoBrush);
165 m_styleCombo->addItem("Nobrush", Qt::NoBrush);
166 m_styleCombo->addItem("Solidpattern", Qt::SolidPattern);
166 m_styleCombo->addItem("Solidpattern", Qt::SolidPattern);
167 m_styleCombo->addItem("Dense1pattern", Qt::Dense1Pattern);
167 m_styleCombo->addItem("Dense1pattern", Qt::Dense1Pattern);
168 m_styleCombo->addItem("Dense2attern", Qt::Dense2Pattern);
168 m_styleCombo->addItem("Dense2attern", Qt::Dense2Pattern);
169 m_styleCombo->addItem("Dense3Pattern", Qt::Dense3Pattern);
169 m_styleCombo->addItem("Dense3Pattern", Qt::Dense3Pattern);
170 m_styleCombo->addItem("Dense4Pattern", Qt::Dense4Pattern);
170 m_styleCombo->addItem("Dense4Pattern", Qt::Dense4Pattern);
171 m_styleCombo->addItem("Dense5Pattern", Qt::Dense5Pattern);
171 m_styleCombo->addItem("Dense5Pattern", Qt::Dense5Pattern);
172 m_styleCombo->addItem("Dense6Pattern", Qt::Dense6Pattern);
172 m_styleCombo->addItem("Dense6Pattern", Qt::Dense6Pattern);
173 m_styleCombo->addItem("Dense7Pattern", Qt::Dense7Pattern);
173 m_styleCombo->addItem("Dense7Pattern", Qt::Dense7Pattern);
174 m_styleCombo->addItem("HorPattern", Qt::HorPattern);
174 m_styleCombo->addItem("HorPattern", Qt::HorPattern);
175 m_styleCombo->addItem("VerPattern", Qt::VerPattern);
175 m_styleCombo->addItem("VerPattern", Qt::VerPattern);
176 m_styleCombo->addItem("CrossPattern", Qt::CrossPattern);
176 m_styleCombo->addItem("CrossPattern", Qt::CrossPattern);
177 m_styleCombo->addItem("BDiagPattern", Qt::BDiagPattern);
177 m_styleCombo->addItem("BDiagPattern", Qt::BDiagPattern);
178 m_styleCombo->addItem("FDiagPattern", Qt::FDiagPattern);
178 m_styleCombo->addItem("FDiagPattern", Qt::FDiagPattern);
179 m_styleCombo->addItem("DiagCrossPattern", Qt::DiagCrossPattern);
179 m_styleCombo->addItem("DiagCrossPattern", Qt::DiagCrossPattern);
180
180
181 QFormLayout *layout = new QFormLayout();
181 QFormLayout *layout = new QFormLayout();
182 layout->addRow("Color", m_colorButton);
182 layout->addRow("Color", m_colorButton);
183 layout->addRow("Style", m_styleCombo);
183 layout->addRow("Style", m_styleCombo);
184 setLayout(layout);
184 setLayout(layout);
185
185
186 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
186 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
187 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle()));
187 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle()));
188 }
188 }
189
189
190 void setBrush(QBrush brush)
190 void setBrush(QBrush brush)
191 {
191 {
192 m_brush = brush;
192 m_brush = brush;
193 m_colorButton->setText(m_brush.color().name());
193 m_colorButton->setText(m_brush.color().name());
194 m_styleCombo->setCurrentIndex(m_brush.style()); // index matches the enum
194 m_styleCombo->setCurrentIndex(m_brush.style()); // index matches the enum
195 }
195 }
196
196
197 QBrush brush() const
197 QBrush brush() const
198 {
198 {
199 return m_brush;
199 return m_brush;
200 }
200 }
201
201
202 QString name()
202 QString name()
203 {
203 {
204 return name(m_brush);
204 return name(m_brush);
205 }
205 }
206
206
207 static QString name(const QBrush &brush)
207 static QString name(const QBrush &brush)
208 {
208 {
209 return brush.color().name();
209 return brush.color().name();
210 }
210 }
211
211
212 Q_SIGNALS:
212 Q_SIGNALS:
213 void changed();
213 void changed();
214
214
215 public Q_SLOTS:
215 public Q_SLOTS:
216
216
217 void showColorDialog()
217 void showColorDialog()
218 {
218 {
219 QColorDialog dialog(m_brush.color());
219 QColorDialog dialog(m_brush.color());
220 dialog.show();
220 dialog.show();
221 dialog.exec();
221 dialog.exec();
222 m_brush.setColor(dialog.selectedColor());
222 m_brush.setColor(dialog.selectedColor());
223 m_colorButton->setText(m_brush.color().name());
223 m_colorButton->setText(m_brush.color().name());
224 emit changed();
224 emit changed();
225 }
225 }
226
226
227 void updateStyle()
227 void updateStyle()
228 {
228 {
229 Qt::BrushStyle style = (Qt::BrushStyle) m_styleCombo->itemData(m_styleCombo->currentIndex()).toInt();
229 Qt::BrushStyle style = (Qt::BrushStyle) m_styleCombo->itemData(m_styleCombo->currentIndex()).toInt();
230 if (m_brush.style() != style) {
230 if (m_brush.style() != style) {
231 m_brush.setStyle(style);
231 m_brush.setStyle(style);
232 emit changed();
232 emit changed();
233 }
233 }
234 }
234 }
235
235
236 private:
236 private:
237 QBrush m_brush;
237 QBrush m_brush;
238 QPushButton *m_colorButton;
238 QPushButton *m_colorButton;
239 QComboBox *m_styleCombo;
239 QComboBox *m_styleCombo;
240 };
240 };
241
241
242 class CustomSlice : public QPieSlice
242 class CustomSlice : public QPieSlice
243 {
243 {
244 Q_OBJECT
244 Q_OBJECT
245 public:
245 public:
246 CustomSlice(qreal value, QString label)
246 CustomSlice(qreal value, QString label)
247 :QPieSlice(value, label)
247 :QPieSlice(value, label)
248 {
248 {
249 connect(this, SIGNAL(hoverEnter()), this, SLOT(handleHoverEnter()));
249 connect(this, SIGNAL(hoverEnter()), this, SLOT(handleHoverEnter()));
250 connect(this, SIGNAL(hoverLeave()), this, SLOT(handleHoverLeave()));
250 connect(this, SIGNAL(hoverLeave()), this, SLOT(handleHoverLeave()));
251 }
251 }
252
252
253 public:
253 public:
254 QBrush originalBrush()
254 QBrush originalBrush()
255 {
255 {
256 return m_originalBrush;
256 return m_originalBrush;
257 }
257 }
258
258
259 public Q_SLOTS:
259 public Q_SLOTS:
260
260
261 void handleHoverEnter()
261 void handleHoverEnter()
262 {
262 {
263 QBrush brush = this->sliceBrush();
263 QBrush brush = this->sliceBrush();
264 m_originalBrush = brush;
264 m_originalBrush = brush;
265 brush.setColor(brush.color().lighter());
265 brush.setColor(brush.color().lighter());
266 setSliceBrush(brush);
266 setSliceBrush(brush);
267 }
267 }
268
268
269 void handleHoverLeave()
269 void handleHoverLeave()
270 {
270 {
271 setSliceBrush(m_originalBrush);
271 setSliceBrush(m_originalBrush);
272 }
272 }
273
273
274 private:
274 private:
275 QBrush m_originalBrush;
275 QBrush m_originalBrush;
276 };
276 };
277
277
278 class MainWidget : public QWidget
278 class MainWidget : public QWidget
279 {
279 {
280 Q_OBJECT
280 Q_OBJECT
281
281
282 public:
282 public:
283 explicit MainWidget(QWidget* parent = 0)
283 explicit MainWidget(QWidget* parent = 0)
284 :QWidget(parent),
284 :QWidget(parent),
285 m_slice(0)
285 m_slice(0)
286 {
286 {
287 // create chart
287 // create chart
288 m_chartView = new QChartView();
288 m_chartView = new QChartView();
289 m_chartView->setChartTitle("Piechart customization");
289 m_chartView->setChartTitle("Piechart customization");
290 m_chartView->setAnimationOptions(QChart::AllAnimations);
290 m_chartView->setAnimationOptions(QChart::AllAnimations);
291
291
292 // create series
292 // create series
293 m_series = new QPieSeries();
293 m_series = new QPieSeries();
294 *m_series << new CustomSlice(10.0, "Slice 1");
294 *m_series << new CustomSlice(10.0, "Slice 1");
295 *m_series << new CustomSlice(20.0, "Slice 2");
295 *m_series << new CustomSlice(20.0, "Slice 2");
296 *m_series << new CustomSlice(30.0, "Slice 3");
296 *m_series << new CustomSlice(30.0, "Slice 3");
297 *m_series << new CustomSlice(40.0, "Slice 4");
297 *m_series << new CustomSlice(40.0, "Slice 4");
298 *m_series << new CustomSlice(50.0, "Slice 5");
298 *m_series << new CustomSlice(50.0, "Slice 5");
299 m_chartView->addSeries(m_series);
299 m_chartView->addSeries(m_series);
300
300
301 connect(m_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(handleSliceClicked(QPieSlice*)));
301 connect(m_series, SIGNAL(clicked(QPieSlice*, Qt::MouseButtons)), this, SLOT(handleSliceClicked(QPieSlice*, Qt::MouseButtons)));
302
302
303 // chart settings
303 // chart settings
304 m_themeComboBox = new QComboBox();
304 m_themeComboBox = new QComboBox();
305 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
305 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
306 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
306 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
307 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
307 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
308 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
308 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
309 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
309 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
310 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
310 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
311 m_themeComboBox->addItem("Icy", QChart::ChartThemeIcy);
311 m_themeComboBox->addItem("Icy", QChart::ChartThemeIcy);
312 m_themeComboBox->addItem("Scientific", QChart::ChartThemeScientific);
312 m_themeComboBox->addItem("Scientific", QChart::ChartThemeScientific);
313
313
314 m_aaCheckBox = new QCheckBox();
314 m_aaCheckBox = new QCheckBox();
315 m_animationsCheckBox = new QCheckBox();
315 m_animationsCheckBox = new QCheckBox();
316 m_animationsCheckBox->setCheckState(Qt::Checked);
316 m_animationsCheckBox->setCheckState(Qt::Checked);
317
317
318 QFormLayout* chartSettingsLayout = new QFormLayout();
318 QFormLayout* chartSettingsLayout = new QFormLayout();
319 chartSettingsLayout->addRow("Theme", m_themeComboBox);
319 chartSettingsLayout->addRow("Theme", m_themeComboBox);
320 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
320 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
321 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
321 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
322 QGroupBox* chartSettings = new QGroupBox("Chart");
322 QGroupBox* chartSettings = new QGroupBox("Chart");
323 chartSettings->setLayout(chartSettingsLayout);
323 chartSettings->setLayout(chartSettingsLayout);
324
324
325 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
325 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
326 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
326 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
327 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
327 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
328
328
329 // series settings
329 // series settings
330 m_hPosition = new QDoubleSpinBox();
330 m_hPosition = new QDoubleSpinBox();
331 m_hPosition->setMinimum(0.0);
331 m_hPosition->setMinimum(0.0);
332 m_hPosition->setMaximum(1.0);
332 m_hPosition->setMaximum(1.0);
333 m_hPosition->setSingleStep(0.1);
333 m_hPosition->setSingleStep(0.1);
334 m_hPosition->setValue(m_series->pieHorizontalPosition());
334 m_hPosition->setValue(m_series->pieHorizontalPosition());
335
335
336 m_vPosition = new QDoubleSpinBox();
336 m_vPosition = new QDoubleSpinBox();
337 m_vPosition->setMinimum(0.0);
337 m_vPosition->setMinimum(0.0);
338 m_vPosition->setMaximum(1.0);
338 m_vPosition->setMaximum(1.0);
339 m_vPosition->setSingleStep(0.1);
339 m_vPosition->setSingleStep(0.1);
340 m_vPosition->setValue(m_series->pieVerticalPosition());
340 m_vPosition->setValue(m_series->pieVerticalPosition());
341
341
342 m_sizeFactor = new QDoubleSpinBox();
342 m_sizeFactor = new QDoubleSpinBox();
343 m_sizeFactor->setMinimum(0.0);
343 m_sizeFactor->setMinimum(0.0);
344 m_sizeFactor->setMaximum(1.0);
344 m_sizeFactor->setMaximum(1.0);
345 m_sizeFactor->setSingleStep(0.1);
345 m_sizeFactor->setSingleStep(0.1);
346 m_sizeFactor->setValue(m_series->pieSize());
346 m_sizeFactor->setValue(m_series->pieSize());
347
347
348 m_startAngle = new QDoubleSpinBox();
348 m_startAngle = new QDoubleSpinBox();
349 m_startAngle->setMinimum(0.0);
349 m_startAngle->setMinimum(0.0);
350 m_startAngle->setMaximum(360);
350 m_startAngle->setMaximum(360);
351 m_startAngle->setValue(m_series->pieStartAngle());
351 m_startAngle->setValue(m_series->pieStartAngle());
352 m_startAngle->setSingleStep(1);
352 m_startAngle->setSingleStep(1);
353
353
354 m_endAngle = new QDoubleSpinBox();
354 m_endAngle = new QDoubleSpinBox();
355 m_endAngle->setMinimum(0.0);
355 m_endAngle->setMinimum(0.0);
356 m_endAngle->setMaximum(360);
356 m_endAngle->setMaximum(360);
357 m_endAngle->setValue(m_series->pieEndAngle());
357 m_endAngle->setValue(m_series->pieEndAngle());
358 m_endAngle->setSingleStep(1);
358 m_endAngle->setSingleStep(1);
359
359
360 QPushButton *addSlice = new QPushButton("Add slice");
360 QPushButton *addSlice = new QPushButton("Add slice");
361 QPushButton *insertSlice = new QPushButton("Insert slice");
361 QPushButton *insertSlice = new QPushButton("Insert slice");
362
362
363 QFormLayout* seriesSettingsLayout = new QFormLayout();
363 QFormLayout* seriesSettingsLayout = new QFormLayout();
364 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
364 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
365 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
365 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
366 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
366 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
367 seriesSettingsLayout->addRow("Start angle", m_startAngle);
367 seriesSettingsLayout->addRow("Start angle", m_startAngle);
368 seriesSettingsLayout->addRow("End angle", m_endAngle);
368 seriesSettingsLayout->addRow("End angle", m_endAngle);
369 seriesSettingsLayout->addRow(addSlice);
369 seriesSettingsLayout->addRow(addSlice);
370 seriesSettingsLayout->addRow(insertSlice);
370 seriesSettingsLayout->addRow(insertSlice);
371 QGroupBox* seriesSettings = new QGroupBox("Series");
371 QGroupBox* seriesSettings = new QGroupBox("Series");
372 seriesSettings->setLayout(seriesSettingsLayout);
372 seriesSettings->setLayout(seriesSettingsLayout);
373
373
374 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
374 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
375 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
375 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
376 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
376 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
377 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
377 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
378 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
378 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
379 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
379 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
380 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
380 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
381
381
382 // slice settings
382 // slice settings
383 m_sliceName = new QLabel("<click a slice>");
383 m_sliceName = new QLabel("<click a slice>");
384 m_sliceValue = new QDoubleSpinBox();
384 m_sliceValue = new QDoubleSpinBox();
385 m_sliceValue->setMaximum(1000);
385 m_sliceValue->setMaximum(1000);
386 m_sliceLabelVisible = new QCheckBox();
386 m_sliceLabelVisible = new QCheckBox();
387 m_sliceLabelArmFactor = new QDoubleSpinBox();
387 m_sliceLabelArmFactor = new QDoubleSpinBox();
388 m_sliceLabelArmFactor->setSingleStep(0.01);
388 m_sliceLabelArmFactor->setSingleStep(0.01);
389 m_sliceExploded = new QCheckBox();
389 m_sliceExploded = new QCheckBox();
390 m_sliceExplodedFactor = new QDoubleSpinBox();
390 m_sliceExplodedFactor = new QDoubleSpinBox();
391 m_sliceExplodedFactor->setSingleStep(0.01);
391 m_sliceExplodedFactor->setSingleStep(0.01);
392 m_pen = new QPushButton();
392 m_pen = new QPushButton();
393 m_penTool = new PenTool("Slice pen", this);
393 m_penTool = new PenTool("Slice pen", this);
394 m_brush = new QPushButton();
394 m_brush = new QPushButton();
395 m_brushTool = new BrushTool("Slice brush", this);
395 m_brushTool = new BrushTool("Slice brush", this);
396 m_font = new QPushButton();
396 m_font = new QPushButton();
397 m_labelArmPen = new QPushButton();
397 m_labelArmPen = new QPushButton();
398 m_labelArmPenTool = new PenTool("Label arm pen", this);
398 m_labelArmPenTool = new PenTool("Label arm pen", this);
399 QPushButton *removeSlice = new QPushButton("Remove slice");
399 QPushButton *removeSlice = new QPushButton("Remove slice");
400
400
401 QFormLayout* sliceSettingsLayout = new QFormLayout();
401 QFormLayout* sliceSettingsLayout = new QFormLayout();
402 sliceSettingsLayout->addRow("Selected", m_sliceName);
402 sliceSettingsLayout->addRow("Selected", m_sliceName);
403 sliceSettingsLayout->addRow("Value", m_sliceValue);
403 sliceSettingsLayout->addRow("Value", m_sliceValue);
404 sliceSettingsLayout->addRow("Pen", m_pen);
404 sliceSettingsLayout->addRow("Pen", m_pen);
405 sliceSettingsLayout->addRow("Brush", m_brush);
405 sliceSettingsLayout->addRow("Brush", m_brush);
406 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
406 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
407 sliceSettingsLayout->addRow("Label font", m_font);
407 sliceSettingsLayout->addRow("Label font", m_font);
408 sliceSettingsLayout->addRow("Label arm pen", m_labelArmPen);
408 sliceSettingsLayout->addRow("Label arm pen", m_labelArmPen);
409 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
409 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
410 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
410 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
411 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
411 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
412 sliceSettingsLayout->addRow(removeSlice);
412 sliceSettingsLayout->addRow(removeSlice);
413 QGroupBox* sliceSettings = new QGroupBox("Slice");
413 QGroupBox* sliceSettings = new QGroupBox("Slice");
414 sliceSettings->setLayout(sliceSettingsLayout);
414 sliceSettings->setLayout(sliceSettingsLayout);
415
415
416 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
416 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
417 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
417 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
418 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
418 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
419 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
419 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
420 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
420 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
421 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
421 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
422 connect(m_labelArmPen, SIGNAL(clicked()), m_labelArmPenTool, SLOT(show()));
422 connect(m_labelArmPen, SIGNAL(clicked()), m_labelArmPenTool, SLOT(show()));
423 connect(m_labelArmPenTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
423 connect(m_labelArmPenTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
424 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
424 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
425 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
425 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
426 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
426 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
427 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
427 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
428 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
428 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
429 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
429 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
430
430
431 // create main layout
431 // create main layout
432 QVBoxLayout *settingsLayout = new QVBoxLayout();
432 QVBoxLayout *settingsLayout = new QVBoxLayout();
433 settingsLayout->addWidget(chartSettings);
433 settingsLayout->addWidget(chartSettings);
434 settingsLayout->addWidget(seriesSettings);
434 settingsLayout->addWidget(seriesSettings);
435 settingsLayout->addWidget(sliceSettings);
435 settingsLayout->addWidget(sliceSettings);
436 settingsLayout->addStretch();
436 settingsLayout->addStretch();
437
437
438 QGridLayout* baseLayout = new QGridLayout();
438 QGridLayout* baseLayout = new QGridLayout();
439 baseLayout->addLayout(settingsLayout, 0, 0);
439 baseLayout->addLayout(settingsLayout, 0, 0);
440 baseLayout->addWidget(m_chartView, 0, 1);
440 baseLayout->addWidget(m_chartView, 0, 1);
441 setLayout(baseLayout);
441 setLayout(baseLayout);
442
442
443 updateSerieSettings();
443 updateSerieSettings();
444 }
444 }
445
445
446 public Q_SLOTS:
446 public Q_SLOTS:
447
447
448 void updateChartSettings()
448 void updateChartSettings()
449 {
449 {
450 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
450 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
451 m_chartView->setChartTheme(theme);
451 m_chartView->setChartTheme(theme);
452 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
452 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
453
453
454 if (m_animationsCheckBox->checkState() == Qt::Checked)
454 if (m_animationsCheckBox->checkState() == Qt::Checked)
455 m_chartView->setAnimationOptions(QChart::AllAnimations);
455 m_chartView->setAnimationOptions(QChart::AllAnimations);
456 else
456 else
457 m_chartView->setAnimationOptions(QChart::NoAnimation);
457 m_chartView->setAnimationOptions(QChart::NoAnimation);
458 }
458 }
459
459
460 void updateSerieSettings()
460 void updateSerieSettings()
461 {
461 {
462 m_series->setPiePosition(m_hPosition->value(), m_vPosition->value());
462 m_series->setPiePosition(m_hPosition->value(), m_vPosition->value());
463 m_series->setPieSize(m_sizeFactor->value());
463 m_series->setPieSize(m_sizeFactor->value());
464 m_series->setPieStartAngle(m_startAngle->value());
464 m_series->setPieStartAngle(m_startAngle->value());
465 m_series->setPieEndAngle(m_endAngle->value());
465 m_series->setPieEndAngle(m_endAngle->value());
466 }
466 }
467
467
468 void updateSliceSettings()
468 void updateSliceSettings()
469 {
469 {
470 if (!m_slice)
470 if (!m_slice)
471 return;
471 return;
472
472
473 m_slice->setValue(m_sliceValue->value());
473 m_slice->setValue(m_sliceValue->value());
474
474
475 m_slice->setSlicePen(m_penTool->pen());
475 m_slice->setSlicePen(m_penTool->pen());
476 m_slice->setSliceBrush(m_brushTool->brush());
476 m_slice->setSliceBrush(m_brushTool->brush());
477
477
478 m_slice->setLabelArmPen(m_labelArmPenTool->pen());
478 m_slice->setLabelArmPen(m_labelArmPenTool->pen());
479 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
479 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
480 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
480 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
481
481
482 m_slice->setExploded(m_sliceExploded->isChecked());
482 m_slice->setExploded(m_sliceExploded->isChecked());
483 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
483 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
484 }
484 }
485
485
486 void handleSliceClicked(QPieSlice* slice)
486 void handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons)
487 {
487 {
488 Q_UNUSED(buttons);
489
488 m_slice = static_cast<CustomSlice*>(slice);
490 m_slice = static_cast<CustomSlice*>(slice);
489
491
490 // name
492 // name
491 m_sliceName->setText(slice->label());
493 m_sliceName->setText(slice->label());
492
494
493 // value
495 // value
494 m_sliceValue->blockSignals(true);
496 m_sliceValue->blockSignals(true);
495 m_sliceValue->setValue(slice->value());
497 m_sliceValue->setValue(slice->value());
496 m_sliceValue->blockSignals(false);
498 m_sliceValue->blockSignals(false);
497
499
498 // pen
500 // pen
499 m_pen->setText(PenTool::name(m_slice->slicePen()));
501 m_pen->setText(PenTool::name(m_slice->slicePen()));
500 m_penTool->setPen(m_slice->slicePen());
502 m_penTool->setPen(m_slice->slicePen());
501
503
502 // brush
504 // brush
503 m_brush->setText(m_slice->originalBrush().color().name());
505 m_brush->setText(m_slice->originalBrush().color().name());
504 m_brushTool->setBrush(m_slice->originalBrush());
506 m_brushTool->setBrush(m_slice->originalBrush());
505
507
506 // label
508 // label
507 m_labelArmPen->setText(PenTool::name(m_slice->labelArmPen()));
509 m_labelArmPen->setText(PenTool::name(m_slice->labelArmPen()));
508 m_labelArmPenTool->setPen(m_slice->labelArmPen());
510 m_labelArmPenTool->setPen(m_slice->labelArmPen());
509 m_font->setText(slice->labelFont().toString());
511 m_font->setText(slice->labelFont().toString());
510 m_sliceLabelVisible->blockSignals(true);
512 m_sliceLabelVisible->blockSignals(true);
511 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
513 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
512 m_sliceLabelVisible->blockSignals(false);
514 m_sliceLabelVisible->blockSignals(false);
513 m_sliceLabelArmFactor->blockSignals(true);
515 m_sliceLabelArmFactor->blockSignals(true);
514 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
516 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
515 m_sliceLabelArmFactor->blockSignals(false);
517 m_sliceLabelArmFactor->blockSignals(false);
516
518
517 // exploded
519 // exploded
518 m_sliceExploded->blockSignals(true);
520 m_sliceExploded->blockSignals(true);
519 m_sliceExploded->setChecked(slice->isExploded());
521 m_sliceExploded->setChecked(slice->isExploded());
520 m_sliceExploded->blockSignals(false);
522 m_sliceExploded->blockSignals(false);
521 m_sliceExplodedFactor->blockSignals(true);
523 m_sliceExplodedFactor->blockSignals(true);
522 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
524 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
523 m_sliceExplodedFactor->blockSignals(false);
525 m_sliceExplodedFactor->blockSignals(false);
524 }
526 }
525
527
526 void showFontDialog()
528 void showFontDialog()
527 {
529 {
528 if (!m_slice)
530 if (!m_slice)
529 return;
531 return;
530
532
531 QFontDialog dialog(m_slice->labelFont());
533 QFontDialog dialog(m_slice->labelFont());
532 dialog.show();
534 dialog.show();
533 dialog.exec();
535 dialog.exec();
534
536
535 m_slice->setLabelFont(dialog.currentFont());
537 m_slice->setLabelFont(dialog.currentFont());
536 m_font->setText(dialog.currentFont().toString());
538 m_font->setText(dialog.currentFont().toString());
537 }
539 }
538
540
539 void addSlice()
541 void addSlice()
540 {
542 {
541 *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1));
543 *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1));
542 }
544 }
543
545
544 void insertSlice()
546 void insertSlice()
545 {
547 {
546 if (!m_slice)
548 if (!m_slice)
547 return;
549 return;
548
550
549 int i = m_series->slices().indexOf(m_slice);
551 int i = m_series->slices().indexOf(m_slice);
550
552
551 m_series->insert(i, new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1)));
553 m_series->insert(i, new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1)));
552 }
554 }
553
555
554 void removeSlice()
556 void removeSlice()
555 {
557 {
556 if (!m_slice)
558 if (!m_slice)
557 return;
559 return;
558
560
559 m_series->remove(m_slice);
561 m_series->remove(m_slice);
560 m_slice = 0;
562 m_slice = 0;
561 }
563 }
562
564
563 private:
565 private:
564 QComboBox *m_themeComboBox;
566 QComboBox *m_themeComboBox;
565 QCheckBox *m_aaCheckBox;
567 QCheckBox *m_aaCheckBox;
566 QCheckBox *m_animationsCheckBox;
568 QCheckBox *m_animationsCheckBox;
567
569
568 QChartView* m_chartView;
570 QChartView* m_chartView;
569 QPieSeries* m_series;
571 QPieSeries* m_series;
570 CustomSlice* m_slice;
572 CustomSlice* m_slice;
571
573
572 QDoubleSpinBox* m_hPosition;
574 QDoubleSpinBox* m_hPosition;
573 QDoubleSpinBox* m_vPosition;
575 QDoubleSpinBox* m_vPosition;
574 QDoubleSpinBox* m_sizeFactor;
576 QDoubleSpinBox* m_sizeFactor;
575 QDoubleSpinBox* m_startAngle;
577 QDoubleSpinBox* m_startAngle;
576 QDoubleSpinBox* m_endAngle;
578 QDoubleSpinBox* m_endAngle;
577
579
578 QLabel* m_sliceName;
580 QLabel* m_sliceName;
579 QDoubleSpinBox* m_sliceValue;
581 QDoubleSpinBox* m_sliceValue;
580 QCheckBox* m_sliceLabelVisible;
582 QCheckBox* m_sliceLabelVisible;
581 QDoubleSpinBox* m_sliceLabelArmFactor;
583 QDoubleSpinBox* m_sliceLabelArmFactor;
582 QCheckBox* m_sliceExploded;
584 QCheckBox* m_sliceExploded;
583 QDoubleSpinBox* m_sliceExplodedFactor;
585 QDoubleSpinBox* m_sliceExplodedFactor;
584 QPushButton *m_brush;
586 QPushButton *m_brush;
585 BrushTool *m_brushTool;
587 BrushTool *m_brushTool;
586 QPushButton *m_pen;
588 QPushButton *m_pen;
587 PenTool *m_penTool;
589 PenTool *m_penTool;
588 QPushButton *m_font;
590 QPushButton *m_font;
589 QPushButton *m_labelArmPen;
591 QPushButton *m_labelArmPen;
590 PenTool *m_labelArmPenTool;
592 PenTool *m_labelArmPenTool;
591 };
593 };
592
594
593 int main(int argc, char *argv[])
595 int main(int argc, char *argv[])
594 {
596 {
595 QApplication a(argc, argv);
597 QApplication a(argc, argv);
596
598
597 QMainWindow window;
599 QMainWindow window;
598
600
599 MainWidget* widget = new MainWidget();
601 MainWidget* widget = new MainWidget();
600
602
601 window.setCentralWidget(widget);
603 window.setCentralWidget(widget);
602 window.resize(900, 600);
604 window.resize(900, 600);
603 window.show();
605 window.show();
604
606
605 return a.exec();
607 return a.exec();
606 }
608 }
607
609
608 #include "main.moc"
610 #include "main.moc"
@@ -1,114 +1,114
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
4 #include <qchartview.h>
5 #include <qpieseries.h>
5 #include <qpieseries.h>
6 #include <qpieslice.h>
6 #include <qpieslice.h>
7 #include <QTime>
7 #include <QTime>
8
8
9 QTCOMMERCIALCHART_USE_NAMESPACE
9 QTCOMMERCIALCHART_USE_NAMESPACE
10
10
11 class DrilldownSlice : public QPieSlice
11 class DrilldownSlice : public QPieSlice
12 {
12 {
13 Q_OBJECT
13 Q_OBJECT
14
14
15 public:
15 public:
16 DrilldownSlice(qreal value, QString prefix, QSeries* drilldownSeries)
16 DrilldownSlice(qreal value, QString prefix, QSeries* drilldownSeries)
17 :m_drilldownSeries(drilldownSeries),
17 :m_drilldownSeries(drilldownSeries),
18 m_prefix(prefix)
18 m_prefix(prefix)
19 {
19 {
20 setValue(value);
20 setValue(value);
21 setLabelVisible(true);
21 setLabelVisible(true);
22 updateLabel();
22 updateLabel();
23 connect(this, SIGNAL(changed()), this, SLOT(updateLabel()));
23 connect(this, SIGNAL(changed()), this, SLOT(updateLabel()));
24 }
24 }
25
25
26 QSeries* drilldownSeries() const { return m_drilldownSeries; }
26 QSeries* drilldownSeries() const { return m_drilldownSeries; }
27
27
28 public Q_SLOTS:
28 public Q_SLOTS:
29 void updateLabel()
29 void updateLabel()
30 {
30 {
31 QString label = m_prefix;
31 QString label = m_prefix;
32 label += " " + QString::number(this->value())+ "e (";
32 label += " " + QString::number(this->value())+ "e (";
33 label += QString::number(this->percentage()*100, 'f', 1) + "%)";
33 label += QString::number(this->percentage()*100, 'f', 1) + "%)";
34 setLabel(label);
34 setLabel(label);
35 }
35 }
36
36
37 private:
37 private:
38 QSeries* m_drilldownSeries;
38 QSeries* m_drilldownSeries;
39 QString m_prefix;
39 QString m_prefix;
40 };
40 };
41
41
42 class DrilldownChart : public QChartView
42 class DrilldownChart : public QChartView
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45 public:
45 public:
46 explicit DrilldownChart(QWidget *parent = 0):QChartView(parent), m_currentSeries(0) {}
46 explicit DrilldownChart(QWidget *parent = 0):QChartView(parent), m_currentSeries(0) {}
47
47
48 void changeSeries(QSeries* series)
48 void changeSeries(QSeries* series)
49 {
49 {
50 // NOTE: if the series is owned by the chart it will be deleted
50 // NOTE: if the series is owned by the chart it will be deleted
51 // here the "window" owns the series...
51 // here the "window" owns the series...
52 if (m_currentSeries)
52 if (m_currentSeries)
53 removeSeries(m_currentSeries);
53 removeSeries(m_currentSeries);
54 m_currentSeries = series;
54 m_currentSeries = series;
55 addSeries(series);
55 addSeries(series);
56 setChartTitle(series->title());
56 setChartTitle(series->title());
57 }
57 }
58
58
59 public Q_SLOTS:
59 public Q_SLOTS:
60 void handleSliceClicked(QPieSlice* slice)
60 void handleSliceClicked(QPieSlice* slice)
61 {
61 {
62 DrilldownSlice* drilldownSlice = static_cast<DrilldownSlice*>(slice);
62 DrilldownSlice* drilldownSlice = static_cast<DrilldownSlice*>(slice);
63 changeSeries(drilldownSlice->drilldownSeries());
63 changeSeries(drilldownSlice->drilldownSeries());
64 }
64 }
65
65
66 private:
66 private:
67 QSeries* m_currentSeries;
67 QSeries* m_currentSeries;
68 };
68 };
69
69
70 int main(int argc, char *argv[])
70 int main(int argc, char *argv[])
71 {
71 {
72 QApplication a(argc, argv);
72 QApplication a(argc, argv);
73
73
74 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
74 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
75
75
76 QMainWindow window;
76 QMainWindow window;
77
77
78 DrilldownChart* drilldownChart = new DrilldownChart(&window);
78 DrilldownChart* drilldownChart = new DrilldownChart(&window);
79 drilldownChart->setRenderHint(QPainter::Antialiasing);
79 drilldownChart->setRenderHint(QPainter::Antialiasing);
80 drilldownChart->setChartTheme(QChart::ChartThemeLight);
80 drilldownChart->setChartTheme(QChart::ChartThemeLight);
81 drilldownChart->setAnimationOptions(QChart::AllAnimations);
81 drilldownChart->setAnimationOptions(QChart::AllAnimations);
82
82
83 QPieSeries* yearSeries = new QPieSeries(&window);
83 QPieSeries* yearSeries = new QPieSeries(&window);
84 yearSeries->setTitle("Sales by year - All");
84 yearSeries->setTitle("Sales by year - All");
85
85
86 QList<QString> months;
86 QList<QString> months;
87 months << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
87 months << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
88 QList<QString> names;
88 QList<QString> names;
89 names << "Jane" << "John" << "Axel" << "Mary" << "Samantha" << "Bob";
89 names << "Jane" << "John" << "Axel" << "Mary" << "Samantha" << "Bob";
90
90
91 foreach (QString name, names) {
91 foreach (QString name, names) {
92 QPieSeries* series = new QPieSeries(&window);
92 QPieSeries* series = new QPieSeries(&window);
93 series->setTitle("Sales by month - " + name);
93 series->setTitle("Sales by month - " + name);
94
94
95 foreach (QString month, months)
95 foreach (QString month, months)
96 *series << new DrilldownSlice(qrand() % 1000, month, yearSeries);
96 *series << new DrilldownSlice(qrand() % 1000, month, yearSeries);
97
97
98 QObject::connect(series, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
98 QObject::connect(series, SIGNAL(clicked(QPieSlice*, Qt::MouseButtons)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
99
99
100 *yearSeries << new DrilldownSlice(series->total(), name, series);
100 *yearSeries << new DrilldownSlice(series->total(), name, series);
101 }
101 }
102
102
103 QObject::connect(yearSeries, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
103 QObject::connect(yearSeries, SIGNAL(clicked(QPieSlice*, Qt::MouseButtons)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
104
104
105 drilldownChart->changeSeries(yearSeries);
105 drilldownChart->changeSeries(yearSeries);
106
106
107 window.setCentralWidget(drilldownChart);
107 window.setCentralWidget(drilldownChart);
108 window.resize(800, 600);
108 window.resize(800, 600);
109 window.show();
109 window.show();
110
110
111 return a.exec();
111 return a.exec();
112 }
112 }
113
113
114 #include "main.moc"
114 #include "main.moc"
@@ -1,191 +1,191
1 #include "piechartitem_p.h"
1 #include "piechartitem_p.h"
2 #include "piesliceitem_p.h"
2 #include "piesliceitem_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpiesliceprivate_p.h"
4 #include "qpiesliceprivate_p.h"
5 #include "qpieseries.h"
5 #include "qpieseries.h"
6 #include "chartpresenter_p.h"
6 #include "chartpresenter_p.h"
7 #include "chartdataset_p.h"
7 #include "chartdataset_p.h"
8 #include "chartanimator_p.h"
8 #include "chartanimator_p.h"
9 #include <QDebug>
9 #include <QDebug>
10 #include <QPainter>
10 #include <QPainter>
11 #include <QTimer>
11 #include <QTimer>
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
16 :ChartItem(presenter),
16 :ChartItem(presenter),
17 m_series(series)
17 m_series(series)
18 {
18 {
19 Q_ASSERT(series);
19 Q_ASSERT(series);
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
24
24
25 QTimer::singleShot(0, this, SLOT(initialize()));
25 QTimer::singleShot(0, this, SLOT(initialize()));
26
26
27 // Note: the following does not affect as long as the item does not have anything to paint
27 // Note: the following does not affect as long as the item does not have anything to paint
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieChartItem::~PieChartItem()
31 PieChartItem::~PieChartItem()
32 {
32 {
33 // slices deleted automatically through QGraphicsItem
33 // slices deleted automatically through QGraphicsItem
34 }
34 }
35
35
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
37 {
37 {
38 Q_UNUSED(painter)
38 Q_UNUSED(painter)
39 // TODO: paint shadows for all components
39 // TODO: paint shadows for all components
40 // - get paths from items & merge & offset and draw with shadow color?
40 // - get paths from items & merge & offset and draw with shadow color?
41 //painter->setBrush(QBrush(Qt::red));
41 //painter->setBrush(QBrush(Qt::red));
42 //painter->drawRect(m_debugRect);
42 //painter->drawRect(m_debugRect);
43 }
43 }
44
44
45 void PieChartItem::initialize()
45 void PieChartItem::initialize()
46 {
46 {
47 handleSlicesAdded(m_series->slices());
47 handleSlicesAdded(m_series->slices());
48 }
48 }
49
49
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
51 {
51 {
52 bool isEmpty = m_slices.isEmpty();
52 bool isEmpty = m_slices.isEmpty();
53
53
54 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
54 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
55
55
56 foreach (QPieSlice *s, slices) {
56 foreach (QPieSlice *s, slices) {
57 PieSliceItem* item = new PieSliceItem(this);
57 PieSliceItem* item = new PieSliceItem(this);
58 m_slices.insert(s, item);
58 m_slices.insert(s, item);
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
60 connect(item, SIGNAL(clicked()), s, SIGNAL(clicked()));
60 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons)));
61 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
61 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
62 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
62 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
63
63
64 PieSliceData data = sliceData(s);
64 PieSliceData data = sliceData(s);
65
65
66 if (animator())
66 if (animator())
67 animator()->addAnimation(this, s, data, isEmpty);
67 animator()->addAnimation(this, s, data, isEmpty);
68 else
68 else
69 setLayout(s, data);
69 setLayout(s, data);
70 }
70 }
71 }
71 }
72
72
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
74 {
74 {
75 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
75 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
76
76
77 foreach (QPieSlice *s, slices) {
77 foreach (QPieSlice *s, slices) {
78 if (animator())
78 if (animator())
79 animator()->removeAnimation(this, s);
79 animator()->removeAnimation(this, s);
80 else
80 else
81 destroySlice(s);
81 destroySlice(s);
82 }
82 }
83 }
83 }
84
84
85 void PieChartItem::handlePieLayoutChanged()
85 void PieChartItem::handlePieLayoutChanged()
86 {
86 {
87 PieLayout layout = calculateLayout();
87 PieLayout layout = calculateLayout();
88 applyLayout(layout);
88 applyLayout(layout);
89 update();
89 update();
90 }
90 }
91
91
92 void PieChartItem::handleSliceChanged()
92 void PieChartItem::handleSliceChanged()
93 {
93 {
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
95 Q_ASSERT(m_slices.contains(slice));
95 Q_ASSERT(m_slices.contains(slice));
96 PieSliceData data = sliceData(slice);
96 PieSliceData data = sliceData(slice);
97 updateLayout(slice, data);
97 updateLayout(slice, data);
98 update();
98 update();
99 }
99 }
100
100
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
102 {
102 {
103 // TODO
103 // TODO
104 }
104 }
105
105
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
107 {
107 {
108 prepareGeometryChange();
108 prepareGeometryChange();
109 m_rect = rect;
109 m_rect = rect;
110 handlePieLayoutChanged();
110 handlePieLayoutChanged();
111 }
111 }
112
112
113 void PieChartItem::calculatePieLayout()
113 void PieChartItem::calculatePieLayout()
114 {
114 {
115 // find pie center coordinates
115 // find pie center coordinates
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
118
118
119 // find maximum radius for pie
119 // find maximum radius for pie
120 m_pieRadius = m_rect.height() / 2;
120 m_pieRadius = m_rect.height() / 2;
121 if (m_rect.width() < m_rect.height())
121 if (m_rect.width() < m_rect.height())
122 m_pieRadius = m_rect.width() / 2;
122 m_pieRadius = m_rect.width() / 2;
123
123
124 // apply size factor
124 // apply size factor
125 m_pieRadius *= m_series->pieSize();
125 m_pieRadius *= m_series->pieSize();
126 }
126 }
127
127
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
129 {
129 {
130 PieSliceData sliceData = slice->data_ptr()->m_data;
130 PieSliceData sliceData = slice->data_ptr()->m_data;
131 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
131 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
132 sliceData.m_radius = m_pieRadius;
132 sliceData.m_radius = m_pieRadius;
133 return sliceData;
133 return sliceData;
134 }
134 }
135
135
136 PieLayout PieChartItem::calculateLayout()
136 PieLayout PieChartItem::calculateLayout()
137 {
137 {
138 calculatePieLayout();
138 calculatePieLayout();
139 PieLayout layout;
139 PieLayout layout;
140 foreach (QPieSlice* s, m_series->slices()) {
140 foreach (QPieSlice* s, m_series->slices()) {
141 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
141 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
142 layout.insert(s, sliceData(s));
142 layout.insert(s, sliceData(s));
143 }
143 }
144 return layout;
144 return layout;
145 }
145 }
146
146
147 void PieChartItem::applyLayout(const PieLayout &layout)
147 void PieChartItem::applyLayout(const PieLayout &layout)
148 {
148 {
149 if (animator())
149 if (animator())
150 animator()->updateLayout(this, layout);
150 animator()->updateLayout(this, layout);
151 else
151 else
152 setLayout(layout);
152 setLayout(layout);
153 }
153 }
154
154
155 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
155 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
156 {
156 {
157 if (animator())
157 if (animator())
158 animator()->updateLayout(this, slice, sliceData);
158 animator()->updateLayout(this, slice, sliceData);
159 else
159 else
160 setLayout(slice, sliceData);
160 setLayout(slice, sliceData);
161 }
161 }
162
162
163 void PieChartItem::setLayout(const PieLayout &layout)
163 void PieChartItem::setLayout(const PieLayout &layout)
164 {
164 {
165 foreach (QPieSlice *slice, layout.keys()) {
165 foreach (QPieSlice *slice, layout.keys()) {
166 PieSliceItem *item = m_slices.value(slice);
166 PieSliceItem *item = m_slices.value(slice);
167 Q_ASSERT(item);
167 Q_ASSERT(item);
168 item->setSliceData(layout.value(slice));
168 item->setSliceData(layout.value(slice));
169 item->updateGeometry();
169 item->updateGeometry();
170 item->update();
170 item->update();
171 }
171 }
172 }
172 }
173
173
174 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
174 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
175 {
175 {
176 // find slice
176 // find slice
177 PieSliceItem *item = m_slices.value(slice);
177 PieSliceItem *item = m_slices.value(slice);
178 Q_ASSERT(item);
178 Q_ASSERT(item);
179 item->setSliceData(sliceData);
179 item->setSliceData(sliceData);
180 item->updateGeometry();
180 item->updateGeometry();
181 item->update();
181 item->update();
182 }
182 }
183
183
184 void PieChartItem::destroySlice(QPieSlice *slice)
184 void PieChartItem::destroySlice(QPieSlice *slice)
185 {
185 {
186 delete m_slices.take(slice);
186 delete m_slices.take(slice);
187 }
187 }
188
188
189 #include "moc_piechartitem_p.cpp"
189 #include "moc_piechartitem_p.cpp"
190
190
191 QTCOMMERCIALCHART_END_NAMESPACE
191 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,184 +1,184
1 #include "piesliceitem_p.h"
1 #include "piesliceitem_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
24 :QGraphicsObject(parent)
24 :QGraphicsObject(parent)
25 {
25 {
26 setAcceptHoverEvents(true);
26 setAcceptHoverEvents(true);
27 setAcceptedMouseButtons(Qt::LeftButton);
27 setAcceptedMouseButtons(Qt::MouseButtonMask);
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieSliceItem::~PieSliceItem()
31 PieSliceItem::~PieSliceItem()
32 {
32 {
33
33
34 }
34 }
35
35
36 QRectF PieSliceItem::boundingRect() const
36 QRectF PieSliceItem::boundingRect() const
37 {
37 {
38 return m_boundingRect;
38 return m_boundingRect;
39 }
39 }
40
40
41 QPainterPath PieSliceItem::shape() const
41 QPainterPath PieSliceItem::shape() const
42 {
42 {
43 // Don't include the label and label arm.
43 // Don't include the label and label arm.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
45 return m_slicePath;
45 return m_slicePath;
46 }
46 }
47
47
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setClipRect(parentItem()->boundingRect());
50 painter->setClipRect(parentItem()->boundingRect());
51
51
52 painter->save();
52 painter->save();
53 painter->setPen(m_data.m_slicePen);
53 painter->setPen(m_data.m_slicePen);
54 painter->setBrush(m_data.m_sliceBrush);
54 painter->setBrush(m_data.m_sliceBrush);
55 painter->drawPath(m_slicePath);
55 painter->drawPath(m_slicePath);
56 painter->restore();
56 painter->restore();
57
57
58 if (m_data.m_isLabelVisible) {
58 if (m_data.m_isLabelVisible) {
59 painter->save();
59 painter->save();
60 painter->setPen(m_data.m_labelArmPen);
60 painter->setPen(m_data.m_labelArmPen);
61 painter->drawPath(m_labelArmPath);
61 painter->drawPath(m_labelArmPath);
62 painter->restore();
62 painter->restore();
63
63
64 painter->setFont(m_data.m_labelFont);
64 painter->setFont(m_data.m_labelFont);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
66 }
66 }
67 }
67 }
68
68
69 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
69 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
70 {
70 {
71 emit hoverEnter();
71 emit hoverEnter();
72 }
72 }
73
73
74 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
74 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
75 {
75 {
76 emit hoverLeave();
76 emit hoverLeave();
77 }
77 }
78
78
79 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
79 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
80 {
80 {
81 emit clicked();
81 emit clicked(event->buttons());
82 }
82 }
83
83
84 void PieSliceItem::setSliceData(PieSliceData sliceData)
84 void PieSliceItem::setSliceData(PieSliceData sliceData)
85 {
85 {
86 m_data = sliceData;
86 m_data = sliceData;
87 }
87 }
88
88
89 void PieSliceItem::updateGeometry()
89 void PieSliceItem::updateGeometry()
90 {
90 {
91 if (m_data.m_radius <= 0)
91 if (m_data.m_radius <= 0)
92 return;
92 return;
93
93
94 prepareGeometryChange();
94 prepareGeometryChange();
95
95
96 // update slice path
96 // update slice path
97 qreal centerAngle;
97 qreal centerAngle;
98 QPointF armStart;
98 QPointF armStart;
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
100
100
101 // update text rect
101 // update text rect
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
103
103
104 // update label arm path
104 // update label arm path
105 QPointF labelTextStart;
105 QPointF labelTextStart;
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
107
107
108 // update text position
108 // update text position
109 m_labelTextRect.moveBottomLeft(labelTextStart);
109 m_labelTextRect.moveBottomLeft(labelTextStart);
110
110
111 // update bounding rect
111 // update bounding rect
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
113 }
113 }
114
114
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
116 {
116 {
117 if (slice->isExploded()) {
117 if (slice->isExploded()) {
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
119 qreal len = radius * slice->explodeDistanceFactor();
119 qreal len = radius * slice->explodeDistanceFactor();
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
122 point += QPointF(dx, dy);
122 point += QPointF(dx, dy);
123 }
123 }
124 return point;
124 return point;
125 }
125 }
126
126
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
128 {
128 {
129 // calculate center angle
129 // calculate center angle
130 *centerAngle = startAngle + (angleSpan/2);
130 *centerAngle = startAngle + (angleSpan/2);
131
131
132 // calculate slice rectangle
132 // calculate slice rectangle
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
134
134
135 // slice path
135 // slice path
136 // TODO: draw the shape so that it might have a hole in the center
136 // TODO: draw the shape so that it might have a hole in the center
137 QPainterPath path;
137 QPainterPath path;
138 path.moveTo(rect.center());
138 path.moveTo(rect.center());
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
140 path.closeSubpath();
140 path.closeSubpath();
141
141
142 // calculate label arm start point
142 // calculate label arm start point
143 *armStart = center;
143 *armStart = center;
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
145
145
146 return path;
146 return path;
147 }
147 }
148
148
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
150 {
150 {
151 qreal dx = qSin(angle*(PI/180)) * length;
151 qreal dx = qSin(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
153 QPointF parm1 = start + QPointF(dx, dy);
153 QPointF parm1 = start + QPointF(dx, dy);
154
154
155 QPointF parm2 = parm1;
155 QPointF parm2 = parm1;
156 if (angle < 180) { // arm swings the other way on the left side
156 if (angle < 180) { // arm swings the other way on the left side
157 parm2 += QPointF(textWidth, 0);
157 parm2 += QPointF(textWidth, 0);
158 *textStart = parm1;
158 *textStart = parm1;
159 }
159 }
160 else {
160 else {
161 parm2 += QPointF(-textWidth,0);
161 parm2 += QPointF(-textWidth,0);
162 *textStart = parm2;
162 *textStart = parm2;
163 }
163 }
164
164
165 // elevate the text position a bit so that it does not hit the line
165 // elevate the text position a bit so that it does not hit the line
166 *textStart += QPointF(0, -5);
166 *textStart += QPointF(0, -5);
167
167
168 QPainterPath path;
168 QPainterPath path;
169 path.moveTo(start);
169 path.moveTo(start);
170 path.lineTo(parm1);
170 path.lineTo(parm1);
171 path.lineTo(parm2);
171 path.lineTo(parm2);
172
172
173 return path;
173 return path;
174 }
174 }
175
175
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
177 {
177 {
178 QFontMetricsF fm(font);
178 QFontMetricsF fm(font);
179 return fm.boundingRect(text);
179 return fm.boundingRect(text);
180 }
180 }
181
181
182 #include "moc_piesliceitem_p.cpp"
182 #include "moc_piesliceitem_p.cpp"
183
183
184 QTCOMMERCIALCHART_END_NAMESPACE
184 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,59
1 #ifndef PIESLICEITEM_H
1 #ifndef PIESLICEITEM_H
2 #define PIESLICEITEM_H
2 #define PIESLICEITEM_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 #include "qpieseries.h"
6 #include "qpieseries.h"
7 #include "qpiesliceprivate_p.h"
7 #include "qpiesliceprivate_p.h"
8 #include <QGraphicsItem>
8 #include <QGraphicsItem>
9 #include <QRectF>
9 #include <QRectF>
10 #include <QColor>
10 #include <QColor>
11 #include <QPen>
11 #include <QPen>
12
12
13 #define PIESLICE_LABEL_GAP 5
13 #define PIESLICE_LABEL_GAP 5
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16 class PieChartItem;
16 class PieChartItem;
17 class PieSliceLabel;
17 class PieSliceLabel;
18 class QPieSlice;
18 class QPieSlice;
19
19
20 class PieSliceItem : public QGraphicsObject
20 class PieSliceItem : public QGraphicsObject
21 {
21 {
22 Q_OBJECT
22 Q_OBJECT
23
23
24 public:
24 public:
25 PieSliceItem(QGraphicsItem* parent = 0);
25 PieSliceItem(QGraphicsItem* parent = 0);
26 ~PieSliceItem();
26 ~PieSliceItem();
27
27
28 public: // from QGraphicsItem
28 public: // from QGraphicsItem
29 QRectF boundingRect() const;
29 QRectF boundingRect() const;
30 QPainterPath shape() const;
30 QPainterPath shape() const;
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
34 void mousePressEvent(QGraphicsSceneMouseEvent *event);
34 void mousePressEvent(QGraphicsSceneMouseEvent *event);
35
35
36 Q_SIGNALS:
36 Q_SIGNALS:
37 void clicked();
37 void clicked(Qt::MouseButtons buttons);
38 void hoverEnter();
38 void hoverEnter();
39 void hoverLeave();
39 void hoverLeave();
40
40
41 public:
41 public:
42 void setSliceData(PieSliceData sliceData);
42 void setSliceData(PieSliceData sliceData);
43 void updateGeometry();
43 void updateGeometry();
44 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
44 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
45 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
45 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
46 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
46 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
47 static QRectF labelTextRect(QFont font, QString text);
47 static QRectF labelTextRect(QFont font, QString text);
48
48
49 private:
49 private:
50 PieSliceData m_data;
50 PieSliceData m_data;
51 QRectF m_boundingRect;
51 QRectF m_boundingRect;
52 QPainterPath m_slicePath;
52 QPainterPath m_slicePath;
53 QPainterPath m_labelArmPath;
53 QPainterPath m_labelArmPath;
54 QRectF m_labelTextRect;
54 QRectF m_labelTextRect;
55 };
55 };
56
56
57 QTCOMMERCIALCHART_END_NAMESPACE
57 QTCOMMERCIALCHART_END_NAMESPACE
58
58
59 #endif // PIESLICEITEM_H
59 #endif // PIESLICEITEM_H
@@ -1,640 +1,640
1 #include "qpieseries.h"
1 #include "qpieseries.h"
2 #include "qpiesliceprivate_p.h"
2 #include "qpiesliceprivate_p.h"
3 #include "qpieseriesprivate_p.h"
3 #include "qpieseriesprivate_p.h"
4 #include <QDebug>
4 #include <QDebug>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
8 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
9 :QObject(parent),
9 :QObject(parent),
10 q_ptr(parent),
10 q_ptr(parent),
11 m_pieRelativeHorPos(0.5),
11 m_pieRelativeHorPos(0.5),
12 m_pieRelativeVerPos(0.5),
12 m_pieRelativeVerPos(0.5),
13 m_pieRelativeSize(0.7),
13 m_pieRelativeSize(0.7),
14 m_pieStartAngle(0),
14 m_pieStartAngle(0),
15 m_pieEndAngle(360),
15 m_pieEndAngle(360),
16 m_total(0)
16 m_total(0)
17 {
17 {
18
18
19 }
19 }
20
20
21 QPieSeriesPrivate::~QPieSeriesPrivate()
21 QPieSeriesPrivate::~QPieSeriesPrivate()
22 {
22 {
23
23
24 }
24 }
25
25
26 void QPieSeriesPrivate::updateDerivativeData()
26 void QPieSeriesPrivate::updateDerivativeData()
27 {
27 {
28 m_total = 0;
28 m_total = 0;
29
29
30 // nothing to do?
30 // nothing to do?
31 if (m_slices.count() == 0)
31 if (m_slices.count() == 0)
32 return;
32 return;
33
33
34 // calculate total
34 // calculate total
35 foreach (QPieSlice* s, m_slices)
35 foreach (QPieSlice* s, m_slices)
36 m_total += s->value();
36 m_total += s->value();
37
37
38 // nothing to show..
38 // nothing to show..
39 if (m_total == 0)
39 if (m_total == 0)
40 return;
40 return;
41
41
42 // update slice attributes
42 // update slice attributes
43 qreal sliceAngle = m_pieStartAngle;
43 qreal sliceAngle = m_pieStartAngle;
44 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
44 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
45 QVector<QPieSlice*> changed;
45 QVector<QPieSlice*> changed;
46 foreach (QPieSlice* s, m_slices) {
46 foreach (QPieSlice* s, m_slices) {
47
47
48 bool isChanged = false;
48 bool isChanged = false;
49
49
50 qreal percentage = s->value() / m_total;
50 qreal percentage = s->value() / m_total;
51 if (s->data_ptr()->m_data.m_percentage != percentage) {
51 if (s->data_ptr()->m_data.m_percentage != percentage) {
52 s->data_ptr()->m_data.m_percentage = percentage;
52 s->data_ptr()->m_data.m_percentage = percentage;
53 isChanged = true;
53 isChanged = true;
54 }
54 }
55
55
56 qreal sliceSpan = pieSpan * percentage;
56 qreal sliceSpan = pieSpan * percentage;
57 if (s->data_ptr()->m_data.m_angleSpan != sliceSpan) {
57 if (s->data_ptr()->m_data.m_angleSpan != sliceSpan) {
58 s->data_ptr()->m_data.m_angleSpan = sliceSpan;
58 s->data_ptr()->m_data.m_angleSpan = sliceSpan;
59 isChanged = true;
59 isChanged = true;
60 }
60 }
61
61
62 if (s->data_ptr()->m_data.m_startAngle != sliceAngle) {
62 if (s->data_ptr()->m_data.m_startAngle != sliceAngle) {
63 s->data_ptr()->m_data.m_startAngle = sliceAngle;
63 s->data_ptr()->m_data.m_startAngle = sliceAngle;
64 isChanged = true;
64 isChanged = true;
65 }
65 }
66 sliceAngle += sliceSpan;
66 sliceAngle += sliceSpan;
67
67
68 if (isChanged)
68 if (isChanged)
69 changed << s;
69 changed << s;
70 }
70 }
71
71
72 // emit signals
72 // emit signals
73 foreach (QPieSlice* s, changed)
73 foreach (QPieSlice* s, changed)
74 emit s->data_ptr()->changed();
74 emit s->data_ptr()->changed();
75 }
75 }
76
76
77 void QPieSeriesPrivate::sliceChanged()
77 void QPieSeriesPrivate::sliceChanged()
78 {
78 {
79 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
79 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
80 updateDerivativeData();
80 updateDerivativeData();
81 }
81 }
82
82
83 void QPieSeriesPrivate::sliceClicked()
83 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
84 {
84 {
85 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
85 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
86 Q_ASSERT(m_slices.contains(slice));
86 Q_ASSERT(m_slices.contains(slice));
87 Q_Q(QPieSeries);
87 Q_Q(QPieSeries);
88 emit q->clicked(slice);
88 emit q->clicked(slice, buttons);
89 }
89 }
90
90
91 void QPieSeriesPrivate::sliceHoverEnter()
91 void QPieSeriesPrivate::sliceHoverEnter()
92 {
92 {
93 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
93 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
94 Q_ASSERT(m_slices.contains(slice));
94 Q_ASSERT(m_slices.contains(slice));
95 Q_Q(QPieSeries);
95 Q_Q(QPieSeries);
96 emit q->hoverEnter(slice);
96 emit q->hoverEnter(slice);
97 }
97 }
98
98
99 void QPieSeriesPrivate::sliceHoverLeave()
99 void QPieSeriesPrivate::sliceHoverLeave()
100 {
100 {
101 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
101 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
102 Q_ASSERT(m_slices.contains(slice));
102 Q_ASSERT(m_slices.contains(slice));
103 Q_Q(QPieSeries);
103 Q_Q(QPieSeries);
104 emit q->hoverLeave(slice);
104 emit q->hoverLeave(slice);
105 }
105 }
106
106
107 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
107 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
108 {
108 {
109 Q_UNUSED(bottomRight)
109 Q_UNUSED(bottomRight)
110 Q_Q(QPieSeries);
110 Q_Q(QPieSeries);
111
111
112 if (m_mapOrientation == Qt::Vertical)
112 if (m_mapOrientation == Qt::Vertical)
113 {
113 {
114 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
114 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
115 if (topLeft.column() == m_mapValues)
115 if (topLeft.column() == m_mapValues)
116 if (m_mapValues == m_mapLabels)
116 if (m_mapValues == m_mapLabels)
117 {
117 {
118 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
118 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
119 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
119 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
120 }
120 }
121 else
121 else
122 {
122 {
123 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
123 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
124 }
124 }
125 else if (topLeft.column() == m_mapLabels)
125 else if (topLeft.column() == m_mapLabels)
126 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
126 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
127 }
127 }
128 else
128 else
129 {
129 {
130 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
130 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
131 if (topLeft.row() == m_mapValues)
131 if (topLeft.row() == m_mapValues)
132 if (m_mapValues == m_mapLabels)
132 if (m_mapValues == m_mapLabels)
133 {
133 {
134 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
134 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
135 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
135 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
136 }
136 }
137 else
137 else
138 {
138 {
139 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
139 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
140 }
140 }
141 else if (topLeft.row() == m_mapLabels)
141 else if (topLeft.row() == m_mapLabels)
142 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
142 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
143 }
143 }
144 }
144 }
145
145
146 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
146 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
147 {
147 {
148 Q_UNUSED(parent)
148 Q_UNUSED(parent)
149 Q_UNUSED(end)
149 Q_UNUSED(end)
150 Q_Q(QPieSeries);
150 Q_Q(QPieSeries);
151
151
152 QPieSlice* newSlice = new QPieSlice;
152 QPieSlice* newSlice = new QPieSlice;
153 newSlice->setLabelVisible(true);
153 newSlice->setLabelVisible(true);
154 if (m_mapOrientation == Qt::Vertical)
154 if (m_mapOrientation == Qt::Vertical)
155 {
155 {
156 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
156 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
157 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
157 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
158 }
158 }
159 else
159 else
160 {
160 {
161 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
161 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
162 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
162 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
163 }
163 }
164
164
165 q->insert(start, newSlice);
165 q->insert(start, newSlice);
166 }
166 }
167
167
168 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
168 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
169 {
169 {
170 Q_UNUSED(parent)
170 Q_UNUSED(parent)
171 Q_UNUSED(end)
171 Q_UNUSED(end)
172 Q_Q(QPieSeries);
172 Q_Q(QPieSeries);
173 q->remove(m_slices.at(start));
173 q->remove(m_slices.at(start));
174 }
174 }
175
175
176
176
177
177
178 /*!
178 /*!
179 \class QPieSeries
179 \class QPieSeries
180 \brief Pie series API for QtCommercial Charts
180 \brief Pie series API for QtCommercial Charts
181
181
182 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
182 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
183 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
183 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
184 The actual slice size is determined by that relative value.
184 The actual slice size is determined by that relative value.
185
185
186 By default the pie is defined as a full pie but it can be a partial pie.
186 By default the pie is defined as a full pie but it can be a partial pie.
187 This can be done by setting a starting angle and angle span to the series.
187 This can be done by setting a starting angle and angle span to the series.
188 */
188 */
189
189
190 /*!
190 /*!
191 Constructs a series object which is a child of \a parent.
191 Constructs a series object which is a child of \a parent.
192 */
192 */
193 QPieSeries::QPieSeries(QObject *parent) :
193 QPieSeries::QPieSeries(QObject *parent) :
194 QSeries(parent),
194 QSeries(parent),
195 d_ptr(new QPieSeriesPrivate(this))
195 d_ptr(new QPieSeriesPrivate(this))
196 {
196 {
197
197
198 }
198 }
199
199
200 /*!
200 /*!
201 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
201 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
202 */
202 */
203 QPieSeries::~QPieSeries()
203 QPieSeries::~QPieSeries()
204 {
204 {
205 // NOTE: d_prt destroyed by QObject
205 // NOTE: d_prt destroyed by QObject
206 }
206 }
207
207
208 /*!
208 /*!
209 Returns QChartSeries::SeriesTypePie.
209 Returns QChartSeries::SeriesTypePie.
210 */
210 */
211 QSeries::QSeriesType QPieSeries::type() const
211 QSeries::QSeriesType QPieSeries::type() const
212 {
212 {
213 return QSeries::SeriesTypePie;
213 return QSeries::SeriesTypePie;
214 }
214 }
215
215
216 /*!
216 /*!
217 Sets an array of \a slices to the series replacing the existing slices.
217 Sets an array of \a slices to the series replacing the existing slices.
218 Slice ownership is passed to the series.
218 Slice ownership is passed to the series.
219 */
219 */
220 void QPieSeries::replace(QList<QPieSlice*> slices)
220 void QPieSeries::replace(QList<QPieSlice*> slices)
221 {
221 {
222 clear();
222 clear();
223 add(slices);
223 add(slices);
224 }
224 }
225
225
226 /*!
226 /*!
227 Adds an array of \a slices to the series.
227 Adds an array of \a slices to the series.
228 Slice ownership is passed to the series.
228 Slice ownership is passed to the series.
229 */
229 */
230 void QPieSeries::add(QList<QPieSlice*> slices)
230 void QPieSeries::add(QList<QPieSlice*> slices)
231 {
231 {
232 Q_D(QPieSeries);
232 Q_D(QPieSeries);
233
233
234 foreach (QPieSlice* s, slices) {
234 foreach (QPieSlice* s, slices) {
235 s->setParent(this);
235 s->setParent(this);
236 d->m_slices << s;
236 d->m_slices << s;
237 }
237 }
238
238
239 d->updateDerivativeData();
239 d->updateDerivativeData();
240
240
241 foreach (QPieSlice* s, slices) {
241 foreach (QPieSlice* s, slices) {
242 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
242 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
243 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
243 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
244 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
244 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
245 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
245 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
246 }
246 }
247
247
248 emit added(slices);
248 emit added(slices);
249 }
249 }
250
250
251 /*!
251 /*!
252 Adds a single \a slice to the series.
252 Adds a single \a slice to the series.
253 Slice ownership is passed to the series.
253 Slice ownership is passed to the series.
254 */
254 */
255 void QPieSeries::add(QPieSlice* slice)
255 void QPieSeries::add(QPieSlice* slice)
256 {
256 {
257 add(QList<QPieSlice*>() << slice);
257 add(QList<QPieSlice*>() << slice);
258 }
258 }
259
259
260 /*!
260 /*!
261 Adds a single \a slice to the series and returns a reference to the series.
261 Adds a single \a slice to the series and returns a reference to the series.
262 Slice ownership is passed to the series.
262 Slice ownership is passed to the series.
263 */
263 */
264 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
264 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
265 {
265 {
266 add(slice);
266 add(slice);
267 return *this;
267 return *this;
268 }
268 }
269
269
270
270
271 /*!
271 /*!
272 Adds a single slice to the series with give \a value and \a name.
272 Adds a single slice to the series with give \a value and \a name.
273 Slice ownership is passed to the series.
273 Slice ownership is passed to the series.
274 */
274 */
275 QPieSlice* QPieSeries::add(qreal value, QString name)
275 QPieSlice* QPieSeries::add(qreal value, QString name)
276 {
276 {
277 QPieSlice* slice = new QPieSlice(value, name);
277 QPieSlice* slice = new QPieSlice(value, name);
278 add(slice);
278 add(slice);
279 return slice;
279 return slice;
280 }
280 }
281
281
282 void QPieSeries::insert(int i, QPieSlice* slice)
282 void QPieSeries::insert(int i, QPieSlice* slice)
283 {
283 {
284 Q_D(QPieSeries);
284 Q_D(QPieSeries);
285 Q_ASSERT(i <= d->m_slices.count());
285 Q_ASSERT(i <= d->m_slices.count());
286 slice->setParent(this);
286 slice->setParent(this);
287 d->m_slices.insert(i, slice);
287 d->m_slices.insert(i, slice);
288
288
289 d->updateDerivativeData();
289 d->updateDerivativeData();
290
290
291 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
291 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
292 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
292 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
293 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
293 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
294 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
294 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
295
295
296 emit added(QList<QPieSlice*>() << slice);
296 emit added(QList<QPieSlice*>() << slice);
297 }
297 }
298
298
299 /*!
299 /*!
300 Removes a single \a slice from the series and deletes the slice.
300 Removes a single \a slice from the series and deletes the slice.
301
301
302 Do not reference this pointer after this call.
302 Do not reference this pointer after this call.
303 */
303 */
304 void QPieSeries::remove(QPieSlice* slice)
304 void QPieSeries::remove(QPieSlice* slice)
305 {
305 {
306 Q_D(QPieSeries);
306 Q_D(QPieSeries);
307 if (!d->m_slices.removeOne(slice)) {
307 if (!d->m_slices.removeOne(slice)) {
308 Q_ASSERT(0); // TODO: how should this be reported?
308 Q_ASSERT(0); // TODO: how should this be reported?
309 return;
309 return;
310 }
310 }
311
311
312 d->updateDerivativeData();
312 d->updateDerivativeData();
313
313
314 emit removed(QList<QPieSlice*>() << slice);
314 emit removed(QList<QPieSlice*>() << slice);
315
315
316 delete slice;
316 delete slice;
317 slice = NULL;
317 slice = NULL;
318 }
318 }
319
319
320 /*!
320 /*!
321 Clears all slices from the series.
321 Clears all slices from the series.
322 */
322 */
323 void QPieSeries::clear()
323 void QPieSeries::clear()
324 {
324 {
325 Q_D(QPieSeries);
325 Q_D(QPieSeries);
326 if (d->m_slices.count() == 0)
326 if (d->m_slices.count() == 0)
327 return;
327 return;
328
328
329 QList<QPieSlice*> slices = d->m_slices;
329 QList<QPieSlice*> slices = d->m_slices;
330 foreach (QPieSlice* s, d->m_slices) {
330 foreach (QPieSlice* s, d->m_slices) {
331 d->m_slices.removeOne(s);
331 d->m_slices.removeOne(s);
332 delete s;
332 delete s;
333 }
333 }
334
334
335 d->updateDerivativeData();
335 d->updateDerivativeData();
336
336
337 emit removed(slices);
337 emit removed(slices);
338 }
338 }
339
339
340 /*!
340 /*!
341 Counts the number of the slices in this series.
341 Counts the number of the slices in this series.
342 */
342 */
343 int QPieSeries::count() const
343 int QPieSeries::count() const
344 {
344 {
345 Q_D(const QPieSeries);
345 Q_D(const QPieSeries);
346 return d->m_slices.count();
346 return d->m_slices.count();
347 }
347 }
348
348
349 /*!
349 /*!
350 Returns true is the series is empty.
350 Returns true is the series is empty.
351 */
351 */
352 bool QPieSeries::isEmpty() const
352 bool QPieSeries::isEmpty() const
353 {
353 {
354 Q_D(const QPieSeries);
354 Q_D(const QPieSeries);
355 return d->m_slices.isEmpty();
355 return d->m_slices.isEmpty();
356 }
356 }
357
357
358 /*!
358 /*!
359 Returns a list of slices that belong to this series.
359 Returns a list of slices that belong to this series.
360 */
360 */
361 QList<QPieSlice*> QPieSeries::slices() const
361 QList<QPieSlice*> QPieSeries::slices() const
362 {
362 {
363 Q_D(const QPieSeries);
363 Q_D(const QPieSeries);
364 return d->m_slices;
364 return d->m_slices;
365 }
365 }
366
366
367 /*!
367 /*!
368 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
368 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
369
369
370 The factors are relative to the chart rectangle where:
370 The factors are relative to the chart rectangle where:
371
371
372 \a relativeHorizontalPosition 0.0 means the absolute left.
372 \a relativeHorizontalPosition 0.0 means the absolute left.
373 \a relativeHorizontalPosition 1.0 means the absolute right.
373 \a relativeHorizontalPosition 1.0 means the absolute right.
374 \a relativeVerticalPosition 0.0 means the absolute top.
374 \a relativeVerticalPosition 0.0 means the absolute top.
375 \a relativeVerticalPosition 1.0 means the absolute bottom.
375 \a relativeVerticalPosition 1.0 means the absolute bottom.
376
376
377 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
377 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
378
378
379 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
379 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
380 */
380 */
381 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
381 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
382 {
382 {
383 Q_D(QPieSeries);
383 Q_D(QPieSeries);
384 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
384 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
385 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
385 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
386 return;
386 return;
387
387
388 if (d->m_pieRelativeHorPos != relativeHorizontalPosition || d->m_pieRelativeVerPos != relativeVerticalPosition) {
388 if (d->m_pieRelativeHorPos != relativeHorizontalPosition || d->m_pieRelativeVerPos != relativeVerticalPosition) {
389 d->m_pieRelativeHorPos = relativeHorizontalPosition;
389 d->m_pieRelativeHorPos = relativeHorizontalPosition;
390 d->m_pieRelativeVerPos = relativeVerticalPosition;
390 d->m_pieRelativeVerPos = relativeVerticalPosition;
391 emit piePositionChanged();
391 emit piePositionChanged();
392 }
392 }
393 }
393 }
394
394
395 /*!
395 /*!
396 Gets the horizontal position of the pie.
396 Gets the horizontal position of the pie.
397
397
398 The returned value is relative to the chart rectangle where:
398 The returned value is relative to the chart rectangle where:
399
399
400 0.0 means the absolute left.
400 0.0 means the absolute left.
401 1.0 means the absolute right.
401 1.0 means the absolute right.
402
402
403 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
403 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
404
404
405 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
405 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
406 */
406 */
407 qreal QPieSeries::pieHorizontalPosition() const
407 qreal QPieSeries::pieHorizontalPosition() const
408 {
408 {
409 Q_D(const QPieSeries);
409 Q_D(const QPieSeries);
410 return d->m_pieRelativeHorPos;
410 return d->m_pieRelativeHorPos;
411 }
411 }
412
412
413 /*!
413 /*!
414 Gets the vertical position position of the pie.
414 Gets the vertical position position of the pie.
415
415
416 The returned value is relative to the chart rectangle where:
416 The returned value is relative to the chart rectangle where:
417
417
418 0.0 means the absolute top.
418 0.0 means the absolute top.
419 1.0 means the absolute bottom.
419 1.0 means the absolute bottom.
420
420
421 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
421 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
422
422
423 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
423 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
424 */
424 */
425 qreal QPieSeries::pieVerticalPosition() const
425 qreal QPieSeries::pieVerticalPosition() const
426 {
426 {
427 Q_D(const QPieSeries);
427 Q_D(const QPieSeries);
428 return d->m_pieRelativeVerPos;
428 return d->m_pieRelativeVerPos;
429 }
429 }
430
430
431 /*!
431 /*!
432 Sets the relative size of the pie.
432 Sets the relative size of the pie.
433
433
434 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
434 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
435
435
436 Default value is 0.7.
436 Default value is 0.7.
437
437
438 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
438 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
439 */
439 */
440 void QPieSeries::setPieSize(qreal relativeSize)
440 void QPieSeries::setPieSize(qreal relativeSize)
441 {
441 {
442 Q_D(QPieSeries);
442 Q_D(QPieSeries);
443 if (relativeSize < 0.0 || relativeSize > 1.0)
443 if (relativeSize < 0.0 || relativeSize > 1.0)
444 return;
444 return;
445
445
446 if (d->m_pieRelativeSize != relativeSize) {
446 if (d->m_pieRelativeSize != relativeSize) {
447 d->m_pieRelativeSize = relativeSize;
447 d->m_pieRelativeSize = relativeSize;
448 emit pieSizeChanged();
448 emit pieSizeChanged();
449 }
449 }
450 }
450 }
451
451
452 /*!
452 /*!
453 Gets the relative size of the pie.
453 Gets the relative size of the pie.
454
454
455 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
455 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
456
456
457 Default value is 0.7.
457 Default value is 0.7.
458
458
459 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
459 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
460 */
460 */
461 qreal QPieSeries::pieSize() const
461 qreal QPieSeries::pieSize() const
462 {
462 {
463 Q_D(const QPieSeries);
463 Q_D(const QPieSeries);
464 return d->m_pieRelativeSize;
464 return d->m_pieRelativeSize;
465 }
465 }
466
466
467
467
468 /*!
468 /*!
469 Sets the end angle of the pie.
469 Sets the end angle of the pie.
470
470
471 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
471 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
472
472
473 \a angle must be less than pie end angle. Default value is 0.
473 \a angle must be less than pie end angle. Default value is 0.
474
474
475 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
475 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
476 */
476 */
477 void QPieSeries::setPieStartAngle(qreal angle)
477 void QPieSeries::setPieStartAngle(qreal angle)
478 {
478 {
479 Q_D(QPieSeries);
479 Q_D(QPieSeries);
480 if (angle >= 0 && angle <= 360 && angle != d->m_pieStartAngle && angle <= d->m_pieEndAngle) {
480 if (angle >= 0 && angle <= 360 && angle != d->m_pieStartAngle && angle <= d->m_pieEndAngle) {
481 d->m_pieStartAngle = angle;
481 d->m_pieStartAngle = angle;
482 d->updateDerivativeData();
482 d->updateDerivativeData();
483 }
483 }
484 }
484 }
485
485
486 /*!
486 /*!
487 Gets the start angle of the pie.
487 Gets the start angle of the pie.
488
488
489 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
489 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
490
490
491 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
491 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
492 */
492 */
493 qreal QPieSeries::pieStartAngle() const
493 qreal QPieSeries::pieStartAngle() const
494 {
494 {
495 Q_D(const QPieSeries);
495 Q_D(const QPieSeries);
496 return d->m_pieStartAngle;
496 return d->m_pieStartAngle;
497 }
497 }
498
498
499 /*!
499 /*!
500 Sets the end angle of the pie.
500 Sets the end angle of the pie.
501
501
502 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
502 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
503
503
504 \a angle must be greater than start angle.
504 \a angle must be greater than start angle.
505
505
506 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
506 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
507 */
507 */
508 void QPieSeries::setPieEndAngle(qreal angle)
508 void QPieSeries::setPieEndAngle(qreal angle)
509 {
509 {
510 Q_D(QPieSeries);
510 Q_D(QPieSeries);
511 if (angle >= 0 && angle <= 360 && angle != d->m_pieEndAngle && angle >= d->m_pieStartAngle) {
511 if (angle >= 0 && angle <= 360 && angle != d->m_pieEndAngle && angle >= d->m_pieStartAngle) {
512 d->m_pieEndAngle = angle;
512 d->m_pieEndAngle = angle;
513 d->updateDerivativeData();
513 d->updateDerivativeData();
514 }
514 }
515 }
515 }
516
516
517 /*!
517 /*!
518 Returns the end angle of the pie.
518 Returns the end angle of the pie.
519
519
520 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
520 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
521
521
522 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
522 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
523 */
523 */
524 qreal QPieSeries::pieEndAngle() const
524 qreal QPieSeries::pieEndAngle() const
525 {
525 {
526 Q_D(const QPieSeries);
526 Q_D(const QPieSeries);
527 return d->m_pieEndAngle;
527 return d->m_pieEndAngle;
528 }
528 }
529
529
530 /*!
530 /*!
531 Sets the all the slice labels \a visible or invisible.
531 Sets the all the slice labels \a visible or invisible.
532
532
533 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
533 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
534 */
534 */
535 void QPieSeries::setLabelsVisible(bool visible)
535 void QPieSeries::setLabelsVisible(bool visible)
536 {
536 {
537 Q_D(QPieSeries);
537 Q_D(QPieSeries);
538 foreach (QPieSlice* s, d->m_slices)
538 foreach (QPieSlice* s, d->m_slices)
539 s->setLabelVisible(visible);
539 s->setLabelVisible(visible);
540 }
540 }
541
541
542 /*!
542 /*!
543 Returns the sum of all slice values in this series.
543 Returns the sum of all slice values in this series.
544
544
545 \sa QPieSlice::value(), QPieSlice::setValue()
545 \sa QPieSlice::value(), QPieSlice::setValue()
546 */
546 */
547 qreal QPieSeries::total() const
547 qreal QPieSeries::total() const
548 {
548 {
549 Q_D(const QPieSeries);
549 Q_D(const QPieSeries);
550 return d->m_total;
550 return d->m_total;
551 }
551 }
552
552
553 /*!
553 /*!
554 \fn void QPieSeries::clicked(QPieSlice* slice)
554 \fn void QPieSeries::clicked(QPieSlice* slice)
555
555
556 This signal is emitted when a \a slice has been clicked.
556 This signal is emitted when a \a slice has been clicked.
557
557
558 \sa QPieSlice::clicked()
558 \sa QPieSlice::clicked()
559 */
559 */
560
560
561 /*!
561 /*!
562 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
562 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
563
563
564 This signal is emitted when user has hovered over a \a slice.
564 This signal is emitted when user has hovered over a \a slice.
565
565
566 \sa QPieSlice::hoverEnter()
566 \sa QPieSlice::hoverEnter()
567 */
567 */
568
568
569 /*!
569 /*!
570 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
570 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
571
571
572 This signal is emitted when user has hovered away from a \a slice.
572 This signal is emitted when user has hovered away from a \a slice.
573
573
574 \sa QPieSlice::hoverLeave()
574 \sa QPieSlice::hoverLeave()
575 */
575 */
576
576
577
577
578
578
579
579
580 bool QPieSeries::setModel(QAbstractItemModel* model)
580 bool QPieSeries::setModel(QAbstractItemModel* model)
581 {
581 {
582 Q_D(QPieSeries);
582 Q_D(QPieSeries);
583 // disconnect signals from old model
583 // disconnect signals from old model
584 if(m_model)
584 if(m_model)
585 {
585 {
586 disconnect(m_model, 0, this, 0);
586 disconnect(m_model, 0, this, 0);
587 d->m_mapValues = -1;
587 d->m_mapValues = -1;
588 d->m_mapLabels = -1;
588 d->m_mapLabels = -1;
589 d->m_mapOrientation = Qt::Vertical;
589 d->m_mapOrientation = Qt::Vertical;
590 }
590 }
591
591
592 // set new model
592 // set new model
593 if(model)
593 if(model)
594 {
594 {
595 m_model = model;
595 m_model = model;
596 return true;
596 return true;
597 }
597 }
598 else
598 else
599 {
599 {
600 m_model = NULL;
600 m_model = NULL;
601 return false;
601 return false;
602 }
602 }
603 }
603 }
604
604
605 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
605 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
606 {
606 {
607 Q_D(QPieSeries);
607 Q_D(QPieSeries);
608
608
609 if (m_model == NULL)
609 if (m_model == NULL)
610 return;
610 return;
611
611
612 d->m_mapValues = modelValuesLine;
612 d->m_mapValues = modelValuesLine;
613 d->m_mapLabels = modelLabelsLine;
613 d->m_mapLabels = modelLabelsLine;
614 d->m_mapOrientation = orientation;
614 d->m_mapOrientation = orientation;
615
615
616 // connect the signals
616 // connect the signals
617 if (d->m_mapOrientation == Qt::Vertical) {
617 if (d->m_mapOrientation == Qt::Vertical) {
618 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
618 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
619 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
619 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
620 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
620 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
621 } else {
621 } else {
622 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
622 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
623 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
623 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
624 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
624 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
625 }
625 }
626
626
627 // create the initial slices set
627 // create the initial slices set
628 if (d->m_mapOrientation == Qt::Vertical) {
628 if (d->m_mapOrientation == Qt::Vertical) {
629 for (int i = 0; i < m_model->rowCount(); i++)
629 for (int i = 0; i < m_model->rowCount(); i++)
630 add(m_model->data(m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
630 add(m_model->data(m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
631 } else {
631 } else {
632 for (int i = 0; i < m_model->columnCount(); i++)
632 for (int i = 0; i < m_model->columnCount(); i++)
633 add(m_model->data(m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
633 add(m_model->data(m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
634 }
634 }
635 }
635 }
636
636
637 #include "moc_qpieseries.cpp"
637 #include "moc_qpieseries.cpp"
638 #include "moc_qpieseriesprivate_p.cpp"
638 #include "moc_qpieseriesprivate_p.cpp"
639
639
640 QTCOMMERCIALCHART_END_NAMESPACE
640 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,80 +1,80
1 #ifndef PIESERIES_H
1 #ifndef PIESERIES_H
2 #define PIESERIES_H
2 #define PIESERIES_H
3
3
4 #include <qseries.h>
4 #include <qseries.h>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 class QPieSeriesPrivate;
7 class QPieSeriesPrivate;
8 class QPieSlice;
8 class QPieSlice;
9
9
10 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
10 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13
13
14 public:
14 public:
15 QPieSeries(QObject *parent = 0);
15 QPieSeries(QObject *parent = 0);
16 virtual ~QPieSeries();
16 virtual ~QPieSeries();
17
17
18 public: // from QChartSeries
18 public: // from QChartSeries
19 QSeriesType type() const;
19 QSeriesType type() const;
20
20
21 public:
21 public:
22
22
23 // slice setters
23 // slice setters
24 void add(QPieSlice* slice);
24 void add(QPieSlice* slice);
25 void add(QList<QPieSlice*> slices);
25 void add(QList<QPieSlice*> slices);
26 void insert(int i, QPieSlice* slice);
26 void insert(int i, QPieSlice* slice);
27 void replace(QList<QPieSlice*> slices);
27 void replace(QList<QPieSlice*> slices);
28 void remove(QPieSlice* slice);
28 void remove(QPieSlice* slice);
29 void clear();
29 void clear();
30
30
31 // slice getters
31 // slice getters
32 QList<QPieSlice*> slices() const;
32 QList<QPieSlice*> slices() const;
33
33
34 // calculated data
34 // calculated data
35 int count() const;
35 int count() const;
36 bool isEmpty() const;
36 bool isEmpty() const;
37 qreal total() const;
37 qreal total() const;
38
38
39 // pie customization
39 // pie customization
40 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
40 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
41 qreal pieHorizontalPosition() const;
41 qreal pieHorizontalPosition() const;
42 qreal pieVerticalPosition() const;
42 qreal pieVerticalPosition() const;
43 void setPieSize(qreal relativeSize);
43 void setPieSize(qreal relativeSize);
44 qreal pieSize() const;
44 qreal pieSize() const;
45 void setPieStartAngle(qreal startAngle);
45 void setPieStartAngle(qreal startAngle);
46 qreal pieStartAngle() const;
46 qreal pieStartAngle() const;
47 void setPieEndAngle(qreal endAngle);
47 void setPieEndAngle(qreal endAngle);
48 qreal pieEndAngle() const;
48 qreal pieEndAngle() const;
49
49
50 // convenience function
50 // convenience function
51 QPieSeries& operator << (QPieSlice* slice);
51 QPieSeries& operator << (QPieSlice* slice);
52 QPieSlice* add(qreal value, QString name);
52 QPieSlice* add(qreal value, QString name);
53 void setLabelsVisible(bool visible = true);
53 void setLabelsVisible(bool visible = true);
54
54
55 // data from model
55 // data from model
56 bool setModel(QAbstractItemModel* model);
56 bool setModel(QAbstractItemModel* model);
57 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
57 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
58
58
59 Q_SIGNALS:
59 Q_SIGNALS:
60 void clicked(QPieSlice* slice);
60 void clicked(QPieSlice* slice, Qt::MouseButtons buttons);
61 void hoverEnter(QPieSlice* slice);
61 void hoverEnter(QPieSlice* slice);
62 void hoverLeave(QPieSlice* slice);
62 void hoverLeave(QPieSlice* slice);
63 void added(QList<QPieSlice*> slices);
63 void added(QList<QPieSlice*> slices);
64 void removed(QList<QPieSlice*> slices);
64 void removed(QList<QPieSlice*> slices);
65 void piePositionChanged();
65 void piePositionChanged();
66 void pieSizeChanged();
66 void pieSizeChanged();
67
67
68 private:
68 private:
69 QPieSeriesPrivate * const d_ptr;
69 QPieSeriesPrivate * const d_ptr;
70 Q_DECLARE_PRIVATE(QPieSeries)
70 Q_DECLARE_PRIVATE(QPieSeries)
71 Q_DISABLE_COPY(QPieSeries)
71 Q_DISABLE_COPY(QPieSeries)
72
72
73 public:
73 public:
74 typedef QPieSeriesPrivate * const DataPtr;
74 typedef QPieSeriesPrivate * const DataPtr;
75 inline DataPtr &data_ptr() { return d_ptr; }
75 inline DataPtr &data_ptr() { return d_ptr; }
76 };
76 };
77
77
78 QTCOMMERCIALCHART_END_NAMESPACE
78 QTCOMMERCIALCHART_END_NAMESPACE
79
79
80 #endif // PIESERIES_H
80 #endif // PIESERIES_H
@@ -1,47 +1,47
1 #ifndef QPIESERIESPRIVATE_P_H
1 #ifndef QPIESERIESPRIVATE_P_H
2 #define QPIESERIESPRIVATE_P_H
2 #define QPIESERIESPRIVATE_P_H
3
3
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 class QPieSeriesPrivate : public QObject
8 class QPieSeriesPrivate : public QObject
9 {
9 {
10 Q_OBJECT
10 Q_OBJECT
11 Q_DECLARE_PUBLIC(QPieSeries)
11 Q_DECLARE_PUBLIC(QPieSeries)
12
12
13 public:
13 public:
14 QPieSeriesPrivate(QPieSeries *parent);
14 QPieSeriesPrivate(QPieSeries *parent);
15 ~QPieSeriesPrivate();
15 ~QPieSeriesPrivate();
16
16
17 void updateDerivativeData();
17 void updateDerivativeData();
18
18
19 public Q_SLOTS: // TODO: should be private and not visible in the interface at all
19 public Q_SLOTS:
20 void sliceChanged();
20 void sliceChanged();
21 void sliceClicked();
21 void sliceClicked(Qt::MouseButtons buttons);
22 void sliceHoverEnter();
22 void sliceHoverEnter();
23 void sliceHoverLeave();
23 void sliceHoverLeave();
24 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
24 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
25 void modelDataAdded(QModelIndex parent, int start, int end);
25 void modelDataAdded(QModelIndex parent, int start, int end);
26 void modelDataRemoved(QModelIndex parent, int start, int end);
26 void modelDataRemoved(QModelIndex parent, int start, int end);
27
27
28 public:
28 public:
29 QPieSeries * const q_ptr;
29 QPieSeries * const q_ptr;
30
30
31 QList<QPieSlice*> m_slices;
31 QList<QPieSlice*> m_slices;
32 qreal m_pieRelativeHorPos;
32 qreal m_pieRelativeHorPos;
33 qreal m_pieRelativeVerPos;
33 qreal m_pieRelativeVerPos;
34 qreal m_pieRelativeSize;
34 qreal m_pieRelativeSize;
35 qreal m_pieStartAngle;
35 qreal m_pieStartAngle;
36 qreal m_pieEndAngle;
36 qreal m_pieEndAngle;
37 qreal m_total;
37 qreal m_total;
38
38
39 // model map
39 // model map
40 int m_mapValues;
40 int m_mapValues;
41 int m_mapLabels;
41 int m_mapLabels;
42 Qt::Orientation m_mapOrientation;
42 Qt::Orientation m_mapOrientation;
43 };
43 };
44
44
45 QTCOMMERCIALCHART_END_NAMESPACE
45 QTCOMMERCIALCHART_END_NAMESPACE
46
46
47 #endif // QPIESERIESPRIVATE_P_H
47 #endif // QPIESERIESPRIVATE_P_H
@@ -1,71 +1,71
1 #ifndef QPIESLICE_H
1 #ifndef QPIESLICE_H
2 #define QPIESLICE_H
2 #define QPIESLICE_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QObject>
5 #include <QObject>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8 #include <QFont>
8 #include <QFont>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 class QPieSlicePrivate;
11 class QPieSlicePrivate;
12
12
13 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
13 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
16 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
17 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
17 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
18
18
19 public:
19 public:
20 QPieSlice(QObject *parent = 0);
20 QPieSlice(QObject *parent = 0);
21 QPieSlice(qreal value, QString label, QObject *parent = 0);
21 QPieSlice(qreal value, QString label, QObject *parent = 0);
22 virtual ~QPieSlice();
22 virtual ~QPieSlice();
23
23
24 // data
24 // data
25 void setValue(qreal value);
25 void setValue(qreal value);
26 qreal value() const;
26 qreal value() const;
27 void setLabel(QString label);
27 void setLabel(QString label);
28 QString label() const;
28 QString label() const;
29 void setLabelVisible(bool visible = true);
29 void setLabelVisible(bool visible = true);
30 bool isLabelVisible() const;
30 bool isLabelVisible() const;
31 void setExploded(bool exploded = true);
31 void setExploded(bool exploded = true);
32 bool isExploded() const;
32 bool isExploded() const;
33
33
34 // generated data
34 // generated data
35 qreal percentage() const;
35 qreal percentage() const;
36 qreal startAngle() const;
36 qreal startAngle() const;
37 qreal endAngle() const;
37 qreal endAngle() const;
38
38
39 // customization
39 // customization
40 void setSlicePen(const QPen &pen);
40 void setSlicePen(const QPen &pen);
41 QPen slicePen() const;
41 QPen slicePen() const;
42 void setSliceBrush(const QBrush &brush);
42 void setSliceBrush(const QBrush &brush);
43 QBrush sliceBrush() const;
43 QBrush sliceBrush() const;
44 void setLabelArmPen(const QPen &pen);
44 void setLabelArmPen(const QPen &pen);
45 QPen labelArmPen() const;
45 QPen labelArmPen() const;
46 void setLabelFont(const QFont &font);
46 void setLabelFont(const QFont &font);
47 QFont labelFont() const;
47 QFont labelFont() const;
48 void setLabelArmLengthFactor(qreal factor);
48 void setLabelArmLengthFactor(qreal factor);
49 qreal labelArmLengthFactor() const;
49 qreal labelArmLengthFactor() const;
50 void setExplodeDistanceFactor(qreal factor);
50 void setExplodeDistanceFactor(qreal factor);
51 qreal explodeDistanceFactor() const;
51 qreal explodeDistanceFactor() const;
52
52
53 Q_SIGNALS:
53 Q_SIGNALS:
54 void clicked();
54 void clicked(Qt::MouseButtons buttons);
55 void hoverEnter();
55 void hoverEnter();
56 void hoverLeave();
56 void hoverLeave();
57 void changed();
57 void changed();
58
58
59 private:
59 private:
60 QPieSlicePrivate * const d_ptr;
60 QPieSlicePrivate * const d_ptr;
61 Q_DECLARE_PRIVATE(QPieSlice)
61 Q_DECLARE_PRIVATE(QPieSlice)
62 Q_DISABLE_COPY(QPieSlice)
62 Q_DISABLE_COPY(QPieSlice)
63
63
64 public:
64 public:
65 typedef QPieSlicePrivate * const DataPtr;
65 typedef QPieSlicePrivate * const DataPtr;
66 inline DataPtr &data_ptr() { return d_ptr; }
66 inline DataPtr &data_ptr() { return d_ptr; }
67 };
67 };
68
68
69 QTCOMMERCIALCHART_END_NAMESPACE
69 QTCOMMERCIALCHART_END_NAMESPACE
70
70
71 #endif // QPIESLICE_H
71 #endif // QPIESLICE_H
General Comments 0
You need to be logged in to leave comments. Login now