##// END OF EJS Templates
API review changes for pie
Jani Honkonen -
r1009:983f422506c5
parent child
Show More
@@ -1,50 +1,48
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "customslice.h"
22 22
23 23 QTCOMMERCIALCHART_USE_NAMESPACE
24 24
25 25 CustomSlice::CustomSlice(qreal value, QString label)
26 26 :QPieSlice(value, label)
27 27 {
28 connect(this, SIGNAL(hoverEnter()), this, SLOT(handleHoverEnter()));
29 connect(this, SIGNAL(hoverLeave()), this, SLOT(handleHoverLeave()));
28 connect(this, SIGNAL(hovered(bool)), this, SLOT(showHighlight(bool)));
30 29 }
31 30
32 31 QBrush CustomSlice::originalBrush()
33 32 {
34 33 return m_originalBrush;
35 34 }
36 35
37 void CustomSlice::handleHoverEnter()
36 void CustomSlice::showHighlight(bool show)
38 37 {
39 QBrush brush = this->brush();
40 m_originalBrush = brush;
41 brush.setColor(brush.color().lighter());
42 setBrush(brush);
43 }
44
45 void CustomSlice::handleHoverLeave()
46 {
47 setBrush(m_originalBrush);
38 if (show) {
39 QBrush brush = this->brush();
40 m_originalBrush = brush;
41 brush.setColor(brush.color().lighter());
42 setBrush(brush);
43 } else {
44 setBrush(m_originalBrush);
45 }
48 46 }
49 47
50 48 #include "moc_customslice.cpp"
@@ -1,45 +1,44
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20 #ifndef CUSTOMSLICE_H
21 21 #define CUSTOMSLICE_H
22 22
23 23 #include <QPieSlice>
24 24
25 25 QTCOMMERCIALCHART_USE_NAMESPACE
26 26
27 27 class CustomSlice : public QPieSlice
28 28 {
29 29 Q_OBJECT
30 30
31 31 public:
32 32 CustomSlice(qreal value, QString label);
33 33
34 34 public:
35 35 QBrush originalBrush();
36 36
37 37 public Q_SLOTS:
38 void handleHoverEnter();
39 void handleHoverLeave();
38 void showHighlight(bool show);
40 39
41 40 private:
42 41 QBrush m_originalBrush;
43 42 };
44 43
45 44 #endif // CUSTOMSLICE_H
@@ -1,324 +1,331
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20 #include "mainwidget.h"
21 21 #include "customslice.h"
22 22 #include "pentool.h"
23 23 #include "brushtool.h"
24 24 #include <QPushButton>
25 25 #include <QComboBox>
26 26 #include <QCheckBox>
27 27 #include <QLabel>
28 28 #include <QGroupBox>
29 29 #include <QDoubleSpinBox>
30 30 #include <QFormLayout>
31 31 #include <QFontDialog>
32 32 #include <QChartView>
33 33 #include <QPieSeries>
34 34
35 35 QTCOMMERCIALCHART_USE_NAMESPACE
36 36
37 37 MainWidget::MainWidget(QWidget* parent)
38 38 :QWidget(parent),
39 39 m_slice(0)
40 40 {
41 41 // create chart
42 42 QChart *chart = new QChart;
43 43 chart->setTitle("Piechart customization");
44 44 chart->setAnimationOptions(QChart::AllAnimations);
45 45
46 46 // create series
47 47 m_series = new QPieSeries();
48 48 *m_series << new CustomSlice(10.0, "Slice 1");
49 49 *m_series << new CustomSlice(20.0, "Slice 2");
50 50 *m_series << new CustomSlice(30.0, "Slice 3");
51 51 *m_series << new CustomSlice(40.0, "Slice 4");
52 52 *m_series << new CustomSlice(50.0, "Slice 5");
53 53 m_series->setLabelsVisible();
54 54 chart->addSeries(m_series);
55 55
56 connect(m_series, SIGNAL(clicked(QPieSlice*,Qt::MouseButtons)), this, SLOT(handleSliceClicked(QPieSlice*,Qt::MouseButtons)));
56 connect(m_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(handleSliceClicked(QPieSlice*)));
57 57
58 58 // chart settings
59 59 m_themeComboBox = new QComboBox();
60 60 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
61 61 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
62 62 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
63 63 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
64 64 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
65 65 m_themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
66 66 m_themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
67 67
68 68 m_aaCheckBox = new QCheckBox();
69 69 m_animationsCheckBox = new QCheckBox();
70 70 m_animationsCheckBox->setCheckState(Qt::Checked);
71 71
72 m_legendCheckBox = new QCheckBox();
73
72 74 QFormLayout* chartSettingsLayout = new QFormLayout();
73 75 chartSettingsLayout->addRow("Theme", m_themeComboBox);
74 76 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
75 77 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
78 chartSettingsLayout->addRow("Legend", m_legendCheckBox);
76 79 QGroupBox* chartSettings = new QGroupBox("Chart");
77 80 chartSettings->setLayout(chartSettingsLayout);
78 81
79 82 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
80 83 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
81 84 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
85 connect(m_legendCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
82 86
83 87 // series settings
84 88 m_hPosition = new QDoubleSpinBox();
85 89 m_hPosition->setMinimum(0.0);
86 90 m_hPosition->setMaximum(1.0);
87 91 m_hPosition->setSingleStep(0.1);
88 92 m_hPosition->setValue(m_series->horizontalPosition());
89 93
90 94 m_vPosition = new QDoubleSpinBox();
91 95 m_vPosition->setMinimum(0.0);
92 96 m_vPosition->setMaximum(1.0);
93 97 m_vPosition->setSingleStep(0.1);
94 98 m_vPosition->setValue(m_series->verticalPosition());
95 99
96 100 m_sizeFactor = new QDoubleSpinBox();
97 101 m_sizeFactor->setMinimum(0.0);
98 102 m_sizeFactor->setMaximum(1.0);
99 103 m_sizeFactor->setSingleStep(0.1);
100 104 m_sizeFactor->setValue(m_series->pieSize());
101 105
102 106 m_startAngle = new QDoubleSpinBox();
103 107 m_startAngle->setMinimum(0.0);
104 108 m_startAngle->setMaximum(360);
105 109 m_startAngle->setValue(m_series->pieStartAngle());
106 110 m_startAngle->setSingleStep(1);
107 111
108 112 m_endAngle = new QDoubleSpinBox();
109 113 m_endAngle->setMinimum(0.0);
110 114 m_endAngle->setMaximum(360);
111 115 m_endAngle->setValue(m_series->pieEndAngle());
112 116 m_endAngle->setSingleStep(1);
113 117
114 118 QPushButton *appendSlice = new QPushButton("Append slice");
115 119 QPushButton *insertSlice = new QPushButton("Insert slice");
116 120
117 121 QFormLayout* seriesSettingsLayout = new QFormLayout();
118 122 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
119 123 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
120 124 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
121 125 seriesSettingsLayout->addRow("Start angle", m_startAngle);
122 126 seriesSettingsLayout->addRow("End angle", m_endAngle);
123 127 seriesSettingsLayout->addRow(appendSlice);
124 128 seriesSettingsLayout->addRow(insertSlice);
125 129 QGroupBox* seriesSettings = new QGroupBox("Series");
126 130 seriesSettings->setLayout(seriesSettingsLayout);
127 131
128 132 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
129 133 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
130 134 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
131 135 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
132 136 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
133 137 connect(appendSlice, SIGNAL(clicked()), this, SLOT(appendSlice()));
134 138 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
135 139
136 140 // slice settings
137 141 m_sliceName = new QLabel("<click a slice>");
138 142 m_sliceValue = new QDoubleSpinBox();
139 143 m_sliceValue->setMaximum(1000);
140 144 m_sliceLabelVisible = new QCheckBox();
141 145 m_sliceLabelArmFactor = new QDoubleSpinBox();
142 146 m_sliceLabelArmFactor->setSingleStep(0.01);
143 147 m_sliceExploded = new QCheckBox();
144 148 m_sliceExplodedFactor = new QDoubleSpinBox();
145 149 m_sliceExplodedFactor->setSingleStep(0.01);
146 150 m_pen = new QPushButton();
147 151 m_penTool = new PenTool("Slice pen", this);
148 152 m_brush = new QPushButton();
149 153 m_brushTool = new BrushTool("Slice brush", this);
150 154 m_font = new QPushButton();
151 155 m_labelPen = new QPushButton();
152 156 m_labelPenTool = new PenTool("Label pen", this);
153 157 QPushButton *removeSlice = new QPushButton("Remove slice");
154 158
155 159 QFormLayout* sliceSettingsLayout = new QFormLayout();
156 160 sliceSettingsLayout->addRow("Selected", m_sliceName);
157 161 sliceSettingsLayout->addRow("Value", m_sliceValue);
158 162 sliceSettingsLayout->addRow("Pen", m_pen);
159 163 sliceSettingsLayout->addRow("Brush", m_brush);
160 164 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
161 165 sliceSettingsLayout->addRow("Label font", m_font);
162 166 sliceSettingsLayout->addRow("Label pen", m_labelPen);
163 167 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
164 168 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
165 169 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
166 170 sliceSettingsLayout->addRow(removeSlice);
167 171 QGroupBox* sliceSettings = new QGroupBox("Slice");
168 172 sliceSettings->setLayout(sliceSettingsLayout);
169 173
170 174 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
171 175 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
172 176 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
173 177 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
174 178 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
175 179 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
176 180 connect(m_labelPen, SIGNAL(clicked()), m_labelPenTool, SLOT(show()));
177 181 connect(m_labelPenTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
178 182 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
179 183 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
180 184 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
181 185 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
182 186 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
183 187 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
184 188
185 189 // create chart view
186 190 m_chartView = new QChartView(chart);
187 191
188 192 // create main layout
189 193 QVBoxLayout *settingsLayout = new QVBoxLayout();
190 194 settingsLayout->addWidget(chartSettings);
191 195 settingsLayout->addWidget(seriesSettings);
192 196 settingsLayout->addWidget(sliceSettings);
193 197 settingsLayout->addStretch();
194 198
195 199 QGridLayout* baseLayout = new QGridLayout();
196 200 baseLayout->addLayout(settingsLayout, 0, 0);
197 201 baseLayout->addWidget(m_chartView, 0, 1);
198 202 setLayout(baseLayout);
199 203
200 204 updateSerieSettings();
201 205 }
202 206
203 207
204 208 void MainWidget::updateChartSettings()
205 209 {
206 210 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
207 211 m_chartView->chart()->setTheme(theme);
208 212 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
209 213
210 214 if (m_animationsCheckBox->checkState() == Qt::Checked)
211 215 m_chartView->chart()->setAnimationOptions(QChart::AllAnimations);
212 216 else
213 217 m_chartView->chart()->setAnimationOptions(QChart::NoAnimation);
218
219 if (m_legendCheckBox->checkState() == Qt::Checked)
220 m_chartView->chart()->legend()->show();
221 else
222 m_chartView->chart()->legend()->hide();
214 223 }
215 224
216 225 void MainWidget::updateSerieSettings()
217 226 {
218 227 m_series->setHorizontalPosition(m_hPosition->value());
219 228 m_series->setVerticalPosition(m_vPosition->value());
220 229 m_series->setPieSize(m_sizeFactor->value());
221 230 m_series->setPieStartAngle(m_startAngle->value());
222 231 m_series->setPieEndAngle(m_endAngle->value());
223 232 }
224 233
225 234 void MainWidget::updateSliceSettings()
226 235 {
227 236 if (!m_slice)
228 237 return;
229 238
230 239 m_slice->setValue(m_sliceValue->value());
231 240
232 241 m_slice->setPen(m_penTool->pen());
233 242 m_slice->setBrush(m_brushTool->brush());
234 243
235 244 m_slice->setLabelPen(m_labelPenTool->pen());
236 245 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
237 246 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
238 247
239 248 m_slice->setExploded(m_sliceExploded->isChecked());
240 249 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
241 250 }
242 251
243 void MainWidget::handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons)
252 void MainWidget::handleSliceClicked(QPieSlice* slice)
244 253 {
245 Q_UNUSED(buttons);
246
247 254 m_slice = static_cast<CustomSlice*>(slice);
248 255
249 256 // name
250 257 m_sliceName->setText(slice->label());
251 258
252 259 // value
253 260 m_sliceValue->blockSignals(true);
254 261 m_sliceValue->setValue(slice->value());
255 262 m_sliceValue->blockSignals(false);
256 263
257 264 // pen
258 265 m_pen->setText(PenTool::name(m_slice->pen()));
259 266 m_penTool->setPen(m_slice->pen());
260 267
261 268 // brush
262 269 m_brush->setText(m_slice->originalBrush().color().name());
263 270 m_brushTool->setBrush(m_slice->originalBrush());
264 271
265 272 // label
266 273 m_labelPen->setText(PenTool::name(m_slice->labelPen()));
267 274 m_labelPenTool->setPen(m_slice->labelPen());
268 275 m_font->setText(slice->labelFont().toString());
269 276 m_sliceLabelVisible->blockSignals(true);
270 277 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
271 278 m_sliceLabelVisible->blockSignals(false);
272 279 m_sliceLabelArmFactor->blockSignals(true);
273 280 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
274 281 m_sliceLabelArmFactor->blockSignals(false);
275 282
276 283 // exploded
277 284 m_sliceExploded->blockSignals(true);
278 285 m_sliceExploded->setChecked(slice->isExploded());
279 286 m_sliceExploded->blockSignals(false);
280 287 m_sliceExplodedFactor->blockSignals(true);
281 288 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
282 289 m_sliceExplodedFactor->blockSignals(false);
283 290 }
284 291
285 292 void MainWidget::showFontDialog()
286 293 {
287 294 if (!m_slice)
288 295 return;
289 296
290 297 QFontDialog dialog(m_slice->labelFont());
291 298 dialog.show();
292 299 dialog.exec();
293 300
294 301 m_slice->setLabelFont(dialog.currentFont());
295 302 m_font->setText(dialog.currentFont().toString());
296 303 }
297 304
298 305 void MainWidget::appendSlice()
299 306 {
300 307 *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1));
301 308 }
302 309
303 310 void MainWidget::insertSlice()
304 311 {
305 312 if (!m_slice)
306 313 return;
307 314
308 315 int i = m_series->slices().indexOf(m_slice);
309 316
310 317 m_series->insert(i, new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1)));
311 318 }
312 319
313 320 void MainWidget::removeSlice()
314 321 {
315 322 if (!m_slice)
316 323 return;
317 324
318 325 m_sliceName->setText("<click a slice>");
319 326
320 327 m_series->remove(m_slice);
321 328 m_slice = 0;
322 329 }
323 330
324 331 #include "moc_mainwidget.cpp"
@@ -1,90 +1,91
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20 #ifndef MAINWIDGET_H
21 21 #define MAINWIDGET_H
22 22
23 23 #include <QWidget>
24 24 #include <QChartGlobal>
25 25
26 26 class QLabel;
27 27 class QPushButton;
28 28 class QCheckBox;
29 29 class QComboBox;
30 30 class QDoubleSpinBox;
31 31 class PenTool;
32 32 class BrushTool;
33 33 class CustomSlice;
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36 class QChartView;
37 37 class QPieSeries;
38 38 class QPieSlice;
39 39 QTCOMMERCIALCHART_END_NAMESPACE
40 40
41 41 QTCOMMERCIALCHART_USE_NAMESPACE
42 42
43 43 class MainWidget : public QWidget
44 44 {
45 45 Q_OBJECT
46 46
47 47 public:
48 48 explicit MainWidget(QWidget* parent = 0);
49 49
50 50 public Q_SLOTS:
51 51 void updateChartSettings();
52 52 void updateSerieSettings();
53 53 void updateSliceSettings();
54 void handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons);
54 void handleSliceClicked(QPieSlice* slice);
55 55 void showFontDialog();
56 56 void appendSlice();
57 57 void insertSlice();
58 58 void removeSlice();
59 59
60 60 private:
61 61 QComboBox *m_themeComboBox;
62 62 QCheckBox *m_aaCheckBox;
63 63 QCheckBox *m_animationsCheckBox;
64 QCheckBox *m_legendCheckBox;
64 65
65 66 QChartView* m_chartView;
66 67 QPieSeries* m_series;
67 68 CustomSlice* m_slice;
68 69
69 70 QDoubleSpinBox* m_hPosition;
70 71 QDoubleSpinBox* m_vPosition;
71 72 QDoubleSpinBox* m_sizeFactor;
72 73 QDoubleSpinBox* m_startAngle;
73 74 QDoubleSpinBox* m_endAngle;
74 75
75 76 QLabel* m_sliceName;
76 77 QDoubleSpinBox* m_sliceValue;
77 78 QCheckBox* m_sliceLabelVisible;
78 79 QDoubleSpinBox* m_sliceLabelArmFactor;
79 80 QCheckBox* m_sliceExploded;
80 81 QDoubleSpinBox* m_sliceExplodedFactor;
81 82 QPushButton *m_brush;
82 83 BrushTool *m_brushTool;
83 84 QPushButton *m_pen;
84 85 PenTool *m_penTool;
85 86 QPushButton *m_font;
86 87 QPushButton *m_labelPen;
87 88 PenTool *m_labelPenTool;
88 89 };
89 90
90 91 #endif // MAINWIDGET_H
@@ -1,70 +1,63
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "drilldownslice.h"
22 22
23 23 QTCOMMERCIALCHART_USE_NAMESPACE
24 24
25 25 DrilldownSlice::DrilldownSlice(qreal value, QString prefix, QAbstractSeries* drilldownSeries)
26 26 :m_drilldownSeries(drilldownSeries),
27 27 m_prefix(prefix)
28 28 {
29 29 setValue(value);
30 30 updateLabel();
31 31 setLabelFont(QFont("Arial", 8));
32 32 connect(this, SIGNAL(changed()), this, SLOT(updateLabel()));
33 connect(this, SIGNAL(hoverEnter()), this, SLOT(showHighlight()));
34 connect(this, SIGNAL(hoverLeave()), this, SLOT(hideHighlight()));
33 connect(this, SIGNAL(hovered(bool)), this, SLOT(showHighlight(bool)));
35 34 }
36 35
37 36 DrilldownSlice::~DrilldownSlice()
38 37 {
39 38
40 39 }
41 40
42 41 QAbstractSeries* DrilldownSlice::drilldownSeries() const
43 42 {
44 43 return m_drilldownSeries;
45 44 }
46 45
47 46 void DrilldownSlice::updateLabel()
48 47 {
49 48 QString label = m_prefix;
50 49 label += " $";
51 50 label += QString::number(this->value());
52 51 label += ", ";
53 52 label += QString::number(this->percentage()*100, 'f', 1);
54 53 label += "%";
55 54 setLabel(label);
56 55 }
57 56
58 void DrilldownSlice::showHighlight()
57 void DrilldownSlice::showHighlight(bool show)
59 58 {
60 setExploded();
61 setLabelVisible();
62 }
63
64 void DrilldownSlice::hideHighlight()
65 {
66 setExploded(false);
67 setLabelVisible(false);
59 setExploded(show);
60 setLabelVisible(show);
68 61 }
69 62
70 63 #include "moc_drilldownslice.cpp"
@@ -1,50 +1,49
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20 #ifndef DRILLDOWNSLICE_H
21 21 #define DRILLDOWNSLICE_H
22 22
23 23 #include <QPieSlice>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26 class QAbstractSeries;
27 27 QTCOMMERCIALCHART_END_NAMESPACE
28 28
29 29 QTCOMMERCIALCHART_USE_NAMESPACE
30 30
31 31 class DrilldownSlice : public QPieSlice
32 32 {
33 33 Q_OBJECT
34 34
35 35 public:
36 36 DrilldownSlice(qreal value, QString prefix, QAbstractSeries* drilldownSeries);
37 37 virtual ~DrilldownSlice();
38 38 QAbstractSeries* drilldownSeries() const;
39 39
40 40 public Q_SLOTS:
41 41 void updateLabel();
42 void showHighlight();
43 void hideHighlight();
42 void showHighlight(bool show);
44 43
45 44 private:
46 45 QAbstractSeries* m_drilldownSeries;
47 46 QString m_prefix;
48 47 };
49 48
50 49 #endif // DRILLDOWNSLICE_H
@@ -1,77 +1,77
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "drilldownchart.h"
22 22 #include "drilldownslice.h"
23 23 #include <QtGui/QApplication>
24 24 #include <QMainWindow>
25 25 #include <QTime>
26 26 #include <QChartView>
27 27 #include <QLegend>
28 28 #include <QPieSeries>
29 29
30 30 QTCOMMERCIALCHART_USE_NAMESPACE
31 31
32 32 int main(int argc, char *argv[])
33 33 {
34 34 QApplication a(argc, argv);
35 35
36 36 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
37 37
38 38 QMainWindow window;
39 39
40 40 DrilldownChart* chart = new DrilldownChart();
41 41 chart->setTheme(QChart::ChartThemeLight);
42 42 chart->setAnimationOptions(QChart::AllAnimations);
43 43 chart->legend()->setVisible(true);
44 44 chart->legend()->setAlignment(QLegend::AlignmentRight);
45 45
46 46 QPieSeries* yearSeries = new QPieSeries(&window);
47 47 yearSeries->setName("Sales by year - All");
48 48
49 49 QList<QString> months;
50 50 months << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
51 51 QList<QString> names;
52 52 names << "Jane" << "John" << "Axel" << "Mary" << "Susan" << "Bob";
53 53
54 54 foreach (QString name, names) {
55 55 QPieSeries* series = new QPieSeries(&window);
56 56 series->setName("Sales by month - " + name);
57 57
58 58 foreach (QString month, months)
59 59 *series << new DrilldownSlice(qrand() % 1000, month, yearSeries);
60 60
61 QObject::connect(series, SIGNAL(clicked(QPieSlice*,Qt::MouseButtons)), chart, SLOT(handleSliceClicked(QPieSlice*)));
61 QObject::connect(series, SIGNAL(clicked(QPieSlice*)), chart, SLOT(handleSliceClicked(QPieSlice*)));
62 62
63 63 *yearSeries << new DrilldownSlice(series->sum(), name, series);
64 64 }
65 65
66 QObject::connect(yearSeries, SIGNAL(clicked(QPieSlice*,Qt::MouseButtons)), chart, SLOT(handleSliceClicked(QPieSlice*)));
66 QObject::connect(yearSeries, SIGNAL(clicked(QPieSlice*)), chart, SLOT(handleSliceClicked(QPieSlice*)));
67 67
68 68 chart->changeSeries(yearSeries);
69 69
70 70 QChartView* chartView = new QChartView(chart);
71 71 chartView->setRenderHint(QPainter::Antialiasing);
72 72 window.setCentralWidget(chartView);
73 73 window.resize(800, 500);
74 74 window.show();
75 75
76 76 return a.exec();
77 77 }
@@ -1,194 +1,194
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "legendmarker_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "qlegend.h"
25 25 #include "qbarseries.h"
26 26 #include "qpieseries.h"
27 27 #include "qpieslice.h"
28 28 #include "qbarset.h"
29 29 #include "qbarset_p.h"
30 30 #include "qareaseries.h"
31 31 #include "qareaseries_p.h"
32 32 #include <QPainter>
33 33 #include <QGraphicsSceneEvent>
34 34 #include <QGraphicsSimpleTextItem>
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) : QGraphicsObject(legend),
39 39 m_series(series),
40 40 m_markerRect(0,0,10.0,10.0),
41 41 m_boundingRect(0,0,0,0),
42 42 m_legend(legend),
43 43 m_textItem(new QGraphicsSimpleTextItem(this)),
44 44 m_rectItem(new QGraphicsRectItem(this))
45 45 {
46 46 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
47 47 m_rectItem->setRect(m_markerRect);
48 48 updateLayout();
49 49 }
50 50
51 51 void LegendMarker::setPen(const QPen &pen)
52 52 {
53 53 m_textItem->setPen(pen);
54 54 updateLayout();
55 55 }
56 56
57 57 QPen LegendMarker::pen() const
58 58 {
59 59 return m_textItem->pen();
60 60 }
61 61
62 62 void LegendMarker::setBrush(const QBrush &brush)
63 63 {
64 64 m_rectItem->setBrush(brush);
65 65 }
66 66
67 67 QBrush LegendMarker::brush() const
68 68 {
69 69 return m_rectItem->brush();
70 70 }
71 71
72 72 void LegendMarker::setLabel(const QString name)
73 73 {
74 74 m_textItem->setText(name);
75 75 updateLayout();
76 76 }
77 77
78 78 void LegendMarker::setSize(const QSize& size)
79 79 {
80 80 m_markerRect = QRectF(0,0,size.width(),size.height());
81 81 }
82 82
83 83 QString LegendMarker::label() const
84 84 {
85 85 return m_textItem->text();
86 86 }
87 87
88 88 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
89 89 {
90 90 Q_UNUSED(option)
91 91 Q_UNUSED(widget)
92 92 Q_UNUSED(painter)
93 93 }
94 94
95 95 QRectF LegendMarker::boundingRect() const
96 96 {
97 97 return m_boundingRect;
98 98 }
99 99
100 100 void LegendMarker::updateLayout()
101 101 {
102 102
103 103 static const qreal margin = 2;
104 104 static const qreal space = 4;
105 105
106 106 const QRectF& textRect = m_textItem->boundingRect();
107 107 prepareGeometryChange();
108 108 m_boundingRect = QRectF(0,0,m_markerRect.width() + 2*margin + space + textRect.width(),qMax(m_markerRect.height()+2*margin,textRect.height()+2*margin));
109 109 m_textItem->setPos(m_markerRect.width() + space + margin,m_boundingRect.height()/2 - textRect.height()/2);
110 110 m_rectItem->setPos(margin,m_boundingRect.height()/2 - m_markerRect.height()/2);
111 111
112 112 }
113 113
114 114 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
115 115 {
116 116 QGraphicsObject::mousePressEvent(event);
117 117 emit selected();
118 118 }
119 119
120 120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
121 121
122 122 AreaLegendMarker::AreaLegendMarker(QAreaSeries *series,QLegend *legend) : LegendMarker(series,legend),
123 123 m_series(series)
124 124 {
125 125 QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
126 126 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
127 127 updated();
128 128 }
129 129
130 130 void AreaLegendMarker::updated()
131 131 {
132 132 setBrush(m_series->brush());
133 133 setLabel(m_series->name());
134 134 }
135 135
136 136 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
137 137
138 138 BarLegendMarker::BarLegendMarker(QBarSeries *barseries,QBarSet *barset, QLegend *legend) : LegendMarker(barseries,legend),
139 139 m_barset(barset)
140 140 {
141 141 QObject::connect(this, SIGNAL(selected()),barseries, SIGNAL(selected()));
142 142 QObject::connect(barset->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(updated()));
143 143 updated();
144 144 }
145 145
146 146 void BarLegendMarker::updated()
147 147 {
148 148 setBrush(m_barset->brush());
149 149 setLabel(m_barset->name());
150 150 }
151 151
152 152 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
153 153
154 154 PieLegendMarker::PieLegendMarker(QPieSeries* series,QPieSlice *pieslice, QLegend *legend) : LegendMarker(series,legend),
155 155 m_pieslice(pieslice)
156 156 {
157 QObject::connect(this, SIGNAL(selected()),pieslice, SIGNAL(selected()));
157 QObject::connect(this, SIGNAL(selected()),pieslice, SIGNAL(clicked()));
158 158 QObject::connect(pieslice, SIGNAL(changed()), this, SLOT(updated()));
159 159 updated();
160 160 }
161 161
162 162 void PieLegendMarker::updated()
163 163 {
164 164 setBrush(m_pieslice->brush());
165 165 setLabel(m_pieslice->label());
166 166 }
167 167
168 168 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
169 169
170 170 XYLegendMarker::XYLegendMarker(QXYSeries *series, QLegend *legend) : LegendMarker(series,legend),
171 171 m_series(series)
172 172 {
173 173 QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
174 174 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
175 175 updated();
176 176 }
177 177
178 178 void XYLegendMarker::updated()
179 179 {
180 180 setLabel(m_series->name());
181 181
182 182 if(m_series->type()== QAbstractSeries::SeriesTypeScatter)
183 183 {
184 184 setBrush(m_series->brush());
185 185
186 186 }
187 187 else {
188 188 setBrush(QBrush(m_series->pen().color()));
189 189 }
190 190 }
191 191
192 192 #include "moc_legendmarker_p.cpp"
193 193
194 194 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,460 +1,463
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qlegend.h"
22 22 #include "qlegend_p.h"
23 23 #include "qabstractseries.h"
24 24 #include "qabstractseries_p.h"
25 25 #include "qchart_p.h"
26 26
27 27 #include "legendmarker_p.h"
28 28 #include "qxyseries.h"
29 29 #include "qlineseries.h"
30 30 #include "qareaseries.h"
31 31 #include "qscatterseries.h"
32 32 #include "qsplineseries.h"
33 33 #include "qbarseries.h"
34 34 #include "qstackedbarseries.h"
35 35 #include "qpercentbarseries.h"
36 36 #include "qbarset.h"
37 37 #include "qpieseries.h"
38 #include "qpieseries_p.h"
38 39 #include "qpieslice.h"
39 40 #include "chartpresenter_p.h"
40 41 #include <QPainter>
41 42 #include <QPen>
42 43 #include <QTimer>
43 44
44 45 #include <QGraphicsSceneEvent>
45 46
46 47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47 48
48 49 /*!
49 50 \class QLegend
50 51 \brief part of QtCommercial chart API.
51 52 \mainclass
52 53
53 54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
54 55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
55 56 handle the drawing manually.
56 57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
57 58
58 59 \image examples_percentbarchart_legend.png
59 60
60 61 \sa QChart
61 62 */
62 63
63 64 /*!
64 65 \enum QLegend::Alignment
65 66
66 67 This enum describes the possible position for legend inside chart.
67 68
68 69 \value AlignmentTop
69 70 \value AlignmentBottom
70 71 \value AlignmentLeft
71 72 \value AlignmentRight
72 73 */
73 74
74 75 /*!
75 76 \fn qreal QLegend::minWidth() const
76 77 Returns minimum width of the legend
77 78 */
78 79
79 80 /*!
80 81 \fn qreal QLegend::minHeight() const
81 82 Returns minimum height of the legend
82 83 */
83 84
84 85 /*!
85 86 Constructs the legend object and sets the parent to \a parent
86 87 */
87 88
88 89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
89 90 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
90 91 {
91 92 setZValue(ChartPresenter::LegendZValue);
92 93 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
93 94 setEnabled(false); // By default legend is disabled
94 95 setVisible(false);
95 96 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries *,Domain*)));
96 97 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries *)));
97 98 }
98 99
99 100 /*!
100 101 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
101 102 */
102 103 QLegend::~QLegend()
103 104 {
104 105 }
105 106
106 107 /*!
107 108 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
108 109 */
109 110
110 111 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
111 112 {
112 113 Q_UNUSED(option)
113 114 Q_UNUSED(widget)
114 115 if(!d_ptr->m_backgroundVisible) return;
115 116
116 117 painter->setOpacity(opacity());
117 118 painter->setPen(d_ptr->m_pen);
118 119 painter->setBrush(d_ptr->m_brush);
119 120 painter->drawRect(boundingRect());
120 121 }
121 122
122 123 /*!
123 124 Bounding rect of legend.
124 125 */
125 126
126 127 QRectF QLegend::boundingRect() const
127 128 {
128 129 return d_ptr->m_rect;
129 130 }
130 131
131 132 /*!
132 133 Sets the \a brush of legend. Brush affects the background of legend.
133 134 */
134 135 void QLegend::setBrush(const QBrush &brush)
135 136 {
136 137 if (d_ptr->m_brush != brush) {
137 138 d_ptr->m_brush = brush;
138 139 update();
139 140 }
140 141 }
141 142
142 143 /*!
143 144 Returns the brush used by legend.
144 145 */
145 146 QBrush QLegend::brush() const
146 147 {
147 148 return d_ptr->m_brush;
148 149 }
149 150
150 151 /*!
151 152 Sets the \a pen of legend. Pen affects the legend borders.
152 153 */
153 154 void QLegend::setPen(const QPen &pen)
154 155 {
155 156 if (d_ptr->m_pen != pen) {
156 157 d_ptr->m_pen = pen;
157 158 update();
158 159 }
159 160 }
160 161
161 162 /*!
162 163 Returns the pen used by legend
163 164 */
164 165
165 166 QPen QLegend::pen() const
166 167 {
167 168 return d_ptr->m_pen;
168 169 }
169 170
170 171 /*!
171 172 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
172 173 \sa QLegend::Alignment
173 174 */
174 175 void QLegend::setAlignment(QLegend::Alignments alignment)
175 176 {
176 177 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
177 178 d_ptr->m_alignment = alignment;
178 179 d_ptr->updateLayout();
179 180 }
180 181 }
181 182
182 183 /*!
183 184 Returns the preferred layout for legend
184 185 */
185 186 QLegend::Alignments QLegend::alignment() const
186 187 {
187 188 return d_ptr->m_alignment;
188 189 }
189 190
190 191 /*!
191 192 Detaches the legend from chart. Chart won't change layout of the legend.
192 193 */
193 194 void QLegend::detachFromChart()
194 195 {
195 196 d_ptr->m_attachedToChart = false;
196 197 }
197 198
198 199 /*!
199 200 Attaches the legend to chart. Chart may change layout of the legend.
200 201 */
201 202 void QLegend::attachToChart()
202 203 {
203 204 d_ptr->m_attachedToChart = true;
204 205 }
205 206
206 207 /*!
207 208 Returns true, if legend is attached to chart.
208 209 */
209 210 bool QLegend::isAttachedToChart()
210 211 {
211 212 return d_ptr->m_attachedToChart;
212 213 }
213 214
214 215 /*!
215 216 Sets the legend's scrolling offset to value defined by \a point.
216 217 */
217 218 void QLegend::setOffset(const QPointF& point)
218 219 {
219 220 d_ptr->setOffset(point.x(),point.y());
220 221 }
221 222
222 223 /*!
223 224 Returns the legend's scrolling offset.
224 225 */
225 226 QPointF QLegend::offset() const
226 227 {
227 228 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
228 229 }
229 230
230 231 /*!
231 232 Sets the visibility of legend background to \a visible
232 233 */
233 234 void QLegend::setBackgroundVisible(bool visible)
234 235 {
235 236 if(d_ptr->m_backgroundVisible!=visible)
236 237 {
237 238 d_ptr->m_backgroundVisible=visible;
238 239 update();
239 240 }
240 241 }
241 242
242 243 /*!
243 244 Returns the visibility of legend background
244 245 */
245 246 bool QLegend::isBackgroundVisible() const
246 247 {
247 248 return d_ptr->m_backgroundVisible;
248 249 }
249 250
250 251 /*!
251 252 \internal \a event see QGraphicsWidget for details
252 253 */
253 254 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
254 255 {
255 256 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
256 257 QGraphicsWidget::resizeEvent(event);
257 258 if(d_ptr->m_rect != rect) {
258 259 d_ptr->m_rect = rect;
259 260 d_ptr->updateLayout();
260 261 }
261 262 }
262 263
263 264 /*!
264 265 \internal \a event see QGraphicsWidget for details
265 266 */
266 267 void QLegend::hideEvent(QHideEvent *event)
267 268 {
268 269 QGraphicsWidget::hideEvent(event);
269 270 setEnabled(false);
270 271 d_ptr->updateLayout();
271 272 }
272 273
273 274 /*!
274 275 \internal \a event see QGraphicsWidget for details
275 276 */
276 277 void QLegend::showEvent(QShowEvent *event)
277 278 {
278 279 QGraphicsWidget::showEvent(event);
279 280 setEnabled(true);
280 281 d_ptr->updateLayout();
281 282 }
282 283
283 284 qreal QLegend::minWidth() const
284 285 {
285 286 return d_ptr->m_minWidth;
286 287 }
287 288
288 289 qreal QLegend::minHeight() const
289 290 {
290 291 return d_ptr->m_minHeight;
291 292 }
292 293
293 294 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
294 295
295 296 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
296 297 q_ptr(q),
297 298 m_presenter(presenter),
298 299 m_markers(new QGraphicsItemGroup(q)),
299 300 m_alignment(QLegend::AlignmentTop),
300 301 m_offsetX(0),
301 302 m_offsetY(0),
302 303 m_minWidth(0),
303 304 m_minHeight(0),
304 305 m_width(0),
305 306 m_height(0),
306 307 m_attachedToChart(true),
307 308 m_backgroundVisible(false)
308 309 {
309 310
310 311 }
311 312
312 313 QLegendPrivate::~QLegendPrivate()
313 314 {
314 315
315 316 }
316 317
317 318 void QLegendPrivate::setOffset(qreal x, qreal y)
318 319 {
319 320
320 321 switch(m_alignment) {
321 322
322 323 case QLegend::AlignmentTop:
323 324 case QLegend::AlignmentBottom: {
324 325 if(m_width<=m_rect.width()) return;
325 326
326 327 if (x != m_offsetX) {
327 328 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
328 329 m_markers->setPos(-m_offsetX,m_rect.top());
329 330 }
330 331 break;
331 332 }
332 333 case QLegend::AlignmentLeft:
333 334 case QLegend::AlignmentRight: {
334 335
335 336 if(m_height<=m_rect.height()) return;
336 337
337 338 if (y != m_offsetY) {
338 339 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
339 340 m_markers->setPos(m_rect.left(),-m_offsetY);
340 341 }
341 342 break;
342 343 }
343 344 }
344 345 }
345 346
346 347
347 348 void QLegendPrivate::updateLayout()
348 349 {
349 350 m_offsetX=0;
350 351 QList<QGraphicsItem *> items = m_markers->childItems();
351 352
352 353 if(items.isEmpty()) return;
353 354
354 355 m_minWidth=0;
355 356 m_minHeight=0;
356 357
357 358 switch(m_alignment) {
358 359
359 360 case QLegend::AlignmentTop:
360 361 case QLegend::AlignmentBottom: {
361 362 QPointF point = m_rect.topLeft();
362 363 m_width = 0;
363 364 foreach (QGraphicsItem *item, items) {
364 365 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
365 366 const QRectF& rect = item->boundingRect();
366 367 qreal w = rect.width();
367 368 m_minWidth=qMax(m_minWidth,w);
368 369 m_minHeight=qMax(m_minHeight,rect.height());
369 370 m_width+=w;
370 371 point.setX(point.x() + w);
371 372 }
372 373 if(m_width<m_rect.width()) {
373 374 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
374 375 }
375 376 else {
376 377 m_markers->setPos(m_rect.topLeft());
377 378 }
378 379 m_height=m_minHeight;
379 380 }
380 381 break;
381 382 case QLegend::AlignmentLeft:
382 383 case QLegend::AlignmentRight: {
383 384 QPointF point = m_rect.topLeft();
384 385 m_height = 0;
385 386 foreach (QGraphicsItem *item, items) {
386 387 item->setPos(point);
387 388 const QRectF& rect = item->boundingRect();
388 389 qreal h = rect.height();
389 390 m_minWidth=qMax(m_minWidth,rect.width());
390 391 m_minHeight=qMax(m_minHeight,h);
391 392 m_height+=h;
392 393 point.setY(point.y() + h);
393 394 }
394 395 if(m_height<m_rect.height()) {
395 396 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
396 397 }
397 398 else {
398 399 m_markers->setPos(m_rect.topLeft());
399 400 }
400 401 m_width=m_minWidth;
401 402 }
402 403 break;
403 404 }
404 405
405 406 m_presenter->updateLayout();
406 407 }
407 408
408 409 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
409 410 {
410 411 Q_UNUSED(domain)
411 412
412 413 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
413 414 foreach(LegendMarker* marker , markers)
414 415 m_markers->addToGroup(marker);
415 416
416 417 if(series->type() == QAbstractSeries::SeriesTypePie)
417 418 {
418 419 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
419 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
420 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
420 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*pieSeries);
421 QObject::connect(d, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
422 QObject::connect(d, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
421 423 }
422 424
423 425 updateLayout();
424 426 }
425 427
426 428 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
427 429 {
428 430
429 431 QList<QGraphicsItem *> items = m_markers->childItems();
430 432
431 433 foreach (QGraphicsItem *markers, items) {
432 434 LegendMarker *marker = static_cast<LegendMarker*>(markers);
433 435 if (marker->series() == series) {
434 436 delete marker;
435 437 }
436 438 }
437 439
438 440 if(series->type() == QAbstractSeries::SeriesTypePie)
439 441 {
440 442 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
441 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
442 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
443 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*pieSeries);
444 QObject::disconnect(d, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
445 QObject::disconnect(d, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
443 446 }
444 447
445 448 updateLayout();
446 449 }
447 450
448 void QLegendPrivate::handleUpdateSeries()
451 void QLegendPrivate::handleUpdatePieSeries()
449 452 {
450 453 //TODO: reimplement to be optimal
451 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
452 Q_ASSERT(series);
453 handleSeriesRemoved(series);
454 handleSeriesAdded(series,0);
454 QPieSeriesPrivate* d = qobject_cast<QPieSeriesPrivate *> (sender());
455 Q_ASSERT(d->q_func());
456 handleSeriesRemoved(d->q_func());
457 handleSeriesAdded(d->q_func(), 0);
455 458 }
456 459
457 460 #include "moc_qlegend.cpp"
458 461 #include "moc_qlegend_p.cpp"
459 462
460 463 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,78 +1,78
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QLEGEND_P_H
31 31 #define QLEGEND_P_H
32 32
33 33 #include "qlegend.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class ChartPresenter;
38 38 class QAbstractSeries;
39 39
40 40 class QLegendPrivate : public QObject
41 41 {
42 42 Q_OBJECT
43 43 public:
44 44 QLegendPrivate(ChartPresenter *chart,QLegend *q);
45 45 ~QLegendPrivate();
46 46
47 47 void setOffset(qreal x, qreal y);
48 48 void updateLayout();
49 49
50 50 public Q_SLOTS:
51 51 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
52 52 void handleSeriesRemoved(QAbstractSeries *series);
53 void handleUpdateSeries(); //TODO remove this function
53 void handleUpdatePieSeries(); //TODO remove this function
54 54
55 55 private:
56 56 QLegend *q_ptr;
57 57 ChartPresenter *m_presenter;
58 58 QGraphicsItemGroup* m_markers;
59 59 QLegend::Alignments m_alignment;
60 60 QBrush m_brush;
61 61 QPen m_pen;
62 62 QRectF m_rect;
63 63 qreal m_offsetX;
64 64 qreal m_offsetY;
65 65 qreal m_minWidth;
66 66 qreal m_minHeight;
67 67 qreal m_width;
68 68 qreal m_height;
69 69 bool m_attachedToChart;
70 70 bool m_backgroundVisible;
71 71
72 72 friend class QLegend;
73 73
74 74 };
75 75
76 76 QTCOMMERCIALCHART_END_NAMESPACE
77 77
78 78 #endif
@@ -1,210 +1,212
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "piechartitem_p.h"
22 22 #include "piesliceitem_p.h"
23 23 #include "qpieslice.h"
24 24 #include "qpieseries.h"
25 #include "qpieseries_p.h"
25 26 #include "chartpresenter_p.h"
26 27 #include "chartdataset_p.h"
27 28 #include "chartanimator_p.h"
28 29 #include <QPainter>
29 30 #include <QTimer>
30 31
31 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 33
33 34 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
34 35 :ChartItem(presenter),
35 36 m_series(series)
36 37 {
37 38 Q_ASSERT(series);
38 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
39 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
40 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
41 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
39
40 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*series);
41 connect(d, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
42 connect(d, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
43 connect(d, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
44 connect(d, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
42 45
43 46 QTimer::singleShot(0, this, SLOT(initialize())); // TODO: get rid of this
44 47
45 48 // Note: the following does not affect as long as the item does not have anything to paint
46 49 setZValue(ChartPresenter::PieSeriesZValue);
47 50 }
48 51
49 52 PieChartItem::~PieChartItem()
50 53 {
51 54 // slices deleted automatically through QGraphicsItem
52 55 }
53 56
54 57 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
55 58 {
56 59 Q_UNUSED(painter)
57 60 // TODO: paint shadows for all components
58 61 // - get paths from items & merge & offset and draw with shadow color?
59 62 //painter->setBrush(QBrush(Qt::red));
60 63 //painter->drawRect(m_debugRect);
61 64 }
62 65
63 66 void PieChartItem::initialize()
64 67 {
65 68 handleSlicesAdded(m_series->slices());
66 69 }
67 70
68 71 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
69 72 {
70 73 bool isEmpty = m_slices.isEmpty();
71 74
72 75 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
73 76
74 77 foreach (QPieSlice *s, slices) {
75 78 PieSliceItem* item = new PieSliceItem(this);
76 79 m_slices.insert(s, item);
77 80 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
78 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons)));
79 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
80 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
81 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked()));
82 connect(item, SIGNAL(hovered(bool)), s, SIGNAL(hovered(bool)));
81 83
82 84 PieSliceData data = sliceData(s);
83 85
84 86 if (animator())
85 87 animator()->addAnimation(this, s, data, isEmpty);
86 88 else
87 89 setLayout(s, data);
88 90 }
89 91 }
90 92
91 93 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
92 94 {
93 95 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
94 96
95 97 foreach (QPieSlice *s, slices) {
96 98 if (animator())
97 99 animator()->removeAnimation(this, s);
98 100 else
99 101 destroySlice(s);
100 102 }
101 103 }
102 104
103 105 void PieChartItem::handlePieLayoutChanged()
104 106 {
105 107 PieLayout layout = calculateLayout();
106 108 applyLayout(layout);
107 109 update();
108 110 }
109 111
110 112 void PieChartItem::handleSliceChanged()
111 113 {
112 114 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
113 115 Q_ASSERT(m_slices.contains(slice));
114 116 PieSliceData data = sliceData(slice);
115 117 updateLayout(slice, data);
116 118 update();
117 119 }
118 120
119 121 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
120 122 {
121 123 // TODO
122 124 }
123 125
124 126 void PieChartItem::handleGeometryChanged(const QRectF& rect)
125 127 {
126 128 prepareGeometryChange();
127 129 m_rect = rect;
128 130 handlePieLayoutChanged();
129 131 }
130 132
131 133 void PieChartItem::calculatePieLayout()
132 134 {
133 135 // find pie center coordinates
134 136 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
135 137 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
136 138
137 139 // find maximum radius for pie
138 140 m_pieRadius = m_rect.height() / 2;
139 141 if (m_rect.width() < m_rect.height())
140 142 m_pieRadius = m_rect.width() / 2;
141 143
142 144 // apply size factor
143 145 m_pieRadius *= m_series->pieSize();
144 146 }
145 147
146 148 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
147 149 {
148 150 // TODO: This function is kid of useless now. Refactor.
149 151 PieSliceData sliceData = PieSliceData::data(slice);
150 152 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
151 153 sliceData.m_radius = m_pieRadius;
152 154 return sliceData;
153 155 }
154 156
155 157 PieLayout PieChartItem::calculateLayout()
156 158 {
157 159 calculatePieLayout();
158 160 PieLayout layout;
159 161 foreach (QPieSlice* s, m_series->slices()) {
160 162 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
161 163 layout.insert(s, sliceData(s));
162 164 }
163 165 return layout;
164 166 }
165 167
166 168 void PieChartItem::applyLayout(const PieLayout &layout)
167 169 {
168 170 if (animator())
169 171 animator()->updateLayout(this, layout);
170 172 else
171 173 setLayout(layout);
172 174 }
173 175
174 176 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
175 177 {
176 178 if (animator())
177 179 animator()->updateLayout(this, slice, sliceData);
178 180 else
179 181 setLayout(slice, sliceData);
180 182 }
181 183
182 184 void PieChartItem::setLayout(const PieLayout &layout)
183 185 {
184 186 foreach (QPieSlice *slice, layout.keys()) {
185 187 PieSliceItem *item = m_slices.value(slice);
186 188 Q_ASSERT(item);
187 189 item->setSliceData(layout.value(slice));
188 190 item->updateGeometry();
189 191 item->update();
190 192 }
191 193 }
192 194
193 195 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
194 196 {
195 197 // find slice
196 198 PieSliceItem *item = m_slices.value(slice);
197 199 Q_ASSERT(item);
198 200 item->setSliceData(sliceData);
199 201 item->updateGeometry();
200 202 item->update();
201 203 }
202 204
203 205 void PieChartItem::destroySlice(QPieSlice *slice)
204 206 {
205 207 delete m_slices.take(slice);
206 208 }
207 209
208 210 #include "moc_piechartitem_p.cpp"
209 211
210 212 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,212 +1,212
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "piesliceitem_p.h"
22 22 #include "piechartitem_p.h"
23 23 #include "qpieseries.h"
24 24 #include "qpieslice.h"
25 25 #include "chartpresenter_p.h"
26 26 #include <QPainter>
27 27 #include <qmath.h>
28 28 #include <QGraphicsSceneEvent>
29 29 #include <QTime>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 #define PI 3.14159265 // TODO: is this defined in some header?
34 34
35 35 QPointF offset(qreal angle, qreal length)
36 36 {
37 37 qreal dx = qSin(angle*(PI/180)) * length;
38 38 qreal dy = qCos(angle*(PI/180)) * length;
39 39 return QPointF(dx, -dy);
40 40 }
41 41
42 42 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
43 43 :QGraphicsObject(parent)
44 44 {
45 45 setAcceptHoverEvents(true);
46 46 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 47 setZValue(ChartPresenter::PieSeriesZValue);
48 48 }
49 49
50 50 PieSliceItem::~PieSliceItem()
51 51 {
52 52
53 53 }
54 54
55 55 QRectF PieSliceItem::boundingRect() const
56 56 {
57 57 return m_boundingRect;
58 58 }
59 59
60 60 QPainterPath PieSliceItem::shape() const
61 61 {
62 62 // Don't include the label and label arm.
63 63 // This is used to detect a mouse clicks. We do not want clicks from label.
64 64 return m_slicePath;
65 65 }
66 66
67 67 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
68 68 {
69 69 painter->save();
70 70 painter->setClipRect(parentItem()->boundingRect());
71 71 painter->setPen(m_data.m_slicePen);
72 72 painter->setBrush(m_data.m_sliceBrush);
73 73 painter->drawPath(m_slicePath);
74 74 painter->restore();
75 75
76 76 if (m_data.m_isLabelVisible) {
77 77 painter->setClipRect(parentItem()->boundingRect());
78 78 painter->setPen(m_data.m_labelPen);
79 79 painter->drawPath(m_labelArmPath);
80 80 // the pen color will affect the font color as well
81 81 painter->setFont(m_data.m_labelFont);
82 82 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
83 83 }
84 84 }
85 85
86 86 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
87 87 {
88 emit hoverEnter(); // TODO: refactor emit hover(somebooleanvalue)
88 emit hovered(true);
89 89 }
90 90
91 91 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
92 92 {
93 emit hoverLeave(); // TODO: refactor emit hover(somebooleanvalue)
93 emit hovered(false);
94 94 }
95 95
96 96 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
97 97 {
98 98 emit clicked(event->buttons());
99 99 }
100 100
101 101 void PieSliceItem::setSliceData(PieSliceData sliceData)
102 102 {
103 103 m_data = sliceData;
104 104 }
105 105
106 106 void PieSliceItem::updateGeometry()
107 107 {
108 108 if (m_data.m_radius <= 0)
109 109 return;
110 110
111 111 prepareGeometryChange();
112 112
113 113 // update slice path
114 114 qreal centerAngle;
115 115 QPointF armStart;
116 116 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
117 117
118 118 // update text rect
119 119 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
120 120
121 121 // update label arm path
122 122 QPointF labelTextStart;
123 123 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
124 124
125 125 // update text position
126 126 m_labelTextRect.moveBottomLeft(labelTextStart);
127 127
128 128 // update bounding rect
129 129 if (m_data.m_isLabelVisible)
130 130 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
131 131 else
132 132 m_boundingRect = m_slicePath.boundingRect();
133 133 }
134 134
135 135 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
136 136 {
137 137 if (slice->isExploded()) {
138 138 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
139 139 qreal len = radius * slice->explodeDistanceFactor();
140 140 qreal dx = qSin(centerAngle*(PI/180)) * len;
141 141 qreal dy = -qCos(centerAngle*(PI/180)) * len;
142 142 point += QPointF(dx, dy);
143 143 }
144 144 return point;
145 145 }
146 146
147 147 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF* armStart)
148 148 {
149 149 // calculate center angle
150 150 *centerAngle = startAngle + (angleSpan/2);
151 151
152 152 // calculate slice rectangle
153 153 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
154 154
155 155 // slice path
156 156 // TODO: draw the shape so that it might have a hole in the center
157 157 QPainterPath path;
158 158 path.moveTo(rect.center());
159 159 path.arcTo(rect, -startAngle + 90, -angleSpan);
160 160 path.closeSubpath();
161 161
162 162 // calculate label arm start point
163 163 *armStart = center;
164 164 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
165 165
166 166 return path;
167 167 }
168 168
169 169 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
170 170 {
171 171 // prevent label arm pointing straight down because it will look bad
172 172 if (angle < 180 && angle > 170)
173 173 angle = 170;
174 174 if (angle > 180 && angle < 190)
175 175 angle = 190;
176 176
177 177 // line from slice to label
178 178 qreal dx = qSin(angle*(PI/180)) * length;
179 179 qreal dy = -qCos(angle*(PI/180)) * length;
180 180 QPointF parm1 = start + QPointF(dx, dy);
181 181
182 182 // line to underline the label
183 183 QPointF parm2 = parm1;
184 184 if (angle < 180) { // arm swings the other way on the left side
185 185 parm2 += QPointF(textWidth, 0);
186 186 *textStart = parm1;
187 187 }
188 188 else {
189 189 parm2 += QPointF(-textWidth,0);
190 190 *textStart = parm2;
191 191 }
192 192
193 193 // elevate the text position a bit so that it does not hit the line
194 194 *textStart += QPointF(0, -3);
195 195
196 196 QPainterPath path;
197 197 path.moveTo(start);
198 198 path.lineTo(parm1);
199 199 path.lineTo(parm2);
200 200
201 201 return path;
202 202 }
203 203
204 204 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
205 205 {
206 206 QFontMetricsF fm(font);
207 207 return fm.boundingRect(text);
208 208 }
209 209
210 210 #include "moc_piesliceitem_p.cpp"
211 211
212 212 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,79 +1,78
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef PIESLICEITEM_H
22 22 #define PIESLICEITEM_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "charttheme_p.h"
26 26 #include "qpieseries.h"
27 27 #include "pieslicedata_p.h"
28 28 #include <QGraphicsItem>
29 29 #include <QRectF>
30 30 #include <QColor>
31 31 #include <QPen>
32 32
33 33 #define PIESLICE_LABEL_GAP 5
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36 class PieChartItem;
37 37 class PieSliceLabel;
38 38 class QPieSlice;
39 39
40 40 class PieSliceItem : public QGraphicsObject
41 41 {
42 42 Q_OBJECT
43 43
44 44 public:
45 45 PieSliceItem(QGraphicsItem* parent = 0);
46 46 ~PieSliceItem();
47 47
48 48 public: // from QGraphicsItem
49 49 QRectF boundingRect() const;
50 50 QPainterPath shape() const;
51 51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 52 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
53 53 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
54 54 void mousePressEvent(QGraphicsSceneMouseEvent *event);
55 55
56 56 Q_SIGNALS:
57 57 void clicked(Qt::MouseButtons buttons);
58 void hoverEnter();
59 void hoverLeave();
58 void hovered(bool state);
60 59
61 60 public:
62 61 void setSliceData(PieSliceData sliceData);
63 62 void updateGeometry();
64 63 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
65 64 QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart);
66 65 QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart);
67 66 QRectF labelTextRect(QFont font, QString text);
68 67
69 68 private:
70 69 PieSliceData m_data;
71 70 QRectF m_boundingRect;
72 71 QPainterPath m_slicePath;
73 72 QPainterPath m_labelArmPath;
74 73 QRectF m_labelTextRect;
75 74 };
76 75
77 76 QTCOMMERCIALCHART_END_NAMESPACE
78 77
79 78 #endif // PIESLICEITEM_H
@@ -1,740 +1,697
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qpieseries.h"
22 22 #include "qpieseries_p.h"
23 23 #include "qpieslice.h"
24 24 #include "pieslicedata_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 27 #include "chartanimator_p.h"
28 28 #include "legendmarker_p.h"
29 29 #include <QAbstractItemModel>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \class QPieSeries
35 35 \brief Pie series API for QtCommercial Charts
36 36
37 37 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 38 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 39 The actual slice size is determined by that relative value.
40 40
41 41 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 42 These relate to the actual chart rectangle.
43 43
44 44 By default the pie is defined as a full pie but it can also be a partial pie.
45 45 This can be done by setting a starting angle and angle span to the series.
46 46 Full pie is 360 degrees where 0 is at 12 a'clock.
47 47
48 48 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
49 49 \image examples_piechart.png
50 50 */
51 51
52 52 /*!
53 53 \property QPieSeries::horizontalPosition
54 54 \brief Defines the horizontal position of the pie.
55 55
56 56 The value is a relative value to the chart rectangle where:
57 57
58 58 \list
59 59 \o 0.0 is the absolute left.
60 60 \o 1.0 is the absolute right.
61 61 \endlist
62 62
63 63 Default value is 0.5 (center).
64 64 */
65 65
66 66 /*!
67 67 \property QPieSeries::verticalPosition
68 68 \brief Defines the vertical position of the pie.
69 69
70 70 The value is a relative value to the chart rectangle where:
71 71
72 72 \list
73 73 \o 0.0 is the absolute top.
74 74 \o 1.0 is the absolute bottom.
75 75 \endlist
76 76
77 77 Default value is 0.5 (center).
78 78 */
79 79
80 80 /*!
81 81 \property QPieSeries::size
82 82 \brief Defines the pie size.
83 83
84 84 The value is a relative value to the chart rectangle where:
85 85
86 86 \list
87 87 \o 0.0 is the minimum size (pie not drawn).
88 88 \o 1.0 is the maximum size that can fit the chart.
89 89 \endlist
90 90
91 91 Default value is 0.7.
92 92 */
93 93
94 94 /*!
95 95 \property QPieSeries::startAngle
96 96 \brief Defines the starting angle of the pie.
97 97
98 98 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
99 99
100 100 Default is value is 0.
101 101 */
102 102
103 103 /*!
104 104 \property QPieSeries::endAngle
105 105 \brief Defines the ending angle of the pie.
106 106
107 107 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
108 108
109 109 Default is value is 360.
110 110 */
111 111
112 112
113 113 /*!
114 114 Constructs a series object which is a child of \a parent.
115 115 */
116 116 QPieSeries::QPieSeries(QObject *parent) :
117 117 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
118 118 {
119 119
120 120 }
121 121
122 122 /*!
123 123 Destroys the series and its slices.
124 124 */
125 125 QPieSeries::~QPieSeries()
126 126 {
127 127 // NOTE: d_prt destroyed by QObject
128 128 }
129 129
130 130 /*!
131 131 Returns QChartSeries::SeriesTypePie.
132 132 */
133 133 QAbstractSeries::QSeriesType QPieSeries::type() const
134 134 {
135 135 return QAbstractSeries::SeriesTypePie;
136 136 }
137 137
138 138 /*!
139 139 Sets an array of \a slices to the series replacing the existing slices.
140 140 Slice ownership is passed to the series.
141 141 */
142 142 void QPieSeries::replace(QList<QPieSlice*> slices)
143 143 {
144 144 clear();
145 145 append(slices);
146 146 }
147 147
148 148 /*!
149 149 Appends an array of \a slices to the series.
150 150 Slice ownership is passed to the series.
151 151 */
152 152 void QPieSeries::append(QList<QPieSlice*> slices)
153 153 {
154 154 Q_D(QPieSeries);
155 155
156 156 foreach (QPieSlice* s, slices) {
157 157 s->setParent(this);
158 158 d->m_slices << s;
159 159 }
160 160
161 161 d->updateDerivativeData();
162 162
163 163 foreach (QPieSlice* s, slices) {
164 164 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
165 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
166 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
167 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
165 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
166 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
168 167 }
169 168
170 emit added(slices);
169 emit d->added(slices);
171 170 }
172 171
173 172 /*!
174 173 Appends a single \a slice to the series.
175 174 Slice ownership is passed to the series.
176 175 */
177 176 void QPieSeries::append(QPieSlice* slice)
178 177 {
179 178 append(QList<QPieSlice*>() << slice);
180 179 }
181 180
182 181 /*!
183 182 Appends a single \a slice to the series and returns a reference to the series.
184 183 Slice ownership is passed to the series.
185 184 */
186 185 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
187 186 {
188 187 append(slice);
189 188 return *this;
190 189 }
191 190
192 191
193 192 /*!
194 193 Appends a single slice to the series with give \a value and \a name.
195 194 Slice ownership is passed to the series.
196 195 */
197 196 QPieSlice* QPieSeries::append(qreal value, QString name)
198 197 {
199 198 QPieSlice* slice = new QPieSlice(value, name);
200 199 append(slice);
201 200 return slice;
202 201 }
203 202
204 203 /*!
205 204 Inserts a single \a slice to the series before the slice at \a index position.
206 205 Slice ownership is passed to the series.
207 206 */
208 207 void QPieSeries::insert(int index, QPieSlice* slice)
209 208 {
210 209 Q_D(QPieSeries);
211 210 Q_ASSERT(index <= d->m_slices.count());
212 211 slice->setParent(this);
213 212 d->m_slices.insert(index, slice);
214 213
215 214 d->updateDerivativeData();
216 215
217 216 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
218 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
219 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
220 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
217 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
218 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
221 219
222 emit added(QList<QPieSlice*>() << slice);
220 emit d->added(QList<QPieSlice*>() << slice);
223 221 }
224 222
225 223 /*!
226 224 Removes a single \a slice from the series and deletes the slice.
227 225
228 226 Do not reference the pointer after this call.
229 227 */
230 228 void QPieSeries::remove(QPieSlice* slice)
231 229 {
232 230 Q_D(QPieSeries);
233 231 if (!d->m_slices.removeOne(slice)) {
234 232 Q_ASSERT(0); // TODO: how should this be reported?
235 233 return;
236 234 }
237 235
238 236 d->updateDerivativeData();
239 237
240 emit removed(QList<QPieSlice*>() << slice);
238 emit d->removed(QList<QPieSlice*>() << slice);
241 239
242 240 delete slice;
243 241 slice = 0;
244 242 }
245 243
246 244 /*!
247 245 Clears all slices from the series.
248 246 */
249 247 void QPieSeries::clear()
250 248 {
251 249 Q_D(QPieSeries);
252 250 if (d->m_slices.count() == 0)
253 251 return;
254 252
255 253 QList<QPieSlice*> slices = d->m_slices;
256 254 foreach (QPieSlice* s, d->m_slices) {
257 255 d->m_slices.removeOne(s);
258 256 delete s;
259 257 }
260 258
261 259 d->updateDerivativeData();
262 260
263 emit removed(slices);
261 emit d->removed(slices);
264 262 }
265 263
266 264 /*!
267 265 returns the number of the slices in this series.
268 266 */
269 267 int QPieSeries::count() const
270 268 {
271 269 Q_D(const QPieSeries);
272 270 return d->m_slices.count();
273 271 }
274 272
275 273 /*!
276 274 Returns true is the series is empty.
277 275 */
278 276 bool QPieSeries::isEmpty() const
279 277 {
280 278 Q_D(const QPieSeries);
281 279 return d->m_slices.isEmpty();
282 280 }
283 281
284 282 /*!
285 283 Returns a list of slices that belong to this series.
286 284 */
287 285 QList<QPieSlice*> QPieSeries::slices() const
288 286 {
289 287 Q_D(const QPieSeries);
290 288 return d->m_slices;
291 289 }
292 290
293 291 void QPieSeries::setHorizontalPosition(qreal relativePosition)
294 292 {
295 293 Q_D(QPieSeries);
296 294 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
297 emit piePositionChanged();
295 emit d->piePositionChanged();
298 296 }
299 297
300 298 void QPieSeries::setVerticalPosition(qreal relativePosition)
301 299 {
302 300 Q_D(QPieSeries);
303 301 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
304 emit piePositionChanged();
302 emit d->piePositionChanged();
305 303 }
306 304
307 305 qreal QPieSeries::horizontalPosition() const
308 306 {
309 307 Q_D(const QPieSeries);
310 308 return d->m_pieRelativeHorPos;
311 309 }
312 310
313 311 qreal QPieSeries::verticalPosition() const
314 312 {
315 313 Q_D(const QPieSeries);
316 314 return d->m_pieRelativeVerPos;
317 315 }
318 316
319 317 void QPieSeries::setPieSize(qreal relativeSize)
320 318 {
321 319 Q_D(QPieSeries);
322 320 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
323 emit pieSizeChanged();
321 emit d->pieSizeChanged();
324 322 }
325 323
326 324 qreal QPieSeries::pieSize() const
327 325 {
328 326 Q_D(const QPieSeries);
329 327 return d->m_pieRelativeSize;
330 328 }
331 329
332 330
333 331 void QPieSeries::setPieStartAngle(qreal angle)
334 332 {
335 333 Q_D(QPieSeries);
336 334 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
337 335 d->updateDerivativeData();
338 336 }
339 337
340 338 qreal QPieSeries::pieStartAngle() const
341 339 {
342 340 Q_D(const QPieSeries);
343 341 return d->m_pieStartAngle;
344 342 }
345 343
346 344 /*!
347 345 Sets the end angle of the pie.
348 346
349 347 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
350 348
351 349 \a angle must be greater than start angle.
352 350
353 351 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
354 352 */
355 353 void QPieSeries::setPieEndAngle(qreal angle)
356 354 {
357 355 Q_D(QPieSeries);
358 356
359 357 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
360 358 d->updateDerivativeData();
361 359 }
362 360
363 361 /*!
364 362 Returns the end angle of the pie.
365 363
366 364 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
367 365
368 366 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
369 367 */
370 368 qreal QPieSeries::pieEndAngle() const
371 369 {
372 370 Q_D(const QPieSeries);
373 371 return d->m_pieEndAngle;
374 372 }
375 373
376 374 /*!
377 375 Sets the all the slice labels \a visible or invisible.
378 376
379 377 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
380 378 */
381 379 void QPieSeries::setLabelsVisible(bool visible)
382 380 {
383 381 Q_D(QPieSeries);
384 382 foreach (QPieSlice* s, d->m_slices)
385 383 s->setLabelVisible(visible);
386 384 }
387 385
388 386 /*!
389 387 Returns the sum of all slice values in this series.
390 388
391 389 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
392 390 */
393 391 qreal QPieSeries::sum() const
394 392 {
395 393 Q_D(const QPieSeries);
396 394 return d->m_sum;
397 395 }
398 396
399 397 /*!
400 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
398 \fn void QPieSeries::clicked(QPieSlice* slice)
401 399
402 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
400 This signal is emitted when a \a slice has been clicked.
403 401
404 402 \sa QPieSlice::clicked()
405 403 */
406 404
407 405 /*!
408 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
406 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
409 407
410 This signal is emitted when user has hovered over a \a slice.
408 This signal is emitted when user has hovered over or away from the \a slice.
411 409
412 \sa QPieSlice::hoverEnter()
413 */
414
415 /*!
416 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
417
418 This signal is emitted when user has hovered away from a \a slice.
419
420 \sa QPieSlice::hoverLeave()
421 */
422
423 /*!
424 \fn void QPieSeries::added(QList<QPieSlice*> slices)
425
426 This signal is emitted when \a slices has been added to the series.
410 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
427 411
428 \sa append(), insert()
429 */
430
431 /*!
432 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
433
434 This signal is emitted when \a slices has been removed from the series.
435
436 \sa remove(), clear()
437 */
438
439 /*!
440 \fn void QPieSeries::piePositionChanged()
441
442 This signal is emitted when pie position has changed.
443
444 \sa verticalPosition(), setVerticalPosition(), horizontalPosition(), setHorizontalPosition()
445 */
446
447 /*!
448 \fn void QPieSeries::pieSizeChanged()
449
450 This signal is emitted when pie size has changed.
451
452 \sa pieSize(), setPieSize()
412 \sa QPieSlice::hovered()
453 413 */
454 414
455 415 /*!
456 416 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
457 417 Sets the \a model to be used as a data source
458 418 */
459 419 bool QPieSeries::setModel(QAbstractItemModel* model)
460 420 {
461 421 Q_D(QPieSeries);
462 422 // disconnect signals from old model
463 423 if(d->m_model)
464 424 {
465 425 disconnect(d->m_model, 0, this, 0);
466 426 d->m_mapValues = -1;
467 427 d->m_mapLabels = -1;
468 428 d->m_mapOrientation = Qt::Vertical;
469 429 }
470 430
471 431 // set new model
472 432 if(model)
473 433 {
474 434 d->m_model = model;
475 435 return true;
476 436 }
477 437 else
478 438 {
479 439 d->m_model = 0;
480 440 return false;
481 441 }
482 442 }
483 443
484 444 /*!
485 445 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
486 446 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
487 447 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
488 448 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
489 449 The \a orientation parameter specifies whether the data is in columns or in rows.
490 450 */
491 451 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
492 452 {
493 453 Q_D(QPieSeries);
494 454
495 455 if (d->m_model == 0)
496 456 return;
497 457
498 458 d->m_mapValues = modelValuesLine;
499 459 d->m_mapLabels = modelLabelsLine;
500 460 d->m_mapOrientation = orientation;
501 461
502 462 // connect the signals
503 463 if (d->m_mapOrientation == Qt::Vertical) {
504 464 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
505 465 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
506 466 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
507 467 } else {
508 468 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
509 469 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
510 470 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
511 471 }
512 472
513 473 // create the initial slices set
514 474 if (d->m_mapOrientation == Qt::Vertical) {
515 475 for (int i = 0; i < d->m_model->rowCount(); i++)
516 476 append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
517 477 } else {
518 478 for (int i = 0; i < d->m_model->columnCount(); i++)
519 479 append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
520 480 }
521 481 }
522 482
523 483 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
524 484
525 485
526 486 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
527 487 QAbstractSeriesPrivate(parent),
528 488 m_pieRelativeHorPos(0.5),
529 489 m_pieRelativeVerPos(0.5),
530 490 m_pieRelativeSize(0.7),
531 491 m_pieStartAngle(0),
532 492 m_pieEndAngle(360),
533 493 m_sum(0),
534 494 m_mapValues(0),
535 495 m_mapLabels(0),
536 496 m_mapOrientation(Qt::Horizontal)
537 497 {
538 498
539 499 }
540 500
541 501 QPieSeriesPrivate::~QPieSeriesPrivate()
542 502 {
543 503
544 504 }
545 505
546 506 void QPieSeriesPrivate::updateDerivativeData()
547 507 {
548 508 m_sum = 0;
549 509
550 510 // nothing to do?
551 511 if (m_slices.count() == 0)
552 512 return;
553 513
554 514 // calculate sum of all slices
555 515 foreach (QPieSlice* s, m_slices)
556 516 m_sum += s->value();
557 517
558 518 // nothing to show..
559 519 if (qFuzzyIsNull(m_sum))
560 520 return;
561 521
562 522 // update slice attributes
563 523 qreal sliceAngle = m_pieStartAngle;
564 524 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
565 525 QVector<QPieSlice*> changed;
566 526 foreach (QPieSlice* s, m_slices) {
567 527
568 528 PieSliceData data = PieSliceData::data(s);
569 529 data.m_percentage = s->value() / m_sum;
570 530 data.m_angleSpan = pieSpan * data.m_percentage;
571 531 data.m_startAngle = sliceAngle;
572 532 sliceAngle += data.m_angleSpan;
573 533
574 534 if (PieSliceData::data(s) != data) {
575 535 PieSliceData::data(s) = data;
576 536 changed << s;
577 537 }
578 538 }
579 539
580 540 // emit signals
581 541 foreach (QPieSlice* s, changed)
582 542 PieSliceData::data(s).emitChangedSignal(s);
583 543 }
584 544
585 void QPieSeriesPrivate::sliceChanged()
545 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
586 546 {
587 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
588 updateDerivativeData();
547 return series.d_func();
589 548 }
590 549
591 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
550 void QPieSeriesPrivate::sliceChanged()
592 551 {
593 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
594 Q_ASSERT(m_slices.contains(slice));
595 Q_Q(QPieSeries);
596 emit q->clicked(slice, buttons);
552 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
553 updateDerivativeData();
597 554 }
598 555
599 void QPieSeriesPrivate::sliceHoverEnter()
556 void QPieSeriesPrivate::sliceClicked()
600 557 {
601 558 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
602 559 Q_ASSERT(m_slices.contains(slice));
603 560 Q_Q(QPieSeries);
604 emit q->hoverEnter(slice);
561 emit q->clicked(slice);
605 562 }
606 563
607 void QPieSeriesPrivate::sliceHoverLeave()
564 void QPieSeriesPrivate::sliceHovered(bool state)
608 565 {
609 566 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
610 567 Q_ASSERT(m_slices.contains(slice));
611 568 Q_Q(QPieSeries);
612 emit q->hoverLeave(slice);
569 emit q->hovered(slice, state);
613 570 }
614 571
615 572 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
616 573 {
617 574 Q_UNUSED(bottomRight)
618 575
619 576 if (m_mapOrientation == Qt::Vertical)
620 577 {
621 578 if (topLeft.column() == m_mapValues)
622 579 if (m_mapValues == m_mapLabels)
623 580 {
624 581 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
625 582 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
626 583 }
627 584 else
628 585 {
629 586 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
630 587 }
631 588 else if (topLeft.column() == m_mapLabels)
632 589 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
633 590 }
634 591 else
635 592 {
636 593 if (topLeft.row() == m_mapValues)
637 594 if (m_mapValues == m_mapLabels)
638 595 {
639 596 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
640 597 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
641 598 }
642 599 else
643 600 {
644 601 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
645 602 }
646 603 else if (topLeft.row() == m_mapLabels)
647 604 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
648 605 }
649 606 }
650 607
651 608 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
652 609 {
653 610 Q_UNUSED(parent)
654 611 Q_UNUSED(end)
655 612 Q_Q(QPieSeries);
656 613
657 614 QPieSlice* newSlice = new QPieSlice;
658 615 newSlice->setLabelVisible(true);
659 616 if (m_mapOrientation == Qt::Vertical)
660 617 {
661 618 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
662 619 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
663 620 }
664 621 else
665 622 {
666 623 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
667 624 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
668 625 }
669 626
670 627 q->insert(start, newSlice);
671 628 }
672 629
673 630 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
674 631 {
675 632 Q_UNUSED(parent)
676 633 Q_UNUSED(end)
677 634 Q_Q(QPieSeries);
678 635 q->remove(m_slices.at(start));
679 636 }
680 637
681 638 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
682 639 {
683 640 // Remove rounding errors
684 641 qreal roundedValue = newValue;
685 642 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
686 643 roundedValue = 0.0;
687 644 else if (qFuzzyCompare(newValue, max))
688 645 roundedValue = max;
689 646 else if (qFuzzyCompare(newValue, min))
690 647 roundedValue = min;
691 648
692 649 // Check if the position is valid after removing the rounding errors
693 650 if (roundedValue < min || roundedValue > max) {
694 651 qWarning("QPieSeries: Illegal value");
695 652 return false;
696 653 }
697 654
698 655 if (!qFuzzyIsNull(value - roundedValue)) {
699 656 value = roundedValue;
700 657 return true;
701 658 }
702 659
703 660 // The change was so small it is considered a rounding error
704 661 return false;
705 662 }
706 663
707 664 void QPieSeriesPrivate::scaleDomain(Domain& domain)
708 665 {
709 666 Q_UNUSED(domain);
710 667 #ifndef QT_NO_DEBUG
711 668 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
712 669 #endif
713 670 }
714 671
715 672 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
716 673 {
717 674 Q_Q(QPieSeries);
718 675 PieChartItem* pie = new PieChartItem(q,presenter);
719 676 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
720 677 presenter->animator()->addAnimation(pie);
721 678 }
722 679 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
723 680 return pie;
724 681 }
725 682
726 683 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
727 684 {
728 685 Q_Q(QPieSeries);
729 686 QList<LegendMarker*> markers;
730 687 foreach(QPieSlice* slice, q->slices()) {
731 688 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
732 689 markers << marker;
733 690 }
734 691 return markers;
735 692 }
736 693
737 694 #include "moc_qpieseries.cpp"
738 695 #include "moc_qpieseries_p.cpp"
739 696
740 697 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,101 +1,89
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef PIESERIES_H
22 22 #define PIESERIES_H
23 23
24 24 #include <qabstractseries.h>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27 class QPieSeriesPrivate;
28 28 class QPieSlice;
29 29
30 30 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
31 31 {
32 32 Q_OBJECT
33 33 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
34 34 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
35 35 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
36 36 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
37 37 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
38 38
39 39 public:
40 40 explicit QPieSeries(QObject *parent = 0);
41 41 virtual ~QPieSeries();
42 42
43 public: // from QChartSeries
44 43 QSeriesType type() const;
45 44
46 public:
47
48 // slice setters
49 45 void append(QPieSlice* slice);
50 46 void append(QList<QPieSlice*> slices);
47 QPieSeries& operator << (QPieSlice* slice);
48 QPieSlice* append(qreal value, QString name);
51 49 void insert(int index, QPieSlice* slice);
52 50 void replace(QList<QPieSlice*> slices);
53 51 void remove(QPieSlice* slice);
54 52 void clear();
55 53
56 // slice getters
57 54 QList<QPieSlice*> slices() const;
58
59 // calculated data
60 55 int count() const;
61 56 bool isEmpty() const;
57
62 58 qreal sum() const;
63 59
64 // pie customization
65 60 void setHorizontalPosition(qreal relativePosition);
66 61 qreal horizontalPosition() const;
67 62 void setVerticalPosition(qreal relativePosition);
68 63 qreal verticalPosition() const;
64
69 65 void setPieSize(qreal relativeSize);
70 66 qreal pieSize() const;
67
71 68 void setPieStartAngle(qreal startAngle);
72 69 qreal pieStartAngle() const;
73 70 void setPieEndAngle(qreal endAngle);
74 71 qreal pieEndAngle() const;
75 72
76 // convenience function
77 QPieSeries& operator << (QPieSlice* slice);
78 QPieSlice* append(qreal value, QString name);
79 73 void setLabelsVisible(bool visible = true);
80 74
81 // data from model
82 75 bool setModel(QAbstractItemModel* model);
83 76 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
84 77
85 78 Q_SIGNALS:
86 void clicked(QPieSlice* slice, Qt::MouseButtons buttons);
87 void hoverEnter(QPieSlice* slice);
88 void hoverLeave(QPieSlice* slice);
89 void added(QList<QPieSlice*> slices);
90 void removed(QList<QPieSlice*> slices);
91 void piePositionChanged();
92 void pieSizeChanged();
79 void clicked(QPieSlice* slice);
80 void hovered(QPieSlice* slice, bool state);
93 81
94 82 private:
95 83 Q_DECLARE_PRIVATE(QPieSeries)
96 84 Q_DISABLE_COPY(QPieSeries)
97 85 };
98 86
99 87 QTCOMMERCIALCHART_END_NAMESPACE
100 88
101 89 #endif // PIESERIES_H
@@ -1,74 +1,84
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QPIESERIES_P_H
22 22 #define QPIESERIES_P_H
23 23
24 24 #include "qpieseries.h"
25 25 #include "qabstractseries_p.h"
26 26
27 27 class QModelIndex;
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 class QLegendPrivate;
30 31
31 32 class QPieSeriesPrivate : public QAbstractSeriesPrivate
32 33 {
33 34 Q_OBJECT
34 35
35 36 public:
36 37 QPieSeriesPrivate(QPieSeries *parent);
37 38 ~QPieSeriesPrivate();
38 39
39 40 void scaleDomain(Domain& domain);
40 Chart* createGraphics(ChartPresenter* presenter);
41 QList<LegendMarker*> createLegendMarker(QLegend* legend);
41 Chart* createGraphics(ChartPresenter *presenter);
42 QList<LegendMarker*> createLegendMarker(QLegend *legend);
42 43
43 44 void updateDerivativeData();
44 45
46 static QPieSeriesPrivate* seriesData(QPieSeries &series);
47
48 Q_SIGNALS:
49 void added(QList<QPieSlice*> slices);
50 void removed(QList<QPieSlice*> slices);
51 void piePositionChanged();
52 void pieSizeChanged();
53
45 54 public Q_SLOTS:
46 55 void sliceChanged();
47 void sliceClicked(Qt::MouseButtons buttons);
48 void sliceHoverEnter();
49 void sliceHoverLeave();
56 void sliceClicked();
57 void sliceHovered(bool state);
50 58 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
51 59 void modelDataAdded(QModelIndex parent, int start, int end);
52 60 void modelDataRemoved(QModelIndex parent, int start, int end);
53 61 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
54 62
55 63 public:
56 64 QList<QPieSlice*> m_slices;
57 65 qreal m_pieRelativeHorPos;
58 66 qreal m_pieRelativeVerPos;
59 67 qreal m_pieRelativeSize;
60 68 qreal m_pieStartAngle;
61 69 qreal m_pieEndAngle;
62 70 qreal m_sum;
63 71
64 72 // model map
65 73 int m_mapValues;
66 74 int m_mapLabels;
67 75 Qt::Orientation m_mapOrientation;
76
68 77 private:
78 friend class QLegendPrivate;
69 79 Q_DECLARE_PUBLIC(QPieSeries)
70 80 };
71 81
72 82 QTCOMMERCIALCHART_END_NAMESPACE
73 83
74 84 #endif // QPIESERIES_P_H
@@ -1,423 +1,410
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qpieslice.h"
22 22 #include "pieslicedata_p.h"
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 /*!
27 27 \class QPieSlice
28 28 \brief Defines a slice in pie series.
29 29
30 30 This object defines the properties of a single slice in a QPieSeries.
31 31
32 32 In addition to the obvious value and label properties the user can also control
33 33 the visual appearance of a slice. By modifying the visual appearance also means that
34 34 the user is overriding the default appearance set by the theme. Even if the theme is
35 35 changed users settings will persist.
36 36
37 37 To enable user interaction customization with the slices some basic signals
38 38 are provided about clicking and hovering.
39 39 */
40 40
41 41 /*!
42 42 \property QPieSlice::label
43 43
44 44 Label of the slice.
45 45 */
46 46
47 47 /*!
48 48 \property QPieSlice::value
49 49
50 50 Value of the slice.
51 51
52 52 \sa percentage(), QPieSeries::sum()
53 53 */
54 54
55 55 /*!
56 56 Constructs an empty slice with a \a parent.
57 57
58 58 \sa QPieSeries::append(), QPieSeries::insert(), QPieSeries::replace()
59 59 */
60 60 QPieSlice::QPieSlice(QObject *parent)
61 61 :QObject(parent),
62 62 d(new PieSliceData())
63 63 {
64 64
65 65 }
66 66
67 67 /*!
68 68 Constructs an empty slice with given \a value, \a label and a \a parent.
69 69 \sa QPieSeries::append(), QPieSeries::insert(), QPieSeries::replace()
70 70 */
71 71 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
72 72 :QObject(parent),
73 73 d(new PieSliceData())
74 74 {
75 75 d->m_value = value;
76 76 d->m_labelText = label;
77 77 }
78 78
79 79 /*!
80 80 Destroys the slice.
81 81 User should not delete the slice if it has been added to the series.
82 82 */
83 83 QPieSlice::~QPieSlice()
84 84 {
85 85 delete d;
86 86 }
87 87
88 88 /*!
89 89 Gets the value of the slice.
90 90 Note that all values in the series
91 91 \sa setValue()
92 92 */
93 93 qreal QPieSlice::value() const
94 94 {
95 95 return d->m_value;
96 96 }
97 97
98 98 /*!
99 99 Gets the label of the slice.
100 100 \sa setLabel()
101 101 */
102 102 QString QPieSlice::label() const
103 103 {
104 104 return d->m_labelText;
105 105 }
106 106
107 107 /*!
108 108 Returns true if label is set as visible.
109 109 \sa setLabelVisible()
110 110 */
111 111 bool QPieSlice::isLabelVisible() const
112 112 {
113 113 return d->m_isLabelVisible;
114 114 }
115 115
116 116 /*!
117 117 Returns true if slice is exloded from the pie.
118 118 \sa setExploded(), explodeDistanceFactor(), setExplodeDistanceFactor()
119 119 */
120 120 bool QPieSlice::isExploded() const
121 121 {
122 122 return d->m_isExploded;
123 123 }
124 124
125 125 /*!
126 126 Returns the explode distance factor.
127 127
128 128 The factor is relative to pie radius. For example:
129 129 1.0 means the distance is the same as the radius.
130 130 0.5 means the distance is half of the radius.
131 131
132 132 Default value is 0.15.
133 133
134 134 \sa setExplodeDistanceFactor(), isExploded(), setExploded()
135 135 */
136 136 qreal QPieSlice::explodeDistanceFactor() const
137 137 {
138 138 return d->m_explodeDistanceFactor;
139 139 }
140 140
141 141 /*!
142 142 Returns the percentage of this slice compared to the sum of all slices in the same series.
143 143 The returned value ranges from 0 to 1.0.
144 144
145 145 Updated internally after the slice is added to the series.
146 146
147 147 \sa QPieSeries::sum()
148 148 */
149 149 qreal QPieSlice::percentage() const
150 150 {
151 151 return d->m_percentage;
152 152 }
153 153
154 154 /*!
155 155 Returns the starting angle of this slice in the series it belongs to.
156 156
157 157 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
158 158
159 159 Updated internally after the slice is added to the series.
160 160 */
161 161 qreal QPieSlice::startAngle() const
162 162 {
163 163 return d->m_startAngle;
164 164 }
165 165
166 166 /*!
167 167 Returns the end angle of this slice in the series it belongs to.
168 168
169 169 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
170 170
171 171 Updated internally after the slice is added to the series.
172 172 */
173 173 qreal QPieSlice::endAngle() const
174 174 {
175 175 return d->m_startAngle + d->m_angleSpan;
176 176 }
177 177
178 178 /*!
179 179 Returns the pen used to draw this slice.
180 180 \sa setPen()
181 181 */
182 182 QPen QPieSlice::pen() const
183 183 {
184 184 return d->m_slicePen;
185 185 }
186 186
187 187 /*!
188 188 Returns the brush used to draw this slice.
189 189 \sa setBrush()
190 190 */
191 191 QBrush QPieSlice::brush() const
192 192 {
193 193 return d->m_sliceBrush;
194 194 }
195 195
196 196 /*!
197 197 Returns the pen used to draw the label in this slice.
198 198 \sa setLabelPen()
199 199 */
200 200 QPen QPieSlice::labelPen() const
201 201 {
202 202 return d->m_labelPen;
203 203 }
204 204
205 205 /*!
206 206 Returns the font used to draw label in this slice.
207 207 \sa setLabelFont()
208 208 */
209 209 QFont QPieSlice::labelFont() const
210 210 {
211 211 return d->m_labelFont;
212 212 }
213 213
214 214 /*!
215 215 Gets the label arm length factor.
216 216
217 217 The factor is relative to pie radius. For example:
218 218 1.0 means the length is the same as the radius.
219 219 0.5 means the length is half of the radius.
220 220
221 221 Default value is 0.15
222 222
223 223 \sa setLabelArmLengthFactor()
224 224 */
225 225 qreal QPieSlice::labelArmLengthFactor() const
226 226 {
227 227 return d->m_labelArmLengthFactor;
228 228 }
229 229
230 230 /*!
231 \fn void QPieSlice::clicked(Qt::MouseButtons buttons)
231 \fn void QPieSlice::clicked()
232 232
233 233 This signal is emitted when user has clicked the slice.
234 Parameter \a buttons hold the information about the clicked mouse buttons.
235 234
236 235 \sa QPieSeries::clicked()
237 236 */
238 237
239 238 /*!
240 \fn void QPieSlice::hoverEnter()
239 \fn void QPieSlice::hovered(bool state)
241 240
242 This signal is emitted when user has hovered over the slice.
241 This signal is emitted when user has hovered over or away from the slice.
243 242
244 \sa QPieSeries::hoverEnter()
245 */
246
247 /*!
248 \fn void QPieSlice::hoverLeave()
249
250 This signal is emitted when user has hovered away from the slice.
243 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
251 244
252 \sa QPieSeries::hoverLeave()
245 \sa QPieSeries::hovered()
253 246 */
254 247
255 248 /*!
256 249 \fn void QPieSlice::changed()
257 250
258 251 This signal emitted when something has changed in the slice.
259 252 */
260 253
261 254 /*!
262 \fn void QPieSlice::selected()
263
264 This signal emitted when this slice has been clicked in the legend.
265 */
266
267 /*!
268 255 Sets the \a value of this slice.
269 256 \sa value()
270 257 */
271 258 void QPieSlice::setValue(qreal value)
272 259 {
273 260 if (!qFuzzyIsNull(d->m_value - value)) {
274 261 d->m_value = value;
275 262 emit changed();
276 263 }
277 264 }
278 265
279 266 /*!
280 267 Sets the \a label of the slice.
281 268 \sa label()
282 269 */
283 270 void QPieSlice::setLabel(QString label)
284 271 {
285 272 if (d->m_labelText != label) {
286 273 d->m_labelText = label;
287 274 emit changed();
288 275 }
289 276 }
290 277
291 278 /*!
292 279 Sets the label \a visible in this slice.
293 280 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
294 281 */
295 282 void QPieSlice::setLabelVisible(bool visible)
296 283 {
297 284 if (d->m_isLabelVisible != visible) {
298 285 d->m_isLabelVisible = visible;
299 286 emit changed();
300 287 }
301 288 }
302 289
303 290 /*!
304 291 Sets this slices \a exploded state.
305 292
306 293 If the slice is exploded it is moved away from the pie center. The distance is defined by the explode distance factor.
307 294
308 295 \sa isExploded(), explodeDistanceFactor(), setExplodeDistanceFactor()
309 296 */
310 297 void QPieSlice::setExploded(bool exploded)
311 298 {
312 299 if (d->m_isExploded != exploded) {
313 300 d->m_isExploded = exploded;
314 301 emit changed();
315 302 }
316 303 }
317 304
318 305 /*!
319 306 Sets the explode distance \a factor.
320 307
321 308 The factor is relative to pie radius. For example:
322 309 1.0 means the distance is the same as the radius.
323 310 0.5 means the distance is half of the radius.
324 311
325 312 Default value is 0.15
326 313
327 314 \sa explodeDistanceFactor(), isExploded(), setExploded()
328 315 */
329 316 void QPieSlice::setExplodeDistanceFactor(qreal factor)
330 317 {
331 318 if (!qFuzzyIsNull(d->m_explodeDistanceFactor - factor)) {
332 319 d->m_explodeDistanceFactor = factor;
333 320 emit changed();
334 321 }
335 322 }
336 323
337 324 /*!
338 325 Sets the \a pen used to draw this slice.
339 326
340 327 Overrides the pen set by the theme.
341 328
342 329 \sa pen()
343 330 */
344 331 void QPieSlice::setPen(const QPen &pen)
345 332 {
346 333 if (d->m_slicePen != pen) {
347 334 d->m_slicePen = pen;
348 335 d->m_slicePen.setThemed(false);
349 336 emit changed();
350 337 }
351 338 }
352 339
353 340 /*!
354 341 Sets the \a brush used to draw this slice.
355 342
356 343 Overrides the brush set by the theme.
357 344
358 345 \sa brush()
359 346 */
360 347 void QPieSlice::setBrush(const QBrush &brush)
361 348 {
362 349 if (d->m_sliceBrush != brush) {
363 350 d->m_sliceBrush = brush;
364 351 d->m_sliceBrush.setThemed(false);
365 352 emit changed();
366 353 }
367 354 }
368 355
369 356 /*!
370 357 Sets the \a pen used to draw the label in this slice.
371 358
372 359 Overrides the pen set by the theme.
373 360
374 361 \sa labelPen()
375 362 */
376 363 void QPieSlice::setLabelPen(const QPen &pen)
377 364 {
378 365 if (d->m_labelPen != pen) {
379 366 d->m_labelPen = pen;
380 367 d->m_labelPen.setThemed(false);
381 368 emit changed();
382 369 }
383 370 }
384 371
385 372 /*!
386 373 Sets the \a font used to draw the label in this slice.
387 374
388 375 Overrides the font set by the theme.
389 376
390 377 \sa labelFont()
391 378 */
392 379 void QPieSlice::setLabelFont(const QFont &font)
393 380 {
394 381 if (d->m_labelFont != font) {
395 382 d->m_labelFont = font;
396 383 d->m_labelFont.setThemed(false);
397 384 emit changed();
398 385 }
399 386 }
400 387
401 388 /*!
402 389 Sets the label arm length \a factor.
403 390
404 391 The factor is relative to pie radius. For example:
405 392 1.0 means the length is the same as the radius.
406 393 0.5 means the length is half of the radius.
407 394
408 395 Default value is 0.15
409 396
410 397 \sa labelArmLengthFactor()
411 398 */
412 399 void QPieSlice::setLabelArmLengthFactor(qreal factor)
413 400 {
414 401 if (!qFuzzyIsNull(d->m_labelArmLengthFactor - factor)) {
415 402 d->m_labelArmLengthFactor = factor;
416 403 emit changed();
417 404 }
418 405 }
419 406
420 407 QTCOMMERCIALCHART_END_NAMESPACE
421 408
422 409 QTCOMMERCIALCHART_USE_NAMESPACE
423 410 #include "moc_qpieslice.cpp"
@@ -1,88 +1,84
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QPIESLICE_H
22 22 #define QPIESLICE_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QObject>
26 26 #include <QPen>
27 27 #include <QBrush>
28 28 #include <QFont>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31 class PieSliceData;
32 32
33 33 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
34 34 {
35 35 Q_OBJECT
36 36 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
37 37 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
38 38
39 39 public:
40 40 explicit QPieSlice(QObject *parent = 0);
41 41 QPieSlice(qreal value, QString label, QObject *parent = 0);
42 42 virtual ~QPieSlice();
43 43
44 // data
45 44 void setValue(qreal value);
46 45 qreal value() const;
47 46 void setLabel(QString label);
48 47 QString label() const;
49 48 void setLabelVisible(bool visible = true);
50 49 bool isLabelVisible() const;
51 50 void setExploded(bool exploded = true);
52 51 bool isExploded() const;
53 52
54 // generated data
55 qreal percentage() const;
56 qreal startAngle() const;
57 qreal endAngle() const;
58
59 // customization
60 53 void setPen(const QPen &pen);
61 54 QPen pen() const;
62 55 void setBrush(const QBrush &brush);
63 56 QBrush brush() const;
64 57 void setLabelPen(const QPen &pen);
65 58 QPen labelPen() const;
66 59 void setLabelFont(const QFont &font);
67 60 QFont labelFont() const;
61
68 62 void setLabelArmLengthFactor(qreal factor);
69 63 qreal labelArmLengthFactor() const;
70 64 void setExplodeDistanceFactor(qreal factor);
71 65 qreal explodeDistanceFactor() const;
72 66
67 qreal percentage() const;
68 qreal startAngle() const;
69 qreal endAngle() const;
70
73 71 Q_SIGNALS:
74 void clicked(Qt::MouseButtons buttons);
75 void hoverEnter();
76 void hoverLeave();
72 void clicked();
73 void hovered(bool state);
77 74 void changed();
78 void selected();
79 75
80 76 private:
81 77 friend class PieSliceData;
82 78 PieSliceData * const d;
83 79 Q_DISABLE_COPY(QPieSlice)
84 80 };
85 81
86 82 QTCOMMERCIALCHART_END_NAMESPACE
87 83
88 84 #endif // QPIESLICE_H
General Comments 0
You need to be logged in to leave comments. Login now