##// END OF EJS Templates
Get pie slice label font and pen from theme
Jani Honkonen -
r714:6705438d7ae7
parent child
Show More
@@ -1,610 +1,611
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
4 #include <qchartview.h>
5 #include <qpieseries.h>
5 #include <qpieseries.h>
6 #include <qpieslice.h>
6 #include <qpieslice.h>
7 #include <QGridLayout>
7 #include <QGridLayout>
8 #include <QFormLayout>
8 #include <QFormLayout>
9 #include <QComboBox>
9 #include <QComboBox>
10 #include <QSpinBox>
10 #include <QSpinBox>
11 #include <QCheckBox>
11 #include <QCheckBox>
12 #include <QGroupBox>
12 #include <QGroupBox>
13 #include <QLabel>
13 #include <QLabel>
14 #include <QPushButton>
14 #include <QPushButton>
15 #include <QColorDialog>
15 #include <QColorDialog>
16 #include <QFontDialog>
16 #include <QFontDialog>
17
17
18 QTCOMMERCIALCHART_USE_NAMESPACE
18 QTCOMMERCIALCHART_USE_NAMESPACE
19
19
20 class PenTool : public QWidget
20 class PenTool : public QWidget
21 {
21 {
22 Q_OBJECT
22 Q_OBJECT
23
23
24 public:
24 public:
25 explicit PenTool(QString title, QWidget *parent = 0)
25 explicit PenTool(QString title, QWidget *parent = 0)
26 :QWidget(parent)
26 :QWidget(parent)
27 {
27 {
28 setWindowTitle(title);
28 setWindowTitle(title);
29 setWindowFlags(Qt::Tool);
29 setWindowFlags(Qt::Tool);
30
30
31 m_colorButton = new QPushButton();
31 m_colorButton = new QPushButton();
32
32
33 m_widthSpinBox = new QDoubleSpinBox();
33 m_widthSpinBox = new QDoubleSpinBox();
34
34
35 m_styleCombo = new QComboBox();
35 m_styleCombo = new QComboBox();
36 m_styleCombo->addItem("NoPen");
36 m_styleCombo->addItem("NoPen");
37 m_styleCombo->addItem("SolidLine");
37 m_styleCombo->addItem("SolidLine");
38 m_styleCombo->addItem("DashLine");
38 m_styleCombo->addItem("DashLine");
39 m_styleCombo->addItem("DotLine");
39 m_styleCombo->addItem("DotLine");
40 m_styleCombo->addItem("DashDotLine");
40 m_styleCombo->addItem("DashDotLine");
41 m_styleCombo->addItem("DashDotDotLine");
41 m_styleCombo->addItem("DashDotDotLine");
42
42
43 m_capStyleCombo = new QComboBox();
43 m_capStyleCombo = new QComboBox();
44 m_capStyleCombo->addItem("FlatCap", Qt::FlatCap);
44 m_capStyleCombo->addItem("FlatCap", Qt::FlatCap);
45 m_capStyleCombo->addItem("SquareCap", Qt::SquareCap);
45 m_capStyleCombo->addItem("SquareCap", Qt::SquareCap);
46 m_capStyleCombo->addItem("RoundCap", Qt::RoundCap);
46 m_capStyleCombo->addItem("RoundCap", Qt::RoundCap);
47
47
48 m_joinStyleCombo = new QComboBox();
48 m_joinStyleCombo = new QComboBox();
49 m_joinStyleCombo->addItem("MiterJoin", Qt::MiterJoin);
49 m_joinStyleCombo->addItem("MiterJoin", Qt::MiterJoin);
50 m_joinStyleCombo->addItem("BevelJoin", Qt::BevelJoin);
50 m_joinStyleCombo->addItem("BevelJoin", Qt::BevelJoin);
51 m_joinStyleCombo->addItem("RoundJoin", Qt::RoundJoin);
51 m_joinStyleCombo->addItem("RoundJoin", Qt::RoundJoin);
52 m_joinStyleCombo->addItem("SvgMiterJoin", Qt::SvgMiterJoin);
52 m_joinStyleCombo->addItem("SvgMiterJoin", Qt::SvgMiterJoin);
53
53
54 QFormLayout *layout = new QFormLayout();
54 QFormLayout *layout = new QFormLayout();
55 layout->addRow("Color", m_colorButton);
55 layout->addRow("Color", m_colorButton);
56 layout->addRow("Width", m_widthSpinBox);
56 layout->addRow("Width", m_widthSpinBox);
57 layout->addRow("Style", m_styleCombo);
57 layout->addRow("Style", m_styleCombo);
58 layout->addRow("Cap style", m_capStyleCombo);
58 layout->addRow("Cap style", m_capStyleCombo);
59 layout->addRow("Join style", m_joinStyleCombo);
59 layout->addRow("Join style", m_joinStyleCombo);
60 setLayout(layout);
60 setLayout(layout);
61
61
62 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
62 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
63 connect(m_widthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateWidth(double)));
63 connect(m_widthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateWidth(double)));
64 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle(int)));
64 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle(int)));
65 connect(m_capStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCapStyle(int)));
65 connect(m_capStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCapStyle(int)));
66 connect(m_joinStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateJoinStyle(int)));
66 connect(m_joinStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateJoinStyle(int)));
67 }
67 }
68
68
69 void setPen(QPen pen)
69 void setPen(QPen pen)
70 {
70 {
71 m_pen = pen;
71 m_pen = pen;
72 m_colorButton->setText(m_pen.color().name());
72 m_colorButton->setText(m_pen.color().name());
73 m_widthSpinBox->setValue(m_pen.widthF());
73 m_widthSpinBox->setValue(m_pen.widthF());
74 m_styleCombo->setCurrentIndex(m_pen.style()); // index matches the enum
74 m_styleCombo->setCurrentIndex(m_pen.style()); // index matches the enum
75 m_capStyleCombo->setCurrentIndex(m_capStyleCombo->findData(m_pen.capStyle()));
75 m_capStyleCombo->setCurrentIndex(m_capStyleCombo->findData(m_pen.capStyle()));
76 m_joinStyleCombo->setCurrentIndex(m_joinStyleCombo->findData(m_pen.joinStyle()));
76 m_joinStyleCombo->setCurrentIndex(m_joinStyleCombo->findData(m_pen.joinStyle()));
77 }
77 }
78
78
79 QPen pen() const
79 QPen pen() const
80 {
80 {
81 return m_pen;
81 return m_pen;
82 }
82 }
83
83
84 QString name()
84 QString name()
85 {
85 {
86 return name(m_pen);
86 return name(m_pen);
87 }
87 }
88
88
89 static QString name(const QPen &pen)
89 static QString name(const QPen &pen)
90 {
90 {
91 return pen.color().name() + ":" + QString::number(pen.widthF());
91 return pen.color().name() + ":" + QString::number(pen.widthF());
92 }
92 }
93
93
94 Q_SIGNALS:
94 Q_SIGNALS:
95 void changed();
95 void changed();
96
96
97 public Q_SLOTS:
97 public Q_SLOTS:
98
98
99 void showColorDialog()
99 void showColorDialog()
100 {
100 {
101 QColorDialog dialog(m_pen.color());
101 QColorDialog dialog(m_pen.color());
102 dialog.show();
102 dialog.show();
103 dialog.exec();
103 dialog.exec();
104 m_pen.setColor(dialog.selectedColor());
104 m_pen.setColor(dialog.selectedColor());
105 m_colorButton->setText(m_pen.color().name());
105 m_colorButton->setText(m_pen.color().name());
106 emit changed();
106 emit changed();
107 }
107 }
108
108
109 void updateWidth(double width)
109 void updateWidth(double width)
110 {
110 {
111 if (width != m_pen.widthF()) {
111 if (width != m_pen.widthF()) {
112 m_pen.setWidthF(width);
112 m_pen.setWidthF(width);
113 emit changed();
113 emit changed();
114 }
114 }
115 }
115 }
116
116
117 void updateStyle(int style)
117 void updateStyle(int style)
118 {
118 {
119 if (m_pen.style() != style) {
119 if (m_pen.style() != style) {
120 m_pen.setStyle((Qt::PenStyle) style);
120 m_pen.setStyle((Qt::PenStyle) style);
121 emit changed();
121 emit changed();
122 }
122 }
123 }
123 }
124
124
125 void updateCapStyle(int index)
125 void updateCapStyle(int index)
126 {
126 {
127 Qt::PenCapStyle capStyle = (Qt::PenCapStyle) m_capStyleCombo->itemData(index).toInt();
127 Qt::PenCapStyle capStyle = (Qt::PenCapStyle) m_capStyleCombo->itemData(index).toInt();
128 if (m_pen.capStyle() != capStyle) {
128 if (m_pen.capStyle() != capStyle) {
129 m_pen.setCapStyle(capStyle);
129 m_pen.setCapStyle(capStyle);
130 emit changed();
130 emit changed();
131 }
131 }
132 }
132 }
133
133
134 void updateJoinStyle(int index)
134 void updateJoinStyle(int index)
135 {
135 {
136 Qt::PenJoinStyle joinStyle = (Qt::PenJoinStyle) m_joinStyleCombo->itemData(index).toInt();
136 Qt::PenJoinStyle joinStyle = (Qt::PenJoinStyle) m_joinStyleCombo->itemData(index).toInt();
137 if (m_pen.joinStyle() != joinStyle) {
137 if (m_pen.joinStyle() != joinStyle) {
138 m_pen.setJoinStyle(joinStyle);
138 m_pen.setJoinStyle(joinStyle);
139 emit changed();
139 emit changed();
140 }
140 }
141 }
141 }
142
142
143 private:
143 private:
144 QPen m_pen;
144 QPen m_pen;
145 QPushButton *m_colorButton;
145 QPushButton *m_colorButton;
146 QDoubleSpinBox *m_widthSpinBox;
146 QDoubleSpinBox *m_widthSpinBox;
147 QComboBox *m_styleCombo;
147 QComboBox *m_styleCombo;
148 QComboBox *m_capStyleCombo;
148 QComboBox *m_capStyleCombo;
149 QComboBox *m_joinStyleCombo;
149 QComboBox *m_joinStyleCombo;
150 };
150 };
151
151
152 class BrushTool : public QWidget
152 class BrushTool : public QWidget
153 {
153 {
154 Q_OBJECT
154 Q_OBJECT
155
155
156 public:
156 public:
157 explicit BrushTool(QString title, QWidget *parent = 0)
157 explicit BrushTool(QString title, QWidget *parent = 0)
158 :QWidget(parent)
158 :QWidget(parent)
159 {
159 {
160 setWindowTitle(title);
160 setWindowTitle(title);
161 setWindowFlags(Qt::Tool);
161 setWindowFlags(Qt::Tool);
162
162
163 m_colorButton = new QPushButton();
163 m_colorButton = new QPushButton();
164 m_styleCombo = new QComboBox();
164 m_styleCombo = new QComboBox();
165 m_styleCombo->addItem("Nobrush", Qt::NoBrush);
165 m_styleCombo->addItem("Nobrush", Qt::NoBrush);
166 m_styleCombo->addItem("Solidpattern", Qt::SolidPattern);
166 m_styleCombo->addItem("Solidpattern", Qt::SolidPattern);
167 m_styleCombo->addItem("Dense1pattern", Qt::Dense1Pattern);
167 m_styleCombo->addItem("Dense1pattern", Qt::Dense1Pattern);
168 m_styleCombo->addItem("Dense2attern", Qt::Dense2Pattern);
168 m_styleCombo->addItem("Dense2attern", Qt::Dense2Pattern);
169 m_styleCombo->addItem("Dense3Pattern", Qt::Dense3Pattern);
169 m_styleCombo->addItem("Dense3Pattern", Qt::Dense3Pattern);
170 m_styleCombo->addItem("Dense4Pattern", Qt::Dense4Pattern);
170 m_styleCombo->addItem("Dense4Pattern", Qt::Dense4Pattern);
171 m_styleCombo->addItem("Dense5Pattern", Qt::Dense5Pattern);
171 m_styleCombo->addItem("Dense5Pattern", Qt::Dense5Pattern);
172 m_styleCombo->addItem("Dense6Pattern", Qt::Dense6Pattern);
172 m_styleCombo->addItem("Dense6Pattern", Qt::Dense6Pattern);
173 m_styleCombo->addItem("Dense7Pattern", Qt::Dense7Pattern);
173 m_styleCombo->addItem("Dense7Pattern", Qt::Dense7Pattern);
174 m_styleCombo->addItem("HorPattern", Qt::HorPattern);
174 m_styleCombo->addItem("HorPattern", Qt::HorPattern);
175 m_styleCombo->addItem("VerPattern", Qt::VerPattern);
175 m_styleCombo->addItem("VerPattern", Qt::VerPattern);
176 m_styleCombo->addItem("CrossPattern", Qt::CrossPattern);
176 m_styleCombo->addItem("CrossPattern", Qt::CrossPattern);
177 m_styleCombo->addItem("BDiagPattern", Qt::BDiagPattern);
177 m_styleCombo->addItem("BDiagPattern", Qt::BDiagPattern);
178 m_styleCombo->addItem("FDiagPattern", Qt::FDiagPattern);
178 m_styleCombo->addItem("FDiagPattern", Qt::FDiagPattern);
179 m_styleCombo->addItem("DiagCrossPattern", Qt::DiagCrossPattern);
179 m_styleCombo->addItem("DiagCrossPattern", Qt::DiagCrossPattern);
180
180
181 QFormLayout *layout = new QFormLayout();
181 QFormLayout *layout = new QFormLayout();
182 layout->addRow("Color", m_colorButton);
182 layout->addRow("Color", m_colorButton);
183 layout->addRow("Style", m_styleCombo);
183 layout->addRow("Style", m_styleCombo);
184 setLayout(layout);
184 setLayout(layout);
185
185
186 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
186 connect(m_colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
187 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle()));
187 connect(m_styleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStyle()));
188 }
188 }
189
189
190 void setBrush(QBrush brush)
190 void setBrush(QBrush brush)
191 {
191 {
192 m_brush = brush;
192 m_brush = brush;
193 m_colorButton->setText(m_brush.color().name());
193 m_colorButton->setText(m_brush.color().name());
194 m_styleCombo->setCurrentIndex(m_brush.style()); // index matches the enum
194 m_styleCombo->setCurrentIndex(m_brush.style()); // index matches the enum
195 }
195 }
196
196
197 QBrush brush() const
197 QBrush brush() const
198 {
198 {
199 return m_brush;
199 return m_brush;
200 }
200 }
201
201
202 QString name()
202 QString name()
203 {
203 {
204 return name(m_brush);
204 return name(m_brush);
205 }
205 }
206
206
207 static QString name(const QBrush &brush)
207 static QString name(const QBrush &brush)
208 {
208 {
209 return brush.color().name();
209 return brush.color().name();
210 }
210 }
211
211
212 Q_SIGNALS:
212 Q_SIGNALS:
213 void changed();
213 void changed();
214
214
215 public Q_SLOTS:
215 public Q_SLOTS:
216
216
217 void showColorDialog()
217 void showColorDialog()
218 {
218 {
219 QColorDialog dialog(m_brush.color());
219 QColorDialog dialog(m_brush.color());
220 dialog.show();
220 dialog.show();
221 dialog.exec();
221 dialog.exec();
222 m_brush.setColor(dialog.selectedColor());
222 m_brush.setColor(dialog.selectedColor());
223 m_colorButton->setText(m_brush.color().name());
223 m_colorButton->setText(m_brush.color().name());
224 emit changed();
224 emit changed();
225 }
225 }
226
226
227 void updateStyle()
227 void updateStyle()
228 {
228 {
229 Qt::BrushStyle style = (Qt::BrushStyle) m_styleCombo->itemData(m_styleCombo->currentIndex()).toInt();
229 Qt::BrushStyle style = (Qt::BrushStyle) m_styleCombo->itemData(m_styleCombo->currentIndex()).toInt();
230 if (m_brush.style() != style) {
230 if (m_brush.style() != style) {
231 m_brush.setStyle(style);
231 m_brush.setStyle(style);
232 emit changed();
232 emit changed();
233 }
233 }
234 }
234 }
235
235
236 private:
236 private:
237 QBrush m_brush;
237 QBrush m_brush;
238 QPushButton *m_colorButton;
238 QPushButton *m_colorButton;
239 QComboBox *m_styleCombo;
239 QComboBox *m_styleCombo;
240 };
240 };
241
241
242 class CustomSlice : public QPieSlice
242 class CustomSlice : public QPieSlice
243 {
243 {
244 Q_OBJECT
244 Q_OBJECT
245 public:
245 public:
246 CustomSlice(qreal value, QString label)
246 CustomSlice(qreal value, QString label)
247 :QPieSlice(value, label)
247 :QPieSlice(value, label)
248 {
248 {
249 connect(this, SIGNAL(hoverEnter()), this, SLOT(handleHoverEnter()));
249 connect(this, SIGNAL(hoverEnter()), this, SLOT(handleHoverEnter()));
250 connect(this, SIGNAL(hoverLeave()), this, SLOT(handleHoverLeave()));
250 connect(this, SIGNAL(hoverLeave()), this, SLOT(handleHoverLeave()));
251 }
251 }
252
252
253 public:
253 public:
254 QBrush originalBrush()
254 QBrush originalBrush()
255 {
255 {
256 return m_originalBrush;
256 return m_originalBrush;
257 }
257 }
258
258
259 public Q_SLOTS:
259 public Q_SLOTS:
260
260
261 void handleHoverEnter()
261 void handleHoverEnter()
262 {
262 {
263 QBrush brush = this->sliceBrush();
263 QBrush brush = this->sliceBrush();
264 m_originalBrush = brush;
264 m_originalBrush = brush;
265 brush.setColor(brush.color().lighter());
265 brush.setColor(brush.color().lighter());
266 setSliceBrush(brush);
266 setSliceBrush(brush);
267 }
267 }
268
268
269 void handleHoverLeave()
269 void handleHoverLeave()
270 {
270 {
271 setSliceBrush(m_originalBrush);
271 setSliceBrush(m_originalBrush);
272 }
272 }
273
273
274 private:
274 private:
275 QBrush m_originalBrush;
275 QBrush m_originalBrush;
276 };
276 };
277
277
278 class MainWidget : public QWidget
278 class MainWidget : public QWidget
279 {
279 {
280 Q_OBJECT
280 Q_OBJECT
281
281
282 public:
282 public:
283 explicit MainWidget(QWidget* parent = 0)
283 explicit MainWidget(QWidget* parent = 0)
284 :QWidget(parent),
284 :QWidget(parent),
285 m_slice(0)
285 m_slice(0)
286 {
286 {
287 // create chart
287 // create chart
288 m_chartView = new QChartView();
288 m_chartView = new QChartView();
289 m_chartView->setChartTitle("Piechart customization");
289 m_chartView->setChartTitle("Piechart customization");
290 m_chartView->setAnimationOptions(QChart::AllAnimations);
290 m_chartView->setAnimationOptions(QChart::AllAnimations);
291
291
292 // create series
292 // create series
293 m_series = new QPieSeries();
293 m_series = new QPieSeries();
294 *m_series << new CustomSlice(10.0, "Slice 1");
294 *m_series << new CustomSlice(10.0, "Slice 1");
295 *m_series << new CustomSlice(20.0, "Slice 2");
295 *m_series << new CustomSlice(20.0, "Slice 2");
296 *m_series << new CustomSlice(30.0, "Slice 3");
296 *m_series << new CustomSlice(30.0, "Slice 3");
297 *m_series << new CustomSlice(40.0, "Slice 4");
297 *m_series << new CustomSlice(40.0, "Slice 4");
298 *m_series << new CustomSlice(50.0, "Slice 5");
298 *m_series << new CustomSlice(50.0, "Slice 5");
299 m_series->setLabelsVisible();
299 m_chartView->addSeries(m_series);
300 m_chartView->addSeries(m_series);
300
301
301 connect(m_series, SIGNAL(clicked(QPieSlice*, Qt::MouseButtons)), this, SLOT(handleSliceClicked(QPieSlice*, Qt::MouseButtons)));
302 connect(m_series, SIGNAL(clicked(QPieSlice*, Qt::MouseButtons)), this, SLOT(handleSliceClicked(QPieSlice*, Qt::MouseButtons)));
302
303
303 // chart settings
304 // chart settings
304 m_themeComboBox = new QComboBox();
305 m_themeComboBox = new QComboBox();
305 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
306 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
306 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
307 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
307 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
308 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
308 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
309 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
309 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
310 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
310 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
311 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
311 m_themeComboBox->addItem("Icy", QChart::ChartThemeIcy);
312 m_themeComboBox->addItem("Icy", QChart::ChartThemeIcy);
312 m_themeComboBox->addItem("Scientific", QChart::ChartThemeScientific);
313 m_themeComboBox->addItem("Scientific", QChart::ChartThemeScientific);
313
314
314 m_aaCheckBox = new QCheckBox();
315 m_aaCheckBox = new QCheckBox();
315 m_animationsCheckBox = new QCheckBox();
316 m_animationsCheckBox = new QCheckBox();
316 m_animationsCheckBox->setCheckState(Qt::Checked);
317 m_animationsCheckBox->setCheckState(Qt::Checked);
317
318
318 QFormLayout* chartSettingsLayout = new QFormLayout();
319 QFormLayout* chartSettingsLayout = new QFormLayout();
319 chartSettingsLayout->addRow("Theme", m_themeComboBox);
320 chartSettingsLayout->addRow("Theme", m_themeComboBox);
320 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
321 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
321 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
322 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
322 QGroupBox* chartSettings = new QGroupBox("Chart");
323 QGroupBox* chartSettings = new QGroupBox("Chart");
323 chartSettings->setLayout(chartSettingsLayout);
324 chartSettings->setLayout(chartSettingsLayout);
324
325
325 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
326 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
326 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
327 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
327 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
328 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
328
329
329 // series settings
330 // series settings
330 m_hPosition = new QDoubleSpinBox();
331 m_hPosition = new QDoubleSpinBox();
331 m_hPosition->setMinimum(0.0);
332 m_hPosition->setMinimum(0.0);
332 m_hPosition->setMaximum(1.0);
333 m_hPosition->setMaximum(1.0);
333 m_hPosition->setSingleStep(0.1);
334 m_hPosition->setSingleStep(0.1);
334 m_hPosition->setValue(m_series->pieHorizontalPosition());
335 m_hPosition->setValue(m_series->pieHorizontalPosition());
335
336
336 m_vPosition = new QDoubleSpinBox();
337 m_vPosition = new QDoubleSpinBox();
337 m_vPosition->setMinimum(0.0);
338 m_vPosition->setMinimum(0.0);
338 m_vPosition->setMaximum(1.0);
339 m_vPosition->setMaximum(1.0);
339 m_vPosition->setSingleStep(0.1);
340 m_vPosition->setSingleStep(0.1);
340 m_vPosition->setValue(m_series->pieVerticalPosition());
341 m_vPosition->setValue(m_series->pieVerticalPosition());
341
342
342 m_sizeFactor = new QDoubleSpinBox();
343 m_sizeFactor = new QDoubleSpinBox();
343 m_sizeFactor->setMinimum(0.0);
344 m_sizeFactor->setMinimum(0.0);
344 m_sizeFactor->setMaximum(1.0);
345 m_sizeFactor->setMaximum(1.0);
345 m_sizeFactor->setSingleStep(0.1);
346 m_sizeFactor->setSingleStep(0.1);
346 m_sizeFactor->setValue(m_series->pieSize());
347 m_sizeFactor->setValue(m_series->pieSize());
347
348
348 m_startAngle = new QDoubleSpinBox();
349 m_startAngle = new QDoubleSpinBox();
349 m_startAngle->setMinimum(0.0);
350 m_startAngle->setMinimum(0.0);
350 m_startAngle->setMaximum(360);
351 m_startAngle->setMaximum(360);
351 m_startAngle->setValue(m_series->pieStartAngle());
352 m_startAngle->setValue(m_series->pieStartAngle());
352 m_startAngle->setSingleStep(1);
353 m_startAngle->setSingleStep(1);
353
354
354 m_endAngle = new QDoubleSpinBox();
355 m_endAngle = new QDoubleSpinBox();
355 m_endAngle->setMinimum(0.0);
356 m_endAngle->setMinimum(0.0);
356 m_endAngle->setMaximum(360);
357 m_endAngle->setMaximum(360);
357 m_endAngle->setValue(m_series->pieEndAngle());
358 m_endAngle->setValue(m_series->pieEndAngle());
358 m_endAngle->setSingleStep(1);
359 m_endAngle->setSingleStep(1);
359
360
360 QPushButton *addSlice = new QPushButton("Add slice");
361 QPushButton *addSlice = new QPushButton("Add slice");
361 QPushButton *insertSlice = new QPushButton("Insert slice");
362 QPushButton *insertSlice = new QPushButton("Insert slice");
362
363
363 QFormLayout* seriesSettingsLayout = new QFormLayout();
364 QFormLayout* seriesSettingsLayout = new QFormLayout();
364 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
365 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
365 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
366 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
366 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
367 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
367 seriesSettingsLayout->addRow("Start angle", m_startAngle);
368 seriesSettingsLayout->addRow("Start angle", m_startAngle);
368 seriesSettingsLayout->addRow("End angle", m_endAngle);
369 seriesSettingsLayout->addRow("End angle", m_endAngle);
369 seriesSettingsLayout->addRow(addSlice);
370 seriesSettingsLayout->addRow(addSlice);
370 seriesSettingsLayout->addRow(insertSlice);
371 seriesSettingsLayout->addRow(insertSlice);
371 QGroupBox* seriesSettings = new QGroupBox("Series");
372 QGroupBox* seriesSettings = new QGroupBox("Series");
372 seriesSettings->setLayout(seriesSettingsLayout);
373 seriesSettings->setLayout(seriesSettingsLayout);
373
374
374 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
375 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
375 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
376 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
376 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
377 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
377 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
378 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
378 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
379 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
379 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
380 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
380 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
381 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
381
382
382 // slice settings
383 // slice settings
383 m_sliceName = new QLabel("<click a slice>");
384 m_sliceName = new QLabel("<click a slice>");
384 m_sliceValue = new QDoubleSpinBox();
385 m_sliceValue = new QDoubleSpinBox();
385 m_sliceValue->setMaximum(1000);
386 m_sliceValue->setMaximum(1000);
386 m_sliceLabelVisible = new QCheckBox();
387 m_sliceLabelVisible = new QCheckBox();
387 m_sliceLabelArmFactor = new QDoubleSpinBox();
388 m_sliceLabelArmFactor = new QDoubleSpinBox();
388 m_sliceLabelArmFactor->setSingleStep(0.01);
389 m_sliceLabelArmFactor->setSingleStep(0.01);
389 m_sliceExploded = new QCheckBox();
390 m_sliceExploded = new QCheckBox();
390 m_sliceExplodedFactor = new QDoubleSpinBox();
391 m_sliceExplodedFactor = new QDoubleSpinBox();
391 m_sliceExplodedFactor->setSingleStep(0.01);
392 m_sliceExplodedFactor->setSingleStep(0.01);
392 m_pen = new QPushButton();
393 m_pen = new QPushButton();
393 m_penTool = new PenTool("Slice pen", this);
394 m_penTool = new PenTool("Slice pen", this);
394 m_brush = new QPushButton();
395 m_brush = new QPushButton();
395 m_brushTool = new BrushTool("Slice brush", this);
396 m_brushTool = new BrushTool("Slice brush", this);
396 m_font = new QPushButton();
397 m_font = new QPushButton();
397 m_labelArmPen = new QPushButton();
398 m_labelPen = new QPushButton();
398 m_labelArmPenTool = new PenTool("Label arm pen", this);
399 m_labelPenTool = new PenTool("Label pen", this);
399 QPushButton *removeSlice = new QPushButton("Remove slice");
400 QPushButton *removeSlice = new QPushButton("Remove slice");
400
401
401 QFormLayout* sliceSettingsLayout = new QFormLayout();
402 QFormLayout* sliceSettingsLayout = new QFormLayout();
402 sliceSettingsLayout->addRow("Selected", m_sliceName);
403 sliceSettingsLayout->addRow("Selected", m_sliceName);
403 sliceSettingsLayout->addRow("Value", m_sliceValue);
404 sliceSettingsLayout->addRow("Value", m_sliceValue);
404 sliceSettingsLayout->addRow("Pen", m_pen);
405 sliceSettingsLayout->addRow("Pen", m_pen);
405 sliceSettingsLayout->addRow("Brush", m_brush);
406 sliceSettingsLayout->addRow("Brush", m_brush);
406 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
407 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
407 sliceSettingsLayout->addRow("Label font", m_font);
408 sliceSettingsLayout->addRow("Label font", m_font);
408 sliceSettingsLayout->addRow("Label arm pen", m_labelArmPen);
409 sliceSettingsLayout->addRow("Label pen", m_labelPen);
409 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
410 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
410 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
411 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
411 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
412 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
412 sliceSettingsLayout->addRow(removeSlice);
413 sliceSettingsLayout->addRow(removeSlice);
413 QGroupBox* sliceSettings = new QGroupBox("Slice");
414 QGroupBox* sliceSettings = new QGroupBox("Slice");
414 sliceSettings->setLayout(sliceSettingsLayout);
415 sliceSettings->setLayout(sliceSettingsLayout);
415
416
416 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
417 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
417 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
418 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
418 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
419 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
419 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
420 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
420 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
421 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
421 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
422 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
422 connect(m_labelArmPen, SIGNAL(clicked()), m_labelArmPenTool, SLOT(show()));
423 connect(m_labelPen, SIGNAL(clicked()), m_labelPenTool, SLOT(show()));
423 connect(m_labelArmPenTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
424 connect(m_labelPenTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
424 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
425 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
425 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
426 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
426 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
427 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
427 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
428 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
428 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
429 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
429 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
430 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
430
431
431 // create main layout
432 // create main layout
432 QVBoxLayout *settingsLayout = new QVBoxLayout();
433 QVBoxLayout *settingsLayout = new QVBoxLayout();
433 settingsLayout->addWidget(chartSettings);
434 settingsLayout->addWidget(chartSettings);
434 settingsLayout->addWidget(seriesSettings);
435 settingsLayout->addWidget(seriesSettings);
435 settingsLayout->addWidget(sliceSettings);
436 settingsLayout->addWidget(sliceSettings);
436 settingsLayout->addStretch();
437 settingsLayout->addStretch();
437
438
438 QGridLayout* baseLayout = new QGridLayout();
439 QGridLayout* baseLayout = new QGridLayout();
439 baseLayout->addLayout(settingsLayout, 0, 0);
440 baseLayout->addLayout(settingsLayout, 0, 0);
440 baseLayout->addWidget(m_chartView, 0, 1);
441 baseLayout->addWidget(m_chartView, 0, 1);
441 setLayout(baseLayout);
442 setLayout(baseLayout);
442
443
443 updateSerieSettings();
444 updateSerieSettings();
444 }
445 }
445
446
446 public Q_SLOTS:
447 public Q_SLOTS:
447
448
448 void updateChartSettings()
449 void updateChartSettings()
449 {
450 {
450 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
451 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
451 m_chartView->setChartTheme(theme);
452 m_chartView->setChartTheme(theme);
452 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
453 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
453
454
454 if (m_animationsCheckBox->checkState() == Qt::Checked)
455 if (m_animationsCheckBox->checkState() == Qt::Checked)
455 m_chartView->setAnimationOptions(QChart::AllAnimations);
456 m_chartView->setAnimationOptions(QChart::AllAnimations);
456 else
457 else
457 m_chartView->setAnimationOptions(QChart::NoAnimation);
458 m_chartView->setAnimationOptions(QChart::NoAnimation);
458 }
459 }
459
460
460 void updateSerieSettings()
461 void updateSerieSettings()
461 {
462 {
462 m_series->setPiePosition(m_hPosition->value(), m_vPosition->value());
463 m_series->setPiePosition(m_hPosition->value(), m_vPosition->value());
463 m_series->setPieSize(m_sizeFactor->value());
464 m_series->setPieSize(m_sizeFactor->value());
464 m_series->setPieStartAngle(m_startAngle->value());
465 m_series->setPieStartAngle(m_startAngle->value());
465 m_series->setPieEndAngle(m_endAngle->value());
466 m_series->setPieEndAngle(m_endAngle->value());
466 }
467 }
467
468
468 void updateSliceSettings()
469 void updateSliceSettings()
469 {
470 {
470 if (!m_slice)
471 if (!m_slice)
471 return;
472 return;
472
473
473 m_slice->setValue(m_sliceValue->value());
474 m_slice->setValue(m_sliceValue->value());
474
475
475 m_slice->setSlicePen(m_penTool->pen());
476 m_slice->setSlicePen(m_penTool->pen());
476 m_slice->setSliceBrush(m_brushTool->brush());
477 m_slice->setSliceBrush(m_brushTool->brush());
477
478
478 m_slice->setLabelArmPen(m_labelArmPenTool->pen());
479 m_slice->setLabelPen(m_labelPenTool->pen());
479 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
480 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
480 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
481 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
481
482
482 m_slice->setExploded(m_sliceExploded->isChecked());
483 m_slice->setExploded(m_sliceExploded->isChecked());
483 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
484 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
484 }
485 }
485
486
486 void handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons)
487 void handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons)
487 {
488 {
488 Q_UNUSED(buttons);
489 Q_UNUSED(buttons);
489
490
490 m_slice = static_cast<CustomSlice*>(slice);
491 m_slice = static_cast<CustomSlice*>(slice);
491
492
492 // name
493 // name
493 m_sliceName->setText(slice->label());
494 m_sliceName->setText(slice->label());
494
495
495 // value
496 // value
496 m_sliceValue->blockSignals(true);
497 m_sliceValue->blockSignals(true);
497 m_sliceValue->setValue(slice->value());
498 m_sliceValue->setValue(slice->value());
498 m_sliceValue->blockSignals(false);
499 m_sliceValue->blockSignals(false);
499
500
500 // pen
501 // pen
501 m_pen->setText(PenTool::name(m_slice->slicePen()));
502 m_pen->setText(PenTool::name(m_slice->slicePen()));
502 m_penTool->setPen(m_slice->slicePen());
503 m_penTool->setPen(m_slice->slicePen());
503
504
504 // brush
505 // brush
505 m_brush->setText(m_slice->originalBrush().color().name());
506 m_brush->setText(m_slice->originalBrush().color().name());
506 m_brushTool->setBrush(m_slice->originalBrush());
507 m_brushTool->setBrush(m_slice->originalBrush());
507
508
508 // label
509 // label
509 m_labelArmPen->setText(PenTool::name(m_slice->labelArmPen()));
510 m_labelPen->setText(PenTool::name(m_slice->labelPen()));
510 m_labelArmPenTool->setPen(m_slice->labelArmPen());
511 m_labelPenTool->setPen(m_slice->labelPen());
511 m_font->setText(slice->labelFont().toString());
512 m_font->setText(slice->labelFont().toString());
512 m_sliceLabelVisible->blockSignals(true);
513 m_sliceLabelVisible->blockSignals(true);
513 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
514 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
514 m_sliceLabelVisible->blockSignals(false);
515 m_sliceLabelVisible->blockSignals(false);
515 m_sliceLabelArmFactor->blockSignals(true);
516 m_sliceLabelArmFactor->blockSignals(true);
516 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
517 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
517 m_sliceLabelArmFactor->blockSignals(false);
518 m_sliceLabelArmFactor->blockSignals(false);
518
519
519 // exploded
520 // exploded
520 m_sliceExploded->blockSignals(true);
521 m_sliceExploded->blockSignals(true);
521 m_sliceExploded->setChecked(slice->isExploded());
522 m_sliceExploded->setChecked(slice->isExploded());
522 m_sliceExploded->blockSignals(false);
523 m_sliceExploded->blockSignals(false);
523 m_sliceExplodedFactor->blockSignals(true);
524 m_sliceExplodedFactor->blockSignals(true);
524 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
525 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
525 m_sliceExplodedFactor->blockSignals(false);
526 m_sliceExplodedFactor->blockSignals(false);
526 }
527 }
527
528
528 void showFontDialog()
529 void showFontDialog()
529 {
530 {
530 if (!m_slice)
531 if (!m_slice)
531 return;
532 return;
532
533
533 QFontDialog dialog(m_slice->labelFont());
534 QFontDialog dialog(m_slice->labelFont());
534 dialog.show();
535 dialog.show();
535 dialog.exec();
536 dialog.exec();
536
537
537 m_slice->setLabelFont(dialog.currentFont());
538 m_slice->setLabelFont(dialog.currentFont());
538 m_font->setText(dialog.currentFont().toString());
539 m_font->setText(dialog.currentFont().toString());
539 }
540 }
540
541
541 void addSlice()
542 void addSlice()
542 {
543 {
543 *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1));
544 *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1));
544 }
545 }
545
546
546 void insertSlice()
547 void insertSlice()
547 {
548 {
548 if (!m_slice)
549 if (!m_slice)
549 return;
550 return;
550
551
551 int i = m_series->slices().indexOf(m_slice);
552 int i = m_series->slices().indexOf(m_slice);
552
553
553 m_series->insert(i, new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1)));
554 m_series->insert(i, new CustomSlice(10.0, "Slice " + QString::number(m_series->count()+1)));
554 }
555 }
555
556
556 void removeSlice()
557 void removeSlice()
557 {
558 {
558 if (!m_slice)
559 if (!m_slice)
559 return;
560 return;
560
561
561 m_series->remove(m_slice);
562 m_series->remove(m_slice);
562 m_slice = 0;
563 m_slice = 0;
563 }
564 }
564
565
565 private:
566 private:
566 QComboBox *m_themeComboBox;
567 QComboBox *m_themeComboBox;
567 QCheckBox *m_aaCheckBox;
568 QCheckBox *m_aaCheckBox;
568 QCheckBox *m_animationsCheckBox;
569 QCheckBox *m_animationsCheckBox;
569
570
570 QChartView* m_chartView;
571 QChartView* m_chartView;
571 QPieSeries* m_series;
572 QPieSeries* m_series;
572 CustomSlice* m_slice;
573 CustomSlice* m_slice;
573
574
574 QDoubleSpinBox* m_hPosition;
575 QDoubleSpinBox* m_hPosition;
575 QDoubleSpinBox* m_vPosition;
576 QDoubleSpinBox* m_vPosition;
576 QDoubleSpinBox* m_sizeFactor;
577 QDoubleSpinBox* m_sizeFactor;
577 QDoubleSpinBox* m_startAngle;
578 QDoubleSpinBox* m_startAngle;
578 QDoubleSpinBox* m_endAngle;
579 QDoubleSpinBox* m_endAngle;
579
580
580 QLabel* m_sliceName;
581 QLabel* m_sliceName;
581 QDoubleSpinBox* m_sliceValue;
582 QDoubleSpinBox* m_sliceValue;
582 QCheckBox* m_sliceLabelVisible;
583 QCheckBox* m_sliceLabelVisible;
583 QDoubleSpinBox* m_sliceLabelArmFactor;
584 QDoubleSpinBox* m_sliceLabelArmFactor;
584 QCheckBox* m_sliceExploded;
585 QCheckBox* m_sliceExploded;
585 QDoubleSpinBox* m_sliceExplodedFactor;
586 QDoubleSpinBox* m_sliceExplodedFactor;
586 QPushButton *m_brush;
587 QPushButton *m_brush;
587 BrushTool *m_brushTool;
588 BrushTool *m_brushTool;
588 QPushButton *m_pen;
589 QPushButton *m_pen;
589 PenTool *m_penTool;
590 PenTool *m_penTool;
590 QPushButton *m_font;
591 QPushButton *m_font;
591 QPushButton *m_labelArmPen;
592 QPushButton *m_labelPen;
592 PenTool *m_labelArmPenTool;
593 PenTool *m_labelPenTool;
593 };
594 };
594
595
595 int main(int argc, char *argv[])
596 int main(int argc, char *argv[])
596 {
597 {
597 QApplication a(argc, argv);
598 QApplication a(argc, argv);
598
599
599 QMainWindow window;
600 QMainWindow window;
600
601
601 MainWidget* widget = new MainWidget();
602 MainWidget* widget = new MainWidget();
602
603
603 window.setCentralWidget(widget);
604 window.setCentralWidget(widget);
604 window.resize(900, 600);
605 window.resize(900, 600);
605 window.show();
606 window.show();
606
607
607 return a.exec();
608 return a.exec();
608 }
609 }
609
610
610 #include "main.moc"
611 #include "main.moc"
@@ -1,369 +1,379
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartview.h"
3 #include "qchartview.h"
4 #include "qlegend.h"
4 #include "qlegend.h"
5 #include "qchartaxis.h"
5 #include "qchartaxis.h"
6 #include <QTime>
6 #include <QTime>
7
7
8 //series
8 //series
9 #include "qbarset.h"
9 #include "qbarset.h"
10 #include "qbarseries.h"
10 #include "qbarseries.h"
11 #include "qstackedbarseries.h"
11 #include "qstackedbarseries.h"
12 #include "qpercentbarseries.h"
12 #include "qpercentbarseries.h"
13 #include "qlineseries.h"
13 #include "qlineseries.h"
14 #include "qareaseries.h"
14 #include "qareaseries.h"
15 #include "qscatterseries.h"
15 #include "qscatterseries.h"
16 #include "qpieseries.h"
16 #include "qpieseries.h"
17 #include "qpieslice.h"
17 #include "qpieslice.h"
18 #include "qsplineseries.h"
18 #include "qsplineseries.h"
19
19
20 //items
20 //items
21 #include "axisitem_p.h"
21 #include "axisitem_p.h"
22 #include "barchartitem_p.h"
22 #include "barchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
24 #include "percentbarchartitem_p.h"
24 #include "percentbarchartitem_p.h"
25 #include "linechartitem_p.h"
25 #include "linechartitem_p.h"
26 #include "areachartitem_p.h"
26 #include "areachartitem_p.h"
27 #include "scatterchartitem_p.h"
27 #include "scatterchartitem_p.h"
28 #include "piechartitem_p.h"
28 #include "piechartitem_p.h"
29 #include "splinechartitem_p.h"
29 #include "splinechartitem_p.h"
30
30
31 //themes
31 //themes
32 #include "chartthemedefault_p.h"
32 #include "chartthemedefault_p.h"
33 #include "chartthemelight_p.h"
33 #include "chartthemelight_p.h"
34 #include "chartthemebluecerulean_p.h"
34 #include "chartthemebluecerulean_p.h"
35 #include "chartthemedark_p.h"
35 #include "chartthemedark_p.h"
36 #include "chartthemebrownsand_p.h"
36 #include "chartthemebrownsand_p.h"
37 #include "chartthemebluencs_p.h"
37 #include "chartthemebluencs_p.h"
38 #include "chartthemeicy_p.h"
38 #include "chartthemeicy_p.h"
39 #include "chartthemescientific_p.h"
39 #include "chartthemescientific_p.h"
40
40
41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42
42
43 ChartTheme::ChartTheme(QChart::ChartTheme id) :
43 ChartTheme::ChartTheme(QChart::ChartTheme id) :
44 m_masterFont(QFont()),
44 m_masterFont(QFont()),
45 m_titleBrush(QColor(QRgb(0x000000))),
45 m_titleBrush(QColor(QRgb(0x000000))),
46 m_axisLinePen(QPen(QRgb(0x000000))),
46 m_axisLinePen(QPen(QRgb(0x000000))),
47 m_axisLabelBrush(QColor(QRgb(0x000000))),
47 m_axisLabelBrush(QColor(QRgb(0x000000))),
48 m_backgroundShadesPen(Qt::NoPen),
48 m_backgroundShadesPen(Qt::NoPen),
49 m_backgroundShadesBrush(Qt::NoBrush),
49 m_backgroundShadesBrush(Qt::NoBrush),
50 m_backgroundShades(BackgroundShadesNone),
50 m_backgroundShades(BackgroundShadesNone),
51 m_gridLinePen(QPen(QRgb(0x000000)))
51 m_gridLinePen(QPen(QRgb(0x000000)))
52 {
52 {
53 m_id = id;
53 m_id = id;
54 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
54 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
55 }
55 }
56
56
57
57
58 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
58 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
59 {
59 {
60 switch(theme) {
60 switch(theme) {
61 case QChart::ChartThemeLight:
61 case QChart::ChartThemeLight:
62 return new ChartThemeLight();
62 return new ChartThemeLight();
63 case QChart::ChartThemeBlueCerulean:
63 case QChart::ChartThemeBlueCerulean:
64 return new ChartThemeBlueCerulean();
64 return new ChartThemeBlueCerulean();
65 case QChart::ChartThemeDark:
65 case QChart::ChartThemeDark:
66 return new ChartThemeDark();
66 return new ChartThemeDark();
67 case QChart::ChartThemeBrownSand:
67 case QChart::ChartThemeBrownSand:
68 return new ChartThemeBrownSand();
68 return new ChartThemeBrownSand();
69 case QChart::ChartThemeBlueNcs:
69 case QChart::ChartThemeBlueNcs:
70 return new ChartThemeBlueNcs();
70 return new ChartThemeBlueNcs();
71 case QChart::ChartThemeIcy:
71 case QChart::ChartThemeIcy:
72 return new ChartThemeIcy();
72 return new ChartThemeIcy();
73 case QChart::ChartThemeScientific:
73 case QChart::ChartThemeScientific:
74 return new ChartThemeScientific();
74 return new ChartThemeScientific();
75 default:
75 default:
76 return new ChartThemeDefault();
76 return new ChartThemeDefault();
77 }
77 }
78 }
78 }
79
79
80 void ChartTheme::decorate(QChart* chart,bool force)
80 void ChartTheme::decorate(QChart* chart,bool force)
81 {
81 {
82 QPen pen;
82 QPen pen;
83 QBrush brush;
83 QBrush brush;
84
84
85 if(brush == chart->backgroundBrush() || force)
85 if(brush == chart->backgroundBrush() || force)
86 {
86 {
87 if (m_backgroundShades == BackgroundShadesNone) {
87 if (m_backgroundShades == BackgroundShadesNone) {
88 chart->setBackgroundBrush(m_chartBackgroundGradient);
88 chart->setBackgroundBrush(m_chartBackgroundGradient);
89 }
89 }
90 else {
90 else {
91 chart->setBackgroundBrush(Qt::NoBrush);
91 chart->setBackgroundBrush(Qt::NoBrush);
92 }
92 }
93 }
93 }
94 chart->setTitleFont(m_masterFont);
94 chart->setTitleFont(m_masterFont);
95 chart->setTitleBrush(m_titleBrush);
95 chart->setTitleBrush(m_titleBrush);
96 }
96 }
97
97
98 void ChartTheme::decorate(QLegend* legend,bool force)
98 void ChartTheme::decorate(QLegend* legend,bool force)
99 {
99 {
100 QPen pen;
100 QPen pen;
101 QBrush brush;
101 QBrush brush;
102
102
103 if (pen == legend->pen() || force){
103 if (pen == legend->pen() || force){
104 //TODO:: legend->setPen();
104 //TODO:: legend->setPen();
105 }
105 }
106
106
107
107
108 if (brush == legend->brush() || force) {
108 if (brush == legend->brush() || force) {
109 legend->setBrush(m_chartBackgroundGradient);
109 legend->setBrush(m_chartBackgroundGradient);
110 }
110 }
111 }
111 }
112
112
113 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
113 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
114 {
114 {
115 QPen pen;
115 QPen pen;
116 QBrush brush;
116 QBrush brush;
117
117
118 if (pen == series->pen() || force){
118 if (pen == series->pen() || force){
119 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
119 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
120 pen.setWidthF(2);
120 pen.setWidthF(2);
121 series->setPen(pen);
121 series->setPen(pen);
122 }
122 }
123
123
124 if (brush == series->brush() || force) {
124 if (brush == series->brush() || force) {
125 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
125 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
126 series->setBrush(brush);
126 series->setBrush(brush);
127 }
127 }
128 }
128 }
129
129
130
130
131 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
131 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
132 {
132 {
133 QPen pen;
133 QPen pen;
134 if(pen == series->pen() || force ){
134 if(pen == series->pen() || force ){
135 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
135 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
136 pen.setWidthF(2);
136 pen.setWidthF(2);
137 series->setPen(pen);
137 series->setPen(pen);
138 }
138 }
139 }
139 }
140
140
141 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
141 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
142 {
142 {
143 QBrush brush;
143 QBrush brush;
144 QPen pen;
144 QPen pen;
145 QList<QBarSet*> sets = series->barSets();
145 QList<QBarSet*> sets = series->barSets();
146
146
147 qreal takeAtPos = 0.5;
147 qreal takeAtPos = 0.5;
148 qreal step = 0.2;
148 qreal step = 0.2;
149 if (sets.count() > 1 ) {
149 if (sets.count() > 1 ) {
150 step = 1.0 / (qreal) sets.count();
150 step = 1.0 / (qreal) sets.count();
151 if (sets.count() % m_seriesGradients.count())
151 if (sets.count() % m_seriesGradients.count())
152 step *= m_seriesGradients.count();
152 step *= m_seriesGradients.count();
153 else
153 else
154 step *= (m_seriesGradients.count() - 1);
154 step *= (m_seriesGradients.count() - 1);
155 }
155 }
156
156
157 for (int i(0); i < sets.count(); i++) {
157 for (int i(0); i < sets.count(); i++) {
158 int colorIndex = (index + i) % m_seriesGradients.count();
158 int colorIndex = (index + i) % m_seriesGradients.count();
159 if (i > 0 && i % m_seriesGradients.count() == 0) {
159 if (i > 0 && i % m_seriesGradients.count() == 0) {
160 // There is no dedicated base color for each sets, generate more colors
160 // There is no dedicated base color for each sets, generate more colors
161 takeAtPos += step;
161 takeAtPos += step;
162 if (takeAtPos == 1.0)
162 if (takeAtPos == 1.0)
163 takeAtPos += step;
163 takeAtPos += step;
164 takeAtPos -= (int) takeAtPos;
164 takeAtPos -= (int) takeAtPos;
165 }
165 }
166 qDebug() << "pos:" << takeAtPos;
166 qDebug() << "pos:" << takeAtPos;
167 if (brush == sets.at(i)->brush() || force )
167 if (brush == sets.at(i)->brush() || force )
168 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
168 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
169
169
170 // Pick label color from the opposite end of the gradient.
170 // Pick label color from the opposite end of the gradient.
171 // 0.3 as a boundary seems to work well.
171 // 0.3 as a boundary seems to work well.
172 if (takeAtPos < 0.3)
172 if (takeAtPos < 0.3)
173 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
173 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
174 else
174 else
175 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
175 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
176
176
177 if (pen == sets.at(i)->pen() || force) {
177 if (pen == sets.at(i)->pen() || force) {
178 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
178 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
179 sets.at(i)->setPen(c);
179 sets.at(i)->setPen(c);
180 }
180 }
181 }
181 }
182 }
182 }
183
183
184 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
184 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
185 {
185 {
186 QPen pen;
186 QPen pen;
187 QBrush brush;
187 QBrush brush;
188
188
189 if (pen == series->pen() || force) {
189 if (pen == series->pen() || force) {
190 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
190 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
191 pen.setWidthF(2);
191 pen.setWidthF(2);
192 series->setPen(pen);
192 series->setPen(pen);
193 }
193 }
194
194
195 if (brush == series->brush() || force) {
195 if (brush == series->brush() || force) {
196 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
196 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
197 series->setBrush(brush);
197 series->setBrush(brush);
198 }
198 }
199 }
199 }
200
200
201 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
201 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
202 {
202 {
203 for (int i(0); i < series->slices().count(); i++) {
203 for (int i(0); i < series->slices().count(); i++) {
204
204
205 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
205 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
206
206
207 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
207 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
208 qreal pos = (qreal) (i + 1) / (qreal) series->count();
208 qreal pos = (qreal) (i + 1) / (qreal) series->count();
209 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
209 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
210
210
211 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
211 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
212 PieSliceData data = s->m_data;
212 PieSliceData data = s->m_data;
213
213
214 if (data.m_slicePen.isThemed() || force) {
214 if (data.m_slicePen.isThemed() || force) {
215 data.m_slicePen = penColor;
215 data.m_slicePen = penColor;
216 data.m_slicePen.setThemed(true);
216 data.m_slicePen.setThemed(true);
217 }
217 }
218
218
219 if (data.m_sliceBrush.isThemed() || force) {
219 if (data.m_sliceBrush.isThemed() || force) {
220 data.m_sliceBrush = brushColor;
220 data.m_sliceBrush = brushColor;
221 data.m_sliceBrush.setThemed(true);
221 data.m_sliceBrush.setThemed(true);
222 }
222 }
223
223
224 if (data.m_labelPen.isThemed() || force) {
225 data.m_labelPen = QPen(m_titleBrush.color());
226 data.m_labelPen.setThemed(true);
227 }
228
229 if (data.m_labelFont.isThemed() || force) {
230 data.m_labelFont = m_masterFont;
231 data.m_labelFont.setThemed(true);
232 }
233
224 if (s->m_data != data) {
234 if (s->m_data != data) {
225 s->m_data = data;
235 s->m_data = data;
226 emit s->changed();
236 emit s->changed();
227 }
237 }
228 }
238 }
229 }
239 }
230
240
231 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
241 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
232 {
242 {
233 QPen pen;
243 QPen pen;
234 if(pen == series->pen() || force){
244 if(pen == series->pen() || force){
235 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
245 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
236 pen.setWidthF(2);
246 pen.setWidthF(2);
237 series->setPen(pen);
247 series->setPen(pen);
238 }
248 }
239 }
249 }
240
250
241 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
251 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
242 {
252 {
243 QPen pen;
253 QPen pen;
244 QBrush brush;
254 QBrush brush;
245 QFont font;
255 QFont font;
246
256
247 if (axis->isAxisVisible()) {
257 if (axis->isAxisVisible()) {
248
258
249 if(brush == axis->labelsBrush() || force){
259 if(brush == axis->labelsBrush() || force){
250 axis->setLabelsBrush(m_axisLabelBrush);
260 axis->setLabelsBrush(m_axisLabelBrush);
251 }
261 }
252 if(pen == axis->labelsPen() || force){
262 if(pen == axis->labelsPen() || force){
253 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
263 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
254 }
264 }
255
265
256
266
257 if (axis->shadesVisible() || force) {
267 if (axis->shadesVisible() || force) {
258
268
259 if(brush == axis->shadesBrush() || force){
269 if(brush == axis->shadesBrush() || force){
260 axis->setShadesBrush(m_backgroundShadesBrush);
270 axis->setShadesBrush(m_backgroundShadesBrush);
261 }
271 }
262
272
263 if(pen == axis->shadesPen() || force){
273 if(pen == axis->shadesPen() || force){
264 axis->setShadesPen(m_backgroundShadesPen);
274 axis->setShadesPen(m_backgroundShadesPen);
265 }
275 }
266
276
267 if(force && (m_backgroundShades == BackgroundShadesBoth
277 if(force && (m_backgroundShades == BackgroundShadesBoth
268 || (m_backgroundShades == BackgroundShadesVertical && axisX)
278 || (m_backgroundShades == BackgroundShadesVertical && axisX)
269 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
279 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
270 axis->setShadesVisible(true);
280 axis->setShadesVisible(true);
271
281
272 }
282 }
273 }
283 }
274
284
275 if(pen == axis->axisPen() || force){
285 if(pen == axis->axisPen() || force){
276 axis->setAxisPen(m_axisLinePen);
286 axis->setAxisPen(m_axisLinePen);
277 }
287 }
278
288
279 if(pen == axis->gridLinePen() || force){
289 if(pen == axis->gridLinePen() || force){
280 axis->setGridLinePen(m_gridLinePen);
290 axis->setGridLinePen(m_gridLinePen);
281 }
291 }
282
292
283 if(font == axis->labelsFont() || force){
293 if(font == axis->labelsFont() || force){
284 axis->setLabelsFont(m_masterFont);
294 axis->setLabelsFont(m_masterFont);
285 }
295 }
286 }
296 }
287 }
297 }
288
298
289 void ChartTheme::generateSeriesGradients()
299 void ChartTheme::generateSeriesGradients()
290 {
300 {
291 // Generate gradients in HSV color space
301 // Generate gradients in HSV color space
292 foreach (QColor color, m_seriesColors) {
302 foreach (QColor color, m_seriesColors) {
293 QLinearGradient g;
303 QLinearGradient g;
294 qreal h = color.hsvHueF();
304 qreal h = color.hsvHueF();
295 qreal s = color.hsvSaturationF();
305 qreal s = color.hsvSaturationF();
296
306
297 // TODO: tune the algorithm to give nice results with most base colors defined in
307 // TODO: tune the algorithm to give nice results with most base colors defined in
298 // most themes. The rest of the gradients we can define manually in theme specific
308 // most themes. The rest of the gradients we can define manually in theme specific
299 // implementation.
309 // implementation.
300 QColor start = color;
310 QColor start = color;
301 start.setHsvF(h, 0.0, 1.0);
311 start.setHsvF(h, 0.0, 1.0);
302 g.setColorAt(0.0, start);
312 g.setColorAt(0.0, start);
303
313
304 g.setColorAt(0.5, color);
314 g.setColorAt(0.5, color);
305
315
306 QColor end = color;
316 QColor end = color;
307 end.setHsvF(h, s, 0.25);
317 end.setHsvF(h, s, 0.25);
308 g.setColorAt(1.0, end);
318 g.setColorAt(1.0, end);
309
319
310 m_seriesGradients << g;
320 m_seriesGradients << g;
311 }
321 }
312 }
322 }
313
323
314
324
315 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
325 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
316 {
326 {
317 Q_ASSERT(pos >=0.0 && pos <= 1.0);
327 Q_ASSERT(pos >=0.0 && pos <= 1.0);
318 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
328 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
319 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
329 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
320 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
330 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
321 QColor c;
331 QColor c;
322 c.setRgbF(r, g, b);
332 c.setRgbF(r, g, b);
323 return c;
333 return c;
324 }
334 }
325
335
326 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
336 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
327 {
337 {
328 Q_ASSERT(pos >=0 && pos <= 1.0);
338 Q_ASSERT(pos >=0 && pos <= 1.0);
329
339
330 // another possibility:
340 // another possibility:
331 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
341 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
332
342
333 QGradientStops stops = gradient.stops();
343 QGradientStops stops = gradient.stops();
334 int count = stops.count();
344 int count = stops.count();
335
345
336 // find previous stop relative to position
346 // find previous stop relative to position
337 QGradientStop prev = stops.first();
347 QGradientStop prev = stops.first();
338 for (int i=0; i<count; i++) {
348 for (int i=0; i<count; i++) {
339 QGradientStop stop = stops.at(i);
349 QGradientStop stop = stops.at(i);
340 if (pos > stop.first)
350 if (pos > stop.first)
341 prev = stop;
351 prev = stop;
342
352
343 // given position is actually a stop position?
353 // given position is actually a stop position?
344 if (pos == stop.first) {
354 if (pos == stop.first) {
345 //qDebug() << "stop color" << pos;
355 //qDebug() << "stop color" << pos;
346 return stop.second;
356 return stop.second;
347 }
357 }
348 }
358 }
349
359
350 // find next stop relative to position
360 // find next stop relative to position
351 QGradientStop next = stops.last();
361 QGradientStop next = stops.last();
352 for (int i=count-1; i>=0; i--) {
362 for (int i=count-1; i>=0; i--) {
353 QGradientStop stop = stops.at(i);
363 QGradientStop stop = stops.at(i);
354 if (pos < stop.first)
364 if (pos < stop.first)
355 next = stop;
365 next = stop;
356 }
366 }
357
367
358 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
368 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
359
369
360 qreal range = next.first - prev.first;
370 qreal range = next.first - prev.first;
361 qreal posDelta = pos - prev.first;
371 qreal posDelta = pos - prev.first;
362 qreal relativePos = posDelta / range;
372 qreal relativePos = posDelta / range;
363
373
364 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
374 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
365
375
366 return colorAt(prev.second, next.second, relativePos);
376 return colorAt(prev.second, next.second, relativePos);
367 }
377 }
368
378
369 QTCOMMERCIALCHART_END_NAMESPACE
379 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,110 +1,110
1 #ifndef PIESLICEDATA_P_H
1 #ifndef PIESLICEDATA_P_H
2 #define PIESLICEDATA_P_H
2 #define PIESLICEDATA_P_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QPen>
5 #include <QPen>
6 #include <QBrush>
6 #include <QBrush>
7 #include <QDebug>
7 #include <QDebug>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 template <class T>
11 template <class T>
12 class Themed : public T
12 class Themed : public T
13 {
13 {
14 public:
14 public:
15 Themed():m_isThemed(true) {}
15 Themed():m_isThemed(true) {}
16
16
17 inline T &operator=(const T &other) { return T::operator =(other); }
17 inline T &operator=(const T &other) { return T::operator =(other); }
18
18
19 inline bool operator!=(const T &other) { return T::operator !=(other); }
19 inline bool operator!=(const T &other) { return T::operator !=(other); }
20 inline bool operator!=(const Themed &other)
20 inline bool operator!=(const Themed &other)
21 {
21 {
22 if (T::operator !=(other))
22 if (T::operator !=(other))
23 return true;
23 return true;
24
24
25 if (m_isThemed != other.m_isThemed)
25 if (m_isThemed != other.m_isThemed)
26 return true;
26 return true;
27
27
28 return false;
28 return false;
29 }
29 }
30
30
31 inline void setThemed(bool state) { m_isThemed = state; }
31 inline void setThemed(bool state) { m_isThemed = state; }
32 inline bool isThemed() const { return m_isThemed; }
32 inline bool isThemed() const { return m_isThemed; }
33
33
34 private:
34 private:
35 bool m_isThemed;
35 bool m_isThemed;
36 };
36 };
37
37
38 class PieSliceData
38 class PieSliceData
39 {
39 {
40 public:
40 public:
41 PieSliceData()
41 PieSliceData()
42 {
42 {
43 m_value = 0;
43 m_value = 0;
44
44
45 m_isExploded = false;
45 m_isExploded = false;
46 m_explodeDistanceFactor = 0.15;
46 m_explodeDistanceFactor = 0.15;
47
47
48 m_isLabelVisible = false;
48 m_isLabelVisible = false;
49 m_labelArmLengthFactor = 0.15;
49 m_labelArmLengthFactor = 0.15;
50
50
51 m_percentage = 0;
51 m_percentage = 0;
52 m_radius = 0;
52 m_radius = 0;
53 m_startAngle = 0;
53 m_startAngle = 0;
54 m_angleSpan = 0;
54 m_angleSpan = 0;
55 }
55 }
56
56
57 bool operator!=(const PieSliceData &other)
57 bool operator!=(const PieSliceData &other)
58 {
58 {
59 if (m_value != other.m_value)
59 if (m_value != other.m_value)
60 return true;
60 return true;
61
61
62 if (m_slicePen != other.m_slicePen ||
62 if (m_slicePen != other.m_slicePen ||
63 m_sliceBrush != other.m_sliceBrush)
63 m_sliceBrush != other.m_sliceBrush)
64 return true;
64 return true;
65
65
66 if (m_isExploded != other.m_isExploded ||
66 if (m_isExploded != other.m_isExploded ||
67 m_explodeDistanceFactor != other.m_explodeDistanceFactor)
67 m_explodeDistanceFactor != other.m_explodeDistanceFactor)
68 return true;
68 return true;
69
69
70 if (m_isLabelVisible != other.m_isLabelVisible ||
70 if (m_isLabelVisible != other.m_isLabelVisible ||
71 m_labelText != other.m_labelText ||
71 m_labelText != other.m_labelText ||
72 m_labelFont != other.m_labelFont ||
72 m_labelFont != other.m_labelFont ||
73 m_labelArmLengthFactor != other.m_labelArmLengthFactor ||
73 m_labelArmLengthFactor != other.m_labelArmLengthFactor ||
74 m_labelArmPen != other.m_labelArmPen)
74 m_labelPen != other.m_labelPen)
75 return true;
75 return true;
76
76
77 if (m_percentage != other.m_percentage ||
77 if (m_percentage != other.m_percentage ||
78 m_center != other.m_center ||
78 m_center != other.m_center ||
79 m_radius != other.m_radius ||
79 m_radius != other.m_radius ||
80 m_startAngle != other.m_startAngle ||
80 m_startAngle != other.m_startAngle ||
81 m_angleSpan != other.m_angleSpan)
81 m_angleSpan != other.m_angleSpan)
82 return true;
82 return true;
83
83
84 return false;
84 return false;
85 }
85 }
86
86
87 qreal m_value;
87 qreal m_value;
88
88
89 Themed<QPen> m_slicePen;
89 Themed<QPen> m_slicePen;
90 Themed<QBrush> m_sliceBrush;
90 Themed<QBrush> m_sliceBrush;
91
91
92 bool m_isExploded;
92 bool m_isExploded;
93 qreal m_explodeDistanceFactor;
93 qreal m_explodeDistanceFactor;
94
94
95 bool m_isLabelVisible;
95 bool m_isLabelVisible;
96 QString m_labelText;
96 QString m_labelText;
97 Themed<QFont> m_labelFont;
97 Themed<QFont> m_labelFont;
98 qreal m_labelArmLengthFactor;
98 qreal m_labelArmLengthFactor;
99 Themed<QPen> m_labelArmPen;
99 Themed<QPen> m_labelPen;
100
100
101 qreal m_percentage;
101 qreal m_percentage;
102 QPointF m_center;
102 QPointF m_center;
103 qreal m_radius;
103 qreal m_radius;
104 qreal m_startAngle;
104 qreal m_startAngle;
105 qreal m_angleSpan;
105 qreal m_angleSpan;
106 };
106 };
107
107
108 QTCOMMERCIALCHART_END_NAMESPACE
108 QTCOMMERCIALCHART_END_NAMESPACE
109
109
110 #endif // PIESLICEDATA_P_H
110 #endif // PIESLICEDATA_P_H
@@ -1,184 +1,182
1 #include "piesliceitem_p.h"
1 #include "piesliceitem_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
24 :QGraphicsObject(parent)
24 :QGraphicsObject(parent)
25 {
25 {
26 setAcceptHoverEvents(true);
26 setAcceptHoverEvents(true);
27 setAcceptedMouseButtons(Qt::MouseButtonMask);
27 setAcceptedMouseButtons(Qt::MouseButtonMask);
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieSliceItem::~PieSliceItem()
31 PieSliceItem::~PieSliceItem()
32 {
32 {
33
33
34 }
34 }
35
35
36 QRectF PieSliceItem::boundingRect() const
36 QRectF PieSliceItem::boundingRect() const
37 {
37 {
38 return m_boundingRect;
38 return m_boundingRect;
39 }
39 }
40
40
41 QPainterPath PieSliceItem::shape() const
41 QPainterPath PieSliceItem::shape() const
42 {
42 {
43 // Don't include the label and label arm.
43 // Don't include the label and label arm.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
45 return m_slicePath;
45 return m_slicePath;
46 }
46 }
47
47
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setClipRect(parentItem()->boundingRect());
50 painter->setClipRect(parentItem()->boundingRect());
51
51
52 painter->save();
52 painter->save();
53 painter->setPen(m_data.m_slicePen);
53 painter->setPen(m_data.m_slicePen);
54 painter->setBrush(m_data.m_sliceBrush);
54 painter->setBrush(m_data.m_sliceBrush);
55 painter->drawPath(m_slicePath);
55 painter->drawPath(m_slicePath);
56 painter->restore();
56 painter->restore();
57
57
58 if (m_data.m_isLabelVisible) {
58 if (m_data.m_isLabelVisible) {
59 painter->save();
59 painter->setPen(m_data.m_labelPen);
60 painter->setPen(m_data.m_labelArmPen);
61 painter->drawPath(m_labelArmPath);
60 painter->drawPath(m_labelArmPath);
62 painter->restore();
61 // the pen color will affect the font color as well
63
64 painter->setFont(m_data.m_labelFont);
62 painter->setFont(m_data.m_labelFont);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
63 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
66 }
64 }
67 }
65 }
68
66
69 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
67 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
70 {
68 {
71 emit hoverEnter();
69 emit hoverEnter();
72 }
70 }
73
71
74 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
72 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
75 {
73 {
76 emit hoverLeave();
74 emit hoverLeave();
77 }
75 }
78
76
79 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
77 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
80 {
78 {
81 emit clicked(event->buttons());
79 emit clicked(event->buttons());
82 }
80 }
83
81
84 void PieSliceItem::setSliceData(PieSliceData sliceData)
82 void PieSliceItem::setSliceData(PieSliceData sliceData)
85 {
83 {
86 m_data = sliceData;
84 m_data = sliceData;
87 }
85 }
88
86
89 void PieSliceItem::updateGeometry()
87 void PieSliceItem::updateGeometry()
90 {
88 {
91 if (m_data.m_radius <= 0)
89 if (m_data.m_radius <= 0)
92 return;
90 return;
93
91
94 prepareGeometryChange();
92 prepareGeometryChange();
95
93
96 // update slice path
94 // update slice path
97 qreal centerAngle;
95 qreal centerAngle;
98 QPointF armStart;
96 QPointF armStart;
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
97 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
100
98
101 // update text rect
99 // update text rect
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
100 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
103
101
104 // update label arm path
102 // update label arm path
105 QPointF labelTextStart;
103 QPointF labelTextStart;
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
104 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
107
105
108 // update text position
106 // update text position
109 m_labelTextRect.moveBottomLeft(labelTextStart);
107 m_labelTextRect.moveBottomLeft(labelTextStart);
110
108
111 // update bounding rect
109 // update bounding rect
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
110 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
113 }
111 }
114
112
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
113 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
116 {
114 {
117 if (slice->isExploded()) {
115 if (slice->isExploded()) {
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
116 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
119 qreal len = radius * slice->explodeDistanceFactor();
117 qreal len = radius * slice->explodeDistanceFactor();
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
118 qreal dx = qSin(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
119 qreal dy = -qCos(centerAngle*(PI/180)) * len;
122 point += QPointF(dx, dy);
120 point += QPointF(dx, dy);
123 }
121 }
124 return point;
122 return point;
125 }
123 }
126
124
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
125 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
128 {
126 {
129 // calculate center angle
127 // calculate center angle
130 *centerAngle = startAngle + (angleSpan/2);
128 *centerAngle = startAngle + (angleSpan/2);
131
129
132 // calculate slice rectangle
130 // calculate slice rectangle
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
131 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
134
132
135 // slice path
133 // slice path
136 // TODO: draw the shape so that it might have a hole in the center
134 // TODO: draw the shape so that it might have a hole in the center
137 QPainterPath path;
135 QPainterPath path;
138 path.moveTo(rect.center());
136 path.moveTo(rect.center());
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
137 path.arcTo(rect, -startAngle + 90, -angleSpan);
140 path.closeSubpath();
138 path.closeSubpath();
141
139
142 // calculate label arm start point
140 // calculate label arm start point
143 *armStart = center;
141 *armStart = center;
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
142 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
145
143
146 return path;
144 return path;
147 }
145 }
148
146
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
147 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
150 {
148 {
151 qreal dx = qSin(angle*(PI/180)) * length;
149 qreal dx = qSin(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
150 qreal dy = -qCos(angle*(PI/180)) * length;
153 QPointF parm1 = start + QPointF(dx, dy);
151 QPointF parm1 = start + QPointF(dx, dy);
154
152
155 QPointF parm2 = parm1;
153 QPointF parm2 = parm1;
156 if (angle < 180) { // arm swings the other way on the left side
154 if (angle < 180) { // arm swings the other way on the left side
157 parm2 += QPointF(textWidth, 0);
155 parm2 += QPointF(textWidth, 0);
158 *textStart = parm1;
156 *textStart = parm1;
159 }
157 }
160 else {
158 else {
161 parm2 += QPointF(-textWidth,0);
159 parm2 += QPointF(-textWidth,0);
162 *textStart = parm2;
160 *textStart = parm2;
163 }
161 }
164
162
165 // elevate the text position a bit so that it does not hit the line
163 // elevate the text position a bit so that it does not hit the line
166 *textStart += QPointF(0, -5);
164 *textStart += QPointF(0, -5);
167
165
168 QPainterPath path;
166 QPainterPath path;
169 path.moveTo(start);
167 path.moveTo(start);
170 path.lineTo(parm1);
168 path.lineTo(parm1);
171 path.lineTo(parm2);
169 path.lineTo(parm2);
172
170
173 return path;
171 return path;
174 }
172 }
175
173
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
174 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
177 {
175 {
178 QFontMetricsF fm(font);
176 QFontMetricsF fm(font);
179 return fm.boundingRect(text);
177 return fm.boundingRect(text);
180 }
178 }
181
179
182 #include "moc_piesliceitem_p.cpp"
180 #include "moc_piesliceitem_p.cpp"
183
181
184 QTCOMMERCIALCHART_END_NAMESPACE
182 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,413 +1,413
1 #include "qpieslice.h"
1 #include "qpieslice.h"
2 #include "qpiesliceprivate_p.h"
2 #include "qpiesliceprivate_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieseriesprivate_p.h"
4 #include "qpieseriesprivate_p.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 /*!
8 /*!
9 \class QPieSlice
9 \class QPieSlice
10 \brief Defines a slice in pie series.
10 \brief Defines a slice in pie series.
11
11
12 Holds all the data of a single slice in a QPieSeries and provides the means
12 Holds all the data of a single slice in a QPieSeries and provides the means
13 to modify slice data and customize the visual appearance of the slice.
13 to modify slice data and customize the visual appearance of the slice.
14
14
15 It also provides the means to customize user interaction with the slice by
15 It also provides the means to customize user interaction with the slice by
16 providing signals for clicking and hover events.
16 providing signals for clicking and hover events.
17 */
17 */
18
18
19 /*!
19 /*!
20 \property QPieSlice::label
20 \property QPieSlice::label
21
21
22 Label of the slice.
22 Label of the slice.
23 */
23 */
24
24
25 /*!
25 /*!
26 \property QPieSlice::value
26 \property QPieSlice::value
27
27
28 Value of the slice.
28 Value of the slice.
29 */
29 */
30
30
31 /*!
31 /*!
32 Constructs an empty slice with a \a parent.
32 Constructs an empty slice with a \a parent.
33
33
34 Note that QPieSeries takes ownership of the slice when it is set/added.
34 Note that QPieSeries takes ownership of the slice when it is set/added.
35
35
36 \sa QPieSeries::replace(), QPieSeries::add()
36 \sa QPieSeries::replace(), QPieSeries::add()
37 */
37 */
38 QPieSlice::QPieSlice(QObject *parent)
38 QPieSlice::QPieSlice(QObject *parent)
39 :QObject(parent),
39 :QObject(parent),
40 d_ptr(new QPieSlicePrivate(this))
40 d_ptr(new QPieSlicePrivate(this))
41 {
41 {
42
42
43 }
43 }
44
44
45 /*!
45 /*!
46 Constructs an empty slice with given \a value, \a label and a \a parent.
46 Constructs an empty slice with given \a value, \a label and a \a parent.
47 Note that QPieSeries takes ownership of the slice when it is set/added.
47 Note that QPieSeries takes ownership of the slice when it is set/added.
48 \sa QPieSeries::replace(), QPieSeries::add()
48 \sa QPieSeries::replace(), QPieSeries::add()
49 */
49 */
50 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
50 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
51 :QObject(parent),
51 :QObject(parent),
52 d_ptr(new QPieSlicePrivate(this))
52 d_ptr(new QPieSlicePrivate(this))
53 {
53 {
54 Q_D(QPieSlice);
54 Q_D(QPieSlice);
55 d->m_data.m_value = value;
55 d->m_data.m_value = value;
56 d->m_data.m_labelText = label;
56 d->m_data.m_labelText = label;
57 }
57 }
58
58
59 /*!
59 /*!
60 Destroys the slice.
60 Destroys the slice.
61 User should not delete the slice if it has been added to the series.
61 User should not delete the slice if it has been added to the series.
62 */
62 */
63 QPieSlice::~QPieSlice()
63 QPieSlice::~QPieSlice()
64 {
64 {
65 delete d_ptr;
65 delete d_ptr;
66 }
66 }
67
67
68 /*!
68 /*!
69 Gets the value of the slice.
69 Gets the value of the slice.
70 Note that all values in the series
70 Note that all values in the series
71 \sa setValue()
71 \sa setValue()
72 */
72 */
73 qreal QPieSlice::value() const
73 qreal QPieSlice::value() const
74 {
74 {
75 Q_D(const QPieSlice);
75 Q_D(const QPieSlice);
76 return d->m_data.m_value;
76 return d->m_data.m_value;
77 }
77 }
78
78
79 /*!
79 /*!
80 Gets the label of the slice.
80 Gets the label of the slice.
81 \sa setLabel()
81 \sa setLabel()
82 */
82 */
83 QString QPieSlice::label() const
83 QString QPieSlice::label() const
84 {
84 {
85 Q_D(const QPieSlice);
85 Q_D(const QPieSlice);
86 return d->m_data.m_labelText;
86 return d->m_data.m_labelText;
87 }
87 }
88
88
89 /*!
89 /*!
90 Returns true if label is set as visible.
90 Returns true if label is set as visible.
91 \sa setLabelVisible()
91 \sa setLabelVisible()
92 */
92 */
93 bool QPieSlice::isLabelVisible() const
93 bool QPieSlice::isLabelVisible() const
94 {
94 {
95 Q_D(const QPieSlice);
95 Q_D(const QPieSlice);
96 return d->m_data.m_isLabelVisible;
96 return d->m_data.m_isLabelVisible;
97 }
97 }
98
98
99 /*!
99 /*!
100 Returns true if slice is exloded from the pie.
100 Returns true if slice is exloded from the pie.
101 \sa setExploded(), setExplodeDistanceFactor()
101 \sa setExploded(), setExplodeDistanceFactor()
102 */
102 */
103 bool QPieSlice::isExploded() const
103 bool QPieSlice::isExploded() const
104 {
104 {
105 Q_D(const QPieSlice);
105 Q_D(const QPieSlice);
106 return d->m_data.m_isExploded;
106 return d->m_data.m_isExploded;
107 }
107 }
108
108
109 /*!
109 /*!
110 Returns the explode distance factor.
110 Returns the explode distance factor.
111
111
112 The factor is relative to pie radius. For example:
112 The factor is relative to pie radius. For example:
113 1.0 means the distance is the same as the radius.
113 1.0 means the distance is the same as the radius.
114 0.5 means the distance is half of the radius.
114 0.5 means the distance is half of the radius.
115
115
116 Default value is 0.15.
116 Default value is 0.15.
117
117
118 \sa setExplodeDistanceFactor()
118 \sa setExplodeDistanceFactor()
119 */
119 */
120 qreal QPieSlice::explodeDistanceFactor() const
120 qreal QPieSlice::explodeDistanceFactor() const
121 {
121 {
122 Q_D(const QPieSlice);
122 Q_D(const QPieSlice);
123 return d->m_data.m_explodeDistanceFactor;
123 return d->m_data.m_explodeDistanceFactor;
124 }
124 }
125
125
126 /*!
126 /*!
127 Returns the percentage of this slice compared to all slices in the same series.
127 Returns the percentage of this slice compared to all slices in the same series.
128 The returned value ranges from 0 to 1.0.
128 The returned value ranges from 0 to 1.0.
129
129
130 Updated internally after the slice is added to the series.
130 Updated internally after the slice is added to the series.
131 */
131 */
132 qreal QPieSlice::percentage() const
132 qreal QPieSlice::percentage() const
133 {
133 {
134 Q_D(const QPieSlice);
134 Q_D(const QPieSlice);
135 return d->m_data.m_percentage;
135 return d->m_data.m_percentage;
136 }
136 }
137
137
138 /*!
138 /*!
139 Returns the starting angle of this slice in the series it belongs to.
139 Returns the starting angle of this slice in the series it belongs to.
140
140
141 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
141 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
142
142
143 Updated internally after the slice is added to the series.
143 Updated internally after the slice is added to the series.
144 */
144 */
145 qreal QPieSlice::startAngle() const
145 qreal QPieSlice::startAngle() const
146 {
146 {
147 Q_D(const QPieSlice);
147 Q_D(const QPieSlice);
148 return d->m_data.m_startAngle;
148 return d->m_data.m_startAngle;
149 }
149 }
150
150
151 /*!
151 /*!
152 Returns the end angle of this slice in the series it belongs to.
152 Returns the end angle of this slice in the series it belongs to.
153
153
154 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
154 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
155
155
156 Updated internally after the slice is added to the series.
156 Updated internally after the slice is added to the series.
157 */
157 */
158 qreal QPieSlice::endAngle() const
158 qreal QPieSlice::endAngle() const
159 {
159 {
160 Q_D(const QPieSlice);
160 Q_D(const QPieSlice);
161 return d->m_data.m_startAngle + d->m_data.m_angleSpan;
161 return d->m_data.m_startAngle + d->m_data.m_angleSpan;
162 }
162 }
163
163
164 /*!
164 /*!
165 Returns the pen used to draw this slice.
165 Returns the pen used to draw this slice.
166 \sa setSlicePen()
166 \sa setSlicePen()
167 */
167 */
168 QPen QPieSlice::slicePen() const
168 QPen QPieSlice::slicePen() const
169 {
169 {
170 Q_D(const QPieSlice);
170 Q_D(const QPieSlice);
171 return d->m_data.m_slicePen;
171 return d->m_data.m_slicePen;
172 }
172 }
173
173
174 /*!
174 /*!
175 Returns the brush used to draw this slice.
175 Returns the brush used to draw this slice.
176 \sa setSliceBrush()
176 \sa setSliceBrush()
177 */
177 */
178 QBrush QPieSlice::sliceBrush() const
178 QBrush QPieSlice::sliceBrush() const
179 {
179 {
180 Q_D(const QPieSlice);
180 Q_D(const QPieSlice);
181 return d->m_data.m_sliceBrush;
181 return d->m_data.m_sliceBrush;
182 }
182 }
183
183
184 /*!
184 /*!
185 Returns the pen used to draw label arm in this slice.
185 Returns the pen used to draw the label in this slice.
186 \sa setLabelArmPen()
186 \sa setLabelArmPen()
187 */
187 */
188 QPen QPieSlice::labelArmPen() const
188 QPen QPieSlice::labelPen() const
189 {
189 {
190 Q_D(const QPieSlice);
190 Q_D(const QPieSlice);
191 return d->m_data.m_labelArmPen;
191 return d->m_data.m_labelPen;
192 }
192 }
193
193
194 /*!
194 /*!
195 Returns the font used to draw label in this slice.
195 Returns the font used to draw label in this slice.
196 \sa setLabelFont()
196 \sa setLabelFont()
197 */
197 */
198 QFont QPieSlice::labelFont() const
198 QFont QPieSlice::labelFont() const
199 {
199 {
200 Q_D(const QPieSlice);
200 Q_D(const QPieSlice);
201 return d->m_data.m_labelFont;
201 return d->m_data.m_labelFont;
202 }
202 }
203
203
204 /*!
204 /*!
205 Gets the label arm length factor.
205 Gets the label arm length factor.
206
206
207 The factor is relative to pie radius. For example:
207 The factor is relative to pie radius. For example:
208 1.0 means the length is the same as the radius.
208 1.0 means the length is the same as the radius.
209 0.5 means the length is half of the radius.
209 0.5 means the length is half of the radius.
210
210
211 Default value is 0.15
211 Default value is 0.15
212
212
213 \sa setLabelArmLengthFactor()
213 \sa setLabelArmLengthFactor()
214 */
214 */
215 qreal QPieSlice::labelArmLengthFactor() const
215 qreal QPieSlice::labelArmLengthFactor() const
216 {
216 {
217 Q_D(const QPieSlice);
217 Q_D(const QPieSlice);
218 return d->m_data.m_labelArmLengthFactor;
218 return d->m_data.m_labelArmLengthFactor;
219 }
219 }
220
220
221 /*!
221 /*!
222 \fn void QPieSlice::clicked()
222 \fn void QPieSlice::clicked()
223
223
224 This signal is emitted when user has clicked the slice.
224 This signal is emitted when user has clicked the slice.
225
225
226 \sa QPieSeries::clicked()
226 \sa QPieSeries::clicked()
227 */
227 */
228
228
229 /*!
229 /*!
230 \fn void QPieSlice::hoverEnter()
230 \fn void QPieSlice::hoverEnter()
231
231
232 This signal is emitted when user has hovered over the slice.
232 This signal is emitted when user has hovered over the slice.
233
233
234 \sa QPieSeries::hoverEnter()
234 \sa QPieSeries::hoverEnter()
235 */
235 */
236
236
237 /*!
237 /*!
238 \fn void QPieSlice::hoverLeave()
238 \fn void QPieSlice::hoverLeave()
239
239
240 This signal is emitted when user has hovered away from the slice.
240 This signal is emitted when user has hovered away from the slice.
241
241
242 \sa QPieSeries::hoverLeave()
242 \sa QPieSeries::hoverLeave()
243 */
243 */
244
244
245 /*!
245 /*!
246 \fn void QPieSlice::changed()
246 \fn void QPieSlice::changed()
247
247
248 This signal emitted when something has changed in the slice.
248 This signal emitted when something has changed in the slice.
249
249
250 \sa QPieSeries::changed()
250 \sa QPieSeries::changed()
251 */
251 */
252
252
253 /*!
253 /*!
254 Sets the \a value of this slice.
254 Sets the \a value of this slice.
255 \sa value()
255 \sa value()
256 */
256 */
257 void QPieSlice::setValue(qreal value)
257 void QPieSlice::setValue(qreal value)
258 {
258 {
259 Q_D(QPieSlice);
259 Q_D(QPieSlice);
260 if (d->m_data.m_value != value) {
260 if (d->m_data.m_value != value) {
261 d->m_data.m_value = value;
261 d->m_data.m_value = value;
262
262
263 QPieSeries *series = qobject_cast<QPieSeries*>(parent());
263 QPieSeries *series = qobject_cast<QPieSeries*>(parent());
264 if (series)
264 if (series)
265 series->data_ptr()->updateDerivativeData(); // will emit changed()
265 series->data_ptr()->updateDerivativeData(); // will emit changed()
266 else
266 else
267 emit changed();
267 emit changed();
268 }
268 }
269 }
269 }
270
270
271 /*!
271 /*!
272 Sets the \a label of the slice.
272 Sets the \a label of the slice.
273 \sa label()
273 \sa label()
274 */
274 */
275 void QPieSlice::setLabel(QString label)
275 void QPieSlice::setLabel(QString label)
276 {
276 {
277 Q_D(QPieSlice);
277 Q_D(QPieSlice);
278 if (d->m_data.m_labelText != label) {
278 if (d->m_data.m_labelText != label) {
279 d->m_data.m_labelText = label;
279 d->m_data.m_labelText = label;
280 emit changed();
280 emit changed();
281 }
281 }
282 }
282 }
283
283
284 /*!
284 /*!
285 Sets the label \a visible in this slice.
285 Sets the label \a visible in this slice.
286 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
286 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
287 */
287 */
288 void QPieSlice::setLabelVisible(bool visible)
288 void QPieSlice::setLabelVisible(bool visible)
289 {
289 {
290 Q_D(QPieSlice);
290 Q_D(QPieSlice);
291 if (d->m_data.m_isLabelVisible != visible) {
291 if (d->m_data.m_isLabelVisible != visible) {
292 d->m_data.m_isLabelVisible = visible;
292 d->m_data.m_isLabelVisible = visible;
293 emit changed();
293 emit changed();
294 }
294 }
295 }
295 }
296
296
297 /*!
297 /*!
298 Sets this slice \a exploded.
298 Sets this slice \a exploded.
299 \sa isExploded(), explodeDistanceFactor()
299 \sa isExploded(), explodeDistanceFactor()
300 */
300 */
301 void QPieSlice::setExploded(bool exploded)
301 void QPieSlice::setExploded(bool exploded)
302 {
302 {
303 Q_D(QPieSlice);
303 Q_D(QPieSlice);
304 if (d->m_data.m_isExploded != exploded) {
304 if (d->m_data.m_isExploded != exploded) {
305 d->m_data.m_isExploded = exploded;
305 d->m_data.m_isExploded = exploded;
306 emit changed();
306 emit changed();
307 }
307 }
308 }
308 }
309
309
310 /*!
310 /*!
311 Sets the explode distance \a factor.
311 Sets the explode distance \a factor.
312
312
313 The factor is relative to pie radius. For example:
313 The factor is relative to pie radius. For example:
314 1.0 means the distance is the same as the radius.
314 1.0 means the distance is the same as the radius.
315 0.5 means the distance is half of the radius.
315 0.5 means the distance is half of the radius.
316
316
317 Default value is 0.15
317 Default value is 0.15
318
318
319 \sa explodeDistanceFactor()
319 \sa explodeDistanceFactor()
320 */
320 */
321 void QPieSlice::setExplodeDistanceFactor(qreal factor)
321 void QPieSlice::setExplodeDistanceFactor(qreal factor)
322 {
322 {
323 Q_D(QPieSlice);
323 Q_D(QPieSlice);
324 if (d->m_data.m_explodeDistanceFactor != factor) {
324 if (d->m_data.m_explodeDistanceFactor != factor) {
325 d->m_data.m_explodeDistanceFactor = factor;
325 d->m_data.m_explodeDistanceFactor = factor;
326 emit changed();
326 emit changed();
327 }
327 }
328 }
328 }
329
329
330 /*!
330 /*!
331 Sets the \a pen used to draw this slice.
331 Sets the \a pen used to draw this slice.
332 Note that applying a theme will override this.
332 Note that applying a theme will override this.
333 \sa slicePen()
333 \sa slicePen()
334 */
334 */
335 void QPieSlice::setSlicePen(const QPen &pen)
335 void QPieSlice::setSlicePen(const QPen &pen)
336 {
336 {
337 Q_D(QPieSlice);
337 Q_D(QPieSlice);
338 if (d->m_data.m_slicePen != pen) {
338 if (d->m_data.m_slicePen != pen) {
339 d->m_data.m_slicePen = pen;
339 d->m_data.m_slicePen = pen;
340 d->m_data.m_slicePen.setThemed(false);
340 d->m_data.m_slicePen.setThemed(false);
341 emit changed();
341 emit changed();
342 }
342 }
343 }
343 }
344
344
345 /*!
345 /*!
346 Sets the \a brush used to draw this slice.
346 Sets the \a brush used to draw this slice.
347 Note that applying a theme will override this.
347 Note that applying a theme will override this.
348 \sa sliceBrush()
348 \sa sliceBrush()
349 */
349 */
350 void QPieSlice::setSliceBrush(const QBrush &brush)
350 void QPieSlice::setSliceBrush(const QBrush &brush)
351 {
351 {
352 Q_D(QPieSlice);
352 Q_D(QPieSlice);
353 if (d->m_data.m_sliceBrush != brush) {
353 if (d->m_data.m_sliceBrush != brush) {
354 d->m_data.m_sliceBrush = brush;
354 d->m_data.m_sliceBrush = brush;
355 d->m_data.m_sliceBrush.setThemed(false);
355 d->m_data.m_sliceBrush.setThemed(false);
356 emit changed();
356 emit changed();
357 }
357 }
358 }
358 }
359
359
360 /*!
360 /*!
361 Sets the \a pen used to draw the label arm in this slice.
361 Sets the \a pen used to draw the label in this slice.
362 Note that applying a theme will override this.
362 Note that applying a theme will override this.
363 \sa labelArmPen()
363 \sa labelArmPen()
364 */
364 */
365 void QPieSlice::setLabelArmPen(const QPen &pen)
365 void QPieSlice::setLabelPen(const QPen &pen)
366 {
366 {
367 Q_D(QPieSlice);
367 Q_D(QPieSlice);
368 if (d->m_data.m_labelArmPen != pen) {
368 if (d->m_data.m_labelPen != pen) {
369 d->m_data.m_labelArmPen = pen;
369 d->m_data.m_labelPen = pen;
370 d->m_data.m_labelArmPen.setThemed(false);
370 d->m_data.m_labelPen.setThemed(false);
371 emit changed();
371 emit changed();
372 }
372 }
373 }
373 }
374
374
375 /*!
375 /*!
376 Sets the \a font used to draw the label in this slice.
376 Sets the \a font used to draw the label in this slice.
377 Note that applying a theme will override this.
377 Note that applying a theme will override this.
378 \sa labelFont()
378 \sa labelFont()
379 */
379 */
380 void QPieSlice::setLabelFont(const QFont &font)
380 void QPieSlice::setLabelFont(const QFont &font)
381 {
381 {
382 Q_D(QPieSlice);
382 Q_D(QPieSlice);
383 if (d->m_data.m_labelFont != font) {
383 if (d->m_data.m_labelFont != font) {
384 d->m_data.m_labelFont = font;
384 d->m_data.m_labelFont = font;
385 d->m_data.m_labelFont.setThemed(false);
385 d->m_data.m_labelFont.setThemed(false);
386 emit changed();
386 emit changed();
387 }
387 }
388 }
388 }
389
389
390 /*!
390 /*!
391 Sets the label arm length \a factor.
391 Sets the label arm length \a factor.
392
392
393 The factor is relative to pie radius. For example:
393 The factor is relative to pie radius. For example:
394 1.0 means the length is the same as the radius.
394 1.0 means the length is the same as the radius.
395 0.5 means the length is half of the radius.
395 0.5 means the length is half of the radius.
396
396
397 Default value is 0.15
397 Default value is 0.15
398
398
399 \sa labelArmLengthFactor()
399 \sa labelArmLengthFactor()
400 */
400 */
401 void QPieSlice::setLabelArmLengthFactor(qreal factor)
401 void QPieSlice::setLabelArmLengthFactor(qreal factor)
402 {
402 {
403 Q_D(QPieSlice);
403 Q_D(QPieSlice);
404 if (d->m_data.m_labelArmLengthFactor != factor) {
404 if (d->m_data.m_labelArmLengthFactor != factor) {
405 d->m_data.m_labelArmLengthFactor = factor;
405 d->m_data.m_labelArmLengthFactor = factor;
406 emit changed();
406 emit changed();
407 }
407 }
408 }
408 }
409
409
410 #include "moc_qpieslice.cpp"
410 #include "moc_qpieslice.cpp"
411 #include "moc_qpiesliceprivate_p.cpp"
411 #include "moc_qpiesliceprivate_p.cpp"
412
412
413 QTCOMMERCIALCHART_END_NAMESPACE
413 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,71
1 #ifndef QPIESLICE_H
1 #ifndef QPIESLICE_H
2 #define QPIESLICE_H
2 #define QPIESLICE_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QObject>
5 #include <QObject>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8 #include <QFont>
8 #include <QFont>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 class QPieSlicePrivate;
11 class QPieSlicePrivate;
12
12
13 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
13 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
16 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
17 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
17 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
18
18
19 public:
19 public:
20 QPieSlice(QObject *parent = 0);
20 QPieSlice(QObject *parent = 0);
21 QPieSlice(qreal value, QString label, QObject *parent = 0);
21 QPieSlice(qreal value, QString label, QObject *parent = 0);
22 virtual ~QPieSlice();
22 virtual ~QPieSlice();
23
23
24 // data
24 // data
25 void setValue(qreal value);
25 void setValue(qreal value);
26 qreal value() const;
26 qreal value() const;
27 void setLabel(QString label);
27 void setLabel(QString label);
28 QString label() const;
28 QString label() const;
29 void setLabelVisible(bool visible = true);
29 void setLabelVisible(bool visible = true);
30 bool isLabelVisible() const;
30 bool isLabelVisible() const;
31 void setExploded(bool exploded = true);
31 void setExploded(bool exploded = true);
32 bool isExploded() const;
32 bool isExploded() const;
33
33
34 // generated data
34 // generated data
35 qreal percentage() const;
35 qreal percentage() const;
36 qreal startAngle() const;
36 qreal startAngle() const;
37 qreal endAngle() const;
37 qreal endAngle() const;
38
38
39 // customization
39 // customization
40 void setSlicePen(const QPen &pen);
40 void setSlicePen(const QPen &pen);
41 QPen slicePen() const;
41 QPen slicePen() const;
42 void setSliceBrush(const QBrush &brush);
42 void setSliceBrush(const QBrush &brush);
43 QBrush sliceBrush() const;
43 QBrush sliceBrush() const;
44 void setLabelArmPen(const QPen &pen);
44 void setLabelPen(const QPen &pen);
45 QPen labelArmPen() const;
45 QPen labelPen() const;
46 void setLabelFont(const QFont &font);
46 void setLabelFont(const QFont &font);
47 QFont labelFont() const;
47 QFont labelFont() const;
48 void setLabelArmLengthFactor(qreal factor);
48 void setLabelArmLengthFactor(qreal factor);
49 qreal labelArmLengthFactor() const;
49 qreal labelArmLengthFactor() const;
50 void setExplodeDistanceFactor(qreal factor);
50 void setExplodeDistanceFactor(qreal factor);
51 qreal explodeDistanceFactor() const;
51 qreal explodeDistanceFactor() const;
52
52
53 Q_SIGNALS:
53 Q_SIGNALS:
54 void clicked(Qt::MouseButtons buttons);
54 void clicked(Qt::MouseButtons buttons);
55 void hoverEnter();
55 void hoverEnter();
56 void hoverLeave();
56 void hoverLeave();
57 void changed();
57 void changed();
58
58
59 private:
59 private:
60 QPieSlicePrivate * const d_ptr;
60 QPieSlicePrivate * const d_ptr;
61 Q_DECLARE_PRIVATE(QPieSlice)
61 Q_DECLARE_PRIVATE(QPieSlice)
62 Q_DISABLE_COPY(QPieSlice)
62 Q_DISABLE_COPY(QPieSlice)
63
63
64 public:
64 public:
65 typedef QPieSlicePrivate * const DataPtr;
65 typedef QPieSlicePrivate * const DataPtr;
66 inline DataPtr &data_ptr() { return d_ptr; }
66 inline DataPtr &data_ptr() { return d_ptr; }
67 };
67 };
68
68
69 QTCOMMERCIALCHART_END_NAMESPACE
69 QTCOMMERCIALCHART_END_NAMESPACE
70
70
71 #endif // QPIESLICE_H
71 #endif // QPIESLICE_H
General Comments 0
You need to be logged in to leave comments. Login now