##// END OF EJS Templates
Donut support simplified. Examples updated
Marek Rosa -
r1838:886026b75e22
parent child
Show More
@@ -1,363 +1,359
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20 #include "mainwidget.h"
20 #include "mainwidget.h"
21 #include "customslice.h"
21 #include "customslice.h"
22 #include "pentool.h"
22 #include "pentool.h"
23 #include "brushtool.h"
23 #include "brushtool.h"
24 #include <QPushButton>
24 #include <QPushButton>
25 #include <QComboBox>
25 #include <QComboBox>
26 #include <QCheckBox>
26 #include <QCheckBox>
27 #include <QLineEdit>
27 #include <QLineEdit>
28 #include <QGroupBox>
28 #include <QGroupBox>
29 #include <QDoubleSpinBox>
29 #include <QDoubleSpinBox>
30 #include <QFormLayout>
30 #include <QFormLayout>
31 #include <QFontDialog>
31 #include <QFontDialog>
32 #include <QChartView>
32 #include <QChartView>
33 #include <QPieSeries>
33 #include <QPieSeries>
34
34
35 QTCOMMERCIALCHART_USE_NAMESPACE
35 QTCOMMERCIALCHART_USE_NAMESPACE
36
36
37 MainWidget::MainWidget(QWidget* parent)
37 MainWidget::MainWidget(QWidget* parent)
38 :QWidget(parent),
38 :QWidget(parent),
39 m_slice(0)
39 m_slice(0)
40 {
40 {
41 // create chart
41 // create chart
42 QChart *chart = new QChart;
42 QChart *chart = new QChart;
43 chart->setTitle("Piechart customization");
43 chart->setTitle("Piechart customization");
44 chart->setAnimationOptions(QChart::AllAnimations);
44 chart->setAnimationOptions(QChart::AllAnimations);
45
45
46 // create series
46 // create series
47 m_series = new QPieSeries();
47 m_series = new QPieSeries();
48 *m_series << new CustomSlice("Slice 1", 10.0);
48 *m_series << new CustomSlice("Slice 1", 10.0);
49 *m_series << new CustomSlice("Slice 2", 20.0);
49 *m_series << new CustomSlice("Slice 2", 20.0);
50 *m_series << new CustomSlice("Slice 3", 30.0);
50 *m_series << new CustomSlice("Slice 3", 30.0);
51 *m_series << new CustomSlice("Slice 4", 40.0);
51 *m_series << new CustomSlice("Slice 4", 40.0);
52 *m_series << new CustomSlice("Slice 5", 50.0);
52 *m_series << new CustomSlice("Slice 5", 50.0);
53 m_series->setLabelsVisible();
53 m_series->setLabelsVisible();
54 chart->addSeries(m_series);
54 chart->addSeries(m_series);
55
55
56 connect(m_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(handleSliceClicked(QPieSlice*)));
56 connect(m_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(handleSliceClicked(QPieSlice*)));
57
57
58 // chart settings
58 // chart settings
59 m_themeComboBox = new QComboBox();
59 m_themeComboBox = new QComboBox();
60 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
60 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
61 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
61 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
62 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
62 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
63 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
63 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
64 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
64 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
65 m_themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
65 m_themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
66 m_themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
66 m_themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
67
67
68 m_aaCheckBox = new QCheckBox();
68 m_aaCheckBox = new QCheckBox();
69 m_animationsCheckBox = new QCheckBox();
69 m_animationsCheckBox = new QCheckBox();
70 m_animationsCheckBox->setCheckState(Qt::Checked);
70 m_animationsCheckBox->setCheckState(Qt::Checked);
71
71
72 m_legendCheckBox = new QCheckBox();
72 m_legendCheckBox = new QCheckBox();
73
73
74 QFormLayout* chartSettingsLayout = new QFormLayout();
74 QFormLayout* chartSettingsLayout = new QFormLayout();
75 chartSettingsLayout->addRow("Theme", m_themeComboBox);
75 chartSettingsLayout->addRow("Theme", m_themeComboBox);
76 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
76 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
77 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
77 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
78 chartSettingsLayout->addRow("Legend", m_legendCheckBox);
78 chartSettingsLayout->addRow("Legend", m_legendCheckBox);
79 QGroupBox* chartSettings = new QGroupBox("Chart");
79 QGroupBox* chartSettings = new QGroupBox("Chart");
80 chartSettings->setLayout(chartSettingsLayout);
80 chartSettings->setLayout(chartSettingsLayout);
81
81
82 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
82 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
83 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
83 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
84 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
84 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
85 connect(m_legendCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
85 connect(m_legendCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
86
86
87 // series settings
87 // series settings
88 m_hPosition = new QDoubleSpinBox();
88 m_hPosition = new QDoubleSpinBox();
89 m_hPosition->setMinimum(0.0);
89 m_hPosition->setMinimum(0.0);
90 m_hPosition->setMaximum(1.0);
90 m_hPosition->setMaximum(1.0);
91 m_hPosition->setSingleStep(0.1);
91 m_hPosition->setSingleStep(0.1);
92 m_hPosition->setValue(m_series->horizontalPosition());
92 m_hPosition->setValue(m_series->horizontalPosition());
93
93
94 m_vPosition = new QDoubleSpinBox();
94 m_vPosition = new QDoubleSpinBox();
95 m_vPosition->setMinimum(0.0);
95 m_vPosition->setMinimum(0.0);
96 m_vPosition->setMaximum(1.0);
96 m_vPosition->setMaximum(1.0);
97 m_vPosition->setSingleStep(0.1);
97 m_vPosition->setSingleStep(0.1);
98 m_vPosition->setValue(m_series->verticalPosition());
98 m_vPosition->setValue(m_series->verticalPosition());
99
99
100 m_sizeFactor = new QDoubleSpinBox();
100 m_sizeFactor = new QDoubleSpinBox();
101 m_sizeFactor->setMinimum(0.0);
101 m_sizeFactor->setMinimum(0.0);
102 m_sizeFactor->setMaximum(1.0);
102 m_sizeFactor->setMaximum(1.0);
103 m_sizeFactor->setSingleStep(0.1);
103 m_sizeFactor->setSingleStep(0.1);
104 m_sizeFactor->setValue(m_series->pieSize());
104 m_sizeFactor->setValue(m_series->pieSize());
105
105
106 m_startAngle = new QDoubleSpinBox();
106 m_startAngle = new QDoubleSpinBox();
107 m_startAngle->setMinimum(-720);
107 m_startAngle->setMinimum(-720);
108 m_startAngle->setMaximum(720);
108 m_startAngle->setMaximum(720);
109 m_startAngle->setValue(m_series->pieStartAngle());
109 m_startAngle->setValue(m_series->pieStartAngle());
110 m_startAngle->setSingleStep(1);
110 m_startAngle->setSingleStep(1);
111
111
112 m_endAngle = new QDoubleSpinBox();
112 m_endAngle = new QDoubleSpinBox();
113 m_endAngle->setMinimum(-720);
113 m_endAngle->setMinimum(-720);
114 m_endAngle->setMaximum(720);
114 m_endAngle->setMaximum(720);
115 m_endAngle->setValue(m_series->pieEndAngle());
115 m_endAngle->setValue(m_series->pieEndAngle());
116 m_endAngle->setSingleStep(1);
116 m_endAngle->setSingleStep(1);
117
117
118 m_isDonut = new QCheckBox();
118 m_holeSize = new QDoubleSpinBox();
119
119 m_holeSize->setMinimum(0.0);
120 m_donutInnerSize = new QDoubleSpinBox();
120 m_holeSize->setMaximum(1.0);
121 m_donutInnerSize->setMinimum(0.0);
121 m_holeSize->setSingleStep(0.1);
122 m_donutInnerSize->setMaximum(1.0);
122 m_holeSize->setValue(m_series->holeSize());
123 m_donutInnerSize->setSingleStep(0.1);
124 m_donutInnerSize->setValue(m_series->donutInnerSize());
125
123
126 QPushButton *appendSlice = new QPushButton("Append slice");
124 QPushButton *appendSlice = new QPushButton("Append slice");
127 QPushButton *insertSlice = new QPushButton("Insert slice");
125 QPushButton *insertSlice = new QPushButton("Insert slice");
128 QPushButton *removeSlice = new QPushButton("Remove selected slice");
126 QPushButton *removeSlice = new QPushButton("Remove selected slice");
129
127
130 QFormLayout* seriesSettingsLayout = new QFormLayout();
128 QFormLayout* seriesSettingsLayout = new QFormLayout();
131 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
129 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
132 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
130 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
133 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
131 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
134 seriesSettingsLayout->addRow("Start angle", m_startAngle);
132 seriesSettingsLayout->addRow("Start angle", m_startAngle);
135 seriesSettingsLayout->addRow("End angle", m_endAngle);
133 seriesSettingsLayout->addRow("End angle", m_endAngle);
136 seriesSettingsLayout->addRow("Is donut", m_isDonut);
134 seriesSettingsLayout->addRow("Hole size", m_holeSize);
137 seriesSettingsLayout->addRow("Donut inner size", m_donutInnerSize);
138 seriesSettingsLayout->addRow(appendSlice);
135 seriesSettingsLayout->addRow(appendSlice);
139 seriesSettingsLayout->addRow(insertSlice);
136 seriesSettingsLayout->addRow(insertSlice);
140 seriesSettingsLayout->addRow(removeSlice);
137 seriesSettingsLayout->addRow(removeSlice);
141 QGroupBox* seriesSettings = new QGroupBox("Series");
138 QGroupBox* seriesSettings = new QGroupBox("Series");
142 seriesSettings->setLayout(seriesSettingsLayout);
139 seriesSettings->setLayout(seriesSettingsLayout);
143
140
144 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
141 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
145 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
142 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
146 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
143 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
147 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
144 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
148 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
145 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
149 connect(m_isDonut, SIGNAL(toggled(bool)), this, SLOT(updateSerieSettings()));
146 connect(m_holeSize, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
150 connect(m_donutInnerSize, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
151 connect(appendSlice, SIGNAL(clicked()), this, SLOT(appendSlice()));
147 connect(appendSlice, SIGNAL(clicked()), this, SLOT(appendSlice()));
152 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
148 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
153 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
149 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
154
150
155 // slice settings
151 // slice settings
156 m_sliceName = new QLineEdit("<click a slice>");
152 m_sliceName = new QLineEdit("<click a slice>");
157 m_sliceName->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
153 m_sliceName->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
158 m_sliceValue = new QDoubleSpinBox();
154 m_sliceValue = new QDoubleSpinBox();
159 m_sliceValue->setMaximum(1000);
155 m_sliceValue->setMaximum(1000);
160 m_sliceLabelVisible = new QCheckBox();
156 m_sliceLabelVisible = new QCheckBox();
161 m_sliceLabelArmFactor = new QDoubleSpinBox();
157 m_sliceLabelArmFactor = new QDoubleSpinBox();
162 m_sliceLabelArmFactor->setSingleStep(0.01);
158 m_sliceLabelArmFactor->setSingleStep(0.01);
163 m_sliceExploded = new QCheckBox();
159 m_sliceExploded = new QCheckBox();
164 m_sliceExplodedFactor = new QDoubleSpinBox();
160 m_sliceExplodedFactor = new QDoubleSpinBox();
165 m_sliceExplodedFactor->setSingleStep(0.01);
161 m_sliceExplodedFactor->setSingleStep(0.01);
166 m_pen = new QPushButton();
162 m_pen = new QPushButton();
167 m_penTool = new PenTool("Slice pen", this);
163 m_penTool = new PenTool("Slice pen", this);
168 m_brush = new QPushButton();
164 m_brush = new QPushButton();
169 m_brushTool = new BrushTool("Slice brush", this);
165 m_brushTool = new BrushTool("Slice brush", this);
170 m_font = new QPushButton();
166 m_font = new QPushButton();
171 m_labelBrush = new QPushButton();
167 m_labelBrush = new QPushButton();
172 m_labelBrushTool = new BrushTool("Label brush", this);
168 m_labelBrushTool = new BrushTool("Label brush", this);
173 m_labelPosition = new QComboBox(this);
169 m_labelPosition = new QComboBox(this);
174 m_labelPosition->addItem("Outside", QPieSlice::LabelOutside);
170 m_labelPosition->addItem("Outside", QPieSlice::LabelOutside);
175 m_labelPosition->addItem("Inside horizontal", QPieSlice::LabelInsideHorizontal);
171 m_labelPosition->addItem("Inside horizontal", QPieSlice::LabelInsideHorizontal);
176 m_labelPosition->addItem("Inside tangential", QPieSlice::LabelInsideTangential);
172 m_labelPosition->addItem("Inside tangential", QPieSlice::LabelInsideTangential);
177 m_labelPosition->addItem("Inside normal", QPieSlice::LabelInsideNormal);
173 m_labelPosition->addItem("Inside normal", QPieSlice::LabelInsideNormal);
178
174
179 QFormLayout* sliceSettingsLayout = new QFormLayout();
175 QFormLayout* sliceSettingsLayout = new QFormLayout();
180 sliceSettingsLayout->addRow("Label", m_sliceName);
176 sliceSettingsLayout->addRow("Label", m_sliceName);
181 sliceSettingsLayout->addRow("Value", m_sliceValue);
177 sliceSettingsLayout->addRow("Value", m_sliceValue);
182 sliceSettingsLayout->addRow("Pen", m_pen);
178 sliceSettingsLayout->addRow("Pen", m_pen);
183 sliceSettingsLayout->addRow("Brush", m_brush);
179 sliceSettingsLayout->addRow("Brush", m_brush);
184 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
180 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
185 sliceSettingsLayout->addRow("Label font", m_font);
181 sliceSettingsLayout->addRow("Label font", m_font);
186 sliceSettingsLayout->addRow("Label brush", m_labelBrush);
182 sliceSettingsLayout->addRow("Label brush", m_labelBrush);
187 sliceSettingsLayout->addRow("Label position", m_labelPosition);
183 sliceSettingsLayout->addRow("Label position", m_labelPosition);
188 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
184 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
189 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
185 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
190 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
186 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
191 QGroupBox* sliceSettings = new QGroupBox("Selected slice");
187 QGroupBox* sliceSettings = new QGroupBox("Selected slice");
192 sliceSettings->setLayout(sliceSettingsLayout);
188 sliceSettings->setLayout(sliceSettingsLayout);
193
189
194 connect(m_sliceName, SIGNAL(textChanged(QString)), this, SLOT(updateSliceSettings()));
190 connect(m_sliceName, SIGNAL(textChanged(QString)), this, SLOT(updateSliceSettings()));
195 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
191 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
196 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
192 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
197 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
193 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
198 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
194 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
199 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
195 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
200 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
196 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
201 connect(m_labelBrush, SIGNAL(clicked()), m_labelBrushTool, SLOT(show()));
197 connect(m_labelBrush, SIGNAL(clicked()), m_labelBrushTool, SLOT(show()));
202 connect(m_labelBrushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
198 connect(m_labelBrushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
203 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
199 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
204 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
200 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
205 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
201 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
206 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
202 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
207 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
203 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
208 connect(m_labelPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSliceSettings()));
204 connect(m_labelPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSliceSettings()));
209
205
210 // create chart view
206 // create chart view
211 m_chartView = new QChartView(chart);
207 m_chartView = new QChartView(chart);
212
208
213 // create main layout
209 // create main layout
214 QVBoxLayout *settingsLayout = new QVBoxLayout();
210 QVBoxLayout *settingsLayout = new QVBoxLayout();
215 settingsLayout->addWidget(chartSettings);
211 settingsLayout->addWidget(chartSettings);
216 settingsLayout->addWidget(seriesSettings);
212 settingsLayout->addWidget(seriesSettings);
217 settingsLayout->addWidget(sliceSettings);
213 settingsLayout->addWidget(sliceSettings);
218 settingsLayout->addStretch();
214 settingsLayout->addStretch();
219
215
220 QGridLayout* baseLayout = new QGridLayout();
216 QGridLayout* baseLayout = new QGridLayout();
221 baseLayout->addLayout(settingsLayout, 0, 0);
217 baseLayout->addLayout(settingsLayout, 0, 0);
222 baseLayout->addWidget(m_chartView, 0, 1);
218 baseLayout->addWidget(m_chartView, 0, 1);
223 setLayout(baseLayout);
219 setLayout(baseLayout);
224
220
225 updateSerieSettings();
221 updateSerieSettings();
226 updateChartSettings();
222 updateChartSettings();
227 }
223 }
228
224
229
225
230 void MainWidget::updateChartSettings()
226 void MainWidget::updateChartSettings()
231 {
227 {
232 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
228 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
233 m_chartView->chart()->setTheme(theme);
229 m_chartView->chart()->setTheme(theme);
234 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
230 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
235
231
236 if (m_animationsCheckBox->checkState() == Qt::Checked)
232 if (m_animationsCheckBox->checkState() == Qt::Checked)
237 m_chartView->chart()->setAnimationOptions(QChart::AllAnimations);
233 m_chartView->chart()->setAnimationOptions(QChart::AllAnimations);
238 else
234 else
239 m_chartView->chart()->setAnimationOptions(QChart::NoAnimation);
235 m_chartView->chart()->setAnimationOptions(QChart::NoAnimation);
240
236
241 if (m_legendCheckBox->checkState() == Qt::Checked)
237 if (m_legendCheckBox->checkState() == Qt::Checked)
242 m_chartView->chart()->legend()->show();
238 m_chartView->chart()->legend()->show();
243 else
239 else
244 m_chartView->chart()->legend()->hide();
240 m_chartView->chart()->legend()->hide();
245 }
241 }
246
242
247 void MainWidget::updateSerieSettings()
243 void MainWidget::updateSerieSettings()
248 {
244 {
249 m_series->setHorizontalPosition(m_hPosition->value());
245 m_series->setHorizontalPosition(m_hPosition->value());
250 m_series->setVerticalPosition(m_vPosition->value());
246 m_series->setVerticalPosition(m_vPosition->value());
251 m_series->setPieSize(m_sizeFactor->value());
247 m_series->setPieSize(m_sizeFactor->value());
248 m_holeSize->setMaximum(m_sizeFactor->value());
252 m_series->setPieStartAngle(m_startAngle->value());
249 m_series->setPieStartAngle(m_startAngle->value());
253 m_series->setPieEndAngle(m_endAngle->value());
250 m_series->setPieEndAngle(m_endAngle->value());
254 m_series->setDonut(m_isDonut->isChecked());
251 m_series->setHoleSize(m_holeSize->value());
255 m_series->setDonutInnerSize(m_donutInnerSize->value());
256 }
252 }
257
253
258 void MainWidget::updateSliceSettings()
254 void MainWidget::updateSliceSettings()
259 {
255 {
260 if (!m_slice)
256 if (!m_slice)
261 return;
257 return;
262
258
263 m_slice->setLabel(m_sliceName->text());
259 m_slice->setLabel(m_sliceName->text());
264
260
265 m_slice->setValue(m_sliceValue->value());
261 m_slice->setValue(m_sliceValue->value());
266
262
267 m_slice->setPen(m_penTool->pen());
263 m_slice->setPen(m_penTool->pen());
268 m_slice->setBrush(m_brushTool->brush());
264 m_slice->setBrush(m_brushTool->brush());
269
265
270 m_slice->setLabelBrush(m_labelBrushTool->brush());
266 m_slice->setLabelBrush(m_labelBrushTool->brush());
271 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
267 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
272 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
268 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
273 m_slice->setLabelPosition((QPieSlice::LabelPosition)m_labelPosition->currentIndex()); // assumes that index is in sync with the enum
269 m_slice->setLabelPosition((QPieSlice::LabelPosition)m_labelPosition->currentIndex()); // assumes that index is in sync with the enum
274
270
275 m_slice->setExploded(m_sliceExploded->isChecked());
271 m_slice->setExploded(m_sliceExploded->isChecked());
276 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
272 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
277 }
273 }
278
274
279 void MainWidget::handleSliceClicked(QPieSlice* slice)
275 void MainWidget::handleSliceClicked(QPieSlice* slice)
280 {
276 {
281 m_slice = static_cast<CustomSlice*>(slice);
277 m_slice = static_cast<CustomSlice*>(slice);
282
278
283 // name
279 // name
284 m_sliceName->blockSignals(true);
280 m_sliceName->blockSignals(true);
285 m_sliceName->setText(slice->label());
281 m_sliceName->setText(slice->label());
286 m_sliceName->blockSignals(false);
282 m_sliceName->blockSignals(false);
287
283
288 // value
284 // value
289 m_sliceValue->blockSignals(true);
285 m_sliceValue->blockSignals(true);
290 m_sliceValue->setValue(slice->value());
286 m_sliceValue->setValue(slice->value());
291 m_sliceValue->blockSignals(false);
287 m_sliceValue->blockSignals(false);
292
288
293 // pen
289 // pen
294 m_pen->setText(PenTool::name(m_slice->pen()));
290 m_pen->setText(PenTool::name(m_slice->pen()));
295 m_penTool->setPen(m_slice->pen());
291 m_penTool->setPen(m_slice->pen());
296
292
297 // brush
293 // brush
298 m_brush->setText(m_slice->originalBrush().color().name());
294 m_brush->setText(m_slice->originalBrush().color().name());
299 m_brushTool->setBrush(m_slice->originalBrush());
295 m_brushTool->setBrush(m_slice->originalBrush());
300
296
301 // label
297 // label
302 m_labelBrush->setText(BrushTool::name(m_slice->labelBrush()));
298 m_labelBrush->setText(BrushTool::name(m_slice->labelBrush()));
303 m_labelBrushTool->setBrush(m_slice->labelBrush());
299 m_labelBrushTool->setBrush(m_slice->labelBrush());
304 m_font->setText(slice->labelFont().toString());
300 m_font->setText(slice->labelFont().toString());
305 m_sliceLabelVisible->blockSignals(true);
301 m_sliceLabelVisible->blockSignals(true);
306 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
302 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
307 m_sliceLabelVisible->blockSignals(false);
303 m_sliceLabelVisible->blockSignals(false);
308 m_sliceLabelArmFactor->blockSignals(true);
304 m_sliceLabelArmFactor->blockSignals(true);
309 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
305 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
310 m_sliceLabelArmFactor->blockSignals(false);
306 m_sliceLabelArmFactor->blockSignals(false);
311 m_labelPosition->blockSignals(true);
307 m_labelPosition->blockSignals(true);
312 m_labelPosition->setCurrentIndex(slice->labelPosition()); // assumes that index is in sync with the enum
308 m_labelPosition->setCurrentIndex(slice->labelPosition()); // assumes that index is in sync with the enum
313 m_labelPosition->blockSignals(false);
309 m_labelPosition->blockSignals(false);
314
310
315 // exploded
311 // exploded
316 m_sliceExploded->blockSignals(true);
312 m_sliceExploded->blockSignals(true);
317 m_sliceExploded->setChecked(slice->isExploded());
313 m_sliceExploded->setChecked(slice->isExploded());
318 m_sliceExploded->blockSignals(false);
314 m_sliceExploded->blockSignals(false);
319 m_sliceExplodedFactor->blockSignals(true);
315 m_sliceExplodedFactor->blockSignals(true);
320 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
316 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
321 m_sliceExplodedFactor->blockSignals(false);
317 m_sliceExplodedFactor->blockSignals(false);
322 }
318 }
323
319
324 void MainWidget::showFontDialog()
320 void MainWidget::showFontDialog()
325 {
321 {
326 if (!m_slice)
322 if (!m_slice)
327 return;
323 return;
328
324
329 QFontDialog dialog(m_slice->labelFont());
325 QFontDialog dialog(m_slice->labelFont());
330 dialog.show();
326 dialog.show();
331 dialog.exec();
327 dialog.exec();
332
328
333 m_slice->setLabelFont(dialog.currentFont());
329 m_slice->setLabelFont(dialog.currentFont());
334 m_font->setText(dialog.currentFont().toString());
330 m_font->setText(dialog.currentFont().toString());
335 }
331 }
336
332
337 void MainWidget::appendSlice()
333 void MainWidget::appendSlice()
338 {
334 {
339 *m_series << new CustomSlice("Slice " + QString::number(m_series->count()+1), 10.0);
335 *m_series << new CustomSlice("Slice " + QString::number(m_series->count()+1), 10.0);
340 }
336 }
341
337
342 void MainWidget::insertSlice()
338 void MainWidget::insertSlice()
343 {
339 {
344 if (!m_slice)
340 if (!m_slice)
345 return;
341 return;
346
342
347 int i = m_series->slices().indexOf(m_slice);
343 int i = m_series->slices().indexOf(m_slice);
348
344
349 m_series->insert(i, new CustomSlice("Slice " + QString::number(m_series->count()+1), 10.0));
345 m_series->insert(i, new CustomSlice("Slice " + QString::number(m_series->count()+1), 10.0));
350 }
346 }
351
347
352 void MainWidget::removeSlice()
348 void MainWidget::removeSlice()
353 {
349 {
354 if (!m_slice)
350 if (!m_slice)
355 return;
351 return;
356
352
357 m_sliceName->setText("<click a slice>");
353 m_sliceName->setText("<click a slice>");
358
354
359 m_series->remove(m_slice);
355 m_series->remove(m_slice);
360 m_slice = 0;
356 m_slice = 0;
361 }
357 }
362
358
363 #include "moc_mainwidget.cpp"
359 #include "moc_mainwidget.cpp"
@@ -1,94 +1,93
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20 #ifndef MAINWIDGET_H
20 #ifndef MAINWIDGET_H
21 #define MAINWIDGET_H
21 #define MAINWIDGET_H
22
22
23 #include <QWidget>
23 #include <QWidget>
24 #include <QChartGlobal>
24 #include <QChartGlobal>
25
25
26 class QLineEdit;
26 class QLineEdit;
27 class QPushButton;
27 class QPushButton;
28 class QCheckBox;
28 class QCheckBox;
29 class QComboBox;
29 class QComboBox;
30 class QDoubleSpinBox;
30 class QDoubleSpinBox;
31 class PenTool;
31 class PenTool;
32 class BrushTool;
32 class BrushTool;
33 class CustomSlice;
33 class CustomSlice;
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 class QChartView;
36 class QChartView;
37 class QPieSeries;
37 class QPieSeries;
38 class QPieSlice;
38 class QPieSlice;
39 QTCOMMERCIALCHART_END_NAMESPACE
39 QTCOMMERCIALCHART_END_NAMESPACE
40
40
41 QTCOMMERCIALCHART_USE_NAMESPACE
41 QTCOMMERCIALCHART_USE_NAMESPACE
42
42
43 class MainWidget : public QWidget
43 class MainWidget : public QWidget
44 {
44 {
45 Q_OBJECT
45 Q_OBJECT
46
46
47 public:
47 public:
48 explicit MainWidget(QWidget* parent = 0);
48 explicit MainWidget(QWidget* parent = 0);
49
49
50 public Q_SLOTS:
50 public Q_SLOTS:
51 void updateChartSettings();
51 void updateChartSettings();
52 void updateSerieSettings();
52 void updateSerieSettings();
53 void updateSliceSettings();
53 void updateSliceSettings();
54 void handleSliceClicked(QPieSlice* slice);
54 void handleSliceClicked(QPieSlice* slice);
55 void showFontDialog();
55 void showFontDialog();
56 void appendSlice();
56 void appendSlice();
57 void insertSlice();
57 void insertSlice();
58 void removeSlice();
58 void removeSlice();
59
59
60 private:
60 private:
61 QComboBox *m_themeComboBox;
61 QComboBox *m_themeComboBox;
62 QCheckBox *m_aaCheckBox;
62 QCheckBox *m_aaCheckBox;
63 QCheckBox *m_animationsCheckBox;
63 QCheckBox *m_animationsCheckBox;
64 QCheckBox *m_legendCheckBox;
64 QCheckBox *m_legendCheckBox;
65
65
66 QChartView* m_chartView;
66 QChartView* m_chartView;
67 QPieSeries* m_series;
67 QPieSeries* m_series;
68 CustomSlice* m_slice;
68 CustomSlice* m_slice;
69
69
70 QDoubleSpinBox* m_hPosition;
70 QDoubleSpinBox* m_hPosition;
71 QDoubleSpinBox* m_vPosition;
71 QDoubleSpinBox* m_vPosition;
72 QDoubleSpinBox* m_sizeFactor;
72 QDoubleSpinBox* m_sizeFactor;
73 QDoubleSpinBox* m_startAngle;
73 QDoubleSpinBox* m_startAngle;
74 QDoubleSpinBox* m_endAngle;
74 QDoubleSpinBox* m_endAngle;
75 QCheckBox* m_isDonut;
75 QDoubleSpinBox* m_holeSize;
76 QDoubleSpinBox* m_donutInnerSize;
77
76
78 QLineEdit* m_sliceName;
77 QLineEdit* m_sliceName;
79 QDoubleSpinBox* m_sliceValue;
78 QDoubleSpinBox* m_sliceValue;
80 QCheckBox* m_sliceLabelVisible;
79 QCheckBox* m_sliceLabelVisible;
81 QDoubleSpinBox* m_sliceLabelArmFactor;
80 QDoubleSpinBox* m_sliceLabelArmFactor;
82 QCheckBox* m_sliceExploded;
81 QCheckBox* m_sliceExploded;
83 QDoubleSpinBox* m_sliceExplodedFactor;
82 QDoubleSpinBox* m_sliceExplodedFactor;
84 QPushButton *m_brush;
83 QPushButton *m_brush;
85 BrushTool *m_brushTool;
84 BrushTool *m_brushTool;
86 QPushButton *m_pen;
85 QPushButton *m_pen;
87 PenTool *m_penTool;
86 PenTool *m_penTool;
88 QPushButton *m_font;
87 QPushButton *m_font;
89 QPushButton *m_labelBrush;
88 QPushButton *m_labelBrush;
90 QComboBox *m_labelPosition;
89 QComboBox *m_labelPosition;
91 BrushTool *m_labelBrushTool;
90 BrushTool *m_labelBrushTool;
92 };
91 };
93
92
94 #endif // MAINWIDGET_H
93 #endif // MAINWIDGET_H
@@ -1,105 +1,108
1 #include "widget.h"
1 #include "widget.h"
2 #include <QChartView>
2 #include <QChartView>
3 #include <QChart>
4 #include <QLegend>
3 #include <QPieSeries>
5 #include <QPieSeries>
4 #include <QPieSlice>
6 #include <QPieSlice>
5 #include <QTime>
7 #include <QTime>
6 #include <QGridLayout>
8 #include <QGridLayout>
7 #include <QTimer>
9 #include <QTimer>
8
10
9 QTCOMMERCIALCHART_USE_NAMESPACE
11 QTCOMMERCIALCHART_USE_NAMESPACE
10
12
11 Widget::Widget(QWidget *parent)
13 Widget::Widget(QWidget *parent)
12 : QWidget(parent)
14 : QWidget(parent)
13 {
15 {
14 setMinimumSize(800, 600);
16 setMinimumSize(800, 600);
15 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
17 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
16
18
17 //! [1]
19 //! [1]
18 QChartView *chartView = new QChartView;
20 QChartView *chartView = new QChartView;
19 chartView->setRenderHint(QPainter::Antialiasing);
21 chartView->setRenderHint(QPainter::Antialiasing);
20 chartView->chart()->setAnimationOptions(QChart::AllAnimations);
22 QChart *chart = chartView->chart();
23 chart->setAnimationOptions(QChart::AllAnimations);
24 chart->legend()->setVisible(false);
21 //! [1]
25 //! [1]
22
26
23 //! [2]
27 //! [2]
24 qreal minSize = 0.1;
28 qreal minSize = 0.1;
25 qreal maxSize = 0.9;
29 qreal maxSize = 0.9;
26 int donutsCount = 5;
30 int donutCount = 5;
27 //! [2]
31 //! [2]
28
32
29 //! [3]
33 //! [3]
30 for (int i = 0; i < donutsCount; i++) {
34 for (int i = 0; i < donutCount; i++) {
31 QPieSeries *donut = new QPieSeries;
35 QPieSeries *donut = new QPieSeries;
32 donut->setDonut();
33 int sliceCount = 3 + qrand() % 3;
36 int sliceCount = 3 + qrand() % 3;
34 for (int j = 0; j < sliceCount; j++) {
37 for (int j = 0; j < sliceCount; j++) {
35 qreal value = 100 + qrand() % 100;
38 qreal value = 100 + qrand() % 100;
36 QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
39 QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
37 slice->setLabelVisible(true);
40 slice->setLabelVisible(true);
38 slice->setLabelColor(Qt::white);
41 slice->setLabelColor(Qt::white);
39 slice->setLabelPosition(QPieSlice::LabelInsideTangential);
42 slice->setLabelPosition(QPieSlice::LabelInsideTangential);
40 connect(slice, SIGNAL(hovered(bool)), this, SLOT(explodeSlice(bool)));
43 connect(slice, SIGNAL(hovered(bool)), this, SLOT(explodeSlice(bool)));
41 donut->append(slice);
44 donut->append(slice);
42 donut->setDonutInnerSize(minSize + i * (maxSize - minSize) / donutsCount);
45 donut->setHoleSize(minSize + i * (maxSize - minSize) / donutCount);
43 donut->setPieSize(minSize + (i + 1) * (maxSize - minSize) / donutsCount);
46 donut->setPieSize(minSize + (i + 1) * (maxSize - minSize) / donutCount);
44 }
47 }
45 m_donuts.append(donut);
48 m_donuts.append(donut);
46 chartView->chart()->addSeries(donut);
49 chartView->chart()->addSeries(donut);
47 }
50 }
48 //! [3]
51 //! [3]
49
52
50 // create main layout
53 // create main layout
51 //! [4]
54 //! [4]
52 QGridLayout* mainLayout = new QGridLayout;
55 QGridLayout* mainLayout = new QGridLayout;
53 mainLayout->addWidget(chartView, 1, 1);
56 mainLayout->addWidget(chartView, 1, 1);
54 setLayout(mainLayout);
57 setLayout(mainLayout);
55 //! [4]
58 //! [4]
56
59
57 //! [5]
60 //! [5]
58 updateTimer = new QTimer(this);
61 updateTimer = new QTimer(this);
59 connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateRotation()));
62 connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateRotation()));
60 updateTimer->start(1250);
63 updateTimer->start(1250);
61 //! [5]
64 //! [5]
62 }
65 }
63
66
64 Widget::~Widget()
67 Widget::~Widget()
65 {
68 {
66
69
67 }
70 }
68
71
69 //! [6]
72 //! [6]
70 void Widget::updateRotation()
73 void Widget::updateRotation()
71 {
74 {
72 for (int i = 0; i < m_donuts.count(); i++) {
75 for (int i = 0; i < m_donuts.count(); i++) {
73 QPieSeries *donut = m_donuts.at(i);
76 QPieSeries *donut = m_donuts.at(i);
74 qreal phaseShift = -50 + qrand() % 100;
77 qreal phaseShift = -50 + qrand() % 100;
75 donut->setPieStartAngle(donut->pieStartAngle() + phaseShift);
78 donut->setPieStartAngle(donut->pieStartAngle() + phaseShift);
76 donut->setPieEndAngle(donut->pieEndAngle() + phaseShift);
79 donut->setPieEndAngle(donut->pieEndAngle() + phaseShift);
77 }
80 }
78 }
81 }
79 //! [6]
82 //! [6]
80
83
81 //! [7]
84 //! [7]
82 void Widget::explodeSlice(bool exploded)
85 void Widget::explodeSlice(bool exploded)
83 {
86 {
84 QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
87 QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
85 if (exploded) {
88 if (exploded) {
86 updateTimer->stop();
89 updateTimer->stop();
87 qreal sliceStartAngle = slice->startAngle();
90 qreal sliceStartAngle = slice->startAngle();
88 qreal sliceEndAngle = slice->startAngle() + slice->angleSpan();
91 qreal sliceEndAngle = slice->startAngle() + slice->angleSpan();
89
92
90 QPieSeries *donut = slice->series();
93 QPieSeries *donut = slice->series();
91 qreal seriesIndex = m_donuts.indexOf(donut);
94 qreal seriesIndex = m_donuts.indexOf(donut);
92 for (int i = seriesIndex + 1; i < m_donuts.count(); i++) {
95 for (int i = seriesIndex + 1; i < m_donuts.count(); i++) {
93 m_donuts.at(i)->setPieStartAngle(sliceEndAngle);
96 m_donuts.at(i)->setPieStartAngle(sliceEndAngle);
94 m_donuts.at(i)->setPieEndAngle(360 + sliceStartAngle);
97 m_donuts.at(i)->setPieEndAngle(360 + sliceStartAngle);
95 }
98 }
96 } else {
99 } else {
97 for (int i = 0; i < m_donuts.count(); i++) {
100 for (int i = 0; i < m_donuts.count(); i++) {
98 m_donuts.at(i)->setPieStartAngle(0);
101 m_donuts.at(i)->setPieStartAngle(0);
99 m_donuts.at(i)->setPieEndAngle(360);
102 m_donuts.at(i)->setPieEndAngle(360);
100 }
103 }
101 updateTimer->start();
104 updateTimer->start();
102 }
105 }
103 slice->setExploded(exploded);
106 slice->setExploded(exploded);
104 }
107 }
105 //! [7]
108 //! [7]
@@ -1,136 +1,138
1 #include "widget.h"
1 #include "widget.h"
2 #include <QGridLayout>
2 #include <QGridLayout>
3
4 #include <QPieSlice>
3 #include <QPieSlice>
5 #include <QTime>
4 #include <QTime>
6 #include <QChartView>
5 #include <QChartView>
6 #include <QChart>
7 #include <QLegend>
7 #include <QTimer>
8 #include <QTimer>
8
9
9 QTCOMMERCIALCHART_USE_NAMESPACE
10 QTCOMMERCIALCHART_USE_NAMESPACE
10
11
11 Widget::Widget(QWidget *parent)
12 Widget::Widget(QWidget *parent)
12 : QWidget(parent),
13 : QWidget(parent),
13 mainData(0)
14 mainData(0)
14 {
15 {
15 setMinimumSize(800, 600);
16 setMinimumSize(800, 600);
16 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
17 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
17
18
18 //! [1]
19 //! [1]
19 QChartView *chartView = new QChartView;
20 QChartView *chartView = new QChartView;
20 chartView->setRenderHint(QPainter::Antialiasing);
21 chartView->setRenderHint(QPainter::Antialiasing);
21 chartView->chart()->setAnimationOptions(QChart::AllAnimations);
22 QChart *chart = chartView->chart();
23 chart->setAnimationOptions(QChart::AllAnimations);
24 chart->legend()->setVisible(false);
22 //! [1]
25 //! [1]
23
26
24 //! [2]
27 //! [2]
25 mainData = new QPieSeries;
28 mainData = new QPieSeries;
26 mainData->setPieSize(0.6);
29 mainData->setPieSize(0.6);
27 //! [2]
30 //! [2]
28
31
29 //! [3]
32 //! [3]
30 for (int j = 0; j < 4; j++) {
33 for (int j = 0; j < 4; j++) {
31 // create new slice for the mainData
34 // create new slice for the mainData
32 QPieSlice *slice = new QPieSlice;
35 QPieSlice *slice = new QPieSlice;
33 slice->setLabelColor(Qt::white);
36 slice->setLabelColor(Qt::white);
34 mainData->append(slice);
37 mainData->append(slice);
35
38
36 // create a new detailed data for the slice
39 // create a new detailed data for the slice
37 QPieSeries *donut = new QPieSeries;
40 QPieSeries *donut = new QPieSeries;
38 donut->setDonut();
41 donut->setHoleSize(mainData->pieSize());
39 donut->setDonutInnerSize(mainData->pieSize());
40 donut->setPieSize(mainData->pieSize() + 0.15);
42 donut->setPieSize(mainData->pieSize() + 0.15);
41
43
42 // when mainData slice is redrawn make sure the detailed data slices are aligned with it
44 // when mainData slice is redrawn make sure the detailed data slices are aligned with it
43 connect(slice, SIGNAL(startAngleChanged()), this, SLOT(updatedStartAngle()));
45 connect(slice, SIGNAL(startAngleChanged()), this, SLOT(updatedStartAngle()));
44 connect(slice, SIGNAL(angleSpanChanged()), this, SLOT(updatedAngleSpan()));
46 connect(slice, SIGNAL(angleSpanChanged()), this, SLOT(updatedAngleSpan()));
45
47
46 // create the detailed data
48 // create the detailed data
47 for (int j = 0; j < 3; j++) {
49 for (int j = 0; j < 3; j++) {
48 qreal value = 10 + qrand() % 100;
50 qreal value = 10 + qrand() % 100;
49 QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
51 QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
50 donut->append(slice);
52 donut->append(slice);
51 }
53 }
52 donut->setLabelsPosition(QPieSlice::LabelOutside);
54 donut->setLabelsPosition(QPieSlice::LabelOutside);
53 donut->setLabelsVisible();
55 donut->setLabelsVisible();
54 detailedData.append(donut);
56 detailedData.append(donut);
55
57
56 // update the value and label of mainData
58 // update the value and label of mainData
57 slice->setValue(donut->sum());
59 slice->setValue(donut->sum());
58 slice->setLabel(QString("%1").arg(donut->sum()));
60 slice->setLabel(QString("%1").arg(donut->sum()));
59 }
61 }
60 //! [3]
62 //! [3]
61
63
62 //! [4]
64 //! [4]
63 mainData->setLabelsVisible();
65 mainData->setLabelsVisible();
64 mainData->setLabelsPosition(QPieSlice::LabelInsideHorizontal);
66 mainData->setLabelsPosition(QPieSlice::LabelInsideHorizontal);
65 chartView->chart()->addSeries(mainData);
67 chartView->chart()->addSeries(mainData);
66 for (int i = 0; i < detailedData.count(); i++)
68 for (int i = 0; i < detailedData.count(); i++)
67 chartView->chart()->addSeries(detailedData.at(i));
69 chartView->chart()->addSeries(detailedData.at(i));
68 //! [4]
70 //! [4]
69
71
70 //! [5]
72 //! [5]
71 // create main layout
73 // create main layout
72 QGridLayout* mainLayout = new QGridLayout;
74 QGridLayout* mainLayout = new QGridLayout;
73 mainLayout->addWidget(chartView, 1, 1);
75 mainLayout->addWidget(chartView, 1, 1);
74 setLayout(mainLayout);
76 setLayout(mainLayout);
75 //! [5]
77 //! [5]
76
78
77 //! [6]
79 //! [6]
78 // modify the value of one detailed slice every 2.5 sec
80 // modify the value of one detailed slice every 2.5 sec
79 QTimer *updateTimer = new QTimer(this);
81 QTimer *updateTimer = new QTimer(this);
80 connect(updateTimer, SIGNAL(timeout()), this, SLOT(highlight()));
82 connect(updateTimer, SIGNAL(timeout()), this, SLOT(highlight()));
81 updateTimer->start(2500);
83 updateTimer->start(2500);
82 //! [6]
84 //! [6]
83 }
85 }
84
86
85 Widget::~Widget()
87 Widget::~Widget()
86 {
88 {
87
89
88 }
90 }
89
91
90 //! [7]
92 //! [7]
91 void Widget::updatedStartAngle()
93 void Widget::updatedStartAngle()
92 {
94 {
93 // when the mainData slice has been updated the detailed data QPieSeries object as well
95 // when the mainData slice has been updated the detailed data QPieSeries object as well
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
96 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
95 QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice));
97 QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice));
96 detailsDonut->setPieStartAngle(slice->startAngle());
98 detailsDonut->setPieStartAngle(slice->startAngle());
97 }
99 }
98
100
99 void Widget::updatedAngleSpan()
101 void Widget::updatedAngleSpan()
100 {
102 {
101 // when the mainData slice has been updated the detailed data QPieSeries object as well
103 // when the mainData slice has been updated the detailed data QPieSeries object as well
102 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
104 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
103 QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice));
105 QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice));
104 detailsDonut->setPieEndAngle(slice->startAngle() + slice->angleSpan());
106 detailsDonut->setPieEndAngle(slice->startAngle() + slice->angleSpan());
105 }
107 }
106 //! [7]
108 //! [7]
107
109
108 //! [8]
110 //! [8]
109 void Widget::highlight()
111 void Widget::highlight()
110 {
112 {
111 // choose one random detailed data slice to be updated.
113 // choose one random detailed data slice to be updated.
112 detailIndex = qrand() % mainData->count();
114 detailIndex = qrand() % mainData->count();
113 sliceIndex = qrand() % detailedData.at(detailIndex)->count();
115 sliceIndex = qrand() % detailedData.at(detailIndex)->count();
114
116
115 // set the slice to exploded to make the change easier to observe
117 // set the slice to exploded to make the change easier to observe
116 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded();
118 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded();
117
119
118 // give the user time to focus on the slice that will be changed
120 // give the user time to focus on the slice that will be changed
119 QTimer::singleShot(1000, this, SLOT(updateRotation()));
121 QTimer::singleShot(1000, this, SLOT(updateRotation()));
120 }
122 }
121
123
122 void Widget::updateRotation()
124 void Widget::updateRotation()
123 {
125 {
124 // update the selected slice
126 // update the selected slice
125 qreal newValue = 10 + qrand() % 100;
127 qreal newValue = 10 + qrand() % 100;
126 detailedData.at(detailIndex)->slices().at(sliceIndex)->setValue(newValue);
128 detailedData.at(detailIndex)->slices().at(sliceIndex)->setValue(newValue);
127 detailedData.at(detailIndex)->slices().at(sliceIndex)->setLabel(QString("%1").arg(newValue));
129 detailedData.at(detailIndex)->slices().at(sliceIndex)->setLabel(QString("%1").arg(newValue));
128
130
129 // update the mainData slice with a new sum of the detailed data values
131 // update the mainData slice with a new sum of the detailed data values
130 mainData->slices().at(detailIndex)->setValue(detailedData.at(detailIndex)->sum());
132 mainData->slices().at(detailIndex)->setValue(detailedData.at(detailIndex)->sum());
131 mainData->slices().at(detailIndex)->setLabel(QString("%1").arg(detailedData.at(detailIndex)->sum()));
133 mainData->slices().at(detailIndex)->setLabel(QString("%1").arg(detailedData.at(detailIndex)->sum()));
132
134
133 // change the explode state of the selected slice back to normal
135 // change the explode state of the selected slice back to normal
134 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded(false);
136 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded(false);
135 }
137 }
136 //! [8]
138 //! [8]
@@ -1,107 +1,107
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "pieanimation_p.h"
21 #include "pieanimation_p.h"
22 #include "piesliceanimation_p.h"
22 #include "piesliceanimation_p.h"
23 #include "piechartitem_p.h"
23 #include "piechartitem_p.h"
24 #include <QTimer>
24 #include <QTimer>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 PieAnimation::PieAnimation(PieChartItem *item)
28 PieAnimation::PieAnimation(PieChartItem *item)
29 :ChartAnimation(item),
29 :ChartAnimation(item),
30 m_item(item)
30 m_item(item)
31 {
31 {
32 }
32 }
33
33
34 PieAnimation::~PieAnimation()
34 PieAnimation::~PieAnimation()
35 {
35 {
36 }
36 }
37
37
38 ChartAnimation* PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
38 ChartAnimation* PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
39 {
39 {
40 PieSliceAnimation *animation = m_animations.value(sliceItem);
40 PieSliceAnimation *animation = m_animations.value(sliceItem);
41 Q_ASSERT(animation);
41 Q_ASSERT(animation);
42 animation->stop();
42 animation->stop();
43
43
44 animation->updateValue(sliceData);
44 animation->updateValue(sliceData);
45 animation->setDuration(ChartAnimationDuration);
45 animation->setDuration(ChartAnimationDuration);
46 animation->setEasingCurve(QEasingCurve::OutQuart);
46 animation->setEasingCurve(QEasingCurve::OutQuart);
47
47
48 return animation;
48 return animation;
49 }
49 }
50
50
51 ChartAnimation* PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
51 ChartAnimation* PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
52 {
52 {
53 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
53 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
54 m_animations.insert(sliceItem, animation);
54 m_animations.insert(sliceItem, animation);
55
55
56 PieSliceData startValue = sliceData;
56 PieSliceData startValue = sliceData;
57 startValue.m_radius = 0;
57 startValue.m_radius = 0;
58 if (startupAnimation)
58 if (startupAnimation)
59 startValue.m_startAngle = 0;
59 startValue.m_startAngle = 0;
60 else
60 else
61 startValue.m_startAngle = sliceData.m_startAngle + (sliceData.m_angleSpan / 2);
61 startValue.m_startAngle = sliceData.m_startAngle + (sliceData.m_angleSpan / 2);
62 startValue.m_angleSpan = 0;
62 startValue.m_angleSpan = 0;
63
63
64 if (sliceData.m_donut)
64 if (sliceData.m_holeRadius > 0)
65 startValue.m_radius = sliceData.m_innerRadius;
65 startValue.m_radius = sliceData.m_holeRadius;
66
66
67 animation->setValue(startValue, sliceData);
67 animation->setValue(startValue, sliceData);
68 animation->setDuration(ChartAnimationDuration);
68 animation->setDuration(ChartAnimationDuration);
69 animation->setEasingCurve(QEasingCurve::OutQuart);
69 animation->setEasingCurve(QEasingCurve::OutQuart);
70
70
71 return animation;
71 return animation;
72 }
72 }
73
73
74 ChartAnimation* PieAnimation::removeSlice(PieSliceItem *sliceItem)
74 ChartAnimation* PieAnimation::removeSlice(PieSliceItem *sliceItem)
75 {
75 {
76 PieSliceAnimation *animation = m_animations.value(sliceItem);
76 PieSliceAnimation *animation = m_animations.value(sliceItem);
77 Q_ASSERT(animation);
77 Q_ASSERT(animation);
78 animation->stop();
78 animation->stop();
79
79
80 PieSliceData endValue = animation->currentSliceValue();
80 PieSliceData endValue = animation->currentSliceValue();
81 if (endValue.m_donut)
81 if (endValue.m_holeRadius > 0)
82 endValue.m_radius = endValue.m_innerRadius;
82 endValue.m_radius = endValue.m_holeRadius;
83 else
83 else
84 endValue.m_radius = 0;
84 endValue.m_radius = 0;
85 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
85 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
86 endValue.m_angleSpan = 0;
86 endValue.m_angleSpan = 0;
87 endValue.m_isLabelVisible = false;
87 endValue.m_isLabelVisible = false;
88
88
89 animation->updateValue(endValue);
89 animation->updateValue(endValue);
90 animation->setDuration(ChartAnimationDuration);
90 animation->setDuration(ChartAnimationDuration);
91 animation->setEasingCurve(QEasingCurve::OutQuart);
91 animation->setEasingCurve(QEasingCurve::OutQuart);
92
92
93 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
93 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
94 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
94 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
95 m_animations.remove(sliceItem);
95 m_animations.remove(sliceItem);
96
96
97 return animation;
97 return animation;
98 }
98 }
99
99
100 void PieAnimation::updateCurrentValue(const QVariant &)
100 void PieAnimation::updateCurrentValue(const QVariant &)
101 {
101 {
102 // nothing to do...
102 // nothing to do...
103 }
103 }
104
104
105 #include "moc_pieanimation_p.cpp"
105 #include "moc_pieanimation_p.cpp"
106
106
107 QTCOMMERCIALCHART_END_NAMESPACE
107 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,126 +1,126
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "piesliceanimation_p.h"
21 #include "piesliceanimation_p.h"
22 #include "piechartitem_p.h"
22 #include "piechartitem_p.h"
23
23
24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 qreal linearPos(qreal start, qreal end, qreal pos)
28 qreal linearPos(qreal start, qreal end, qreal pos)
29 {
29 {
30 return start + ((end - start) * pos);
30 return start + ((end - start) * pos);
31 }
31 }
32
32
33 QPointF linearPos(QPointF start, QPointF end, qreal pos)
33 QPointF linearPos(QPointF start, QPointF end, qreal pos)
34 {
34 {
35 qreal x = linearPos(start.x(), end.x(), pos);
35 qreal x = linearPos(start.x(), end.x(), pos);
36 qreal y = linearPos(start.y(), end.y(), pos);
36 qreal y = linearPos(start.y(), end.y(), pos);
37 return QPointF(x, y);
37 return QPointF(x, y);
38 }
38 }
39
39
40 QPen linearPos(QPen start, QPen end, qreal pos)
40 QPen linearPos(QPen start, QPen end, qreal pos)
41 {
41 {
42 QColor c;
42 QColor c;
43 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
43 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
44 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
44 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
45 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
45 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
46 end.setColor(c);
46 end.setColor(c);
47 return end;
47 return end;
48 }
48 }
49
49
50 QBrush linearPos(QBrush start, QBrush end, qreal pos)
50 QBrush linearPos(QBrush start, QBrush end, qreal pos)
51 {
51 {
52 QColor c;
52 QColor c;
53 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
53 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
54 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
54 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
55 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
55 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
56 end.setColor(c);
56 end.setColor(c);
57 return end;
57 return end;
58 }
58 }
59
59
60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
61 :ChartAnimation(sliceItem),
61 :ChartAnimation(sliceItem),
62 m_sliceItem(sliceItem)
62 m_sliceItem(sliceItem)
63 {
63 {
64 }
64 }
65
65
66 PieSliceAnimation::~PieSliceAnimation()
66 PieSliceAnimation::~PieSliceAnimation()
67 {
67 {
68 }
68 }
69
69
70 void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue)
70 void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue)
71 {
71 {
72 if (state() != QAbstractAnimation::Stopped)
72 if (state() != QAbstractAnimation::Stopped)
73 stop();
73 stop();
74
74
75 m_currentValue = startValue;
75 m_currentValue = startValue;
76
76
77 setKeyValueAt(0.0, qVariantFromValue(startValue));
77 setKeyValueAt(0.0, qVariantFromValue(startValue));
78 setKeyValueAt(1.0, qVariantFromValue(endValue));
78 setKeyValueAt(1.0, qVariantFromValue(endValue));
79 }
79 }
80
80
81 void PieSliceAnimation::updateValue(const PieSliceData &endValue)
81 void PieSliceAnimation::updateValue(const PieSliceData &endValue)
82 {
82 {
83 if (state() != QAbstractAnimation::Stopped)
83 if (state() != QAbstractAnimation::Stopped)
84 stop();
84 stop();
85
85
86 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
86 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
87 setKeyValueAt(1.0, qVariantFromValue(endValue));
87 setKeyValueAt(1.0, qVariantFromValue(endValue));
88 }
88 }
89
89
90 PieSliceData PieSliceAnimation::currentSliceValue()
90 PieSliceData PieSliceAnimation::currentSliceValue()
91 {
91 {
92 // NOTE:
92 // NOTE:
93 // We must use an internal current value because QVariantAnimation::currentValue() is updated
93 // We must use an internal current value because QVariantAnimation::currentValue() is updated
94 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
94 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
95 // will have the end value set from the first call and the second call will interpolate that instead of
95 // will have the end value set from the first call and the second call will interpolate that instead of
96 // the original current value as it was before the first call.
96 // the original current value as it was before the first call.
97 return m_currentValue;
97 return m_currentValue;
98 }
98 }
99
99
100 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
100 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
101 {
101 {
102 PieSliceData startValue = qVariantValue<PieSliceData>(start);
102 PieSliceData startValue = qVariantValue<PieSliceData>(start);
103 PieSliceData endValue = qVariantValue<PieSliceData>(end);
103 PieSliceData endValue = qVariantValue<PieSliceData>(end);
104
104
105 PieSliceData result;
105 PieSliceData result;
106 result = endValue;
106 result = endValue;
107 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
107 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
108 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
108 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
109 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
109 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
110 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
110 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
111 result.m_slicePen = linearPos(startValue.m_slicePen, endValue.m_slicePen, progress);
111 result.m_slicePen = linearPos(startValue.m_slicePen, endValue.m_slicePen, progress);
112 result.m_sliceBrush = linearPos(startValue.m_sliceBrush, endValue.m_sliceBrush, progress);
112 result.m_sliceBrush = linearPos(startValue.m_sliceBrush, endValue.m_sliceBrush, progress);
113 result.m_innerRadius = linearPos(startValue.m_innerRadius, endValue.m_innerRadius, progress);
113 result.m_holeRadius = linearPos(startValue.m_holeRadius, endValue.m_holeRadius, progress);
114
114
115 return qVariantFromValue(result);
115 return qVariantFromValue(result);
116 }
116 }
117
117
118 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
118 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
119 {
119 {
120 if (state() != QAbstractAnimation::Stopped) { //workaround
120 if (state() != QAbstractAnimation::Stopped) { //workaround
121 m_currentValue = qVariantValue<PieSliceData>(value);
121 m_currentValue = qVariantValue<PieSliceData>(value);
122 m_sliceItem->setLayout(m_currentValue);
122 m_sliceItem->setLayout(m_currentValue);
123 }
123 }
124 }
124 }
125
125
126 QTCOMMERCIALCHART_END_NAMESPACE
126 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,243 +1,242
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "piechartitem_p.h"
21 #include "piechartitem_p.h"
22 #include "piesliceitem_p.h"
22 #include "piesliceitem_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "qpieslice_p.h"
24 #include "qpieslice_p.h"
25 #include "qpieseries.h"
25 #include "qpieseries.h"
26 #include "qpieseries_p.h"
26 #include "qpieseries_p.h"
27 #include "chartpresenter_p.h"
27 #include "chartpresenter_p.h"
28 #include "chartdataset_p.h"
28 #include "chartdataset_p.h"
29 #include "pieanimation_p.h"
29 #include "pieanimation_p.h"
30 #include <QPainter>
30 #include <QPainter>
31 #include <QTimer>
31 #include <QTimer>
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
34
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
36 :ChartItem(presenter),
36 :ChartItem(presenter),
37 m_series(series),
37 m_series(series),
38 m_animation(0)
38 m_animation(0)
39 {
39 {
40 Q_ASSERT(series);
40 Q_ASSERT(series);
41
41
42 QPieSeriesPrivate *p = QPieSeriesPrivate::fromSeries(series);
42 QPieSeriesPrivate *p = QPieSeriesPrivate::fromSeries(series);
43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
44 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
44 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
45 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
45 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
46 connect(p, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
46 connect(p, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
47 connect(p, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
47 connect(p, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
48 connect(p, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
48 connect(p, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
49 connect(p, SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
49 connect(p, SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
50
50
51 // Note: the following does not affect as long as the item does not have anything to paint
51 // Note: the following does not affect as long as the item does not have anything to paint
52 setZValue(ChartPresenter::PieSeriesZValue);
52 setZValue(ChartPresenter::PieSeriesZValue);
53
53
54 // Note: will not create slice items until we have a proper rectangle to draw on.
54 // Note: will not create slice items until we have a proper rectangle to draw on.
55 }
55 }
56
56
57 PieChartItem::~PieChartItem()
57 PieChartItem::~PieChartItem()
58 {
58 {
59 // slices deleted automatically through QGraphicsItem
59 // slices deleted automatically through QGraphicsItem
60 }
60 }
61
61
62 void PieChartItem::setAnimation(PieAnimation* animation)
62 void PieChartItem::setAnimation(PieAnimation* animation)
63 {
63 {
64 m_animation=animation;
64 m_animation=animation;
65 }
65 }
66
66
67 ChartAnimation* PieChartItem::animation() const
67 ChartAnimation* PieChartItem::animation() const
68 {
68 {
69 return m_animation;
69 return m_animation;
70 }
70 }
71
71
72 void PieChartItem::handleGeometryChanged(const QRectF& rect)
72 void PieChartItem::handleGeometryChanged(const QRectF& rect)
73 {
73 {
74 prepareGeometryChange();
74 prepareGeometryChange();
75 m_rect = rect;
75 m_rect = rect;
76 updateLayout();
76 updateLayout();
77
77
78 // This is for delayed initialization of the slice items during startup.
78 // This is for delayed initialization of the slice items during startup.
79 // It ensures that startup animation originates from the correct position.
79 // It ensures that startup animation originates from the correct position.
80 if (m_sliceItems.isEmpty())
80 if (m_sliceItems.isEmpty())
81 handleSlicesAdded(m_series->slices());
81 handleSlicesAdded(m_series->slices());
82 }
82 }
83
83
84 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
84 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
85 {
85 {
86 Q_UNUSED(minX);
86 Q_UNUSED(minX);
87 Q_UNUSED(maxX);
87 Q_UNUSED(maxX);
88 Q_UNUSED(minY);
88 Q_UNUSED(minY);
89 Q_UNUSED(maxY);
89 Q_UNUSED(maxY);
90 // does not apply to pie
90 // does not apply to pie
91 }
91 }
92
92
93 void PieChartItem::handleDomainUpdated()
93 void PieChartItem::handleDomainUpdated()
94 {
94 {
95 // does not apply to pie
95 // does not apply to pie
96 }
96 }
97
97
98 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
98 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
99 {
99 {
100 Q_UNUSED(min);
100 Q_UNUSED(min);
101 Q_UNUSED(max);
101 Q_UNUSED(max);
102 Q_UNUSED(tickXCount);
102 Q_UNUSED(tickXCount);
103 // does not apply to pie
103 // does not apply to pie
104 }
104 }
105
105
106 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
106 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
107 {
107 {
108 Q_UNUSED(min);
108 Q_UNUSED(min);
109 Q_UNUSED(max);
109 Q_UNUSED(max);
110 Q_UNUSED(tickYCount);
110 Q_UNUSED(tickYCount);
111 // does not apply to pie
111 // does not apply to pie
112 }
112 }
113
113
114 void PieChartItem::updateLayout()
114 void PieChartItem::updateLayout()
115 {
115 {
116 // find pie center coordinates
116 // find pie center coordinates
117 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
117 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
118 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
118 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
119
119
120 // find maximum radius for pie
120 // find maximum radius for pie
121 m_pieRadius = m_rect.height() / 2;
121 m_pieRadius = m_rect.height() / 2;
122 if (m_rect.width() < m_rect.height())
122 if (m_rect.width() < m_rect.height())
123 m_pieRadius = m_rect.width() / 2;
123 m_pieRadius = m_rect.width() / 2;
124
124
125 m_donutInnerRadius = m_pieRadius;
125 m_holeSize = m_pieRadius;
126 // apply size factor
126 // apply size factor
127 m_pieRadius *= m_series->pieSize();
127 m_pieRadius *= m_series->pieSize();
128 m_donutInnerRadius *= m_series->donutInnerSize();
128 m_holeSize *= m_series->holeSize();
129
129
130 // set layouts for existing slice items
130 // set layouts for existing slice items
131 foreach (QPieSlice* slice, m_series->slices()) {
131 foreach (QPieSlice* slice, m_series->slices()) {
132 PieSliceItem *sliceItem = m_sliceItems.value(slice);
132 PieSliceItem *sliceItem = m_sliceItems.value(slice);
133 if (sliceItem) {
133 if (sliceItem) {
134 PieSliceData sliceData = updateSliceGeometry(slice);
134 PieSliceData sliceData = updateSliceGeometry(slice);
135 if (m_animation){
135 if (m_animation){
136 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
136 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
137 }
137 }
138 else
138 else
139 sliceItem->setLayout(sliceData);
139 sliceItem->setLayout(sliceData);
140 }
140 }
141 }
141 }
142
142
143 update();
143 update();
144 }
144 }
145
145
146 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
146 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
147 {
147 {
148 // delay creating slice items until there is a proper rectangle
148 // delay creating slice items until there is a proper rectangle
149 if (!m_rect.isValid() && m_sliceItems.isEmpty())
149 if (!m_rect.isValid() && m_sliceItems.isEmpty())
150 return;
150 return;
151
151
152 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
152 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
153
153
154 bool startupAnimation = m_sliceItems.isEmpty();
154 bool startupAnimation = m_sliceItems.isEmpty();
155
155
156 foreach (QPieSlice *slice, slices) {
156 foreach (QPieSlice *slice, slices) {
157 PieSliceItem* sliceItem = new PieSliceItem(this);
157 PieSliceItem* sliceItem = new PieSliceItem(this);
158 m_sliceItems.insert(slice, sliceItem);
158 m_sliceItems.insert(slice, sliceItem);
159
159
160 // Note: no need to connect to slice valueChanged() etc.
160 // Note: no need to connect to slice valueChanged() etc.
161 // This is handled through calculatedDataChanged signal.
161 // This is handled through calculatedDataChanged signal.
162 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
162 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
163 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
163 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
164 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
164 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
165 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
165 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
166 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
166 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
167 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
167 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
168
168
169 QPieSlicePrivate *p = QPieSlicePrivate::fromSlice(slice);
169 QPieSlicePrivate *p = QPieSlicePrivate::fromSlice(slice);
170 connect(p, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
170 connect(p, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
171 connect(p, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
171 connect(p, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
172 connect(p, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
172 connect(p, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
173 connect(p, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
173 connect(p, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
174
174
175 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
175 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
176 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
176 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
177
177
178 PieSliceData sliceData = updateSliceGeometry(slice);
178 PieSliceData sliceData = updateSliceGeometry(slice);
179 if (m_animation)
179 if (m_animation)
180 presenter()->startAnimation(m_animation->addSlice(sliceItem, sliceData, startupAnimation));
180 presenter()->startAnimation(m_animation->addSlice(sliceItem, sliceData, startupAnimation));
181 else
181 else
182 sliceItem->setLayout(sliceData);
182 sliceItem->setLayout(sliceData);
183 }
183 }
184 }
184 }
185
185
186 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
186 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
187 {
187 {
188 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
188 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
189
189
190 foreach (QPieSlice *slice, slices) {
190 foreach (QPieSlice *slice, slices) {
191
191
192 PieSliceItem *sliceItem = m_sliceItems.value(slice);
192 PieSliceItem *sliceItem = m_sliceItems.value(slice);
193
193
194 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
194 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
195 if (!sliceItem)
195 if (!sliceItem)
196 continue;
196 continue;
197
197
198 m_sliceItems.remove(slice);
198 m_sliceItems.remove(slice);
199
199
200 if (m_animation)
200 if (m_animation)
201 presenter()->startAnimation(m_animation->removeSlice(sliceItem)); // animator deletes the PieSliceItem
201 presenter()->startAnimation(m_animation->removeSlice(sliceItem)); // animator deletes the PieSliceItem
202 else
202 else
203 delete sliceItem;
203 delete sliceItem;
204 }
204 }
205 }
205 }
206
206
207 void PieChartItem::handleSliceChanged()
207 void PieChartItem::handleSliceChanged()
208 {
208 {
209 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
209 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
210 if (!slice) {
210 if (!slice) {
211 QPieSlicePrivate* slicep = qobject_cast<QPieSlicePrivate *>(sender());
211 QPieSlicePrivate* slicep = qobject_cast<QPieSlicePrivate *>(sender());
212 slice = slicep->q_ptr;
212 slice = slicep->q_ptr;
213 }
213 }
214 Q_ASSERT(m_sliceItems.contains(slice));
214 Q_ASSERT(m_sliceItems.contains(slice));
215
215
216 PieSliceItem *sliceItem = m_sliceItems.value(slice);
216 PieSliceItem *sliceItem = m_sliceItems.value(slice);
217 PieSliceData sliceData = updateSliceGeometry(slice);
217 PieSliceData sliceData = updateSliceGeometry(slice);
218 if (m_animation)
218 if (m_animation)
219 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
219 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
220 else
220 else
221 sliceItem->setLayout(sliceData);
221 sliceItem->setLayout(sliceData);
222
222
223 update();
223 update();
224 }
224 }
225
225
226 void PieChartItem::handleSeriesVisibleChanged()
226 void PieChartItem::handleSeriesVisibleChanged()
227 {
227 {
228 setVisible(m_series->isVisible());
228 setVisible(m_series->isVisible());
229 }
229 }
230
230
231 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
231 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
232 {
232 {
233 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
233 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
234 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
234 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
235 sliceData.m_radius = m_pieRadius;
235 sliceData.m_radius = m_pieRadius;
236 sliceData.m_donut = m_series->donut();
236 sliceData.m_holeRadius = m_holeSize;
237 sliceData.m_innerRadius = m_donutInnerRadius;
238 return sliceData;
237 return sliceData;
239 }
238 }
240
239
241 #include "moc_piechartitem_p.cpp"
240 #include "moc_piechartitem_p.cpp"
242
241
243 QTCOMMERCIALCHART_END_NAMESPACE
242 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,88 +1,88
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef PIECHARTITEM_H
30 #ifndef PIECHARTITEM_H
31 #define PIECHARTITEM_H
31 #define PIECHARTITEM_H
32
32
33 #include "qpieseries.h"
33 #include "qpieseries.h"
34 #include "chartitem_p.h"
34 #include "chartitem_p.h"
35 #include "piesliceitem_p.h"
35 #include "piesliceitem_p.h"
36
36
37 class QGraphicsItem;
37 class QGraphicsItem;
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 class QPieSlice;
39 class QPieSlice;
40 class ChartPresenter;
40 class ChartPresenter;
41 class PieAnimation;
41 class PieAnimation;
42
42
43 class PieChartItem : public ChartItem
43 class PieChartItem : public ChartItem
44 {
44 {
45 Q_OBJECT
45 Q_OBJECT
46
46
47 public:
47 public:
48 explicit PieChartItem(QPieSeries *series, ChartPresenter *presenter);
48 explicit PieChartItem(QPieSeries *series, ChartPresenter *presenter);
49 ~PieChartItem();
49 ~PieChartItem();
50
50
51 // from QGraphicsItem
51 // from QGraphicsItem
52 QRectF boundingRect() const { return m_rect; }
52 QRectF boundingRect() const { return m_rect; }
53 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
53 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
54
54
55 public Q_SLOTS:
55 public Q_SLOTS:
56 // from Chart
56 // from Chart
57 virtual void handleGeometryChanged(const QRectF &rect);
57 virtual void handleGeometryChanged(const QRectF &rect);
58 virtual void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
58 virtual void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
59 virtual void handleDomainUpdated();
59 virtual void handleDomainUpdated();
60 virtual void rangeXChanged(qreal min, qreal max, int tickXCount);
60 virtual void rangeXChanged(qreal min, qreal max, int tickXCount);
61 virtual void rangeYChanged(qreal min, qreal max, int tickYCount);
61 virtual void rangeYChanged(qreal min, qreal max, int tickYCount);
62
62
63 void updateLayout();
63 void updateLayout();
64 void handleSlicesAdded(QList<QPieSlice*> slices);
64 void handleSlicesAdded(QList<QPieSlice*> slices);
65 void handleSlicesRemoved(QList<QPieSlice*> slices);
65 void handleSlicesRemoved(QList<QPieSlice*> slices);
66 void handleSliceChanged();
66 void handleSliceChanged();
67 void handleSeriesVisibleChanged();
67 void handleSeriesVisibleChanged();
68
68
69 void setAnimation(PieAnimation* animation);
69 void setAnimation(PieAnimation* animation);
70 ChartAnimation* animation() const;
70 ChartAnimation* animation() const;
71
71
72 private:
72 private:
73 PieSliceData updateSliceGeometry(QPieSlice *slice);
73 PieSliceData updateSliceGeometry(QPieSlice *slice);
74
74
75 private:
75 private:
76 QHash<QPieSlice*, PieSliceItem*> m_sliceItems;
76 QHash<QPieSlice*, PieSliceItem*> m_sliceItems;
77 QPieSeries *m_series;
77 QPieSeries *m_series;
78 QRectF m_rect;
78 QRectF m_rect;
79 QPointF m_pieCenter;
79 QPointF m_pieCenter;
80 qreal m_pieRadius;
80 qreal m_pieRadius;
81 qreal m_donutInnerRadius;
81 qreal m_holeSize;
82 PieAnimation* m_animation;
82 PieAnimation* m_animation;
83
83
84 };
84 };
85
85
86 QTCOMMERCIALCHART_END_NAMESPACE
86 QTCOMMERCIALCHART_END_NAMESPACE
87
87
88 #endif // PIECHARTITEM_H
88 #endif // PIECHARTITEM_H
@@ -1,148 +1,146
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef PIESLICEDATA_P_H
30 #ifndef PIESLICEDATA_P_H
31 #define PIESLICEDATA_P_H
31 #define PIESLICEDATA_P_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "qpieslice.h"
34 #include "qpieslice.h"
35 #include <QPen>
35 #include <QPen>
36 #include <QBrush>
36 #include <QBrush>
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 template <class T>
40 template <class T>
41 class Themed : public T
41 class Themed : public T
42 {
42 {
43 public:
43 public:
44 Themed():m_isThemed(true) {}
44 Themed():m_isThemed(true) {}
45
45
46 inline T &operator=(const T &other) { return T::operator =(other); }
46 inline T &operator=(const T &other) { return T::operator =(other); }
47
47
48 inline bool operator!=(const T &other) const { return T::operator !=(other); }
48 inline bool operator!=(const T &other) const { return T::operator !=(other); }
49 inline bool operator!=(const Themed &other) const
49 inline bool operator!=(const Themed &other) const
50 {
50 {
51 if (T::operator !=(other))
51 if (T::operator !=(other))
52 return true;
52 return true;
53
53
54 if (m_isThemed != other.m_isThemed)
54 if (m_isThemed != other.m_isThemed)
55 return true;
55 return true;
56
56
57 return false;
57 return false;
58 }
58 }
59
59
60 inline void setThemed(bool state) { m_isThemed = state; }
60 inline void setThemed(bool state) { m_isThemed = state; }
61 inline bool isThemed() const { return m_isThemed; }
61 inline bool isThemed() const { return m_isThemed; }
62
62
63 private:
63 private:
64 bool m_isThemed;
64 bool m_isThemed;
65 };
65 };
66
66
67 class PieSliceData
67 class PieSliceData
68 {
68 {
69 public:
69 public:
70 PieSliceData()
70 PieSliceData()
71 {
71 {
72 m_value = 0;
72 m_value = 0;
73
73
74 m_isExploded = false;
74 m_isExploded = false;
75 m_explodeDistanceFactor = 0.15;
75 m_explodeDistanceFactor = 0.15;
76
76
77 m_isLabelVisible = false;
77 m_isLabelVisible = false;
78 m_labelPosition = QPieSlice::LabelOutside;
78 m_labelPosition = QPieSlice::LabelOutside;
79 m_labelArmLengthFactor = 0.15;
79 m_labelArmLengthFactor = 0.15;
80
80
81 m_percentage = 0;
81 m_percentage = 0;
82 m_radius = 0;
82 m_radius = 0;
83 m_startAngle = 0;
83 m_startAngle = 0;
84 m_angleSpan = 0;
84 m_angleSpan = 0;
85
85
86 m_donut = false;
86 m_holeRadius = 0;
87 m_innerRadius = 0;
88 }
87 }
89
88
90 bool operator!=(const PieSliceData &other) const
89 bool operator!=(const PieSliceData &other) const
91 {
90 {
92 if (!qFuzzyIsNull(m_value - other.m_value))
91 if (!qFuzzyIsNull(m_value - other.m_value))
93 return true;
92 return true;
94
93
95 if (m_slicePen != other.m_slicePen ||
94 if (m_slicePen != other.m_slicePen ||
96 m_sliceBrush != other.m_sliceBrush)
95 m_sliceBrush != other.m_sliceBrush)
97 return true;
96 return true;
98
97
99 if (m_isExploded != other.m_isExploded ||
98 if (m_isExploded != other.m_isExploded ||
100 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
99 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
101 return true;
100 return true;
102
101
103 if (m_isLabelVisible != other.m_isLabelVisible ||
102 if (m_isLabelVisible != other.m_isLabelVisible ||
104 m_labelText != other.m_labelText ||
103 m_labelText != other.m_labelText ||
105 m_labelFont != other.m_labelFont ||
104 m_labelFont != other.m_labelFont ||
106 m_labelPosition != other.m_labelPosition ||
105 m_labelPosition != other.m_labelPosition ||
107 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
106 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
108 m_labelBrush != other.m_labelBrush)
107 m_labelBrush != other.m_labelBrush)
109 return true;
108 return true;
110
109
111 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
110 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
112 m_center != other.m_center ||
111 m_center != other.m_center ||
113 !qFuzzyIsNull(m_radius - other.m_radius) ||
112 !qFuzzyIsNull(m_radius - other.m_radius) ||
114 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
113 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
115 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
114 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
116 return true;
115 return true;
117
116
118 return false;
117 return false;
119 }
118 }
120
119
121 qreal m_value;
120 qreal m_value;
122
121
123 Themed<QPen> m_slicePen;
122 Themed<QPen> m_slicePen;
124 Themed<QBrush> m_sliceBrush;
123 Themed<QBrush> m_sliceBrush;
125
124
126 bool m_isExploded;
125 bool m_isExploded;
127 qreal m_explodeDistanceFactor;
126 qreal m_explodeDistanceFactor;
128
127
129 bool m_isLabelVisible;
128 bool m_isLabelVisible;
130 QString m_labelText;
129 QString m_labelText;
131 Themed<QFont> m_labelFont;
130 Themed<QFont> m_labelFont;
132 QPieSlice::LabelPosition m_labelPosition;
131 QPieSlice::LabelPosition m_labelPosition;
133 qreal m_labelArmLengthFactor;
132 qreal m_labelArmLengthFactor;
134 Themed<QBrush> m_labelBrush;
133 Themed<QBrush> m_labelBrush;
135
134
136 qreal m_percentage;
135 qreal m_percentage;
137 QPointF m_center;
136 QPointF m_center;
138 qreal m_radius;
137 qreal m_radius;
139 qreal m_startAngle;
138 qreal m_startAngle;
140 qreal m_angleSpan;
139 qreal m_angleSpan;
141
140
142 bool m_donut;
141 qreal m_holeRadius;
143 qreal m_innerRadius;
144 };
142 };
145
143
146 QTCOMMERCIALCHART_END_NAMESPACE
144 QTCOMMERCIALCHART_END_NAMESPACE
147
145
148 #endif // PIESLICEDATA_P_H
146 #endif // PIESLICEDATA_P_H
@@ -1,275 +1,275
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "piesliceitem_p.h"
21 #include "piesliceitem_p.h"
22 #include "piechartitem_p.h"
22 #include "piechartitem_p.h"
23 #include "qpieseries.h"
23 #include "qpieseries.h"
24 #include "qpieslice.h"
24 #include "qpieslice.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QGraphicsSceneEvent>
28 #include <QGraphicsSceneEvent>
29 #include <QTime>
29 #include <QTime>
30 #include <QDebug>
30 #include <QDebug>
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 QPointF offset(qreal angle, qreal length)
34 QPointF offset(qreal angle, qreal length)
35 {
35 {
36 qreal dx = qSin(angle*(M_PI/180)) * length;
36 qreal dx = qSin(angle*(M_PI/180)) * length;
37 qreal dy = qCos(angle*(M_PI/180)) * length;
37 qreal dy = qCos(angle*(M_PI/180)) * length;
38 return QPointF(dx, -dy);
38 return QPointF(dx, -dy);
39 }
39 }
40
40
41 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
41 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
42 :QGraphicsObject(parent),
42 :QGraphicsObject(parent),
43 m_hovered(false)
43 m_hovered(false)
44 {
44 {
45 setAcceptHoverEvents(true);
45 setAcceptHoverEvents(true);
46 setAcceptedMouseButtons(Qt::MouseButtonMask);
46 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 setZValue(ChartPresenter::PieSeriesZValue);
47 setZValue(ChartPresenter::PieSeriesZValue);
48 }
48 }
49
49
50 PieSliceItem::~PieSliceItem()
50 PieSliceItem::~PieSliceItem()
51 {
51 {
52 // If user is hovering over the slice and it gets destroyed we do
52 // If user is hovering over the slice and it gets destroyed we do
53 // not get a hover leave event. So we must emit the signal here.
53 // not get a hover leave event. So we must emit the signal here.
54 if (m_hovered)
54 if (m_hovered)
55 emit hovered(false);
55 emit hovered(false);
56 }
56 }
57
57
58 QRectF PieSliceItem::boundingRect() const
58 QRectF PieSliceItem::boundingRect() const
59 {
59 {
60 return m_boundingRect;
60 return m_boundingRect;
61 }
61 }
62
62
63 QPainterPath PieSliceItem::shape() const
63 QPainterPath PieSliceItem::shape() const
64 {
64 {
65 // Don't include the label and label arm.
65 // Don't include the label and label arm.
66 // This is used to detect a mouse clicks. We do not want clicks from label.
66 // This is used to detect a mouse clicks. We do not want clicks from label.
67 return m_slicePath;
67 return m_slicePath;
68 }
68 }
69
69
70 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
70 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
71 {
71 {
72 painter->save();
72 painter->save();
73 painter->setClipRect(parentItem()->boundingRect());
73 painter->setClipRect(parentItem()->boundingRect());
74 painter->setPen(m_data.m_slicePen);
74 painter->setPen(m_data.m_slicePen);
75 painter->setBrush(m_data.m_sliceBrush);
75 painter->setBrush(m_data.m_sliceBrush);
76 painter->drawPath(m_slicePath);
76 painter->drawPath(m_slicePath);
77 painter->restore();
77 painter->restore();
78
78
79 if (m_data.m_isLabelVisible) {
79 if (m_data.m_isLabelVisible) {
80 painter->save();
80 painter->save();
81
81
82 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
82 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
83 // Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
83 // Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
84 painter->setPen(m_data.m_labelBrush.color());
84 painter->setPen(m_data.m_labelBrush.color());
85 painter->setBrush(m_data.m_labelBrush);
85 painter->setBrush(m_data.m_labelBrush);
86 painter->setFont(m_data.m_labelFont);
86 painter->setFont(m_data.m_labelFont);
87
87
88 switch (m_data.m_labelPosition)
88 switch (m_data.m_labelPosition)
89 {
89 {
90 case QPieSlice::LabelOutside:
90 case QPieSlice::LabelOutside:
91 painter->setClipRect(parentItem()->boundingRect());
91 painter->setClipRect(parentItem()->boundingRect());
92 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
92 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
93 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
93 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
94 break;
94 break;
95 case QPieSlice::LabelInsideHorizontal:
95 case QPieSlice::LabelInsideHorizontal:
96 painter->setClipPath(m_slicePath);
96 painter->setClipPath(m_slicePath);
97 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
97 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
98 break;
98 break;
99 case QPieSlice::LabelInsideTangential:
99 case QPieSlice::LabelInsideTangential:
100 painter->setClipPath(m_slicePath);
100 painter->setClipPath(m_slicePath);
101 painter->translate(m_labelTextRect.center());
101 painter->translate(m_labelTextRect.center());
102 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
102 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
103 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
103 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
104 break;
104 break;
105 case QPieSlice::LabelInsideNormal:
105 case QPieSlice::LabelInsideNormal:
106 painter->setClipPath(m_slicePath);
106 painter->setClipPath(m_slicePath);
107 painter->translate(m_labelTextRect.center());
107 painter->translate(m_labelTextRect.center());
108 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
108 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
109 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
109 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
110 else
110 else
111 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
111 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
112 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
112 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
113 break;
113 break;
114 }
114 }
115
115
116 painter->restore();
116 painter->restore();
117 }
117 }
118 }
118 }
119
119
120 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
120 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
121 {
121 {
122 m_hovered = true;
122 m_hovered = true;
123 emit hovered(true);
123 emit hovered(true);
124 }
124 }
125
125
126 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
126 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
127 {
127 {
128 m_hovered = false;
128 m_hovered = false;
129 emit hovered(false);
129 emit hovered(false);
130 }
130 }
131
131
132 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
132 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
133 {
133 {
134 emit clicked(event->buttons());
134 emit clicked(event->buttons());
135 QGraphicsItem::mousePressEvent(event);
135 QGraphicsItem::mousePressEvent(event);
136 }
136 }
137
137
138 void PieSliceItem::setLayout(const PieSliceData &sliceData)
138 void PieSliceItem::setLayout(const PieSliceData &sliceData)
139 {
139 {
140 m_data = sliceData;
140 m_data = sliceData;
141 updateGeometry();
141 updateGeometry();
142 update();
142 update();
143 }
143 }
144
144
145 void PieSliceItem::updateGeometry()
145 void PieSliceItem::updateGeometry()
146 {
146 {
147 if (m_data.m_radius <= 0)
147 if (m_data.m_radius <= 0)
148 return;
148 return;
149
149
150 prepareGeometryChange();
150 prepareGeometryChange();
151
151
152 // slice path
152 // slice path
153 qreal centerAngle;
153 qreal centerAngle;
154 QPointF armStart;
154 QPointF armStart;
155 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
155 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
156
156
157 // text rect
157 // text rect
158 QFontMetricsF fm(m_data.m_labelFont);
158 QFontMetricsF fm(m_data.m_labelFont);
159 m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
159 m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
160
160
161 // label arm path
161 // label arm path
162 QPointF labelTextStart;
162 QPointF labelTextStart;
163 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
163 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
164
164
165 // text position
165 // text position
166 switch (m_data.m_labelPosition)
166 switch (m_data.m_labelPosition)
167 {
167 {
168 case QPieSlice::LabelOutside:
168 case QPieSlice::LabelOutside:
169 m_labelTextRect.moveBottomLeft(labelTextStart);
169 m_labelTextRect.moveBottomLeft(labelTextStart);
170 break;
170 break;
171 case QPieSlice::LabelInsideHorizontal:
171 case QPieSlice::LabelInsideHorizontal:
172 case QPieSlice::LabelInsideTangential:
172 case QPieSlice::LabelInsideTangential:
173 case QPieSlice::LabelInsideNormal:{
173 case QPieSlice::LabelInsideNormal:{
174 QPointF textCenter;
174 QPointF textCenter;
175 if (m_data.m_donut)
175 if (m_data.m_holeRadius > 0)
176 textCenter = m_data.m_center + offset(centerAngle, m_data.m_innerRadius + (m_data.m_radius - m_data.m_innerRadius) / 2);
176 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
177 else
177 else
178 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
178 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
179 m_labelTextRect.moveCenter(textCenter);
179 m_labelTextRect.moveCenter(textCenter);
180 break;
180 break;
181 }
181 }
182 }
182 }
183
183
184 // bounding rect
184 // bounding rect
185 if (m_data.m_isLabelVisible)
185 if (m_data.m_isLabelVisible)
186 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
186 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
187 else
187 else
188 m_boundingRect = m_slicePath.boundingRect();
188 m_boundingRect = m_slicePath.boundingRect();
189 }
189 }
190
190
191 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
191 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
192 {
192 {
193 if (slice->isExploded()) {
193 if (slice->isExploded()) {
194 qreal centerAngle = slice->startAngle() + (slice->angleSpan()/2);
194 qreal centerAngle = slice->startAngle() + (slice->angleSpan()/2);
195 qreal len = radius * slice->explodeDistanceFactor();
195 qreal len = radius * slice->explodeDistanceFactor();
196 point += offset(centerAngle, len);
196 point += offset(centerAngle, len);
197 }
197 }
198 return point;
198 return point;
199 }
199 }
200
200
201 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF* armStart)
201 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF* armStart)
202 {
202 {
203 // calculate center angle
203 // calculate center angle
204 *centerAngle = startAngle + (angleSpan/2);
204 *centerAngle = startAngle + (angleSpan/2);
205
205
206 // calculate slice rectangle
206 // calculate slice rectangle
207 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
207 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
208
208
209 // slice path
209 // slice path
210 QPainterPath path;
210 QPainterPath path;
211 if (m_data.m_donut) {
211 if (m_data.m_holeRadius > 0) {
212 QRectF insideRect(center.x() - m_data.m_innerRadius, center.y()-m_data.m_innerRadius, m_data.m_innerRadius*2, m_data.m_innerRadius*2);
212 QRectF insideRect(center.x() - m_data.m_holeRadius, center.y()-m_data.m_holeRadius, m_data.m_holeRadius*2, m_data.m_holeRadius*2);
213 path.arcMoveTo(rect, -startAngle + 90);
213 path.arcMoveTo(rect, -startAngle + 90);
214 path.arcTo(rect, -startAngle + 90, -angleSpan);
214 path.arcTo(rect, -startAngle + 90, -angleSpan);
215 path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
215 path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
216 path.closeSubpath();
216 path.closeSubpath();
217 } else {
217 } else {
218 path.moveTo(rect.center());
218 path.moveTo(rect.center());
219 path.arcTo(rect, -startAngle + 90, -angleSpan);
219 path.arcTo(rect, -startAngle + 90, -angleSpan);
220 path.closeSubpath();
220 path.closeSubpath();
221 }
221 }
222
222
223 // calculate label arm start point
223 // calculate label arm start point
224 *armStart = center;
224 *armStart = center;
225 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
225 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
226
226
227 return path;
227 return path;
228 }
228 }
229
229
230 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
230 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
231 {
231 {
232 // Normalize the angle to 0-360 range
232 // Normalize the angle to 0-360 range
233 // NOTE: We are using int here on purpose. Depenging on platform and hardware
233 // NOTE: We are using int here on purpose. Depenging on platform and hardware
234 // qreal can be a double, float or something the user gives to the Qt configure
234 // qreal can be a double, float or something the user gives to the Qt configure
235 // (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
235 // (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
236 // but there are fmod() and fmodf() functions for that. So instead of some #ifdef
236 // but there are fmod() and fmodf() functions for that. So instead of some #ifdef
237 // that might break we just use int. Precision for this is just fine for our needs.
237 // that might break we just use int. Precision for this is just fine for our needs.
238 int normalized = angle * 10.0;
238 int normalized = angle * 10.0;
239 normalized = normalized % 3600;
239 normalized = normalized % 3600;
240 if (normalized < 0)
240 if (normalized < 0)
241 normalized += 3600;
241 normalized += 3600;
242 angle = (qreal) normalized / 10.0;
242 angle = (qreal) normalized / 10.0;
243
243
244 // prevent label arm pointing straight down because it will look bad
244 // prevent label arm pointing straight down because it will look bad
245 if (angle < 180 && angle > 170)
245 if (angle < 180 && angle > 170)
246 angle = 170;
246 angle = 170;
247 if (angle > 180 && angle < 190)
247 if (angle > 180 && angle < 190)
248 angle = 190;
248 angle = 190;
249
249
250 // line from slice to label
250 // line from slice to label
251 QPointF parm1 = start + offset(angle, length);
251 QPointF parm1 = start + offset(angle, length);
252
252
253 // line to underline the label
253 // line to underline the label
254 QPointF parm2 = parm1;
254 QPointF parm2 = parm1;
255 if (angle < 180) { // arm swings the other way on the left side
255 if (angle < 180) { // arm swings the other way on the left side
256 parm2 += QPointF(textWidth, 0);
256 parm2 += QPointF(textWidth, 0);
257 *textStart = parm1;
257 *textStart = parm1;
258 }
258 }
259 else {
259 else {
260 parm2 += QPointF(-textWidth,0);
260 parm2 += QPointF(-textWidth,0);
261 *textStart = parm2;
261 *textStart = parm2;
262 }
262 }
263
263
264 QPainterPath path;
264 QPainterPath path;
265 path.moveTo(start);
265 path.moveTo(start);
266 path.lineTo(parm1);
266 path.lineTo(parm1);
267 path.lineTo(parm2);
267 path.lineTo(parm2);
268
268
269 return path;
269 return path;
270 }
270 }
271
271
272 #include "moc_piesliceitem_p.cpp"
272 #include "moc_piesliceitem_p.cpp"
273
273
274 QTCOMMERCIALCHART_END_NAMESPACE
274 QTCOMMERCIALCHART_END_NAMESPACE
275
275
@@ -1,897 +1,872
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qpieseries.h"
21 #include "qpieseries.h"
22 #include "qpieseries_p.h"
22 #include "qpieseries_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "qpieslice_p.h"
24 #include "qpieslice_p.h"
25 #include "pieslicedata_p.h"
25 #include "pieslicedata_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "charttheme_p.h"
27 #include "charttheme_p.h"
28 #include "legendmarker_p.h"
28 #include "legendmarker_p.h"
29 #include "qabstractaxis.h"
29 #include "qabstractaxis.h"
30 #include "pieanimation_p.h"
30 #include "pieanimation_p.h"
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /*!
34 /*!
35 \class QPieSeries
35 \class QPieSeries
36 \brief Pie series API for QtCommercial Charts
36 \brief Pie series API for QtCommercial Charts
37
37
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 The actual slice size is determined by that relative value.
40 The actual slice size is determined by that relative value.
41
41
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 These relate to the actual chart rectangle.
43 These relate to the actual chart rectangle.
44
44
45 By default the pie is defined as a full pie but it can also be a partial pie.
45 By default the pie is defined as a full pie but it can also be a partial pie.
46 This can be done by setting a starting angle and angle span to the series.
46 This can be done by setting a starting angle and angle span to the series.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
48
48
49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
50 \image examples_piechart.png
50 \image examples_piechart.png
51 */
51 */
52 /*!
52 /*!
53 \qmlclass PieSeries QPieSeries
53 \qmlclass PieSeries QPieSeries
54 \inherits AbstractSeries
54 \inherits AbstractSeries
55
55
56 The following QML shows how to create a simple pie chart.
56 The following QML shows how to create a simple pie chart.
57
57
58 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
58 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
59
59
60 \beginfloatleft
60 \beginfloatleft
61 \image demos_qmlchart1.png
61 \image demos_qmlchart1.png
62 \endfloat
62 \endfloat
63 \clearfloat
63 \clearfloat
64 */
64 */
65
65
66 /*!
66 /*!
67 \property QPieSeries::horizontalPosition
67 \property QPieSeries::horizontalPosition
68 \brief Defines the horizontal position of the pie.
68 \brief Defines the horizontal position of the pie.
69
69
70 The value is a relative value to the chart rectangle where:
70 The value is a relative value to the chart rectangle where:
71
71
72 \list
72 \list
73 \o 0.0 is the absolute left.
73 \o 0.0 is the absolute left.
74 \o 1.0 is the absolute right.
74 \o 1.0 is the absolute right.
75 \endlist
75 \endlist
76 Default value is 0.5 (center).
76 Default value is 0.5 (center).
77 \sa verticalPosition
77 \sa verticalPosition
78 */
78 */
79
79
80 /*!
80 /*!
81 \qmlproperty real PieSeries::horizontalPosition
81 \qmlproperty real PieSeries::horizontalPosition
82
82
83 Defines the horizontal position of the pie.
83 Defines the horizontal position of the pie.
84
84
85 The value is a relative value to the chart rectangle where:
85 The value is a relative value to the chart rectangle where:
86
86
87 \list
87 \list
88 \o 0.0 is the absolute left.
88 \o 0.0 is the absolute left.
89 \o 1.0 is the absolute right.
89 \o 1.0 is the absolute right.
90 \endlist
90 \endlist
91 Default value is 0.5 (center).
91 Default value is 0.5 (center).
92 \sa verticalPosition
92 \sa verticalPosition
93 */
93 */
94
94
95 /*!
95 /*!
96 \property QPieSeries::verticalPosition
96 \property QPieSeries::verticalPosition
97 \brief Defines the vertical position of the pie.
97 \brief Defines the vertical position of the pie.
98
98
99 The value is a relative value to the chart rectangle where:
99 The value is a relative value to the chart rectangle where:
100
100
101 \list
101 \list
102 \o 0.0 is the absolute top.
102 \o 0.0 is the absolute top.
103 \o 1.0 is the absolute bottom.
103 \o 1.0 is the absolute bottom.
104 \endlist
104 \endlist
105 Default value is 0.5 (center).
105 Default value is 0.5 (center).
106 \sa horizontalPosition
106 \sa horizontalPosition
107 */
107 */
108
108
109 /*!
109 /*!
110 \qmlproperty real PieSeries::verticalPosition
110 \qmlproperty real PieSeries::verticalPosition
111
111
112 Defines the vertical position of the pie.
112 Defines the vertical position of the pie.
113
113
114 The value is a relative value to the chart rectangle where:
114 The value is a relative value to the chart rectangle where:
115
115
116 \list
116 \list
117 \o 0.0 is the absolute top.
117 \o 0.0 is the absolute top.
118 \o 1.0 is the absolute bottom.
118 \o 1.0 is the absolute bottom.
119 \endlist
119 \endlist
120 Default value is 0.5 (center).
120 Default value is 0.5 (center).
121 \sa horizontalPosition
121 \sa horizontalPosition
122 */
122 */
123
123
124 /*!
124 /*!
125 \property QPieSeries::size
125 \property QPieSeries::size
126 \brief Defines the pie size.
126 \brief Defines the pie size.
127
127
128 The value is a relative value to the chart rectangle where:
128 The value is a relative value to the chart rectangle where:
129
129
130 \list
130 \list
131 \o 0.0 is the minimum size (pie not drawn).
131 \o 0.0 is the minimum size (pie not drawn).
132 \o 1.0 is the maximum size that can fit the chart.
132 \o 1.0 is the maximum size that can fit the chart.
133 \endlist
133 \endlist
134
134
135 When setting this property the donutInnerSize property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
135 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
136
136
137 Default value is 0.7.
137 Default value is 0.7.
138 */
138 */
139
139
140 /*!
140 /*!
141 \qmlproperty real PieSeries::size
141 \qmlproperty real PieSeries::size
142
142
143 Defines the pie size.
143 Defines the pie size.
144
144
145 The value is a relative value to the chart rectangle where:
145 The value is a relative value to the chart rectangle where:
146
146
147 \list
147 \list
148 \o 0.0 is the minimum size (pie not drawn).
148 \o 0.0 is the minimum size (pie not drawn).
149 \o 1.0 is the maximum size that can fit the chart.
149 \o 1.0 is the maximum size that can fit the chart.
150 \endlist
150 \endlist
151
151
152 Default value is 0.7.
152 Default value is 0.7.
153 */
153 */
154
154
155 /*!
155 /*!
156 \property QPieSeries::donutInnerSize
156 \property QPieSeries::holeSize
157 \brief Defines the donut inner size.
157 \brief Defines the donut hole size.
158
158
159 The value is a relative value to the chart rectangle where:
159 The value is a relative value to the chart rectangle where:
160
160
161 \list
161 \list
162 \o 0.0 is the minimum size (pie not drawn).
162 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
163 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
163 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
164 \endlist
164 \endlist
165
165
166 The value is never greater then size property.
166 The value is never greater then size property.
167 Default value is 0.5.
167 Default value is 0.0.
168 */
168 */
169
169
170 /*!
170 /*!
171 \qmlproperty real PieSeries::donutInnerSize
171 \qmlproperty real PieSeries::holeSize
172
172
173 Defines the donut inner size.
173 Defines the donut hole size.
174
174
175 The value is a relative value to the chart rectangle where:
175 The value is a relative value to the chart rectangle where:
176
176
177 \list
177 \list
178 \o 0.0 is the minimum size (donut is a pie).
178 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
179 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
179 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
180 \endlist
180 \endlist
181
181
182 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
182 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
183
183
184 Default value is 0.5.
184 Default value is 0.0.
185 */
185 */
186
186
187 /*!
187 /*!
188 \property QPieSeries::startAngle
188 \property QPieSeries::startAngle
189 \brief Defines the starting angle of the pie.
189 \brief Defines the starting angle of the pie.
190
190
191 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
191 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
192
192
193 Default is value is 0.
193 Default is value is 0.
194 */
194 */
195
195
196 /*!
196 /*!
197 \qmlproperty real PieSeries::startAngle
197 \qmlproperty real PieSeries::startAngle
198
198
199 Defines the starting angle of the pie.
199 Defines the starting angle of the pie.
200
200
201 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
201 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
202
202
203 Default is value is 0.
203 Default is value is 0.
204 */
204 */
205
205
206 /*!
206 /*!
207 \property QPieSeries::endAngle
207 \property QPieSeries::endAngle
208 \brief Defines the ending angle of the pie.
208 \brief Defines the ending angle of the pie.
209
209
210 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
210 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
211
211
212 Default is value is 360.
212 Default is value is 360.
213 */
213 */
214
214
215 /*!
215 /*!
216 \qmlproperty real PieSeries::endAngle
216 \qmlproperty real PieSeries::endAngle
217
217
218 Defines the ending angle of the pie.
218 Defines the ending angle of the pie.
219
219
220 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
220 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
221
221
222 Default is value is 360.
222 Default is value is 360.
223 */
223 */
224
224
225 /*!
225 /*!
226 \property QPieSeries::count
226 \property QPieSeries::count
227
227
228 Number of slices in the series.
228 Number of slices in the series.
229 */
229 */
230
230
231 /*!
231 /*!
232 \qmlproperty int PieSeries::count
232 \qmlproperty int PieSeries::count
233
233
234 Number of slices in the series.
234 Number of slices in the series.
235 */
235 */
236
236
237 /*!
237 /*!
238 \property QPieSeries::donut
239
240 Defines whether the series should be drawn as a donut
241 */
242
243 /*!
244 \qmlproperty int PieSeries::donut
245
246 Defines whether the series should be drawn as a donut
247 */
248
249 /*!
250 \fn void QPieSeries::countChanged()
238 \fn void QPieSeries::countChanged()
251 Emitted when the slice count has changed.
239 Emitted when the slice count has changed.
252 \sa count
240 \sa count
253 */
241 */
254 /*!
242 /*!
255 \qmlsignal PieSeries::onCountChanged()
243 \qmlsignal PieSeries::onCountChanged()
256 Emitted when the slice count has changed.
244 Emitted when the slice count has changed.
257 */
245 */
258
246
259 /*!
247 /*!
260 \property QPieSeries::sum
248 \property QPieSeries::sum
261
249
262 Sum of all slices.
250 Sum of all slices.
263
251
264 The series keeps track of the sum of all slices it holds.
252 The series keeps track of the sum of all slices it holds.
265 */
253 */
266
254
267 /*!
255 /*!
268 \qmlproperty real PieSeries::sum
256 \qmlproperty real PieSeries::sum
269
257
270 Sum of all slices.
258 Sum of all slices.
271
259
272 The series keeps track of the sum of all slices it holds.
260 The series keeps track of the sum of all slices it holds.
273 */
261 */
274
262
275 /*!
263 /*!
276 \fn void QPieSeries::sumChanged()
264 \fn void QPieSeries::sumChanged()
277 Emitted when the sum of all slices has changed.
265 Emitted when the sum of all slices has changed.
278 \sa sum
266 \sa sum
279 */
267 */
280 /*!
268 /*!
281 \qmlsignal PieSeries::onSumChanged()
269 \qmlsignal PieSeries::onSumChanged()
282 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
270 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
283 change value of a slice.
271 change value of a slice.
284 */
272 */
285
273
286 /*!
274 /*!
287 \fn void QPieSeries::added(QList<QPieSlice*> slices)
275 \fn void QPieSeries::added(QList<QPieSlice*> slices)
288
276
289 This signal is emitted when \a slices have been added to the series.
277 This signal is emitted when \a slices have been added to the series.
290
278
291 \sa append(), insert()
279 \sa append(), insert()
292 */
280 */
293 /*!
281 /*!
294 \qmlsignal PieSeries::onAdded(PieSlice slice)
282 \qmlsignal PieSeries::onAdded(PieSlice slice)
295 Emitted when \a slice has been added to the series.
283 Emitted when \a slice has been added to the series.
296 */
284 */
297
285
298 /*!
286 /*!
299 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
287 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
300 This signal is emitted when \a slices have been removed from the series.
288 This signal is emitted when \a slices have been removed from the series.
301 \sa remove()
289 \sa remove()
302 */
290 */
303 /*!
291 /*!
304 \qmlsignal PieSeries::onRemoved(PieSlice slice)
292 \qmlsignal PieSeries::onRemoved(PieSlice slice)
305 Emitted when \a slice has been removed from the series.
293 Emitted when \a slice has been removed from the series.
306 */
294 */
307
295
308 /*!
296 /*!
309 \fn void QPieSeries::clicked(QPieSlice* slice)
297 \fn void QPieSeries::clicked(QPieSlice* slice)
310 This signal is emitted when a \a slice has been clicked.
298 This signal is emitted when a \a slice has been clicked.
311 \sa QPieSlice::clicked()
299 \sa QPieSlice::clicked()
312 */
300 */
313 /*!
301 /*!
314 \qmlsignal PieSeries::onClicked(PieSlice slice)
302 \qmlsignal PieSeries::onClicked(PieSlice slice)
315 This signal is emitted when a \a slice has been clicked.
303 This signal is emitted when a \a slice has been clicked.
316 */
304 */
317
305
318 /*!
306 /*!
319 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
307 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
320 This signal is emitted when user has hovered over or away from the \a slice.
308 This signal is emitted when user has hovered over or away from the \a slice.
321 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
309 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
322 \sa QPieSlice::hovered()
310 \sa QPieSlice::hovered()
323 */
311 */
324 /*!
312 /*!
325 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
313 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
326 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
314 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
327 over the slice and false when hover has moved away from the slice.
315 over the slice and false when hover has moved away from the slice.
328 */
316 */
329
317
330 /*!
318 /*!
331 \qmlmethod PieSlice PieSeries::at(int index)
319 \qmlmethod PieSlice PieSeries::at(int index)
332 Returns slice at \a index. Returns null if the index is not valid.
320 Returns slice at \a index. Returns null if the index is not valid.
333 */
321 */
334
322
335 /*!
323 /*!
336 \qmlmethod PieSlice PieSeries::find(string label)
324 \qmlmethod PieSlice PieSeries::find(string label)
337 Returns the first slice with \a label. Returns null if the index is not valid.
325 Returns the first slice with \a label. Returns null if the index is not valid.
338 */
326 */
339
327
340 /*!
328 /*!
341 \qmlmethod PieSlice PieSeries::append(string label, real value)
329 \qmlmethod PieSlice PieSeries::append(string label, real value)
342 Adds a new slice with \a label and \a value to the pie.
330 Adds a new slice with \a label and \a value to the pie.
343 */
331 */
344
332
345 /*!
333 /*!
346 \qmlmethod bool PieSeries::remove(PieSlice slice)
334 \qmlmethod bool PieSeries::remove(PieSlice slice)
347 Removes the \a slice from the pie. Returns true if the removal was successfull, false otherwise.
335 Removes the \a slice from the pie. Returns true if the removal was successfull, false otherwise.
348 */
336 */
349
337
350 /*!
338 /*!
351 \qmlmethod PieSeries::clear()
339 \qmlmethod PieSeries::clear()
352 Removes all slices from the pie.
340 Removes all slices from the pie.
353 */
341 */
354
342
355 /*!
343 /*!
356 Constructs a series object which is a child of \a parent.
344 Constructs a series object which is a child of \a parent.
357 */
345 */
358 QPieSeries::QPieSeries(QObject *parent) :
346 QPieSeries::QPieSeries(QObject *parent) :
359 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
347 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
360 {
348 {
361
349
362 }
350 }
363
351
364 /*!
352 /*!
365 Destroys the series and its slices.
353 Destroys the series and its slices.
366 */
354 */
367 QPieSeries::~QPieSeries()
355 QPieSeries::~QPieSeries()
368 {
356 {
369 // NOTE: d_prt destroyed by QObject
357 // NOTE: d_prt destroyed by QObject
370 }
358 }
371
359
372 /*!
360 /*!
373 Returns QChartSeries::SeriesTypePie.
361 Returns QChartSeries::SeriesTypePie.
374 */
362 */
375 QAbstractSeries::SeriesType QPieSeries::type() const
363 QAbstractSeries::SeriesType QPieSeries::type() const
376 {
364 {
377 return QAbstractSeries::SeriesTypePie;
365 return QAbstractSeries::SeriesTypePie;
378 }
366 }
379
367
380 /*!
368 /*!
381 Appends a single \a slice to the series.
369 Appends a single \a slice to the series.
382 Slice ownership is passed to the series.
370 Slice ownership is passed to the series.
383
371
384 Returns true if append was succesfull.
372 Returns true if append was succesfull.
385 */
373 */
386 bool QPieSeries::append(QPieSlice* slice)
374 bool QPieSeries::append(QPieSlice* slice)
387 {
375 {
388 return append(QList<QPieSlice*>() << slice);
376 return append(QList<QPieSlice*>() << slice);
389 }
377 }
390
378
391 /*!
379 /*!
392 Appends an array of \a slices to the series.
380 Appends an array of \a slices to the series.
393 Slice ownership is passed to the series.
381 Slice ownership is passed to the series.
394
382
395 Returns true if append was successfull.
383 Returns true if append was successfull.
396 */
384 */
397 bool QPieSeries::append(QList<QPieSlice*> slices)
385 bool QPieSeries::append(QList<QPieSlice*> slices)
398 {
386 {
399 Q_D(QPieSeries);
387 Q_D(QPieSeries);
400
388
401 if (slices.count() == 0)
389 if (slices.count() == 0)
402 return false;
390 return false;
403
391
404 foreach (QPieSlice* s, slices) {
392 foreach (QPieSlice* s, slices) {
405 if (!s || d->m_slices.contains(s))
393 if (!s || d->m_slices.contains(s))
406 return false;
394 return false;
407 if (s->series()) // already added to some series
395 if (s->series()) // already added to some series
408 return false;
396 return false;
409 }
397 }
410
398
411 foreach (QPieSlice* s, slices) {
399 foreach (QPieSlice* s, slices) {
412 s->setParent(this);
400 s->setParent(this);
413 QPieSlicePrivate::fromSlice(s)->m_series = this;
401 QPieSlicePrivate::fromSlice(s)->m_series = this;
414 d->m_slices << s;
402 d->m_slices << s;
415 }
403 }
416
404
417 d->updateDerivativeData();
405 d->updateDerivativeData();
418
406
419 foreach (QPieSlice* s, slices) {
407 foreach (QPieSlice* s, slices) {
420 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
408 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
421 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
409 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
422 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
410 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
423 }
411 }
424
412
425 emit added(slices);
413 emit added(slices);
426 emit countChanged();
414 emit countChanged();
427
415
428 return true;
416 return true;
429 }
417 }
430
418
431 /*!
419 /*!
432 Appends a single \a slice to the series and returns a reference to the series.
420 Appends a single \a slice to the series and returns a reference to the series.
433 Slice ownership is passed to the series.
421 Slice ownership is passed to the series.
434 */
422 */
435 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
423 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
436 {
424 {
437 append(slice);
425 append(slice);
438 return *this;
426 return *this;
439 }
427 }
440
428
441
429
442 /*!
430 /*!
443 Appends a single slice to the series with give \a value and \a label.
431 Appends a single slice to the series with give \a value and \a label.
444 Slice ownership is passed to the series.
432 Slice ownership is passed to the series.
445 */
433 */
446 QPieSlice* QPieSeries::append(QString label, qreal value)
434 QPieSlice* QPieSeries::append(QString label, qreal value)
447 {
435 {
448 QPieSlice* slice = new QPieSlice(label, value);
436 QPieSlice* slice = new QPieSlice(label, value);
449 append(slice);
437 append(slice);
450 return slice;
438 return slice;
451 }
439 }
452
440
453 /*!
441 /*!
454 Inserts a single \a slice to the series before the slice at \a index position.
442 Inserts a single \a slice to the series before the slice at \a index position.
455 Slice ownership is passed to the series.
443 Slice ownership is passed to the series.
456
444
457 Returns true if insert was successfull.
445 Returns true if insert was successfull.
458 */
446 */
459 bool QPieSeries::insert(int index, QPieSlice* slice)
447 bool QPieSeries::insert(int index, QPieSlice* slice)
460 {
448 {
461 Q_D(QPieSeries);
449 Q_D(QPieSeries);
462
450
463 if (index < 0 || index > d->m_slices.count())
451 if (index < 0 || index > d->m_slices.count())
464 return false;
452 return false;
465
453
466 if (!slice || d->m_slices.contains(slice))
454 if (!slice || d->m_slices.contains(slice))
467 return false;
455 return false;
468
456
469 if (slice->series()) // already added to some series
457 if (slice->series()) // already added to some series
470 return false;
458 return false;
471
459
472 slice->setParent(this);
460 slice->setParent(this);
473 QPieSlicePrivate::fromSlice(slice)->m_series = this;
461 QPieSlicePrivate::fromSlice(slice)->m_series = this;
474 d->m_slices.insert(index, slice);
462 d->m_slices.insert(index, slice);
475
463
476 d->updateDerivativeData();
464 d->updateDerivativeData();
477
465
478 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
466 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
479 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
467 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
480 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
468 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
481
469
482 emit added(QList<QPieSlice*>() << slice);
470 emit added(QList<QPieSlice*>() << slice);
483 emit countChanged();
471 emit countChanged();
484
472
485 return true;
473 return true;
486 }
474 }
487
475
488 /*!
476 /*!
489 Removes a single \a slice from the series and deletes the slice.
477 Removes a single \a slice from the series and deletes the slice.
490
478
491 Do not reference the pointer after this call.
479 Do not reference the pointer after this call.
492
480
493 Returns true if remove was successfull.
481 Returns true if remove was successfull.
494 */
482 */
495 bool QPieSeries::remove(QPieSlice* slice)
483 bool QPieSeries::remove(QPieSlice* slice)
496 {
484 {
497 Q_D(QPieSeries);
485 Q_D(QPieSeries);
498
486
499 if (!d->m_slices.removeOne(slice))
487 if (!d->m_slices.removeOne(slice))
500 return false;
488 return false;
501
489
502 d->updateDerivativeData();
490 d->updateDerivativeData();
503
491
504 emit removed(QList<QPieSlice*>() << slice);
492 emit removed(QList<QPieSlice*>() << slice);
505 emit countChanged();
493 emit countChanged();
506
494
507 delete slice;
495 delete slice;
508 slice = 0;
496 slice = 0;
509
497
510 return true;
498 return true;
511 }
499 }
512
500
513 /*!
501 /*!
514 Takes a single \a slice from the series. Does not destroy the slice object.
502 Takes a single \a slice from the series. Does not destroy the slice object.
515
503
516 NOTE: The series remains as the slice's parent object. You must set the
504 NOTE: The series remains as the slice's parent object. You must set the
517 parent object to take full ownership.
505 parent object to take full ownership.
518
506
519 Returns true if take was successfull.
507 Returns true if take was successfull.
520 */
508 */
521 bool QPieSeries::take(QPieSlice* slice)
509 bool QPieSeries::take(QPieSlice* slice)
522 {
510 {
523 Q_D(QPieSeries);
511 Q_D(QPieSeries);
524
512
525 if (!d->m_slices.removeOne(slice))
513 if (!d->m_slices.removeOne(slice))
526 return false;
514 return false;
527
515
528 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
516 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
529
517
530 d->updateDerivativeData();
518 d->updateDerivativeData();
531
519
532 emit removed(QList<QPieSlice*>() << slice);
520 emit removed(QList<QPieSlice*>() << slice);
533 emit countChanged();
521 emit countChanged();
534
522
535 return true;
523 return true;
536 }
524 }
537
525
538 /*!
526 /*!
539 Clears all slices from the series.
527 Clears all slices from the series.
540 */
528 */
541 void QPieSeries::clear()
529 void QPieSeries::clear()
542 {
530 {
543 Q_D(QPieSeries);
531 Q_D(QPieSeries);
544 if (d->m_slices.count() == 0)
532 if (d->m_slices.count() == 0)
545 return;
533 return;
546
534
547 QList<QPieSlice*> slices = d->m_slices;
535 QList<QPieSlice*> slices = d->m_slices;
548 foreach (QPieSlice* s, d->m_slices) {
536 foreach (QPieSlice* s, d->m_slices) {
549 d->m_slices.removeOne(s);
537 d->m_slices.removeOne(s);
550 delete s;
538 delete s;
551 }
539 }
552
540
553 d->updateDerivativeData();
541 d->updateDerivativeData();
554
542
555 emit removed(slices);
543 emit removed(slices);
556 emit countChanged();
544 emit countChanged();
557 }
545 }
558
546
559 /*!
547 /*!
560 Returns a list of slices that belong to this series.
548 Returns a list of slices that belong to this series.
561 */
549 */
562 QList<QPieSlice*> QPieSeries::slices() const
550 QList<QPieSlice*> QPieSeries::slices() const
563 {
551 {
564 Q_D(const QPieSeries);
552 Q_D(const QPieSeries);
565 return d->m_slices;
553 return d->m_slices;
566 }
554 }
567
555
568 /*!
556 /*!
569 returns the number of the slices in this series.
557 returns the number of the slices in this series.
570 */
558 */
571 int QPieSeries::count() const
559 int QPieSeries::count() const
572 {
560 {
573 Q_D(const QPieSeries);
561 Q_D(const QPieSeries);
574 return d->m_slices.count();
562 return d->m_slices.count();
575 }
563 }
576
564
577 /*!
565 /*!
578 Returns true is the series is empty.
566 Returns true is the series is empty.
579 */
567 */
580 bool QPieSeries::isEmpty() const
568 bool QPieSeries::isEmpty() const
581 {
569 {
582 Q_D(const QPieSeries);
570 Q_D(const QPieSeries);
583 return d->m_slices.isEmpty();
571 return d->m_slices.isEmpty();
584 }
572 }
585
573
586 /*!
574 /*!
587 Returns the sum of all slice values in this series.
575 Returns the sum of all slice values in this series.
588
576
589 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
577 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
590 */
578 */
591 qreal QPieSeries::sum() const
579 qreal QPieSeries::sum() const
592 {
580 {
593 Q_D(const QPieSeries);
581 Q_D(const QPieSeries);
594 return d->m_sum;
582 return d->m_sum;
595 }
583 }
596
584
597 void QPieSeries::setDonut(bool donut)
585 void QPieSeries::setHoleSize(qreal holeSize)
598 {
599 Q_D(QPieSeries);
600 d->m_donutChart = donut;
601 d->updateDerivativeData();
602 }
603
604 bool QPieSeries::donut() const
605 {
606 Q_D(const QPieSeries);
607 return d->m_donutChart;
608 }
609
610 void QPieSeries::setDonutInnerSize(qreal innerSize)
611 {
586 {
612 Q_D(QPieSeries);
587 Q_D(QPieSeries);
613 innerSize = qBound((qreal)0.0, innerSize, (qreal)1.0);
588 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
614 d->setSizes(innerSize, qMax(d->m_pieRelativeSize, innerSize));
589 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
615 }
590 }
616
591
617 qreal QPieSeries::donutInnerSize() const
592 qreal QPieSeries::holeSize() const
618 {
593 {
619 Q_D(const QPieSeries);
594 Q_D(const QPieSeries);
620 return d->m_donutRelativeInnerSize;
595 return d->m_holeRelativeSize;
621 }
596 }
622
597
623 void QPieSeries::setHorizontalPosition(qreal relativePosition)
598 void QPieSeries::setHorizontalPosition(qreal relativePosition)
624 {
599 {
625 Q_D(QPieSeries);
600 Q_D(QPieSeries);
626
601
627 if (relativePosition < 0.0)
602 if (relativePosition < 0.0)
628 relativePosition = 0.0;
603 relativePosition = 0.0;
629 if (relativePosition > 1.0)
604 if (relativePosition > 1.0)
630 relativePosition = 1.0;
605 relativePosition = 1.0;
631
606
632 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
607 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
633 d->m_pieRelativeHorPos = relativePosition;
608 d->m_pieRelativeHorPos = relativePosition;
634 emit d->horizontalPositionChanged();
609 emit d->horizontalPositionChanged();
635 }
610 }
636 }
611 }
637
612
638 qreal QPieSeries::horizontalPosition() const
613 qreal QPieSeries::horizontalPosition() const
639 {
614 {
640 Q_D(const QPieSeries);
615 Q_D(const QPieSeries);
641 return d->m_pieRelativeHorPos;
616 return d->m_pieRelativeHorPos;
642 }
617 }
643
618
644 void QPieSeries::setVerticalPosition(qreal relativePosition)
619 void QPieSeries::setVerticalPosition(qreal relativePosition)
645 {
620 {
646 Q_D(QPieSeries);
621 Q_D(QPieSeries);
647
622
648 if (relativePosition < 0.0)
623 if (relativePosition < 0.0)
649 relativePosition = 0.0;
624 relativePosition = 0.0;
650 if (relativePosition > 1.0)
625 if (relativePosition > 1.0)
651 relativePosition = 1.0;
626 relativePosition = 1.0;
652
627
653 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
628 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
654 d->m_pieRelativeVerPos = relativePosition;
629 d->m_pieRelativeVerPos = relativePosition;
655 emit d->verticalPositionChanged();
630 emit d->verticalPositionChanged();
656 }
631 }
657 }
632 }
658
633
659 qreal QPieSeries::verticalPosition() const
634 qreal QPieSeries::verticalPosition() const
660 {
635 {
661 Q_D(const QPieSeries);
636 Q_D(const QPieSeries);
662 return d->m_pieRelativeVerPos;
637 return d->m_pieRelativeVerPos;
663 }
638 }
664
639
665 void QPieSeries::setPieSize(qreal relativeSize)
640 void QPieSeries::setPieSize(qreal relativeSize)
666 {
641 {
667 Q_D(QPieSeries);
642 Q_D(QPieSeries);
668 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
643 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
669 d->setSizes(qMin(d->m_donutRelativeInnerSize, relativeSize), relativeSize);
644 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
670
645
671 }
646 }
672
647
673 qreal QPieSeries::pieSize() const
648 qreal QPieSeries::pieSize() const
674 {
649 {
675 Q_D(const QPieSeries);
650 Q_D(const QPieSeries);
676 return d->m_pieRelativeSize;
651 return d->m_pieRelativeSize;
677 }
652 }
678
653
679
654
680 void QPieSeries::setPieStartAngle(qreal angle)
655 void QPieSeries::setPieStartAngle(qreal angle)
681 {
656 {
682 Q_D(QPieSeries);
657 Q_D(QPieSeries);
683 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
658 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
684 return;
659 return;
685 d->m_pieStartAngle = angle;
660 d->m_pieStartAngle = angle;
686 d->updateDerivativeData();
661 d->updateDerivativeData();
687 emit d->pieStartAngleChanged();
662 emit d->pieStartAngleChanged();
688 }
663 }
689
664
690 qreal QPieSeries::pieStartAngle() const
665 qreal QPieSeries::pieStartAngle() const
691 {
666 {
692 Q_D(const QPieSeries);
667 Q_D(const QPieSeries);
693 return d->m_pieStartAngle;
668 return d->m_pieStartAngle;
694 }
669 }
695
670
696 /*!
671 /*!
697 Sets the end angle of the pie.
672 Sets the end angle of the pie.
698
673
699 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
674 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
700
675
701 \a angle must be greater than start angle.
676 \a angle must be greater than start angle.
702
677
703 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
678 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
704 */
679 */
705 void QPieSeries::setPieEndAngle(qreal angle)
680 void QPieSeries::setPieEndAngle(qreal angle)
706 {
681 {
707 Q_D(QPieSeries);
682 Q_D(QPieSeries);
708 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
683 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
709 return;
684 return;
710 d->m_pieEndAngle = angle;
685 d->m_pieEndAngle = angle;
711 d->updateDerivativeData();
686 d->updateDerivativeData();
712 emit d->pieEndAngleChanged();
687 emit d->pieEndAngleChanged();
713 }
688 }
714
689
715 /*!
690 /*!
716 Returns the end angle of the pie.
691 Returns the end angle of the pie.
717
692
718 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
693 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
719
694
720 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
695 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
721 */
696 */
722 qreal QPieSeries::pieEndAngle() const
697 qreal QPieSeries::pieEndAngle() const
723 {
698 {
724 Q_D(const QPieSeries);
699 Q_D(const QPieSeries);
725 return d->m_pieEndAngle;
700 return d->m_pieEndAngle;
726 }
701 }
727
702
728 /*!
703 /*!
729 Sets the all the slice labels \a visible or invisible.
704 Sets the all the slice labels \a visible or invisible.
730
705
731 Note that this affects only the current slices in the series.
706 Note that this affects only the current slices in the series.
732 If user adds a new slice the default label visibility is false.
707 If user adds a new slice the default label visibility is false.
733
708
734 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
709 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
735 */
710 */
736 void QPieSeries::setLabelsVisible(bool visible)
711 void QPieSeries::setLabelsVisible(bool visible)
737 {
712 {
738 Q_D(QPieSeries);
713 Q_D(QPieSeries);
739 foreach (QPieSlice* s, d->m_slices)
714 foreach (QPieSlice* s, d->m_slices)
740 s->setLabelVisible(visible);
715 s->setLabelVisible(visible);
741 }
716 }
742
717
743 /*!
718 /*!
744 Sets the all the slice labels \a position
719 Sets the all the slice labels \a position
745
720
746 Note that this affects only the current slices in the series.
721 Note that this affects only the current slices in the series.
747 If user adds a new slice the default label position is LabelOutside
722 If user adds a new slice the default label position is LabelOutside
748
723
749 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
724 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
750 */
725 */
751 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
726 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
752 {
727 {
753 Q_D(QPieSeries);
728 Q_D(QPieSeries);
754 foreach (QPieSlice* s, d->m_slices)
729 foreach (QPieSlice* s, d->m_slices)
755 s->setLabelPosition(position);
730 s->setLabelPosition(position);
756 }
731 }
757
732
758 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
733 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
759
734
760
735
761 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
736 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
762 QAbstractSeriesPrivate(parent),
737 QAbstractSeriesPrivate(parent),
763 m_pieRelativeHorPos(0.5),
738 m_pieRelativeHorPos(0.5),
764 m_pieRelativeVerPos(0.5),
739 m_pieRelativeVerPos(0.5),
765 m_pieRelativeSize(0.7),
740 m_pieRelativeSize(0.7),
766 m_pieStartAngle(0),
741 m_pieStartAngle(0),
767 m_pieEndAngle(360),
742 m_pieEndAngle(360),
768 m_sum(0),
743 m_sum(0),
769 m_donutChart(false),
744 // m_donutChart(false),
770 m_donutRelativeInnerSize(0.5)
745 m_holeRelativeSize(0.0)
771 {
746 {
772 }
747 }
773
748
774 QPieSeriesPrivate::~QPieSeriesPrivate()
749 QPieSeriesPrivate::~QPieSeriesPrivate()
775 {
750 {
776 }
751 }
777
752
778 void QPieSeriesPrivate::updateDerivativeData()
753 void QPieSeriesPrivate::updateDerivativeData()
779 {
754 {
780 // calculate sum of all slices
755 // calculate sum of all slices
781 qreal sum = 0;
756 qreal sum = 0;
782 foreach (QPieSlice* s, m_slices)
757 foreach (QPieSlice* s, m_slices)
783 sum += s->value();
758 sum += s->value();
784
759
785 if (!qFuzzyIsNull(m_sum - sum)) {
760 if (!qFuzzyIsNull(m_sum - sum)) {
786 m_sum = sum;
761 m_sum = sum;
787 emit q_func()->sumChanged();
762 emit q_func()->sumChanged();
788 }
763 }
789
764
790 // nothing to show..
765 // nothing to show..
791 if (qFuzzyIsNull(m_sum))
766 if (qFuzzyIsNull(m_sum))
792 return;
767 return;
793
768
794 // update slice attributes
769 // update slice attributes
795 qreal sliceAngle = m_pieStartAngle;
770 qreal sliceAngle = m_pieStartAngle;
796 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
771 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
797 QVector<QPieSlice*> changed;
772 QVector<QPieSlice*> changed;
798 foreach (QPieSlice* s, m_slices) {
773 foreach (QPieSlice* s, m_slices) {
799 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
774 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
800 d->setPercentage(s->value() / m_sum);
775 d->setPercentage(s->value() / m_sum);
801 d->setStartAngle(sliceAngle);
776 d->setStartAngle(sliceAngle);
802 d->setAngleSpan(pieSpan * s->percentage());
777 d->setAngleSpan(pieSpan * s->percentage());
803 sliceAngle += s->angleSpan();
778 sliceAngle += s->angleSpan();
804 }
779 }
805
780
806
781
807 emit calculatedDataChanged();
782 emit calculatedDataChanged();
808 }
783 }
809
784
810 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
785 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
811 {
786 {
812 bool changed = false;
787 bool changed = false;
813
788
814 if (!qFuzzyIsNull(m_donutRelativeInnerSize - innerSize)) {
789 if (!qFuzzyIsNull(m_holeRelativeSize - innerSize)) {
815 m_donutRelativeInnerSize = innerSize;
790 m_holeRelativeSize = innerSize;
816 changed = true;
791 changed = true;
817 }
792 }
818
793
819 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
794 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
820 m_pieRelativeSize = outerSize;
795 m_pieRelativeSize = outerSize;
821 changed = true;
796 changed = true;
822 }
797 }
823
798
824 if (changed)
799 if (changed)
825 emit pieSizeChanged();
800 emit pieSizeChanged();
826 }
801 }
827
802
828 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
803 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
829 {
804 {
830 return series->d_func();
805 return series->d_func();
831 }
806 }
832
807
833 void QPieSeriesPrivate::sliceValueChanged()
808 void QPieSeriesPrivate::sliceValueChanged()
834 {
809 {
835 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
810 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
836 updateDerivativeData();
811 updateDerivativeData();
837 }
812 }
838
813
839 void QPieSeriesPrivate::sliceClicked()
814 void QPieSeriesPrivate::sliceClicked()
840 {
815 {
841 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
816 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
842 Q_ASSERT(m_slices.contains(slice));
817 Q_ASSERT(m_slices.contains(slice));
843 Q_Q(QPieSeries);
818 Q_Q(QPieSeries);
844 emit q->clicked(slice);
819 emit q->clicked(slice);
845 }
820 }
846
821
847 void QPieSeriesPrivate::sliceHovered(bool state)
822 void QPieSeriesPrivate::sliceHovered(bool state)
848 {
823 {
849 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
824 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
850 Q_ASSERT(m_slices.contains(slice));
825 Q_ASSERT(m_slices.contains(slice));
851 Q_Q(QPieSeries);
826 Q_Q(QPieSeries);
852 emit q->hovered(slice, state);
827 emit q->hovered(slice, state);
853 }
828 }
854
829
855 void QPieSeriesPrivate::scaleDomain(Domain& domain)
830 void QPieSeriesPrivate::scaleDomain(Domain& domain)
856 {
831 {
857 Q_UNUSED(domain);
832 Q_UNUSED(domain);
858 // does not apply to pie
833 // does not apply to pie
859 }
834 }
860
835
861 ChartElement* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
836 ChartElement* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
862 {
837 {
863 Q_Q(QPieSeries);
838 Q_Q(QPieSeries);
864 PieChartItem* pie = new PieChartItem(q,presenter);
839 PieChartItem* pie = new PieChartItem(q,presenter);
865 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
840 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
866 pie->setAnimation(new PieAnimation(pie));
841 pie->setAnimation(new PieAnimation(pie));
867 }
842 }
868 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
843 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
869 return pie;
844 return pie;
870 }
845 }
871
846
872 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
847 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
873 {
848 {
874 Q_Q(QPieSeries);
849 Q_Q(QPieSeries);
875 QList<LegendMarker*> markers;
850 QList<LegendMarker*> markers;
876 foreach(QPieSlice* slice, q->slices()) {
851 foreach(QPieSlice* slice, q->slices()) {
877 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
852 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
878 markers << marker;
853 markers << marker;
879 }
854 }
880 return markers;
855 return markers;
881 }
856 }
882
857
883 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
858 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
884 {
859 {
885 Q_UNUSED(axis);
860 Q_UNUSED(axis);
886 }
861 }
887
862
888 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
863 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
889 {
864 {
890 Q_UNUSED(orientation);
865 Q_UNUSED(orientation);
891 return QAbstractAxis::AxisTypeNoAxis;
866 return QAbstractAxis::AxisTypeNoAxis;
892 }
867 }
893
868
894 #include "moc_qpieseries.cpp"
869 #include "moc_qpieseries.cpp"
895 #include "moc_qpieseries_p.cpp"
870 #include "moc_qpieseries_p.cpp"
896
871
897 QTCOMMERCIALCHART_END_NAMESPACE
872 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,107 +1,104
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef PIESERIES_H
21 #ifndef PIESERIES_H
22 #define PIESERIES_H
22 #define PIESERIES_H
23
23
24 #include <qabstractseries.h>
24 #include <qabstractseries.h>
25 #include <QPieSlice>
25 #include <QPieSlice>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 class QPieSeriesPrivate;
28 class QPieSeriesPrivate;
29 //class QPieSlice;
29 //class QPieSlice;
30
30
31 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
31 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
32 {
32 {
33 Q_OBJECT
33 Q_OBJECT
34 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
34 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
35 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
35 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
36 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
36 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
37 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
37 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
38 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
38 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
39 Q_PROPERTY(int count READ count NOTIFY countChanged)
39 Q_PROPERTY(int count READ count NOTIFY countChanged)
40 Q_PROPERTY(qreal sum READ sum NOTIFY sumChanged)
40 Q_PROPERTY(qreal sum READ sum NOTIFY sumChanged)
41 Q_PROPERTY(qreal donutInnerSize READ donutInnerSize WRITE setDonutInnerSize)
41 Q_PROPERTY(qreal holeSize READ holeSize WRITE setHoleSize)
42 Q_PROPERTY(bool donut READ donut WRITE setDonut)
42 // Q_PROPERTY(bool donut READ donut WRITE setDonut)
43
43
44 public:
44 public:
45 explicit QPieSeries(QObject *parent = 0);
45 explicit QPieSeries(QObject *parent = 0);
46 virtual ~QPieSeries();
46 virtual ~QPieSeries();
47
47
48 QAbstractSeries::SeriesType type() const;
48 QAbstractSeries::SeriesType type() const;
49
49
50 bool append(QPieSlice* slice);
50 bool append(QPieSlice* slice);
51 bool append(QList<QPieSlice*> slices);
51 bool append(QList<QPieSlice*> slices);
52 QPieSeries& operator << (QPieSlice* slice);
52 QPieSeries& operator << (QPieSlice* slice);
53 QPieSlice* append(QString label, qreal value);
53 QPieSlice* append(QString label, qreal value);
54
54
55 bool insert(int index, QPieSlice* slice);
55 bool insert(int index, QPieSlice* slice);
56
56
57 bool remove(QPieSlice* slice);
57 bool remove(QPieSlice* slice);
58 bool take(QPieSlice* slice);
58 bool take(QPieSlice* slice);
59 void clear();
59 void clear();
60
60
61 QList<QPieSlice*> slices() const;
61 QList<QPieSlice*> slices() const;
62 int count() const;
62 int count() const;
63
63
64 bool isEmpty() const;
64 bool isEmpty() const;
65
65
66 qreal sum() const;
66 qreal sum() const;
67
67
68 void setDonut(bool donut = true);
68 void setHoleSize(qreal holeSize);
69 bool donut() const;
69 qreal holeSize() const;
70
71 void setDonutInnerSize(qreal innerSize);
72 qreal donutInnerSize() const;
73
70
74 void setHorizontalPosition(qreal relativePosition);
71 void setHorizontalPosition(qreal relativePosition);
75 qreal horizontalPosition() const;
72 qreal horizontalPosition() const;
76
73
77 void setVerticalPosition(qreal relativePosition);
74 void setVerticalPosition(qreal relativePosition);
78 qreal verticalPosition() const;
75 qreal verticalPosition() const;
79
76
80 void setPieSize(qreal relativeSize);
77 void setPieSize(qreal relativeSize);
81 qreal pieSize() const;
78 qreal pieSize() const;
82
79
83 void setPieStartAngle(qreal startAngle);
80 void setPieStartAngle(qreal startAngle);
84 qreal pieStartAngle() const;
81 qreal pieStartAngle() const;
85
82
86 void setPieEndAngle(qreal endAngle);
83 void setPieEndAngle(qreal endAngle);
87 qreal pieEndAngle() const;
84 qreal pieEndAngle() const;
88
85
89 void setLabelsVisible(bool visible = true);
86 void setLabelsVisible(bool visible = true);
90 void setLabelsPosition(QPieSlice::LabelPosition position);
87 void setLabelsPosition(QPieSlice::LabelPosition position);
91
88
92 Q_SIGNALS:
89 Q_SIGNALS:
93 void added(QList<QPieSlice*> slices);
90 void added(QList<QPieSlice*> slices);
94 void removed(QList<QPieSlice*> slices);
91 void removed(QList<QPieSlice*> slices);
95 void clicked(QPieSlice* slice);
92 void clicked(QPieSlice* slice);
96 void hovered(QPieSlice* slice, bool state);
93 void hovered(QPieSlice* slice, bool state);
97 void countChanged();
94 void countChanged();
98 void sumChanged();
95 void sumChanged();
99
96
100 private:
97 private:
101 Q_DECLARE_PRIVATE(QPieSeries)
98 Q_DECLARE_PRIVATE(QPieSeries)
102 Q_DISABLE_COPY(QPieSeries)
99 Q_DISABLE_COPY(QPieSeries)
103 };
100 };
104
101
105 QTCOMMERCIALCHART_END_NAMESPACE
102 QTCOMMERCIALCHART_END_NAMESPACE
106
103
107 #endif // PIESERIES_H
104 #endif // PIESERIES_H
@@ -1,89 +1,88
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QPIESERIES_P_H
30 #ifndef QPIESERIES_P_H
31 #define QPIESERIES_P_H
31 #define QPIESERIES_P_H
32
32
33 #include "qpieseries.h"
33 #include "qpieseries.h"
34 #include "qabstractseries_p.h"
34 #include "qabstractseries_p.h"
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 class QLegendPrivate;
37 class QLegendPrivate;
38
38
39 class QPieSeriesPrivate : public QAbstractSeriesPrivate
39 class QPieSeriesPrivate : public QAbstractSeriesPrivate
40 {
40 {
41 Q_OBJECT
41 Q_OBJECT
42
42
43 public:
43 public:
44 QPieSeriesPrivate(QPieSeries *parent);
44 QPieSeriesPrivate(QPieSeries *parent);
45 ~QPieSeriesPrivate();
45 ~QPieSeriesPrivate();
46
46
47 void scaleDomain(Domain& domain);
47 void scaleDomain(Domain& domain);
48 ChartElement* createGraphics(ChartPresenter *presenter);
48 ChartElement* createGraphics(ChartPresenter *presenter);
49 QList<LegendMarker*> createLegendMarker(QLegend *legend);
49 QList<LegendMarker*> createLegendMarker(QLegend *legend);
50 void initializeAxis(QAbstractAxis* axis);
50 void initializeAxis(QAbstractAxis* axis);
51 QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
51 QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
52
52
53 void updateDerivativeData();
53 void updateDerivativeData();
54 void setSizes(qreal innerSize, qreal outerSize);
54 void setSizes(qreal innerSize, qreal outerSize);
55
55
56 static QPieSeriesPrivate* fromSeries(QPieSeries *series);
56 static QPieSeriesPrivate* fromSeries(QPieSeries *series);
57
57
58 signals:
58 signals:
59 void calculatedDataChanged();
59 void calculatedDataChanged();
60 void pieSizeChanged();
60 void pieSizeChanged();
61 void pieStartAngleChanged();
61 void pieStartAngleChanged();
62 void pieEndAngleChanged();
62 void pieEndAngleChanged();
63 void horizontalPositionChanged();
63 void horizontalPositionChanged();
64 void verticalPositionChanged();
64 void verticalPositionChanged();
65
65
66 public Q_SLOTS:
66 public Q_SLOTS:
67 void sliceValueChanged();
67 void sliceValueChanged();
68 void sliceClicked();
68 void sliceClicked();
69 void sliceHovered(bool state);
69 void sliceHovered(bool state);
70
70
71 private:
71 private:
72 QList<QPieSlice*> m_slices;
72 QList<QPieSlice*> m_slices;
73 qreal m_pieRelativeHorPos;
73 qreal m_pieRelativeHorPos;
74 qreal m_pieRelativeVerPos;
74 qreal m_pieRelativeVerPos;
75 qreal m_pieRelativeSize;
75 qreal m_pieRelativeSize;
76 qreal m_pieStartAngle;
76 qreal m_pieStartAngle;
77 qreal m_pieEndAngle;
77 qreal m_pieEndAngle;
78 qreal m_sum;
78 qreal m_sum;
79 bool m_donutChart;
79 qreal m_holeRelativeSize;
80 qreal m_donutRelativeInnerSize;
81
80
82 private:
81 private:
83 friend class QLegendPrivate;
82 friend class QLegendPrivate;
84 Q_DECLARE_PUBLIC(QPieSeries)
83 Q_DECLARE_PUBLIC(QPieSeries)
85 };
84 };
86
85
87 QTCOMMERCIALCHART_END_NAMESPACE
86 QTCOMMERCIALCHART_END_NAMESPACE
88
87
89 #endif // QPIESERIES_P_H
88 #endif // QPIESERIES_P_H
@@ -1,640 +1,638
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include <QtTest/QtTest>
21 #include <QtTest/QtTest>
22 #include <qchartview.h>
22 #include <qchartview.h>
23 #include <qchart.h>
23 #include <qchart.h>
24 #include <qpieseries.h>
24 #include <qpieseries.h>
25 #include <qpieslice.h>
25 #include <qpieslice.h>
26 #include <qpiemodelmapper.h>
26 #include <qpiemodelmapper.h>
27 #include <QStandardItemModel>
27 #include <QStandardItemModel>
28 #include <tst_definitions.h>
28 #include <tst_definitions.h>
29
29
30 QTCOMMERCIALCHART_USE_NAMESPACE
30 QTCOMMERCIALCHART_USE_NAMESPACE
31
31
32 Q_DECLARE_METATYPE(QPieSlice*)
32 Q_DECLARE_METATYPE(QPieSlice*)
33 Q_DECLARE_METATYPE(QList<QPieSlice*>)
33 Q_DECLARE_METATYPE(QList<QPieSlice*>)
34
34
35 class tst_qpieseries : public QObject
35 class tst_qpieseries : public QObject
36 {
36 {
37 Q_OBJECT
37 Q_OBJECT
38
38
39 public slots:
39 public slots:
40 void initTestCase();
40 void initTestCase();
41 void cleanupTestCase();
41 void cleanupTestCase();
42 void init();
42 void init();
43 void cleanup();
43 void cleanup();
44
44
45 private slots:
45 private slots:
46 void properties();
46 void properties();
47 void append();
47 void append();
48 void appendAnimated();
48 void appendAnimated();
49 void insert();
49 void insert();
50 void insertAnimated();
50 void insertAnimated();
51 void remove();
51 void remove();
52 void removeAnimated();
52 void removeAnimated();
53 void take();
53 void take();
54 void takeAnimated();
54 void takeAnimated();
55 void calculatedValues();
55 void calculatedValues();
56 void clickedSignal();
56 void clickedSignal();
57 void hoverSignal();
57 void hoverSignal();
58 void sliceSeries();
58 void sliceSeries();
59 void destruction();
59 void destruction();
60
60
61 private:
61 private:
62 void verifyCalculatedData(const QPieSeries &series, bool *ok);
62 void verifyCalculatedData(const QPieSeries &series, bool *ok);
63
63
64 private:
64 private:
65 QChartView *m_view;
65 QChartView *m_view;
66 QPieSeries *m_series;
66 QPieSeries *m_series;
67 };
67 };
68
68
69 void tst_qpieseries::initTestCase()
69 void tst_qpieseries::initTestCase()
70 {
70 {
71 qRegisterMetaType<QPieSlice*>("QPieSlice*");
71 qRegisterMetaType<QPieSlice*>("QPieSlice*");
72 qRegisterMetaType<QList<QPieSlice*> >("QList<QPieSlice*>");
72 qRegisterMetaType<QList<QPieSlice*> >("QList<QPieSlice*>");
73 }
73 }
74
74
75 void tst_qpieseries::cleanupTestCase()
75 void tst_qpieseries::cleanupTestCase()
76 {
76 {
77 }
77 }
78
78
79 void tst_qpieseries::init()
79 void tst_qpieseries::init()
80 {
80 {
81 m_view = new QChartView();
81 m_view = new QChartView();
82 m_series = new QPieSeries(m_view);
82 m_series = new QPieSeries(m_view);
83 m_view->show();
83 m_view->show();
84 QTest::qWaitForWindowShown(m_view);
84 QTest::qWaitForWindowShown(m_view);
85
85
86 }
86 }
87
87
88 void tst_qpieseries::cleanup()
88 void tst_qpieseries::cleanup()
89 {
89 {
90 delete m_view;
90 delete m_view;
91 m_view = 0;
91 m_view = 0;
92 m_series = 0;
92 m_series = 0;
93 }
93 }
94
94
95 void tst_qpieseries::properties()
95 void tst_qpieseries::properties()
96 {
96 {
97 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
97 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
98 QSignalSpy sumSpy(m_series, SIGNAL(sumChanged()));
98 QSignalSpy sumSpy(m_series, SIGNAL(sumChanged()));
99
99
100 QVERIFY(m_series->type() == QAbstractSeries::SeriesTypePie);
100 QVERIFY(m_series->type() == QAbstractSeries::SeriesTypePie);
101 QVERIFY(m_series->count() == 0);
101 QVERIFY(m_series->count() == 0);
102 QVERIFY(m_series->isEmpty());
102 QVERIFY(m_series->isEmpty());
103 QCOMPARE(m_series->sum(), 0.0);
103 QCOMPARE(m_series->sum(), 0.0);
104 QCOMPARE(m_series->horizontalPosition(), 0.5);
104 QCOMPARE(m_series->horizontalPosition(), 0.5);
105 QCOMPARE(m_series->verticalPosition(), 0.5);
105 QCOMPARE(m_series->verticalPosition(), 0.5);
106 QCOMPARE(m_series->pieSize(), 0.7);
106 QCOMPARE(m_series->pieSize(), 0.7);
107 QCOMPARE(m_series->pieStartAngle(), 0.0);
107 QCOMPARE(m_series->pieStartAngle(), 0.0);
108 QCOMPARE(m_series->pieEndAngle(), 360.0);
108 QCOMPARE(m_series->pieEndAngle(), 360.0);
109
109
110 m_series->append("s1", 1);
110 m_series->append("s1", 1);
111 m_series->append("s2", 1);
111 m_series->append("s2", 1);
112 m_series->append("s3", 1);
112 m_series->append("s3", 1);
113 m_series->insert(1, new QPieSlice("s4", 1));
113 m_series->insert(1, new QPieSlice("s4", 1));
114 m_series->remove(m_series->slices().first());
114 m_series->remove(m_series->slices().first());
115 QCOMPARE(m_series->count(), 3);
115 QCOMPARE(m_series->count(), 3);
116 QCOMPARE(m_series->sum(), 3.0);
116 QCOMPARE(m_series->sum(), 3.0);
117 m_series->clear();
117 m_series->clear();
118 QCOMPARE(m_series->count(), 0);
118 QCOMPARE(m_series->count(), 0);
119 QCOMPARE(m_series->sum(), 0.0);
119 QCOMPARE(m_series->sum(), 0.0);
120 QCOMPARE(countSpy.count(), 6);
120 QCOMPARE(countSpy.count(), 6);
121 QCOMPARE(sumSpy.count(), 6);
121 QCOMPARE(sumSpy.count(), 6);
122
122
123 m_series->setPieSize(-1.0);
123 m_series->setPieSize(-1.0);
124 QCOMPARE(m_series->pieSize(), 0.0);
124 QCOMPARE(m_series->pieSize(), 0.0);
125 m_series->setPieSize(0.0);
125 m_series->setPieSize(0.0);
126 m_series->setPieSize(0.9);
126 m_series->setPieSize(0.9);
127 m_series->setPieSize(2.0);
127 m_series->setPieSize(2.0);
128 QCOMPARE(m_series->pieSize(), 1.0);
128 QCOMPARE(m_series->pieSize(), 1.0);
129
129
130 m_series->setPieSize(0.7);
130 m_series->setPieSize(0.7);
131 QCOMPARE(m_series->pieSize(), 0.7);
131 QCOMPARE(m_series->pieSize(), 0.7);
132 m_series->setDonut();
133 QVERIFY(m_series->donut());
134
132
135 m_series->setDonutInnerSize(-1.0);
133 m_series->setHoleSize(-1.0);
136 QCOMPARE(m_series->donutInnerSize(), 0.0);
134 QCOMPARE(m_series->holeSize(), 0.0);
137 m_series->setDonutInnerSize(0.5);
135 m_series->setHoleSize(0.5);
138 QCOMPARE(m_series->donutInnerSize(), 0.5);
136 QCOMPARE(m_series->holeSize(), 0.5);
139
137
140 m_series->setDonutInnerSize(0.8);
138 m_series->setHoleSize(0.8);
141 QCOMPARE(m_series->donutInnerSize(), 0.8);
139 QCOMPARE(m_series->holeSize(), 0.8);
142 QCOMPARE(m_series->pieSize(), 0.8);
140 QCOMPARE(m_series->pieSize(), 0.8);
143
141
144 m_series->setPieSize(0.4);
142 m_series->setPieSize(0.4);
145 QCOMPARE(m_series->pieSize(), 0.4);
143 QCOMPARE(m_series->pieSize(), 0.4);
146 QCOMPARE(m_series->donutInnerSize(), 0.4);
144 QCOMPARE(m_series->holeSize(), 0.4);
147
145
148 m_series->setPieStartAngle(0);
146 m_series->setPieStartAngle(0);
149 m_series->setPieStartAngle(-180);
147 m_series->setPieStartAngle(-180);
150 m_series->setPieStartAngle(180);
148 m_series->setPieStartAngle(180);
151 QCOMPARE(m_series->pieStartAngle(), 180.0);
149 QCOMPARE(m_series->pieStartAngle(), 180.0);
152
150
153 m_series->setPieEndAngle(360);
151 m_series->setPieEndAngle(360);
154 m_series->setPieEndAngle(-180);
152 m_series->setPieEndAngle(-180);
155 m_series->setPieEndAngle(180);
153 m_series->setPieEndAngle(180);
156 QCOMPARE(m_series->pieEndAngle(), 180.0);
154 QCOMPARE(m_series->pieEndAngle(), 180.0);
157
155
158 m_series->setHorizontalPosition(0.5);
156 m_series->setHorizontalPosition(0.5);
159 m_series->setHorizontalPosition(-1.0);
157 m_series->setHorizontalPosition(-1.0);
160 QCOMPARE(m_series->horizontalPosition(), 0.0);
158 QCOMPARE(m_series->horizontalPosition(), 0.0);
161 m_series->setHorizontalPosition(1.0);
159 m_series->setHorizontalPosition(1.0);
162 m_series->setHorizontalPosition(2.0);
160 m_series->setHorizontalPosition(2.0);
163 QCOMPARE(m_series->horizontalPosition(), 1.0);
161 QCOMPARE(m_series->horizontalPosition(), 1.0);
164
162
165 m_series->setVerticalPosition(0.5);
163 m_series->setVerticalPosition(0.5);
166 m_series->setVerticalPosition(-1.0);
164 m_series->setVerticalPosition(-1.0);
167 QCOMPARE(m_series->verticalPosition(), 0.0);
165 QCOMPARE(m_series->verticalPosition(), 0.0);
168 m_series->setVerticalPosition(1.0);
166 m_series->setVerticalPosition(1.0);
169 m_series->setVerticalPosition(2.0);
167 m_series->setVerticalPosition(2.0);
170 QCOMPARE(m_series->verticalPosition(), 1.0);
168 QCOMPARE(m_series->verticalPosition(), 1.0);
171 }
169 }
172
170
173 void tst_qpieseries::append()
171 void tst_qpieseries::append()
174 {
172 {
175 m_view->chart()->addSeries(m_series);
173 m_view->chart()->addSeries(m_series);
176 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
174 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
177
175
178 // append pointer
176 // append pointer
179 QPieSlice *slice1 = 0;
177 QPieSlice *slice1 = 0;
180 QVERIFY(!m_series->append(slice1));
178 QVERIFY(!m_series->append(slice1));
181 slice1 = new QPieSlice("slice 1", 1);
179 slice1 = new QPieSlice("slice 1", 1);
182 QVERIFY(m_series->append(slice1));
180 QVERIFY(m_series->append(slice1));
183 QVERIFY(!m_series->append(slice1));
181 QVERIFY(!m_series->append(slice1));
184 QCOMPARE(m_series->count(), 1);
182 QCOMPARE(m_series->count(), 1);
185 QCOMPARE(addedSpy.count(), 1);
183 QCOMPARE(addedSpy.count(), 1);
186 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(0).at(0));
184 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(0).at(0));
187 QCOMPARE(added.count(), 1);
185 QCOMPARE(added.count(), 1);
188 QCOMPARE(added.first(), slice1);
186 QCOMPARE(added.first(), slice1);
189
187
190 // try to append same slice to another series
188 // try to append same slice to another series
191 QPieSeries series2;
189 QPieSeries series2;
192 QVERIFY(!series2.append(slice1));
190 QVERIFY(!series2.append(slice1));
193
191
194 // append pointer list
192 // append pointer list
195 QList<QPieSlice *> list;
193 QList<QPieSlice *> list;
196 QVERIFY(!m_series->append(list));
194 QVERIFY(!m_series->append(list));
197 list << (QPieSlice *) 0;
195 list << (QPieSlice *) 0;
198 QVERIFY(!m_series->append(list));
196 QVERIFY(!m_series->append(list));
199 list.clear();
197 list.clear();
200 list << new QPieSlice("slice 2", 2);
198 list << new QPieSlice("slice 2", 2);
201 list << new QPieSlice("slice 3", 3);
199 list << new QPieSlice("slice 3", 3);
202 QVERIFY(m_series->append(list));
200 QVERIFY(m_series->append(list));
203 QVERIFY(!m_series->append(list));
201 QVERIFY(!m_series->append(list));
204 QCOMPARE(m_series->count(), 3);
202 QCOMPARE(m_series->count(), 3);
205 QCOMPARE(addedSpy.count(), 2);
203 QCOMPARE(addedSpy.count(), 2);
206 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(1).at(0));
204 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(1).at(0));
207 QCOMPARE(added.count(), 2);
205 QCOMPARE(added.count(), 2);
208 QCOMPARE(added, list);
206 QCOMPARE(added, list);
209
207
210 // append operator
208 // append operator
211 QPieSlice *slice4 = new QPieSlice("slice 4", 4);
209 QPieSlice *slice4 = new QPieSlice("slice 4", 4);
212 *m_series << slice4;
210 *m_series << slice4;
213 *m_series << slice1; // fails because already added
211 *m_series << slice1; // fails because already added
214 QCOMPARE(m_series->count(), 4);
212 QCOMPARE(m_series->count(), 4);
215 QCOMPARE(addedSpy.count(), 3);
213 QCOMPARE(addedSpy.count(), 3);
216 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(2).at(0));
214 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(2).at(0));
217 QCOMPARE(added.count(), 1);
215 QCOMPARE(added.count(), 1);
218 QCOMPARE(added.first(), slice4);
216 QCOMPARE(added.first(), slice4);
219
217
220 // append with params
218 // append with params
221 QPieSlice *slice5 = m_series->append("slice 5", 5);
219 QPieSlice *slice5 = m_series->append("slice 5", 5);
222 QVERIFY(slice5 != 0);
220 QVERIFY(slice5 != 0);
223 QCOMPARE(slice5->value(), 5.0);
221 QCOMPARE(slice5->value(), 5.0);
224 QCOMPARE(slice5->label(), QString("slice 5"));
222 QCOMPARE(slice5->label(), QString("slice 5"));
225 QCOMPARE(m_series->count(), 5);
223 QCOMPARE(m_series->count(), 5);
226 QCOMPARE(addedSpy.count(), 4);
224 QCOMPARE(addedSpy.count(), 4);
227 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(3).at(0));
225 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(3).at(0));
228 QCOMPARE(added.count(), 1);
226 QCOMPARE(added.count(), 1);
229 QCOMPARE(added.first(), slice5);
227 QCOMPARE(added.first(), slice5);
230
228
231 // check slices
229 // check slices
232 QVERIFY(!m_series->isEmpty());
230 QVERIFY(!m_series->isEmpty());
233 for (int i=0; i<m_series->count(); i++) {
231 for (int i=0; i<m_series->count(); i++) {
234 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
232 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
235 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
233 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
236 }
234 }
237 }
235 }
238
236
239 void tst_qpieseries::appendAnimated()
237 void tst_qpieseries::appendAnimated()
240 {
238 {
241 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
239 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
242 append();
240 append();
243 }
241 }
244
242
245 void tst_qpieseries::insert()
243 void tst_qpieseries::insert()
246 {
244 {
247 m_view->chart()->addSeries(m_series);
245 m_view->chart()->addSeries(m_series);
248 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
246 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
249
247
250 // insert one slice
248 // insert one slice
251 QPieSlice *slice1 = 0;
249 QPieSlice *slice1 = 0;
252 QVERIFY(!m_series->insert(0, slice1));
250 QVERIFY(!m_series->insert(0, slice1));
253 slice1 = new QPieSlice("slice 1", 1);
251 slice1 = new QPieSlice("slice 1", 1);
254 QVERIFY(!m_series->insert(-1, slice1));
252 QVERIFY(!m_series->insert(-1, slice1));
255 QVERIFY(!m_series->insert(5, slice1));
253 QVERIFY(!m_series->insert(5, slice1));
256 QVERIFY(m_series->insert(0, slice1));
254 QVERIFY(m_series->insert(0, slice1));
257 QVERIFY(!m_series->insert(0, slice1));
255 QVERIFY(!m_series->insert(0, slice1));
258 QCOMPARE(m_series->count(), 1);
256 QCOMPARE(m_series->count(), 1);
259 QCOMPARE(addedSpy.count(), 1);
257 QCOMPARE(addedSpy.count(), 1);
260 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(0).at(0));
258 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(0).at(0));
261 QCOMPARE(added.count(), 1);
259 QCOMPARE(added.count(), 1);
262 QCOMPARE(added.first(), slice1);
260 QCOMPARE(added.first(), slice1);
263
261
264 // try to insert same slice to another series
262 // try to insert same slice to another series
265 QPieSeries series2;
263 QPieSeries series2;
266 QVERIFY(!series2.insert(0, slice1));
264 QVERIFY(!series2.insert(0, slice1));
267
265
268 // add some more slices
266 // add some more slices
269 QPieSlice *slice2 = m_series->append("slice 2", 2);
267 QPieSlice *slice2 = m_series->append("slice 2", 2);
270 QPieSlice *slice4 = m_series->append("slice 4", 4);
268 QPieSlice *slice4 = m_series->append("slice 4", 4);
271 QCOMPARE(m_series->count(), 3);
269 QCOMPARE(m_series->count(), 3);
272 QCOMPARE(addedSpy.count(), 3);
270 QCOMPARE(addedSpy.count(), 3);
273 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(1).at(0));
271 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(1).at(0));
274 QCOMPARE(added.count(), 1);
272 QCOMPARE(added.count(), 1);
275 QCOMPARE(added.first(), slice2);
273 QCOMPARE(added.first(), slice2);
276 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(2).at(0));
274 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(2).at(0));
277 QCOMPARE(added.count(), 1);
275 QCOMPARE(added.count(), 1);
278 QCOMPARE(added.first(), slice4);
276 QCOMPARE(added.first(), slice4);
279
277
280 // insert between slices
278 // insert between slices
281 QPieSlice *slice3 = new QPieSlice("slice 3", 3);
279 QPieSlice *slice3 = new QPieSlice("slice 3", 3);
282 m_series->insert(2, slice3);
280 m_series->insert(2, slice3);
283 QCOMPARE(m_series->count(), 4);
281 QCOMPARE(m_series->count(), 4);
284 QCOMPARE(addedSpy.count(), 4);
282 QCOMPARE(addedSpy.count(), 4);
285 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(3).at(0));
283 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(3).at(0));
286 QCOMPARE(added.count(), 1);
284 QCOMPARE(added.count(), 1);
287 QCOMPARE(added.first(), slice3);
285 QCOMPARE(added.first(), slice3);
288
286
289 // check slices
287 // check slices
290 for (int i=0; i<m_series->count(); i++) {
288 for (int i=0; i<m_series->count(); i++) {
291 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
289 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
292 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
290 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
293 QVERIFY(m_series->slices().at(i)->parent() == m_series);
291 QVERIFY(m_series->slices().at(i)->parent() == m_series);
294 }
292 }
295 }
293 }
296
294
297 void tst_qpieseries::insertAnimated()
295 void tst_qpieseries::insertAnimated()
298 {
296 {
299 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
297 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
300 insert();
298 insert();
301 }
299 }
302
300
303 void tst_qpieseries::remove()
301 void tst_qpieseries::remove()
304 {
302 {
305 m_view->chart()->addSeries(m_series);
303 m_view->chart()->addSeries(m_series);
306 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
304 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
307
305
308 // add some slices
306 // add some slices
309 QPieSlice *slice1 = m_series->append("slice 1", 1);
307 QPieSlice *slice1 = m_series->append("slice 1", 1);
310 QPieSlice *slice2 = m_series->append("slice 2", 2);
308 QPieSlice *slice2 = m_series->append("slice 2", 2);
311 QPieSlice *slice3 = m_series->append("slice 3", 3);
309 QPieSlice *slice3 = m_series->append("slice 3", 3);
312 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
310 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
313 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
311 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
314 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
312 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
315 QCOMPARE(m_series->count(), 3);
313 QCOMPARE(m_series->count(), 3);
316
314
317 // null pointer remove
315 // null pointer remove
318 QVERIFY(!m_series->remove(0));
316 QVERIFY(!m_series->remove(0));
319
317
320 // remove first
318 // remove first
321 QVERIFY(m_series->remove(slice1));
319 QVERIFY(m_series->remove(slice1));
322 QVERIFY(!m_series->remove(slice1));
320 QVERIFY(!m_series->remove(slice1));
323 QCOMPARE(m_series->count(), 2);
321 QCOMPARE(m_series->count(), 2);
324 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
322 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
325 QCOMPARE(removedSpy.count(), 1);
323 QCOMPARE(removedSpy.count(), 1);
326 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(0).at(0));
324 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(0).at(0));
327 QCOMPARE(removed.count(), 1);
325 QCOMPARE(removed.count(), 1);
328 QCOMPARE(removed.first(), slice1);
326 QCOMPARE(removed.first(), slice1);
329
327
330 // remove all
328 // remove all
331 m_series->clear();
329 m_series->clear();
332 QVERIFY(m_series->isEmpty());
330 QVERIFY(m_series->isEmpty());
333 QVERIFY(m_series->slices().isEmpty());
331 QVERIFY(m_series->slices().isEmpty());
334 QCOMPARE(m_series->count(), 0);
332 QCOMPARE(m_series->count(), 0);
335 QCOMPARE(removedSpy.count(), 2);
333 QCOMPARE(removedSpy.count(), 2);
336 removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(1).at(0));
334 removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(1).at(0));
337 QCOMPARE(removed.count(), 2);
335 QCOMPARE(removed.count(), 2);
338 QCOMPARE(removed.first(), slice2);
336 QCOMPARE(removed.first(), slice2);
339 QCOMPARE(removed.last(), slice3);
337 QCOMPARE(removed.last(), slice3);
340
338
341 // check that slices were actually destroyed
339 // check that slices were actually destroyed
342 TRY_COMPARE(spy1.count(), 1);
340 TRY_COMPARE(spy1.count(), 1);
343 TRY_COMPARE(spy2.count(), 1);
341 TRY_COMPARE(spy2.count(), 1);
344 TRY_COMPARE(spy3.count(), 1);
342 TRY_COMPARE(spy3.count(), 1);
345 }
343 }
346
344
347 void tst_qpieseries::removeAnimated()
345 void tst_qpieseries::removeAnimated()
348 {
346 {
349 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
347 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
350 remove();
348 remove();
351 }
349 }
352
350
353 void tst_qpieseries::take()
351 void tst_qpieseries::take()
354 {
352 {
355 m_view->chart()->addSeries(m_series);
353 m_view->chart()->addSeries(m_series);
356 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
354 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
357
355
358 // add some slices
356 // add some slices
359 QPieSlice *slice1 = m_series->append("slice 1", 1);
357 QPieSlice *slice1 = m_series->append("slice 1", 1);
360 QPieSlice *slice2 = m_series->append("slice 2", 2);
358 QPieSlice *slice2 = m_series->append("slice 2", 2);
361 m_series->append("slice 3", 3);
359 m_series->append("slice 3", 3);
362 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
360 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
363 QCOMPARE(m_series->count(), 3);
361 QCOMPARE(m_series->count(), 3);
364
362
365 // null pointer remove
363 // null pointer remove
366 QVERIFY(!m_series->take(0));
364 QVERIFY(!m_series->take(0));
367
365
368 // take first
366 // take first
369 QVERIFY(m_series->take(slice1));
367 QVERIFY(m_series->take(slice1));
370 TRY_COMPARE(spy1.count(), 0);
368 TRY_COMPARE(spy1.count(), 0);
371 QVERIFY(slice1->parent() == m_series); // series is still the parent object
369 QVERIFY(slice1->parent() == m_series); // series is still the parent object
372 QVERIFY(!m_series->take(slice1));
370 QVERIFY(!m_series->take(slice1));
373 QCOMPARE(m_series->count(), 2);
371 QCOMPARE(m_series->count(), 2);
374 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
372 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
375 QCOMPARE(removedSpy.count(), 1);
373 QCOMPARE(removedSpy.count(), 1);
376 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(0).at(0));
374 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(0).at(0));
377 QCOMPARE(removed.count(), 1);
375 QCOMPARE(removed.count(), 1);
378 QCOMPARE(removed.first(), slice1);
376 QCOMPARE(removed.first(), slice1);
379 }
377 }
380
378
381 void tst_qpieseries::takeAnimated()
379 void tst_qpieseries::takeAnimated()
382 {
380 {
383 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
381 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
384 take();
382 take();
385 }
383 }
386
384
387 void tst_qpieseries::calculatedValues()
385 void tst_qpieseries::calculatedValues()
388 {
386 {
389 m_view->chart()->addSeries(m_series);
387 m_view->chart()->addSeries(m_series);
390
388
391 QPieSlice *slice1 = new QPieSlice("slice 1", 1);
389 QPieSlice *slice1 = new QPieSlice("slice 1", 1);
392 QSignalSpy percentageSpy(slice1, SIGNAL(percentageChanged()));
390 QSignalSpy percentageSpy(slice1, SIGNAL(percentageChanged()));
393 QSignalSpy startAngleSpy(slice1, SIGNAL(startAngleChanged()));
391 QSignalSpy startAngleSpy(slice1, SIGNAL(startAngleChanged()));
394 QSignalSpy angleSpanSpy(slice1, SIGNAL(angleSpanChanged()));
392 QSignalSpy angleSpanSpy(slice1, SIGNAL(angleSpanChanged()));
395
393
396 // add a slice
394 // add a slice
397 m_series->append(slice1);
395 m_series->append(slice1);
398 bool ok;
396 bool ok;
399 verifyCalculatedData(*m_series, &ok);
397 verifyCalculatedData(*m_series, &ok);
400 if (!ok)
398 if (!ok)
401 return;
399 return;
402 QCOMPARE(percentageSpy.count(), 1);
400 QCOMPARE(percentageSpy.count(), 1);
403 QCOMPARE(startAngleSpy.count(), 0);
401 QCOMPARE(startAngleSpy.count(), 0);
404 QCOMPARE(angleSpanSpy.count(), 1);
402 QCOMPARE(angleSpanSpy.count(), 1);
405
403
406 // add some more slices
404 // add some more slices
407 QList<QPieSlice *> list;
405 QList<QPieSlice *> list;
408 list << new QPieSlice("slice 2", 2);
406 list << new QPieSlice("slice 2", 2);
409 list << new QPieSlice("slice 3", 3);
407 list << new QPieSlice("slice 3", 3);
410 m_series->append(list);
408 m_series->append(list);
411 verifyCalculatedData(*m_series, &ok);
409 verifyCalculatedData(*m_series, &ok);
412 if (!ok)
410 if (!ok)
413 return;
411 return;
414 QCOMPARE(percentageSpy.count(), 2);
412 QCOMPARE(percentageSpy.count(), 2);
415 QCOMPARE(startAngleSpy.count(), 0);
413 QCOMPARE(startAngleSpy.count(), 0);
416 QCOMPARE(angleSpanSpy.count(), 2);
414 QCOMPARE(angleSpanSpy.count(), 2);
417
415
418 // remove a slice
416 // remove a slice
419 m_series->remove(list.first()); // remove slice 2
417 m_series->remove(list.first()); // remove slice 2
420 verifyCalculatedData(*m_series, &ok);
418 verifyCalculatedData(*m_series, &ok);
421 if (!ok)
419 if (!ok)
422 return;
420 return;
423 QCOMPARE(percentageSpy.count(), 3);
421 QCOMPARE(percentageSpy.count(), 3);
424 QCOMPARE(startAngleSpy.count(), 0);
422 QCOMPARE(startAngleSpy.count(), 0);
425 QCOMPARE(angleSpanSpy.count(), 3);
423 QCOMPARE(angleSpanSpy.count(), 3);
426
424
427 // insert a slice
425 // insert a slice
428 m_series->insert(0, new QPieSlice("Slice 4", 4));
426 m_series->insert(0, new QPieSlice("Slice 4", 4));
429 verifyCalculatedData(*m_series, &ok);
427 verifyCalculatedData(*m_series, &ok);
430 if (!ok)
428 if (!ok)
431 return;
429 return;
432 QCOMPARE(percentageSpy.count(), 4);
430 QCOMPARE(percentageSpy.count(), 4);
433 QCOMPARE(startAngleSpy.count(), 1);
431 QCOMPARE(startAngleSpy.count(), 1);
434 QCOMPARE(angleSpanSpy.count(), 4);
432 QCOMPARE(angleSpanSpy.count(), 4);
435
433
436 // modify pie angles
434 // modify pie angles
437 m_series->setPieStartAngle(-90);
435 m_series->setPieStartAngle(-90);
438 m_series->setPieEndAngle(90);
436 m_series->setPieEndAngle(90);
439 verifyCalculatedData(*m_series, &ok);
437 verifyCalculatedData(*m_series, &ok);
440 if (!ok)
438 if (!ok)
441 return;
439 return;
442 QCOMPARE(percentageSpy.count(), 4);
440 QCOMPARE(percentageSpy.count(), 4);
443 QCOMPARE(startAngleSpy.count(), 3);
441 QCOMPARE(startAngleSpy.count(), 3);
444 QCOMPARE(angleSpanSpy.count(), 6);
442 QCOMPARE(angleSpanSpy.count(), 6);
445
443
446 // clear all
444 // clear all
447 m_series->clear();
445 m_series->clear();
448 verifyCalculatedData(*m_series, &ok);
446 verifyCalculatedData(*m_series, &ok);
449 if (!ok)
447 if (!ok)
450 return;
448 return;
451 QCOMPARE(percentageSpy.count(), 4);
449 QCOMPARE(percentageSpy.count(), 4);
452 QCOMPARE(startAngleSpy.count(), 3);
450 QCOMPARE(startAngleSpy.count(), 3);
453 QCOMPARE(angleSpanSpy.count(), 6);
451 QCOMPARE(angleSpanSpy.count(), 6);
454 }
452 }
455
453
456 void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
454 void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
457 {
455 {
458 *ok = false;
456 *ok = false;
459
457
460 qreal sum = 0;
458 qreal sum = 0;
461 foreach (const QPieSlice *slice, series.slices())
459 foreach (const QPieSlice *slice, series.slices())
462 sum += slice->value();
460 sum += slice->value();
463 QCOMPARE(series.sum(), sum);
461 QCOMPARE(series.sum(), sum);
464
462
465 qreal startAngle = series.pieStartAngle();
463 qreal startAngle = series.pieStartAngle();
466 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
464 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
467 foreach (const QPieSlice *slice, series.slices()) {
465 foreach (const QPieSlice *slice, series.slices()) {
468 qreal ratio = slice->value() / sum;
466 qreal ratio = slice->value() / sum;
469 qreal sliceSpan = pieAngleSpan * ratio;
467 qreal sliceSpan = pieAngleSpan * ratio;
470 QCOMPARE(slice->startAngle(), startAngle);
468 QCOMPARE(slice->startAngle(), startAngle);
471 QCOMPARE(slice->angleSpan(), sliceSpan);
469 QCOMPARE(slice->angleSpan(), sliceSpan);
472 QCOMPARE(slice->percentage(), ratio);
470 QCOMPARE(slice->percentage(), ratio);
473 startAngle += sliceSpan;
471 startAngle += sliceSpan;
474 }
472 }
475
473
476 if (!series.isEmpty())
474 if (!series.isEmpty())
477 QCOMPARE(series.slices().last()->startAngle() + series.slices().last()->angleSpan(), series.pieEndAngle());
475 QCOMPARE(series.slices().last()->startAngle() + series.slices().last()->angleSpan(), series.pieEndAngle());
478
476
479 *ok = true;
477 *ok = true;
480 }
478 }
481
479
482
480
483 void tst_qpieseries::clickedSignal()
481 void tst_qpieseries::clickedSignal()
484 {
482 {
485 // add some slices
483 // add some slices
486 QPieSlice *s1 = m_series->append("slice 1", 1);
484 QPieSlice *s1 = m_series->append("slice 1", 1);
487 QPieSlice *s2 = m_series->append("slice 2", 1);
485 QPieSlice *s2 = m_series->append("slice 2", 1);
488 QPieSlice *s3 = m_series->append("slice 3", 1);
486 QPieSlice *s3 = m_series->append("slice 3", 1);
489 QPieSlice *s4 = m_series->append("slice 4", 1);
487 QPieSlice *s4 = m_series->append("slice 4", 1);
490 QSignalSpy clickSpy(m_series, SIGNAL(clicked(QPieSlice*)));
488 QSignalSpy clickSpy(m_series, SIGNAL(clicked(QPieSlice*)));
491
489
492 // add series to the chart
490 // add series to the chart
493 m_view->chart()->legend()->setVisible(false);
491 m_view->chart()->legend()->setVisible(false);
494 m_view->resize(200, 200);
492 m_view->resize(200, 200);
495 m_view->chart()->addSeries(m_series);
493 m_view->chart()->addSeries(m_series);
496 m_view->show();
494 m_view->show();
497 QTest::qWaitForWindowShown(m_view);
495 QTest::qWaitForWindowShown(m_view);
498
496
499 // if you devide the chart in four equal tiles these
497 // if you devide the chart in four equal tiles these
500 // are the center points of those tiles
498 // are the center points of those tiles
501 QPoint p1(90.25, 90);
499 QPoint p1(90.25, 90);
502 QPoint p2(150, 90);
500 QPoint p2(150, 90);
503 QPoint p3(90, 150);
501 QPoint p3(90, 150);
504 QPoint p4(150, 150);
502 QPoint p4(150, 150);
505
503
506 QPoint center(120, 120);
504 QPoint center(120, 120);
507
505
508 m_series->setPieSize(1.0);
506 m_series->setPieSize(1.0);
509 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
507 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
510 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
508 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
511 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
509 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
512 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
510 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
513 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
511 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
514 TRY_COMPARE(clickSpy.count(), 5); // all hit
512 TRY_COMPARE(clickSpy.count(), 5); // all hit
515 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s4);
513 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s4);
516 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s1);
514 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s1);
517 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
515 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
518 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s2);
516 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s2);
519 clickSpy.clear();
517 clickSpy.clear();
520
518
521 m_series->setPieSize(0.5);
519 m_series->setPieSize(0.5);
522 m_series->setVerticalPosition(0.25);
520 m_series->setVerticalPosition(0.25);
523 m_series->setHorizontalPosition(0.25);
521 m_series->setHorizontalPosition(0.25);
524 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1); // hits
522 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1); // hits
525 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
523 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
526 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
524 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
527 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
525 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
528 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
526 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
529 TRY_COMPARE(clickSpy.count(), 1);
527 TRY_COMPARE(clickSpy.count(), 1);
530 clickSpy.clear();
528 clickSpy.clear();
531
529
532 m_series->setVerticalPosition(0.25);
530 m_series->setVerticalPosition(0.25);
533 m_series->setHorizontalPosition(0.75);
531 m_series->setHorizontalPosition(0.75);
534 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
532 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
535 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2); // hits
533 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2); // hits
536 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
534 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
537 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
535 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
538 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
536 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
539 TRY_COMPARE(clickSpy.count(), 1);
537 TRY_COMPARE(clickSpy.count(), 1);
540 clickSpy.clear();
538 clickSpy.clear();
541
539
542 m_series->setVerticalPosition(0.75);
540 m_series->setVerticalPosition(0.75);
543 m_series->setHorizontalPosition(0.25);
541 m_series->setHorizontalPosition(0.25);
544 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
542 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
545 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
543 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
546 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3); // hits
544 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3); // hits
547 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
545 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
548 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
546 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
549 TRY_COMPARE(clickSpy.count(), 1);
547 TRY_COMPARE(clickSpy.count(), 1);
550 clickSpy.clear();
548 clickSpy.clear();
551
549
552 m_series->setVerticalPosition(0.75);
550 m_series->setVerticalPosition(0.75);
553 m_series->setHorizontalPosition(0.75);
551 m_series->setHorizontalPosition(0.75);
554 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
552 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
555 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
553 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
556 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
554 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
557 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4); // hits
555 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4); // hits
558 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
556 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
559 TRY_COMPARE(clickSpy.count(), 1);
557 TRY_COMPARE(clickSpy.count(), 1);
560 clickSpy.clear();
558 clickSpy.clear();
561 }
559 }
562
560
563 void tst_qpieseries::hoverSignal()
561 void tst_qpieseries::hoverSignal()
564 {
562 {
565 // add some slices
563 // add some slices
566 m_series->setPieSize(1.0);
564 m_series->setPieSize(1.0);
567 QPieSlice *s1 = m_series->append("slice 1", 1);
565 QPieSlice *s1 = m_series->append("slice 1", 1);
568 m_series->append("slice 2", 2);
566 m_series->append("slice 2", 2);
569 m_series->append("slice 3", 3);
567 m_series->append("slice 3", 3);
570
568
571 // add series to the chart
569 // add series to the chart
572 m_view->chart()->legend()->setVisible(false);
570 m_view->chart()->legend()->setVisible(false);
573 m_view->resize(200, 200);
571 m_view->resize(200, 200);
574 m_view->chart()->addSeries(m_series);
572 m_view->chart()->addSeries(m_series);
575 m_view->show();
573 m_view->show();
576 QTest::qWaitForWindowShown(m_view);
574 QTest::qWaitForWindowShown(m_view);
577
575
578 // first move to right top corner
576 // first move to right top corner
579 QTest::mouseMove(m_view->viewport(), QPoint(200, 0));
577 QTest::mouseMove(m_view->viewport(), QPoint(200, 0));
580 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
578 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
581
579
582 // move inside the slice
580 // move inside the slice
583 // pie rectangle: QRectF(60,60 121x121)
581 // pie rectangle: QRectF(60,60 121x121)
584 QSignalSpy hoverSpy(m_series, SIGNAL(hovered(QPieSlice*,bool)));
582 QSignalSpy hoverSpy(m_series, SIGNAL(hovered(QPieSlice*,bool)));
585 QTest::mouseMove(m_view->viewport(), QPoint(139, 85));
583 QTest::mouseMove(m_view->viewport(), QPoint(139, 85));
586 TRY_COMPARE(hoverSpy.count(), 1);
584 TRY_COMPARE(hoverSpy.count(), 1);
587 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(0).at(0)), s1);
585 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(0).at(0)), s1);
588 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(0).at(1)), true);
586 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(0).at(1)), true);
589
587
590 // move outside the slice
588 // move outside the slice
591 QTest::mouseMove(m_view->viewport(), QPoint(200, 0));
589 QTest::mouseMove(m_view->viewport(), QPoint(200, 0));
592 TRY_COMPARE(hoverSpy.count(), 2);
590 TRY_COMPARE(hoverSpy.count(), 2);
593 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(1).at(0)), s1);
591 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(1).at(0)), s1);
594 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(1).at(1)), false);
592 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(1).at(1)), false);
595 }
593 }
596
594
597 void tst_qpieseries::sliceSeries()
595 void tst_qpieseries::sliceSeries()
598 {
596 {
599 QPieSlice *slice = new QPieSlice();
597 QPieSlice *slice = new QPieSlice();
600 QVERIFY(!slice->series());
598 QVERIFY(!slice->series());
601 delete slice;
599 delete slice;
602
600
603 slice = new QPieSlice(m_series);
601 slice = new QPieSlice(m_series);
604 QVERIFY(!slice->series());
602 QVERIFY(!slice->series());
605
603
606 m_series->append(slice);
604 m_series->append(slice);
607 QCOMPARE(slice->series(), m_series);
605 QCOMPARE(slice->series(), m_series);
608
606
609 slice = new QPieSlice();
607 slice = new QPieSlice();
610 m_series->insert(0, slice);
608 m_series->insert(0, slice);
611 QCOMPARE(slice->series(), m_series);
609 QCOMPARE(slice->series(), m_series);
612
610
613 m_series->take(slice);
611 m_series->take(slice);
614 QCOMPARE(slice->series(), (QPieSeries*) 0);
612 QCOMPARE(slice->series(), (QPieSeries*) 0);
615 }
613 }
616
614
617 void tst_qpieseries::destruction()
615 void tst_qpieseries::destruction()
618 {
616 {
619 // add some slices
617 // add some slices
620 QPieSlice *slice1 = m_series->append("slice 1", 1);
618 QPieSlice *slice1 = m_series->append("slice 1", 1);
621 QPieSlice *slice2 = m_series->append("slice 2", 2);
619 QPieSlice *slice2 = m_series->append("slice 2", 2);
622 QPieSlice *slice3 = m_series->append("slice 3", 3);
620 QPieSlice *slice3 = m_series->append("slice 3", 3);
623 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
621 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
624 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
622 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
625 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
623 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
626
624
627 // destroy series
625 // destroy series
628 delete m_series;
626 delete m_series;
629 m_series = 0;
627 m_series = 0;
630
628
631 // check that series has destroyed its slices
629 // check that series has destroyed its slices
632 QCOMPARE(spy1.count(), 1);
630 QCOMPARE(spy1.count(), 1);
633 QCOMPARE(spy2.count(), 1);
631 QCOMPARE(spy2.count(), 1);
634 QCOMPARE(spy3.count(), 1);
632 QCOMPARE(spy3.count(), 1);
635 }
633 }
636
634
637 QTEST_MAIN(tst_qpieseries)
635 QTEST_MAIN(tst_qpieseries)
638
636
639 #include "tst_qpieseries.moc"
637 #include "tst_qpieseries.moc"
640
638
General Comments 0
You need to be logged in to leave comments. Login now