##// END OF EJS Templates
Use qFuzzyIsNull to compare (in)equality of real values
Jani Honkonen -
r768:dd9d32f835df
parent child
Show More
@@ -1,611 +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 (!qFuzzyIsNull(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->brush();
263 QBrush brush = this->brush();
264 m_originalBrush = brush;
264 m_originalBrush = brush;
265 brush.setColor(brush.color().lighter());
265 brush.setColor(brush.color().lighter());
266 setBrush(brush);
266 setBrush(brush);
267 }
267 }
268
268
269 void handleHoverLeave()
269 void handleHoverLeave()
270 {
270 {
271 setBrush(m_originalBrush);
271 setBrush(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(new QChart());
288 m_chartView = new QChartView(new QChart());
289 m_chartView->chart()->setTitle("Piechart customization");
289 m_chartView->chart()->setTitle("Piechart customization");
290 m_chartView->chart()->setAnimationOptions(QChart::AllAnimations);
290 m_chartView->chart()->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_series->setLabelsVisible();
300 m_chartView->chart()->addSeries(m_series);
300 m_chartView->chart()->addSeries(m_series);
301
301
302 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)));
303
303
304 // chart settings
304 // chart settings
305 m_themeComboBox = new QComboBox();
305 m_themeComboBox = new QComboBox();
306 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
306 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
307 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
307 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
308 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
308 m_themeComboBox->addItem("BlueCerulean", QChart::ChartThemeBlueCerulean);
309 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
309 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
310 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
310 m_themeComboBox->addItem("BrownSand", QChart::ChartThemeBrownSand);
311 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
311 m_themeComboBox->addItem("BlueNcs", QChart::ChartThemeBlueNcs);
312 m_themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
312 m_themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
313 m_themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
313 m_themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
314
314
315 m_aaCheckBox = new QCheckBox();
315 m_aaCheckBox = new QCheckBox();
316 m_animationsCheckBox = new QCheckBox();
316 m_animationsCheckBox = new QCheckBox();
317 m_animationsCheckBox->setCheckState(Qt::Checked);
317 m_animationsCheckBox->setCheckState(Qt::Checked);
318
318
319 QFormLayout* chartSettingsLayout = new QFormLayout();
319 QFormLayout* chartSettingsLayout = new QFormLayout();
320 chartSettingsLayout->addRow("Theme", m_themeComboBox);
320 chartSettingsLayout->addRow("Theme", m_themeComboBox);
321 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
321 chartSettingsLayout->addRow("Antialiasing", m_aaCheckBox);
322 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
322 chartSettingsLayout->addRow("Animations", m_animationsCheckBox);
323 QGroupBox* chartSettings = new QGroupBox("Chart");
323 QGroupBox* chartSettings = new QGroupBox("Chart");
324 chartSettings->setLayout(chartSettingsLayout);
324 chartSettings->setLayout(chartSettingsLayout);
325
325
326 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
326 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateChartSettings()));
327 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
327 connect(m_aaCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
328 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
328 connect(m_animationsCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateChartSettings()));
329
329
330 // series settings
330 // series settings
331 m_hPosition = new QDoubleSpinBox();
331 m_hPosition = new QDoubleSpinBox();
332 m_hPosition->setMinimum(0.0);
332 m_hPosition->setMinimum(0.0);
333 m_hPosition->setMaximum(1.0);
333 m_hPosition->setMaximum(1.0);
334 m_hPosition->setSingleStep(0.1);
334 m_hPosition->setSingleStep(0.1);
335 m_hPosition->setValue(m_series->pieHorizontalPosition());
335 m_hPosition->setValue(m_series->pieHorizontalPosition());
336
336
337 m_vPosition = new QDoubleSpinBox();
337 m_vPosition = new QDoubleSpinBox();
338 m_vPosition->setMinimum(0.0);
338 m_vPosition->setMinimum(0.0);
339 m_vPosition->setMaximum(1.0);
339 m_vPosition->setMaximum(1.0);
340 m_vPosition->setSingleStep(0.1);
340 m_vPosition->setSingleStep(0.1);
341 m_vPosition->setValue(m_series->pieVerticalPosition());
341 m_vPosition->setValue(m_series->pieVerticalPosition());
342
342
343 m_sizeFactor = new QDoubleSpinBox();
343 m_sizeFactor = new QDoubleSpinBox();
344 m_sizeFactor->setMinimum(0.0);
344 m_sizeFactor->setMinimum(0.0);
345 m_sizeFactor->setMaximum(1.0);
345 m_sizeFactor->setMaximum(1.0);
346 m_sizeFactor->setSingleStep(0.1);
346 m_sizeFactor->setSingleStep(0.1);
347 m_sizeFactor->setValue(m_series->pieSize());
347 m_sizeFactor->setValue(m_series->pieSize());
348
348
349 m_startAngle = new QDoubleSpinBox();
349 m_startAngle = new QDoubleSpinBox();
350 m_startAngle->setMinimum(0.0);
350 m_startAngle->setMinimum(0.0);
351 m_startAngle->setMaximum(360);
351 m_startAngle->setMaximum(360);
352 m_startAngle->setValue(m_series->pieStartAngle());
352 m_startAngle->setValue(m_series->pieStartAngle());
353 m_startAngle->setSingleStep(1);
353 m_startAngle->setSingleStep(1);
354
354
355 m_endAngle = new QDoubleSpinBox();
355 m_endAngle = new QDoubleSpinBox();
356 m_endAngle->setMinimum(0.0);
356 m_endAngle->setMinimum(0.0);
357 m_endAngle->setMaximum(360);
357 m_endAngle->setMaximum(360);
358 m_endAngle->setValue(m_series->pieEndAngle());
358 m_endAngle->setValue(m_series->pieEndAngle());
359 m_endAngle->setSingleStep(1);
359 m_endAngle->setSingleStep(1);
360
360
361 QPushButton *addSlice = new QPushButton("Add slice");
361 QPushButton *addSlice = new QPushButton("Add slice");
362 QPushButton *insertSlice = new QPushButton("Insert slice");
362 QPushButton *insertSlice = new QPushButton("Insert slice");
363
363
364 QFormLayout* seriesSettingsLayout = new QFormLayout();
364 QFormLayout* seriesSettingsLayout = new QFormLayout();
365 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
365 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
366 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
366 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
367 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
367 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
368 seriesSettingsLayout->addRow("Start angle", m_startAngle);
368 seriesSettingsLayout->addRow("Start angle", m_startAngle);
369 seriesSettingsLayout->addRow("End angle", m_endAngle);
369 seriesSettingsLayout->addRow("End angle", m_endAngle);
370 seriesSettingsLayout->addRow(addSlice);
370 seriesSettingsLayout->addRow(addSlice);
371 seriesSettingsLayout->addRow(insertSlice);
371 seriesSettingsLayout->addRow(insertSlice);
372 QGroupBox* seriesSettings = new QGroupBox("Series");
372 QGroupBox* seriesSettings = new QGroupBox("Series");
373 seriesSettings->setLayout(seriesSettingsLayout);
373 seriesSettings->setLayout(seriesSettingsLayout);
374
374
375 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
375 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
376 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
376 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
377 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
377 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
378 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
378 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
379 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
379 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
380 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
380 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
381 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
381 connect(insertSlice, SIGNAL(clicked()), this, SLOT(insertSlice()));
382
382
383 // slice settings
383 // slice settings
384 m_sliceName = new QLabel("<click a slice>");
384 m_sliceName = new QLabel("<click a slice>");
385 m_sliceValue = new QDoubleSpinBox();
385 m_sliceValue = new QDoubleSpinBox();
386 m_sliceValue->setMaximum(1000);
386 m_sliceValue->setMaximum(1000);
387 m_sliceLabelVisible = new QCheckBox();
387 m_sliceLabelVisible = new QCheckBox();
388 m_sliceLabelArmFactor = new QDoubleSpinBox();
388 m_sliceLabelArmFactor = new QDoubleSpinBox();
389 m_sliceLabelArmFactor->setSingleStep(0.01);
389 m_sliceLabelArmFactor->setSingleStep(0.01);
390 m_sliceExploded = new QCheckBox();
390 m_sliceExploded = new QCheckBox();
391 m_sliceExplodedFactor = new QDoubleSpinBox();
391 m_sliceExplodedFactor = new QDoubleSpinBox();
392 m_sliceExplodedFactor->setSingleStep(0.01);
392 m_sliceExplodedFactor->setSingleStep(0.01);
393 m_pen = new QPushButton();
393 m_pen = new QPushButton();
394 m_penTool = new PenTool("Slice pen", this);
394 m_penTool = new PenTool("Slice pen", this);
395 m_brush = new QPushButton();
395 m_brush = new QPushButton();
396 m_brushTool = new BrushTool("Slice brush", this);
396 m_brushTool = new BrushTool("Slice brush", this);
397 m_font = new QPushButton();
397 m_font = new QPushButton();
398 m_labelPen = new QPushButton();
398 m_labelPen = new QPushButton();
399 m_labelPenTool = new PenTool("Label pen", this);
399 m_labelPenTool = new PenTool("Label pen", this);
400 QPushButton *removeSlice = new QPushButton("Remove slice");
400 QPushButton *removeSlice = new QPushButton("Remove slice");
401
401
402 QFormLayout* sliceSettingsLayout = new QFormLayout();
402 QFormLayout* sliceSettingsLayout = new QFormLayout();
403 sliceSettingsLayout->addRow("Selected", m_sliceName);
403 sliceSettingsLayout->addRow("Selected", m_sliceName);
404 sliceSettingsLayout->addRow("Value", m_sliceValue);
404 sliceSettingsLayout->addRow("Value", m_sliceValue);
405 sliceSettingsLayout->addRow("Pen", m_pen);
405 sliceSettingsLayout->addRow("Pen", m_pen);
406 sliceSettingsLayout->addRow("Brush", m_brush);
406 sliceSettingsLayout->addRow("Brush", m_brush);
407 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
407 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
408 sliceSettingsLayout->addRow("Label font", m_font);
408 sliceSettingsLayout->addRow("Label font", m_font);
409 sliceSettingsLayout->addRow("Label pen", m_labelPen);
409 sliceSettingsLayout->addRow("Label pen", m_labelPen);
410 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
410 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
411 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
411 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
412 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
412 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
413 sliceSettingsLayout->addRow(removeSlice);
413 sliceSettingsLayout->addRow(removeSlice);
414 QGroupBox* sliceSettings = new QGroupBox("Slice");
414 QGroupBox* sliceSettings = new QGroupBox("Slice");
415 sliceSettings->setLayout(sliceSettingsLayout);
415 sliceSettings->setLayout(sliceSettingsLayout);
416
416
417 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
417 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
418 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
418 connect(m_pen, SIGNAL(clicked()), m_penTool, SLOT(show()));
419 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
419 connect(m_penTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
420 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
420 connect(m_brush, SIGNAL(clicked()), m_brushTool, SLOT(show()));
421 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
421 connect(m_brushTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
422 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
422 connect(m_font, SIGNAL(clicked()), this, SLOT(showFontDialog()));
423 connect(m_labelPen, SIGNAL(clicked()), m_labelPenTool, SLOT(show()));
423 connect(m_labelPen, SIGNAL(clicked()), m_labelPenTool, SLOT(show()));
424 connect(m_labelPenTool, SIGNAL(changed()), this, SLOT(updateSliceSettings()));
424 connect(m_labelPenTool, SIGNAL(changed()), 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_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
427 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
427 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
428 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
428 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
429 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
429 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
430 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
430 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
431
431
432 // create main layout
432 // create main layout
433 QVBoxLayout *settingsLayout = new QVBoxLayout();
433 QVBoxLayout *settingsLayout = new QVBoxLayout();
434 settingsLayout->addWidget(chartSettings);
434 settingsLayout->addWidget(chartSettings);
435 settingsLayout->addWidget(seriesSettings);
435 settingsLayout->addWidget(seriesSettings);
436 settingsLayout->addWidget(sliceSettings);
436 settingsLayout->addWidget(sliceSettings);
437 settingsLayout->addStretch();
437 settingsLayout->addStretch();
438
438
439 QGridLayout* baseLayout = new QGridLayout();
439 QGridLayout* baseLayout = new QGridLayout();
440 baseLayout->addLayout(settingsLayout, 0, 0);
440 baseLayout->addLayout(settingsLayout, 0, 0);
441 baseLayout->addWidget(m_chartView, 0, 1);
441 baseLayout->addWidget(m_chartView, 0, 1);
442 setLayout(baseLayout);
442 setLayout(baseLayout);
443
443
444 updateSerieSettings();
444 updateSerieSettings();
445 }
445 }
446
446
447 public Q_SLOTS:
447 public Q_SLOTS:
448
448
449 void updateChartSettings()
449 void updateChartSettings()
450 {
450 {
451 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();
452 m_chartView->chart()->setTheme(theme);
452 m_chartView->chart()->setTheme(theme);
453 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
453 m_chartView->setRenderHint(QPainter::Antialiasing, m_aaCheckBox->isChecked());
454
454
455 if (m_animationsCheckBox->checkState() == Qt::Checked)
455 if (m_animationsCheckBox->checkState() == Qt::Checked)
456 m_chartView->chart()->setAnimationOptions(QChart::AllAnimations);
456 m_chartView->chart()->setAnimationOptions(QChart::AllAnimations);
457 else
457 else
458 m_chartView->chart()->setAnimationOptions(QChart::NoAnimation);
458 m_chartView->chart()->setAnimationOptions(QChart::NoAnimation);
459 }
459 }
460
460
461 void updateSerieSettings()
461 void updateSerieSettings()
462 {
462 {
463 m_series->setPiePosition(m_hPosition->value(), m_vPosition->value());
463 m_series->setPiePosition(m_hPosition->value(), m_vPosition->value());
464 m_series->setPieSize(m_sizeFactor->value());
464 m_series->setPieSize(m_sizeFactor->value());
465 m_series->setPieStartAngle(m_startAngle->value());
465 m_series->setPieStartAngle(m_startAngle->value());
466 m_series->setPieEndAngle(m_endAngle->value());
466 m_series->setPieEndAngle(m_endAngle->value());
467 }
467 }
468
468
469 void updateSliceSettings()
469 void updateSliceSettings()
470 {
470 {
471 if (!m_slice)
471 if (!m_slice)
472 return;
472 return;
473
473
474 m_slice->setValue(m_sliceValue->value());
474 m_slice->setValue(m_sliceValue->value());
475
475
476 m_slice->setPen(m_penTool->pen());
476 m_slice->setPen(m_penTool->pen());
477 m_slice->setBrush(m_brushTool->brush());
477 m_slice->setBrush(m_brushTool->brush());
478
478
479 m_slice->setLabelPen(m_labelPenTool->pen());
479 m_slice->setLabelPen(m_labelPenTool->pen());
480 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
480 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
481 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
481 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
482
482
483 m_slice->setExploded(m_sliceExploded->isChecked());
483 m_slice->setExploded(m_sliceExploded->isChecked());
484 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
484 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
485 }
485 }
486
486
487 void handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons)
487 void handleSliceClicked(QPieSlice* slice, Qt::MouseButtons buttons)
488 {
488 {
489 Q_UNUSED(buttons);
489 Q_UNUSED(buttons);
490
490
491 m_slice = static_cast<CustomSlice*>(slice);
491 m_slice = static_cast<CustomSlice*>(slice);
492
492
493 // name
493 // name
494 m_sliceName->setText(slice->label());
494 m_sliceName->setText(slice->label());
495
495
496 // value
496 // value
497 m_sliceValue->blockSignals(true);
497 m_sliceValue->blockSignals(true);
498 m_sliceValue->setValue(slice->value());
498 m_sliceValue->setValue(slice->value());
499 m_sliceValue->blockSignals(false);
499 m_sliceValue->blockSignals(false);
500
500
501 // pen
501 // pen
502 m_pen->setText(PenTool::name(m_slice->pen()));
502 m_pen->setText(PenTool::name(m_slice->pen()));
503 m_penTool->setPen(m_slice->pen());
503 m_penTool->setPen(m_slice->pen());
504
504
505 // brush
505 // brush
506 m_brush->setText(m_slice->originalBrush().color().name());
506 m_brush->setText(m_slice->originalBrush().color().name());
507 m_brushTool->setBrush(m_slice->originalBrush());
507 m_brushTool->setBrush(m_slice->originalBrush());
508
508
509 // label
509 // label
510 m_labelPen->setText(PenTool::name(m_slice->labelPen()));
510 m_labelPen->setText(PenTool::name(m_slice->labelPen()));
511 m_labelPenTool->setPen(m_slice->labelPen());
511 m_labelPenTool->setPen(m_slice->labelPen());
512 m_font->setText(slice->labelFont().toString());
512 m_font->setText(slice->labelFont().toString());
513 m_sliceLabelVisible->blockSignals(true);
513 m_sliceLabelVisible->blockSignals(true);
514 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
514 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
515 m_sliceLabelVisible->blockSignals(false);
515 m_sliceLabelVisible->blockSignals(false);
516 m_sliceLabelArmFactor->blockSignals(true);
516 m_sliceLabelArmFactor->blockSignals(true);
517 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
517 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
518 m_sliceLabelArmFactor->blockSignals(false);
518 m_sliceLabelArmFactor->blockSignals(false);
519
519
520 // exploded
520 // exploded
521 m_sliceExploded->blockSignals(true);
521 m_sliceExploded->blockSignals(true);
522 m_sliceExploded->setChecked(slice->isExploded());
522 m_sliceExploded->setChecked(slice->isExploded());
523 m_sliceExploded->blockSignals(false);
523 m_sliceExploded->blockSignals(false);
524 m_sliceExplodedFactor->blockSignals(true);
524 m_sliceExplodedFactor->blockSignals(true);
525 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
525 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
526 m_sliceExplodedFactor->blockSignals(false);
526 m_sliceExplodedFactor->blockSignals(false);
527 }
527 }
528
528
529 void showFontDialog()
529 void showFontDialog()
530 {
530 {
531 if (!m_slice)
531 if (!m_slice)
532 return;
532 return;
533
533
534 QFontDialog dialog(m_slice->labelFont());
534 QFontDialog dialog(m_slice->labelFont());
535 dialog.show();
535 dialog.show();
536 dialog.exec();
536 dialog.exec();
537
537
538 m_slice->setLabelFont(dialog.currentFont());
538 m_slice->setLabelFont(dialog.currentFont());
539 m_font->setText(dialog.currentFont().toString());
539 m_font->setText(dialog.currentFont().toString());
540 }
540 }
541
541
542 void addSlice()
542 void addSlice()
543 {
543 {
544 *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));
545 }
545 }
546
546
547 void insertSlice()
547 void insertSlice()
548 {
548 {
549 if (!m_slice)
549 if (!m_slice)
550 return;
550 return;
551
551
552 int i = m_series->slices().indexOf(m_slice);
552 int i = m_series->slices().indexOf(m_slice);
553
553
554 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)));
555 }
555 }
556
556
557 void removeSlice()
557 void removeSlice()
558 {
558 {
559 if (!m_slice)
559 if (!m_slice)
560 return;
560 return;
561
561
562 m_series->remove(m_slice);
562 m_series->remove(m_slice);
563 m_slice = 0;
563 m_slice = 0;
564 }
564 }
565
565
566 private:
566 private:
567 QComboBox *m_themeComboBox;
567 QComboBox *m_themeComboBox;
568 QCheckBox *m_aaCheckBox;
568 QCheckBox *m_aaCheckBox;
569 QCheckBox *m_animationsCheckBox;
569 QCheckBox *m_animationsCheckBox;
570
570
571 QChartView* m_chartView;
571 QChartView* m_chartView;
572 QPieSeries* m_series;
572 QPieSeries* m_series;
573 CustomSlice* m_slice;
573 CustomSlice* m_slice;
574
574
575 QDoubleSpinBox* m_hPosition;
575 QDoubleSpinBox* m_hPosition;
576 QDoubleSpinBox* m_vPosition;
576 QDoubleSpinBox* m_vPosition;
577 QDoubleSpinBox* m_sizeFactor;
577 QDoubleSpinBox* m_sizeFactor;
578 QDoubleSpinBox* m_startAngle;
578 QDoubleSpinBox* m_startAngle;
579 QDoubleSpinBox* m_endAngle;
579 QDoubleSpinBox* m_endAngle;
580
580
581 QLabel* m_sliceName;
581 QLabel* m_sliceName;
582 QDoubleSpinBox* m_sliceValue;
582 QDoubleSpinBox* m_sliceValue;
583 QCheckBox* m_sliceLabelVisible;
583 QCheckBox* m_sliceLabelVisible;
584 QDoubleSpinBox* m_sliceLabelArmFactor;
584 QDoubleSpinBox* m_sliceLabelArmFactor;
585 QCheckBox* m_sliceExploded;
585 QCheckBox* m_sliceExploded;
586 QDoubleSpinBox* m_sliceExplodedFactor;
586 QDoubleSpinBox* m_sliceExplodedFactor;
587 QPushButton *m_brush;
587 QPushButton *m_brush;
588 BrushTool *m_brushTool;
588 BrushTool *m_brushTool;
589 QPushButton *m_pen;
589 QPushButton *m_pen;
590 PenTool *m_penTool;
590 PenTool *m_penTool;
591 QPushButton *m_font;
591 QPushButton *m_font;
592 QPushButton *m_labelPen;
592 QPushButton *m_labelPen;
593 PenTool *m_labelPenTool;
593 PenTool *m_labelPenTool;
594 };
594 };
595
595
596 int main(int argc, char *argv[])
596 int main(int argc, char *argv[])
597 {
597 {
598 QApplication a(argc, argv);
598 QApplication a(argc, argv);
599
599
600 QMainWindow window;
600 QMainWindow window;
601
601
602 MainWidget* widget = new MainWidget();
602 MainWidget* widget = new MainWidget();
603
603
604 window.setCentralWidget(widget);
604 window.setCentralWidget(widget);
605 window.resize(900, 600);
605 window.resize(900, 600);
606 window.show();
606 window.show();
607
607
608 return a.exec();
608 return a.exec();
609 }
609 }
610
610
611 #include "main.moc"
611 #include "main.moc"
@@ -1,421 +1,422
1 #include "axisitem_p.h"
1 #include "axisitem_p.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartanimator_p.h"
4 #include "chartanimator_p.h"
5 #include <QPainter>
5 #include <QPainter>
6 #include <QDebug>
6 #include <QDebug>
7 #include <cmath>
7 #include <cmath>
8
8
9 static int label_padding = 5;
9 static int label_padding = 5;
10
10
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
12
13 Axis::Axis(QChartAxis *axis,ChartPresenter *presenter,AxisType type) : Chart(presenter),
13 Axis::Axis(QChartAxis *axis,ChartPresenter *presenter,AxisType type) : Chart(presenter),
14 m_chartAxis(axis),
14 m_chartAxis(axis),
15 m_type(type),
15 m_type(type),
16 m_labelsAngle(0),
16 m_labelsAngle(0),
17 m_grid(presenter->rootItem()),
17 m_grid(presenter->rootItem()),
18 m_shades(presenter->rootItem()),
18 m_shades(presenter->rootItem()),
19 m_labels(presenter->rootItem()),
19 m_labels(presenter->rootItem()),
20 m_axis(presenter->rootItem()),
20 m_axis(presenter->rootItem()),
21 m_min(0),
21 m_min(0),
22 m_max(0),
22 m_max(0),
23 m_ticksCount(0)
23 m_ticksCount(0)
24 {
24 {
25 //initial initialization
25 //initial initialization
26 m_axis.setZValue(ChartPresenter::AxisZValue);
26 m_axis.setZValue(ChartPresenter::AxisZValue);
27 m_axis.setHandlesChildEvents(false);
27 m_axis.setHandlesChildEvents(false);
28
28
29 m_shades.setZValue(ChartPresenter::ShadesZValue);
29 m_shades.setZValue(ChartPresenter::ShadesZValue);
30 m_grid.setZValue(ChartPresenter::GridZValue);
30 m_grid.setZValue(ChartPresenter::GridZValue);
31
31
32 connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
32 connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
33 connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
33 connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
34
34
35 handleAxisUpdated();
35 handleAxisUpdated();
36 }
36 }
37
37
38 Axis::~Axis()
38 Axis::~Axis()
39 {
39 {
40 }
40 }
41
41
42 void Axis::createItems(int count)
42 void Axis::createItems(int count)
43 {
43 {
44
44
45 if (m_axis.children().size() == 0)
45 if (m_axis.children().size() == 0)
46 m_axis.addToGroup(new AxisItem(this));
46 m_axis.addToGroup(new AxisItem(this));
47 for (int i = 0; i < count; ++i) {
47 for (int i = 0; i < count; ++i) {
48 m_grid.addToGroup(new QGraphicsLineItem());
48 m_grid.addToGroup(new QGraphicsLineItem());
49 m_labels.addToGroup(new QGraphicsSimpleTextItem());
49 m_labels.addToGroup(new QGraphicsSimpleTextItem());
50 m_axis.addToGroup(new QGraphicsLineItem());
50 m_axis.addToGroup(new QGraphicsLineItem());
51 if ((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
51 if ((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
52 }
52 }
53 }
53 }
54
54
55 void Axis::deleteItems(int count)
55 void Axis::deleteItems(int count)
56 {
56 {
57 QList<QGraphicsItem *> lines = m_grid.childItems();
57 QList<QGraphicsItem *> lines = m_grid.childItems();
58 QList<QGraphicsItem *> labels = m_labels.childItems();
58 QList<QGraphicsItem *> labels = m_labels.childItems();
59 QList<QGraphicsItem *> shades = m_shades.childItems();
59 QList<QGraphicsItem *> shades = m_shades.childItems();
60 QList<QGraphicsItem *> axis = m_axis.childItems();
60 QList<QGraphicsItem *> axis = m_axis.childItems();
61
61
62 for (int i = 0; i < count; ++i) {
62 for (int i = 0; i < count; ++i) {
63 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
63 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
64 delete(lines.takeLast());
64 delete(lines.takeLast());
65 delete(labels.takeLast());
65 delete(labels.takeLast());
66 delete(axis.takeLast());
66 delete(axis.takeLast());
67 }
67 }
68 }
68 }
69
69
70 void Axis::updateLayout(QVector<qreal> &layout)
70 void Axis::updateLayout(QVector<qreal> &layout)
71 {
71 {
72 if (animator()) {
72 if (animator()) {
73 animator()->updateLayout(this,layout);
73 animator()->updateLayout(this,layout);
74 } else {
74 } else {
75 setLayout(layout);
75 setLayout(layout);
76 }
76 }
77 }
77 }
78
78
79 bool Axis::createLabels(QStringList &labels,qreal min, qreal max,int ticks) const
79 bool Axis::createLabels(QStringList &labels,qreal min, qreal max,int ticks) const
80 {
80 {
81 Q_ASSERT(max>=min);
81 Q_ASSERT(max>=min);
82 Q_ASSERT(ticks>1);
82 Q_ASSERT(ticks>1);
83
83
84 QChartAxisCategories* categories = m_chartAxis->categories();
84 QChartAxisCategories* categories = m_chartAxis->categories();
85
85
86 bool category = categories->count()>0;
86 bool category = categories->count()>0;
87
87
88 if (!category) {
88 if (!category) {
89 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
89 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
90 for (int i=0; i< ticks; i++) {
90 for (int i=0; i< ticks; i++) {
91 qreal value = min + (i * (max - min)/ (ticks-1));
91 qreal value = min + (i * (max - min)/ (ticks-1));
92 labels << QString::number(value,'f',n);
92 labels << QString::number(value,'f',n);
93 }
93 }
94 } else {
94 } else {
95 QList<qreal> values = categories->values();
95 QList<qreal> values = categories->values();
96 for (int i=0; i< ticks; i++) {
96 for (int i=0; i< ticks; i++) {
97 qreal value = (min + (i * (max - min)/ (ticks-1)));
97 qreal value = (min + (i * (max - min)/ (ticks-1)));
98 int j=0;
98 int j=0;
99 for (; j<values.count(); j++) {
99 for (; j<values.count(); j++) {
100 if (values.at(j) > value) break;
100 if (values.at(j) > value) break;
101 }
101 }
102 if (j!=0) value=values.at(j-1);
102 if (j!=0) value=values.at(j-1);
103
103
104 QString label = categories->label(value);
104 QString label = categories->label(value);
105 labels << label;
105 labels << label;
106 }
106 }
107 }
107 }
108
108
109 return category;
109 return category;
110 }
110 }
111
111
112 void Axis::setAxisOpacity(qreal opacity)
112 void Axis::setAxisOpacity(qreal opacity)
113 {
113 {
114 m_axis.setOpacity(opacity);
114 m_axis.setOpacity(opacity);
115 }
115 }
116
116
117 qreal Axis::axisOpacity() const
117 qreal Axis::axisOpacity() const
118 {
118 {
119 return m_axis.opacity();
119 return m_axis.opacity();
120 }
120 }
121
121
122 void Axis::setGridOpacity(qreal opacity)
122 void Axis::setGridOpacity(qreal opacity)
123 {
123 {
124 m_grid.setOpacity(opacity);
124 m_grid.setOpacity(opacity);
125 }
125 }
126
126
127 qreal Axis::gridOpacity() const
127 qreal Axis::gridOpacity() const
128 {
128 {
129 return m_grid.opacity();
129 return m_grid.opacity();
130 }
130 }
131
131
132 void Axis::setLabelsOpacity(qreal opacity)
132 void Axis::setLabelsOpacity(qreal opacity)
133 {
133 {
134 m_labels.setOpacity(opacity);
134 m_labels.setOpacity(opacity);
135 }
135 }
136
136
137 qreal Axis::labelsOpacity() const
137 qreal Axis::labelsOpacity() const
138 {
138 {
139 return m_labels.opacity();
139 return m_labels.opacity();
140 }
140 }
141
141
142 void Axis::setShadesOpacity(qreal opacity)
142 void Axis::setShadesOpacity(qreal opacity)
143 {
143 {
144 m_shades.setOpacity(opacity);
144 m_shades.setOpacity(opacity);
145 }
145 }
146
146
147 qreal Axis::shadesOpacity() const
147 qreal Axis::shadesOpacity() const
148 {
148 {
149 return m_shades.opacity();
149 return m_shades.opacity();
150 }
150 }
151
151
152 void Axis::setLabelsAngle(int angle)
152 void Axis::setLabelsAngle(int angle)
153 {
153 {
154 foreach(QGraphicsItem* item , m_labels.childItems()) {
154 foreach(QGraphicsItem* item , m_labels.childItems()) {
155 QPointF center = item->boundingRect().center();
155 QPointF center = item->boundingRect().center();
156 item->setRotation(angle);
156 item->setRotation(angle);
157 }
157 }
158
158
159 m_labelsAngle=angle;
159 m_labelsAngle=angle;
160 }
160 }
161
161
162 void Axis::setLabelsPen(const QPen &pen)
162 void Axis::setLabelsPen(const QPen &pen)
163 {
163 {
164 foreach(QGraphicsItem* item , m_labels.childItems()) {
164 foreach(QGraphicsItem* item , m_labels.childItems()) {
165 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
165 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
166 }
166 }
167 }
167 }
168
168
169 void Axis::setLabelsBrush(const QBrush &brush)
169 void Axis::setLabelsBrush(const QBrush &brush)
170 {
170 {
171 foreach(QGraphicsItem* item , m_labels.childItems()) {
171 foreach(QGraphicsItem* item , m_labels.childItems()) {
172 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
172 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
173 }
173 }
174 }
174 }
175
175
176 void Axis::setLabelsFont(const QFont &font)
176 void Axis::setLabelsFont(const QFont &font)
177 {
177 {
178 foreach(QGraphicsItem* item , m_labels.childItems()) {
178 foreach(QGraphicsItem* item , m_labels.childItems()) {
179 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
179 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
180 }
180 }
181 }
181 }
182
182
183 void Axis::setShadesBrush(const QBrush &brush)
183 void Axis::setShadesBrush(const QBrush &brush)
184 {
184 {
185 foreach(QGraphicsItem* item , m_shades.childItems()) {
185 foreach(QGraphicsItem* item , m_shades.childItems()) {
186 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
186 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
187 }
187 }
188 }
188 }
189
189
190 void Axis::setShadesPen(const QPen &pen)
190 void Axis::setShadesPen(const QPen &pen)
191 {
191 {
192 foreach(QGraphicsItem* item , m_shades.childItems()) {
192 foreach(QGraphicsItem* item , m_shades.childItems()) {
193 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
193 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
194 }
194 }
195 }
195 }
196
196
197 void Axis::setAxisPen(const QPen &pen)
197 void Axis::setAxisPen(const QPen &pen)
198 {
198 {
199 foreach(QGraphicsItem* item , m_axis.childItems()) {
199 foreach(QGraphicsItem* item , m_axis.childItems()) {
200 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
200 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
201 }
201 }
202 }
202 }
203
203
204 void Axis::setGridPen(const QPen &pen)
204 void Axis::setGridPen(const QPen &pen)
205 {
205 {
206 foreach(QGraphicsItem* item , m_grid.childItems()) {
206 foreach(QGraphicsItem* item , m_grid.childItems()) {
207 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
207 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
208 }
208 }
209 }
209 }
210
210
211 QVector<qreal> Axis::calculateLayout() const
211 QVector<qreal> Axis::calculateLayout() const
212 {
212 {
213 Q_ASSERT(m_ticksCount>=2);
213 Q_ASSERT(m_ticksCount>=2);
214
214
215 QVector<qreal> points;
215 QVector<qreal> points;
216 points.resize(m_ticksCount);
216 points.resize(m_ticksCount);
217
217
218 switch (m_type)
218 switch (m_type)
219 {
219 {
220 case X_AXIS:
220 case X_AXIS:
221 {
221 {
222 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
222 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
223 for (int i = 0; i < m_ticksCount; ++i) {
223 for (int i = 0; i < m_ticksCount; ++i) {
224 int x = i * deltaX + m_rect.left();
224 int x = i * deltaX + m_rect.left();
225 points[i] = x;
225 points[i] = x;
226 }
226 }
227 }
227 }
228 break;
228 break;
229 case Y_AXIS:
229 case Y_AXIS:
230 {
230 {
231 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
231 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
232 for (int i = 0; i < m_ticksCount; ++i) {
232 for (int i = 0; i < m_ticksCount; ++i) {
233 int y = i * -deltaY + m_rect.bottom();
233 int y = i * -deltaY + m_rect.bottom();
234 points[i] = y;
234 points[i] = y;
235 }
235 }
236 }
236 }
237 break;
237 break;
238 }
238 }
239 return points;
239 return points;
240 }
240 }
241
241
242 void Axis::setLayout(QVector<qreal> &layout)
242 void Axis::setLayout(QVector<qreal> &layout)
243 {
243 {
244 int diff = m_layoutVector.size() - layout.size();
244 int diff = m_layoutVector.size() - layout.size();
245
245
246 if (diff>0) {
246 if (diff>0) {
247 deleteItems(diff);
247 deleteItems(diff);
248 } else if (diff<0) {
248 } else if (diff<0) {
249 createItems(-diff);
249 createItems(-diff);
250 }
250 }
251
251
252 if( diff!=0) handleAxisUpdated();
252 if( diff!=0) handleAxisUpdated();
253
253
254 QStringList ticksList;
254 QStringList ticksList;
255
255
256 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
256 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
257
257
258 QList<QGraphicsItem *> lines = m_grid.childItems();
258 QList<QGraphicsItem *> lines = m_grid.childItems();
259 QList<QGraphicsItem *> labels = m_labels.childItems();
259 QList<QGraphicsItem *> labels = m_labels.childItems();
260 QList<QGraphicsItem *> shades = m_shades.childItems();
260 QList<QGraphicsItem *> shades = m_shades.childItems();
261 QList<QGraphicsItem *> axis = m_axis.childItems();
261 QList<QGraphicsItem *> axis = m_axis.childItems();
262
262
263 Q_ASSERT(labels.size() == ticksList.size());
263 Q_ASSERT(labels.size() == ticksList.size());
264 Q_ASSERT(layout.size() == ticksList.size());
264 Q_ASSERT(layout.size() == ticksList.size());
265
265
266 switch (m_type)
266 switch (m_type)
267 {
267 {
268 case X_AXIS:
268 case X_AXIS:
269 {
269 {
270 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
270 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
271 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
271 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
272
272
273 for (int i = 0; i < layout.size(); ++i) {
273 for (int i = 0; i < layout.size(); ++i) {
274 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
274 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
275 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
275 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
276 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
276 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
277 if (!categories) {
277 if (!categories) {
278 labelItem->setText(ticksList.at(i));
278 labelItem->setText(ticksList.at(i));
279 QPointF center = labelItem->boundingRect().center();
279 QPointF center = labelItem->boundingRect().center();
280 labelItem->setTransformOriginPoint(center.x(), center.y());
280 labelItem->setTransformOriginPoint(center.x(), center.y());
281 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
281 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
282 } else if(i>0) {
282 } else if(i>0) {
283 labelItem->setText(ticksList.at(i));
283 labelItem->setText(ticksList.at(i));
284 QPointF center = labelItem->boundingRect().center();
284 QPointF center = labelItem->boundingRect().center();
285 labelItem->setTransformOriginPoint(center.x(), center.y());
285 labelItem->setTransformOriginPoint(center.x(), center.y());
286 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
286 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
287 }
287 }
288
288
289 if ((i+1)%2 && i>1) {
289 if ((i+1)%2 && i>1) {
290 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
290 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
291 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
291 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
292 }
292 }
293 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
293 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
294 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
294 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
295 }
295 }
296 }
296 }
297 break;
297 break;
298
298
299 case Y_AXIS:
299 case Y_AXIS:
300 {
300 {
301 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
301 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
302 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
302 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
303
303
304 for (int i = 0; i < layout.size(); ++i) {
304 for (int i = 0; i < layout.size(); ++i) {
305 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
305 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
306 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
306 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
307 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
307 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
308
308
309 if (!categories) {
309 if (!categories) {
310 labelItem->setText(ticksList.at(i));
310 labelItem->setText(ticksList.at(i));
311 QPointF center = labelItem->boundingRect().center();
311 QPointF center = labelItem->boundingRect().center();
312 labelItem->setTransformOriginPoint(center.x(), center.y());
312 labelItem->setTransformOriginPoint(center.x(), center.y());
313 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
313 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
314 } else if (i>0) {
314 } else if (i>0) {
315 labelItem->setText(ticksList.at(i));
315 labelItem->setText(ticksList.at(i));
316 QPointF center = labelItem->boundingRect().center();
316 QPointF center = labelItem->boundingRect().center();
317 labelItem->setTransformOriginPoint(center.x(), center.y());
317 labelItem->setTransformOriginPoint(center.x(), center.y());
318 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
318 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
319 }
319 }
320
320
321 if ((i+1)%2 && i>1) {
321 if ((i+1)%2 && i>1) {
322 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
322 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
323 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
323 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
324 }
324 }
325 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
325 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
326 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
326 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
327 }
327 }
328 }
328 }
329 break;
329 break;
330 default:
330 default:
331 qDebug()<<"Unknown axis type";
331 qDebug()<<"Unknown axis type";
332 break;
332 break;
333 }
333 }
334
334
335 m_layoutVector=layout;
335 m_layoutVector=layout;
336 }
336 }
337
337
338 bool Axis::isEmpty()
338 bool Axis::isEmpty()
339 {
339 {
340 return m_rect.isEmpty() || m_min==m_max || m_ticksCount==0;
340 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max) || m_ticksCount==0;
341 }
341 }
342
342
343 //handlers
343 //handlers
344
344
345 void Axis::handleAxisCategoriesUpdated()
345 void Axis::handleAxisCategoriesUpdated()
346 {
346 {
347 if (isEmpty()) return;
347 if (isEmpty()) return;
348 updateLayout(m_layoutVector);
348 updateLayout(m_layoutVector);
349 }
349 }
350
350
351 void Axis::handleAxisUpdated()
351 void Axis::handleAxisUpdated()
352 {
352 {
353
353
354 if (isEmpty()) return;
354 if (isEmpty()) return;
355
355
356 if (m_chartAxis->isAxisVisible()) {
356 if (m_chartAxis->isAxisVisible()) {
357 setAxisOpacity(100);
357 setAxisOpacity(100);
358 } else {
358 } else {
359 setAxisOpacity(0);
359 setAxisOpacity(0);
360 }
360 }
361
361
362 if (m_chartAxis->isGridLineVisible()) {
362 if (m_chartAxis->isGridLineVisible()) {
363 setGridOpacity(100);
363 setGridOpacity(100);
364 } else {
364 } else {
365 setGridOpacity(0);
365 setGridOpacity(0);
366 }
366 }
367
367
368 if (m_chartAxis->labelsVisible()) {
368 if (m_chartAxis->labelsVisible()) {
369 setLabelsOpacity(100);
369 setLabelsOpacity(100);
370 } else {
370 } else {
371 setLabelsOpacity(0);
371 setLabelsOpacity(0);
372 }
372 }
373
373
374 if (m_chartAxis->shadesVisible()) {
374 if (m_chartAxis->shadesVisible()) {
375 setShadesOpacity(m_chartAxis->shadesOpacity());
375 setShadesOpacity(m_chartAxis->shadesOpacity());
376 } else {
376 } else {
377 setShadesOpacity(0);
377 setShadesOpacity(0);
378 }
378 }
379
379
380 setLabelsAngle(m_chartAxis->labelsAngle());
380 setLabelsAngle(m_chartAxis->labelsAngle());
381 setAxisPen(m_chartAxis->axisPen());
381 setAxisPen(m_chartAxis->axisPen());
382 setLabelsPen(m_chartAxis->labelsPen());
382 setLabelsPen(m_chartAxis->labelsPen());
383 setLabelsBrush(m_chartAxis->labelsBrush());
383 setLabelsBrush(m_chartAxis->labelsBrush());
384 setLabelsFont(m_chartAxis->labelsFont());
384 setLabelsFont(m_chartAxis->labelsFont());
385 setGridPen(m_chartAxis->gridLinePen());
385 setGridPen(m_chartAxis->gridLinePen());
386 setShadesPen(m_chartAxis->shadesPen());
386 setShadesPen(m_chartAxis->shadesPen());
387 setShadesBrush(m_chartAxis->shadesBrush());
387 setShadesBrush(m_chartAxis->shadesBrush());
388
388
389 }
389 }
390
390
391 void Axis::handleRangeChanged(qreal min, qreal max,int tickCount)
391 void Axis::handleRangeChanged(qreal min, qreal max,int tickCount)
392 {
392 {
393 if (min==max || tickCount<2) return;
393 if (qFuzzyIsNull(min - max) || tickCount < 2)
394 return;
394
395
395 m_min = min;
396 m_min = min;
396 m_max = max;
397 m_max = max;
397 m_ticksCount= tickCount;
398 m_ticksCount= tickCount;
398
399
399 if (isEmpty()) return;
400 if (isEmpty()) return;
400 QVector<qreal> layout = calculateLayout();
401 QVector<qreal> layout = calculateLayout();
401 updateLayout(layout);
402 updateLayout(layout);
402
403
403 }
404 }
404
405
405 void Axis::handleGeometryChanged(const QRectF &rect)
406 void Axis::handleGeometryChanged(const QRectF &rect)
406 {
407 {
407 m_rect = rect;
408 m_rect = rect;
408 if (isEmpty()) return;
409 if (isEmpty()) return;
409 QVector<qreal> layout = calculateLayout();
410 QVector<qreal> layout = calculateLayout();
410 updateLayout(layout);
411 updateLayout(layout);
411 }
412 }
412
413
413 void Axis::axisSelected()
414 void Axis::axisSelected()
414 {
415 {
415 qDebug()<<"TODO axis clicked";
416 qDebug()<<"TODO axis clicked";
416 }
417 }
417
418
418 //TODO "nice numbers algorithm"
419 //TODO "nice numbers algorithm"
419 #include "moc_axisitem_p.cpp"
420 #include "moc_axisitem_p.cpp"
420
421
421 QTCOMMERCIALCHART_END_NAMESPACE
422 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,401 +1,401
1 #include "qchartaxis.h"
1 #include "qchartaxis.h"
2
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
4
5 /*!
5 /*!
6 \class QChartAxis
6 \class QChartAxis
7 \brief The QChartAxis class is used for manipulating chart's axis
7 \brief The QChartAxis class is used for manipulating chart's axis
8 and for adding optional axes to the chart.
8 and for adding optional axes to the chart.
9 \mainclass
9 \mainclass
10
10
11 There is only one x Axis, however there can be multiple y axes.
11 There is only one x Axis, however there can be multiple y axes.
12 Each chart series can be bound to exactly one Y axis and the share common X axis.
12 Each chart series can be bound to exactly one Y axis and the share common X axis.
13 Axis can be setup to show axis line with ticks, gird lines and shades.
13 Axis can be setup to show axis line with ticks, gird lines and shades.
14
14
15 */
15 */
16
16
17 /*!
17 /*!
18 \fn bool QChartAxis::isAxisVisible() const
18 \fn bool QChartAxis::isAxisVisible() const
19 \brief Returns if axis is visible
19 \brief Returns if axis is visible
20 \sa setAxisVisible()
20 \sa setAxisVisible()
21 */
21 */
22
22
23 /*!
23 /*!
24 \fn QPen QChartAxis::axisPen() const
24 \fn QPen QChartAxis::axisPen() const
25 \brief Returns pen used to draw axis and ticks.
25 \brief Returns pen used to draw axis and ticks.
26 \sa setAxisPen()
26 \sa setAxisPen()
27 */
27 */
28
28
29
29
30 /*!
30 /*!
31 \fn bool QChartAxis::isGridLineVisible() const
31 \fn bool QChartAxis::isGridLineVisible() const
32 \brief Returns if grid is visible
32 \brief Returns if grid is visible
33 \sa setGridLineVisible()
33 \sa setGridLineVisible()
34 */
34 */
35
35
36 /*!
36 /*!
37 \fn QPen QChartAxis::gridLinePen() const
37 \fn QPen QChartAxis::gridLinePen() const
38 \brief Returns pen used to draw grid.
38 \brief Returns pen used to draw grid.
39 \sa setGridLinePen()
39 \sa setGridLinePen()
40 */
40 */
41
41
42 /*!
42 /*!
43 \fn bool QChartAxis::labelsVisible() const
43 \fn bool QChartAxis::labelsVisible() const
44 \brief Returns if grid is visible
44 \brief Returns if grid is visible
45 \sa setLabelsVisible()
45 \sa setLabelsVisible()
46 */
46 */
47
47
48 /*!
48 /*!
49 \fn QPen QChartAxis::labelsPen() const
49 \fn QPen QChartAxis::labelsPen() const
50 \brief Returns the pen used to labels.
50 \brief Returns the pen used to labels.
51 \sa setLabelsPen()
51 \sa setLabelsPen()
52 */
52 */
53
53
54 /*!
54 /*!
55 \fn QBrush QChartAxis::labelsBrush() const
55 \fn QBrush QChartAxis::labelsBrush() const
56 \brief Returns brush used to draw labels.
56 \brief Returns brush used to draw labels.
57 \sa setLabelsBrush()
57 \sa setLabelsBrush()
58 */
58 */
59
59
60 /*!
60 /*!
61 \fn QFont QChartAxis::labelsFont() const
61 \fn QFont QChartAxis::labelsFont() const
62 \brief Returns font used to draw labels.
62 \brief Returns font used to draw labels.
63 \sa setLabelsFont()
63 \sa setLabelsFont()
64 */
64 */
65
65
66 /*!
66 /*!
67 \fn QFont QChartAxis::labelsAngle() const
67 \fn QFont QChartAxis::labelsAngle() const
68 \brief Returns angle used to draw labels.
68 \brief Returns angle used to draw labels.
69 \sa setLabelsAngle()
69 \sa setLabelsAngle()
70 */
70 */
71
71
72 /*!
72 /*!
73 \fn bool QChartAxis::shadesVisible() const
73 \fn bool QChartAxis::shadesVisible() const
74 \brief Returns if shades are visible.
74 \brief Returns if shades are visible.
75 \sa setShadesVisible()
75 \sa setShadesVisible()
76 */
76 */
77
77
78 /*!
78 /*!
79 \fn qreal QChartAxis::shadesOpacity() const
79 \fn qreal QChartAxis::shadesOpacity() const
80 \brief Returns opacity of shades.
80 \brief Returns opacity of shades.
81 */
81 */
82
82
83 /*!
83 /*!
84 \fn QPen QChartAxis::shadesPen() const
84 \fn QPen QChartAxis::shadesPen() const
85 \brief Returns pen used to draw shades.
85 \brief Returns pen used to draw shades.
86 \sa setShadesPen()
86 \sa setShadesPen()
87 */
87 */
88
88
89 /*!
89 /*!
90 \fn QBrush QChartAxis::shadesBrush() const
90 \fn QBrush QChartAxis::shadesBrush() const
91 \brief Returns brush used to draw shades.
91 \brief Returns brush used to draw shades.
92 \sa setShadesBrush()
92 \sa setShadesBrush()
93 */
93 */
94
94
95 /*!
95 /*!
96 \fn qreal QChartAxis::min() const
96 \fn qreal QChartAxis::min() const
97 \brief Returns minimum value on the axis.
97 \brief Returns minimum value on the axis.
98 \sa setMin()
98 \sa setMin()
99 */
99 */
100
100
101 /*!
101 /*!
102 \fn qreal QChartAxis::max() const
102 \fn qreal QChartAxis::max() const
103 \brief Returns maximim value on the axis.
103 \brief Returns maximim value on the axis.
104 \sa setMax()
104 \sa setMax()
105 */
105 */
106
106
107 /*!
107 /*!
108 \fn void QChartAxis::minChanged(qreal min)
108 \fn void QChartAxis::minChanged(qreal min)
109 \brief Axis emits signal when \a min of axis has changed.
109 \brief Axis emits signal when \a min of axis has changed.
110 */
110 */
111
111
112 /*!
112 /*!
113 \fn void QChartAxis::maxChanged(qreal max)
113 \fn void QChartAxis::maxChanged(qreal max)
114 \brief Axis emits signal when \a max of axis has changed.
114 \brief Axis emits signal when \a max of axis has changed.
115 */
115 */
116
116
117 /*!
117 /*!
118 \fn void QChartAxis::rangeChanged(qreal min, qreal max)
118 \fn void QChartAxis::rangeChanged(qreal min, qreal max)
119 \brief Axis emits signal when \a min or \a max of axis has changed.
119 \brief Axis emits signal when \a min or \a max of axis has changed.
120 */
120 */
121
121
122 /*!
122 /*!
123 \fn int QChartAxis::ticksCount() const
123 \fn int QChartAxis::ticksCount() const
124 \brief Return number of ticks on the axis
124 \brief Return number of ticks on the axis
125 \sa setTicksCount()
125 \sa setTicksCount()
126 */
126 */
127
127
128 /*!
128 /*!
129 \fn void QChartAxis::updated()
129 \fn void QChartAxis::updated()
130 \brief \internal
130 \brief \internal
131 */
131 */
132
132
133 /*!
133 /*!
134 \fn void QChartAxis::handleAxisRangeChanged(qreal min, qreal max)
134 \fn void QChartAxis::handleAxisRangeChanged(qreal min, qreal max)
135 \brief \internal \a min \a max
135 \brief \internal \a min \a max
136 */
136 */
137
137
138 /*!
138 /*!
139 Constructs new axis object which is a child of \a parent. Ownership is taken by
139 Constructs new axis object which is a child of \a parent. Ownership is taken by
140 QChatView or QChart when axis added.
140 QChatView or QChart when axis added.
141 */
141 */
142
142
143 QChartAxis::QChartAxis(QObject *parent) : QObject(parent),
143 QChartAxis::QChartAxis(QObject *parent) : QObject(parent),
144 m_axisVisible(true),
144 m_axisVisible(true),
145 m_gridLineVisible(true),
145 m_gridLineVisible(true),
146 m_labelsVisible(true),
146 m_labelsVisible(true),
147 m_labelsAngle(0),
147 m_labelsAngle(0),
148 m_shadesVisible(false),
148 m_shadesVisible(false),
149 m_shadesOpacity(1.0),
149 m_shadesOpacity(1.0),
150 m_min(0),
150 m_min(0),
151 m_max(0),
151 m_max(0),
152 m_ticksCount(5),
152 m_ticksCount(5),
153 m_niceNumbers(false)
153 m_niceNumbers(false)
154 {
154 {
155
155
156 }
156 }
157
157
158 /*!
158 /*!
159 Destructor of the axis object. When axis is added to chart, chart object takes ownership.
159 Destructor of the axis object. When axis is added to chart, chart object takes ownership.
160 */
160 */
161
161
162 QChartAxis::~QChartAxis()
162 QChartAxis::~QChartAxis()
163 {
163 {
164 }
164 }
165
165
166 /*!
166 /*!
167 Sets \a pen used to draw axis line and ticks.
167 Sets \a pen used to draw axis line and ticks.
168 */
168 */
169 void QChartAxis::setAxisPen(const QPen &pen)
169 void QChartAxis::setAxisPen(const QPen &pen)
170 {
170 {
171 if (pen != m_axisPen) {
171 if (pen != m_axisPen) {
172 m_axisPen = pen;
172 m_axisPen = pen;
173 emit updated();
173 emit updated();
174 }
174 }
175 }
175 }
176
176
177 /*!
177 /*!
178 Sets if axis and ticks are \a visible.
178 Sets if axis and ticks are \a visible.
179 */
179 */
180 void QChartAxis::setAxisVisible(bool visible)
180 void QChartAxis::setAxisVisible(bool visible)
181 {
181 {
182 if (m_axisVisible != visible) {
182 if (m_axisVisible != visible) {
183 m_axisVisible = visible;
183 m_axisVisible = visible;
184 emit updated();
184 emit updated();
185 }
185 }
186 }
186 }
187
187
188 /*!
188 /*!
189 Sets if grid line is \a visible.
189 Sets if grid line is \a visible.
190 */
190 */
191 void QChartAxis::setGridLineVisible(bool visible)
191 void QChartAxis::setGridLineVisible(bool visible)
192 {
192 {
193 if (m_gridLineVisible != visible) {
193 if (m_gridLineVisible != visible) {
194 m_gridLineVisible = visible;
194 m_gridLineVisible = visible;
195 emit updated();
195 emit updated();
196 }
196 }
197 }
197 }
198
198
199 /*!
199 /*!
200 Sets \a pen used to draw grid line.
200 Sets \a pen used to draw grid line.
201 */
201 */
202 void QChartAxis::setGridLinePen(const QPen &pen)
202 void QChartAxis::setGridLinePen(const QPen &pen)
203 {
203 {
204 if (m_gridLinePen != pen) {
204 if (m_gridLinePen != pen) {
205 m_gridLinePen = pen;
205 m_gridLinePen = pen;
206 emit updated();
206 emit updated();
207 }
207 }
208 }
208 }
209
209
210 /*!
210 /*!
211 Sets if axis' labels are \a visible.
211 Sets if axis' labels are \a visible.
212 */
212 */
213 void QChartAxis::setLabelsVisible(bool visible)
213 void QChartAxis::setLabelsVisible(bool visible)
214 {
214 {
215 if (m_labelsVisible != visible) {
215 if (m_labelsVisible != visible) {
216 m_labelsVisible = visible;
216 m_labelsVisible = visible;
217 emit updated();
217 emit updated();
218 }
218 }
219 }
219 }
220
220
221 /*!
221 /*!
222 Sets \a pen used to draw labels.
222 Sets \a pen used to draw labels.
223 */
223 */
224 void QChartAxis::setLabelsPen(const QPen &pen)
224 void QChartAxis::setLabelsPen(const QPen &pen)
225 {
225 {
226 if (m_labelsPen != pen) {
226 if (m_labelsPen != pen) {
227 m_labelsPen = pen;
227 m_labelsPen = pen;
228 emit updated();
228 emit updated();
229 }
229 }
230 }
230 }
231
231
232 /*!
232 /*!
233 Sets \a brush used to draw labels.
233 Sets \a brush used to draw labels.
234 */
234 */
235 void QChartAxis::setLabelsBrush(const QBrush &brush)
235 void QChartAxis::setLabelsBrush(const QBrush &brush)
236 {
236 {
237 if (m_labelsBrush != brush) {
237 if (m_labelsBrush != brush) {
238 m_labelsBrush = brush;
238 m_labelsBrush = brush;
239 emit updated();
239 emit updated();
240 }
240 }
241 }
241 }
242
242
243 /*!
243 /*!
244 Sets \a font used to draw labels.
244 Sets \a font used to draw labels.
245 */
245 */
246 void QChartAxis::setLabelsFont(const QFont &font)
246 void QChartAxis::setLabelsFont(const QFont &font)
247 {
247 {
248 if (m_labelsFont != font) {
248 if (m_labelsFont != font) {
249 m_labelsFont = font;
249 m_labelsFont = font;
250 emit updated();
250 emit updated();
251 }
251 }
252 }
252 }
253
253
254 /*!
254 /*!
255 Sets \a angle for all the labels on given axis.
255 Sets \a angle for all the labels on given axis.
256 */
256 */
257 void QChartAxis::setLabelsAngle(int angle)
257 void QChartAxis::setLabelsAngle(int angle)
258 {
258 {
259 if (m_labelsAngle != angle) {
259 if (m_labelsAngle != angle) {
260 m_labelsAngle = angle;
260 m_labelsAngle = angle;
261 emit updated();
261 emit updated();
262 }
262 }
263 }
263 }
264
264
265 /*!
265 /*!
266 Sets if shades are \a visible.
266 Sets if shades are \a visible.
267 */
267 */
268 void QChartAxis::setShadesVisible(bool visible)
268 void QChartAxis::setShadesVisible(bool visible)
269 {
269 {
270 if (m_shadesVisible != visible) {
270 if (m_shadesVisible != visible) {
271 m_shadesVisible = visible;
271 m_shadesVisible = visible;
272 emit updated();
272 emit updated();
273 }
273 }
274 }
274 }
275
275
276 /*!
276 /*!
277 Sets \a pen used to draw shades.
277 Sets \a pen used to draw shades.
278 */
278 */
279 void QChartAxis::setShadesPen(const QPen &pen)
279 void QChartAxis::setShadesPen(const QPen &pen)
280 {
280 {
281 if (m_shadesPen != pen) {
281 if (m_shadesPen != pen) {
282 m_shadesPen = pen;
282 m_shadesPen = pen;
283 emit updated();
283 emit updated();
284 }
284 }
285 }
285 }
286
286
287 /*!
287 /*!
288 Sets \a brush used to draw shades.
288 Sets \a brush used to draw shades.
289 */
289 */
290 void QChartAxis::setShadesBrush(const QBrush &brush)
290 void QChartAxis::setShadesBrush(const QBrush &brush)
291 {
291 {
292 if (m_shadesBrush != brush) {
292 if (m_shadesBrush != brush) {
293 m_shadesBrush = brush;
293 m_shadesBrush = brush;
294 emit updated();
294 emit updated();
295 }
295 }
296 }
296 }
297
297
298 /*!
298 /*!
299 Sets \a opacity of the shades.
299 Sets \a opacity of the shades.
300 */
300 */
301 void QChartAxis::setShadesOpacity(qreal opacity)
301 void QChartAxis::setShadesOpacity(qreal opacity)
302 {
302 {
303 if (m_shadesOpacity != opacity) {
303 if (m_shadesOpacity != opacity) {
304 m_shadesOpacity=opacity;
304 m_shadesOpacity=opacity;
305 emit updated();
305 emit updated();
306 }
306 }
307 }
307 }
308
308
309 /*!
309 /*!
310 Sets \a min value on the axis.
310 Sets \a min value on the axis.
311 */
311 */
312 void QChartAxis::setMin(qreal min)
312 void QChartAxis::setMin(qreal min)
313 {
313 {
314 setRange(min,m_max);
314 setRange(min,m_max);
315 }
315 }
316
316
317 /*!
317 /*!
318 Sets \a max value on the axis.
318 Sets \a max value on the axis.
319 */
319 */
320 void QChartAxis::setMax(qreal max)
320 void QChartAxis::setMax(qreal max)
321 {
321 {
322 setRange(m_min,max);
322 setRange(m_min,max);
323 }
323 }
324
324
325 /*!
325 /*!
326 Sets range from \a min to \a max on the axis.
326 Sets range from \a min to \a max on the axis.
327 */
327 */
328 void QChartAxis::setRange(qreal min, qreal max)
328 void QChartAxis::setRange(qreal min, qreal max)
329 {
329 {
330 bool changed = false;
330 bool changed = false;
331 if (m_min != min) {
331 if (!qFuzzyIsNull(m_min - min)) {
332 m_min = min;
332 m_min = min;
333 changed = true;
333 changed = true;
334 emit minChanged(min);
334 emit minChanged(min);
335 }
335 }
336
336
337 if (m_max != max) {
337 if (!qFuzzyIsNull(m_max - max)) {
338 m_max = max;
338 m_max = max;
339 changed = true;
339 changed = true;
340 emit maxChanged(max);
340 emit maxChanged(max);
341 }
341 }
342
342
343 if (changed) {
343 if (changed) {
344 emit rangeChanged(m_min,m_max);
344 emit rangeChanged(m_min,m_max);
345 emit this->changed(m_min, m_max, m_ticksCount, m_niceNumbers);
345 emit this->changed(m_min, m_max, m_ticksCount, m_niceNumbers);
346 }
346 }
347 }
347 }
348
348
349 /*!
349 /*!
350 Sets \a count for ticks on the axis.
350 Sets \a count for ticks on the axis.
351 */
351 */
352 void QChartAxis::setTicksCount(int count)
352 void QChartAxis::setTicksCount(int count)
353 {
353 {
354 if (m_ticksCount != count) {
354 if (m_ticksCount != count) {
355 m_ticksCount = count;
355 m_ticksCount = count;
356 emit ticksCountChanged(count);
356 emit ticksCountChanged(count);
357 emit changed(m_min, m_max, m_ticksCount, m_niceNumbers);
357 emit changed(m_min, m_max, m_ticksCount, m_niceNumbers);
358 }
358 }
359 }
359 }
360
360
361 /*!
361 /*!
362 Sets axis, shades, labels and grid lines to be visible.
362 Sets axis, shades, labels and grid lines to be visible.
363 */
363 */
364 void QChartAxis::show()
364 void QChartAxis::show()
365 {
365 {
366 m_axisVisible=true;
366 m_axisVisible=true;
367 m_gridLineVisible=true;
367 m_gridLineVisible=true;
368 m_labelsVisible=true;
368 m_labelsVisible=true;
369 m_shadesVisible=true;
369 m_shadesVisible=true;
370 emit updated();
370 emit updated();
371 }
371 }
372
372
373 /*!
373 /*!
374 Sets axis, shades, labels and grid lines to not be visible.
374 Sets axis, shades, labels and grid lines to not be visible.
375 */
375 */
376 void QChartAxis::hide()
376 void QChartAxis::hide()
377 {
377 {
378 m_axisVisible = false;
378 m_axisVisible = false;
379 m_gridLineVisible = false;
379 m_gridLineVisible = false;
380 m_labelsVisible = false;
380 m_labelsVisible = false;
381 m_shadesVisible = false;
381 m_shadesVisible = false;
382 emit updated();
382 emit updated();
383 }
383 }
384
384
385 void QChartAxis::handleAxisRangeChanged(qreal min, qreal max,int count)
385 void QChartAxis::handleAxisRangeChanged(qreal min, qreal max,int count)
386 {
386 {
387 setRange(min,max);
387 setRange(min,max);
388 setTicksCount(count);
388 setTicksCount(count);
389 }
389 }
390
390
391 void QChartAxis::setNiceNumbers(bool enabled)
391 void QChartAxis::setNiceNumbers(bool enabled)
392 {
392 {
393 if (m_niceNumbers != enabled){
393 if (m_niceNumbers != enabled){
394 m_niceNumbers = enabled;
394 m_niceNumbers = enabled;
395 emit changed(m_min, m_max, m_ticksCount, m_niceNumbers);
395 emit changed(m_min, m_max, m_ticksCount, m_niceNumbers);
396 }
396 }
397 }
397 }
398
398
399 #include "moc_qchartaxis.cpp"
399 #include "moc_qchartaxis.cpp"
400
400
401 QTCOMMERCIALCHART_END_NAMESPACE
401 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,215 +1,215
1 #include "barchartitem_p.h"
1 #include "barchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include "qchart.h"
6 #include "qchart.h"
7 #include "qchartaxis.h"
7 #include "qchartaxis.h"
8 #include "qchartaxiscategories.h"
8 #include "qchartaxiscategories.h"
9 #include "chartpresenter_p.h"
9 #include "chartpresenter_p.h"
10 #include "chartanimator_p.h"
10 #include "chartanimator_p.h"
11 #include "chartdataset_p.h"
11 #include "chartdataset_p.h"
12 #include <QDebug>
12 #include <QDebug>
13 #include <QToolTip>
13 #include <QToolTip>
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16
16
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
18 ChartItem(presenter),
18 ChartItem(presenter),
19 m_layoutSet(false),
19 m_layoutSet(false),
20 m_series(series)
20 m_series(series)
21 {
21 {
22 connect(series, SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString)));
22 connect(series, SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString)));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
26 setZValue(ChartPresenter::BarSeriesZValue);
26 setZValue(ChartPresenter::BarSeriesZValue);
27 dataChanged();
27 dataChanged();
28 }
28 }
29
29
30 BarChartItem::~BarChartItem()
30 BarChartItem::~BarChartItem()
31 {
31 {
32 disconnect(this,SLOT(showToolTip(QPoint,QString)));
32 disconnect(this,SLOT(showToolTip(QPoint,QString)));
33 }
33 }
34
34
35 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
35 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
36 {
36 {
37 if (!m_layoutSet) {
37 if (!m_layoutSet) {
38 qWarning() << "BarChartItem::paint called without layout set. Aborting.";
38 qWarning() << "BarChartItem::paint called without layout set. Aborting.";
39 return;
39 return;
40 }
40 }
41
41
42 foreach(QGraphicsItem* i, childItems())
42 foreach(QGraphicsItem* i, childItems())
43 i->paint(painter,option,widget);
43 i->paint(painter,option,widget);
44 }
44 }
45
45
46 QRectF BarChartItem::boundingRect() const
46 QRectF BarChartItem::boundingRect() const
47 {
47 {
48 return m_rect;
48 return m_rect;
49 }
49 }
50
50
51 void BarChartItem::dataChanged()
51 void BarChartItem::dataChanged()
52 {
52 {
53 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
53 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
54 // Delete old bars
54 // Delete old bars
55 foreach (QGraphicsItem *item, childItems())
55 foreach (QGraphicsItem *item, childItems())
56 delete item;
56 delete item;
57
57
58 m_bars.clear();
58 m_bars.clear();
59 m_floatingValues.clear();
59 m_floatingValues.clear();
60 m_layout.clear();
60 m_layout.clear();
61
61
62 // Create new graphic items for bars
62 // Create new graphic items for bars
63 for (int c = 0; c < m_series->categoryCount(); c++) {
63 for (int c = 0; c < m_series->categoryCount(); c++) {
64 QString category = m_series->categoryName(c);
64 QString category = m_series->categoryName(c);
65 for (int s = 0; s < m_series->barsetCount(); s++) {
65 for (int s = 0; s < m_series->barsetCount(); s++) {
66 QBarSet *set = m_series->barsetAt(s);
66 QBarSet *set = m_series->barsetAt(s);
67 Bar *bar = new Bar(category,this);
67 Bar *bar = new Bar(category,this);
68 childItems().append(bar);
68 childItems().append(bar);
69 m_bars.append(bar);
69 m_bars.append(bar);
70 connect(bar, SIGNAL(clicked(QString)), set, SIGNAL(clicked(QString)));
70 connect(bar, SIGNAL(clicked(QString)), set, SIGNAL(clicked(QString)));
71 connect(bar, SIGNAL(rightClicked(QString)), set, SIGNAL(rightClicked(QString)));
71 connect(bar, SIGNAL(rightClicked(QString)), set, SIGNAL(rightClicked(QString)));
72 connect(bar, SIGNAL(hoverEntered(QPoint)), set, SLOT(barHoverEnterEvent(QPoint)));
72 connect(bar, SIGNAL(hoverEntered(QPoint)), set, SLOT(barHoverEnterEvent(QPoint)));
73 connect(bar, SIGNAL(hoverLeaved()), set, SLOT(barHoverLeaveEvent()));
73 connect(bar, SIGNAL(hoverLeaved()), set, SLOT(barHoverLeaveEvent()));
74 m_layout.append(QRectF(0, 0, 0, 0));
74 m_layout.append(QRectF(0, 0, 0, 0));
75 }
75 }
76 }
76 }
77
77
78 // Create floating values
78 // Create floating values
79 for (int category = 0; category < m_series->categoryCount(); category++) {
79 for (int category = 0; category < m_series->categoryCount(); category++) {
80 for (int s = 0; s < m_series->barsetCount(); s++) {
80 for (int s = 0; s < m_series->barsetCount(); s++) {
81 QBarSet *set = m_series->barsetAt(s);
81 QBarSet *set = m_series->barsetAt(s);
82 BarValue *value = new BarValue(*set, this);
82 BarValue *value = new BarValue(*set, this);
83 childItems().append(value);
83 childItems().append(value);
84 m_floatingValues.append(value);
84 m_floatingValues.append(value);
85 connect(set, SIGNAL(toggleFloatingValues()), value, SLOT(toggleVisible()));
85 connect(set, SIGNAL(toggleFloatingValues()), value, SLOT(toggleVisible()));
86 }
86 }
87 }
87 }
88 }
88 }
89 QVector<QRectF> BarChartItem::calculateLayout()
89 QVector<QRectF> BarChartItem::calculateLayout()
90 {
90 {
91 QVector<QRectF> layout;
91 QVector<QRectF> layout;
92
92
93 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
93 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
94 qreal categoryCount = m_series->categoryCount();
94 qreal categoryCount = m_series->categoryCount();
95 qreal setCount = m_series->barsetCount();
95 qreal setCount = m_series->barsetCount();
96
96
97 qreal width = geometry().width();
97 qreal width = geometry().width();
98 qreal height = geometry().height();
98 qreal height = geometry().height();
99
99
100 qreal max = m_series->max();
100 qreal max = m_series->max();
101
101
102 // Domain:
102 // Domain:
103 if (m_domainMaxY > max) {
103 if (m_domainMaxY > max) {
104 max = m_domainMaxY;
104 max = m_domainMaxY;
105 }
105 }
106
106
107 qreal scale = (height / max);
107 qreal scale = (height / max);
108 qreal categoryWidth = width / categoryCount;
108 qreal categoryWidth = width / categoryCount;
109 qreal barWidth = categoryWidth / (setCount+1);
109 qreal barWidth = categoryWidth / (setCount+1);
110
110
111 int itemIndex(0);
111 int itemIndex(0);
112 for (int category = 0; category < categoryCount; category++) {
112 for (int category = 0; category < categoryCount; category++) {
113 qreal xPos = categoryWidth * category + barWidth / 2;
113 qreal xPos = categoryWidth * category + barWidth / 2;
114 qreal yPos = height;
114 qreal yPos = height;
115 for (int set = 0; set < setCount; set++) {
115 for (int set = 0; set < setCount; set++) {
116 qreal barHeight = m_series->valueAt(set, category) * scale;
116 qreal barHeight = m_series->valueAt(set, category) * scale;
117 Bar* bar = m_bars.at(itemIndex);
117 Bar* bar = m_bars.at(itemIndex);
118
118
119 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
119 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
120 layout.append(rect);
120 layout.append(rect);
121 bar->setPen(m_series->barsetAt(set)->pen());
121 bar->setPen(m_series->barsetAt(set)->pen());
122 bar->setBrush(m_series->barsetAt(set)->brush());
122 bar->setBrush(m_series->barsetAt(set)->brush());
123 itemIndex++;
123 itemIndex++;
124 xPos += barWidth;
124 xPos += barWidth;
125 }
125 }
126 }
126 }
127
127
128 // Position floating values
128 // Position floating values
129 itemIndex = 0;
129 itemIndex = 0;
130 for (int category = 0; category < m_series->categoryCount(); category++) {
130 for (int category = 0; category < m_series->categoryCount(); category++) {
131 qreal xPos = categoryWidth * category + barWidth;
131 qreal xPos = categoryWidth * category + barWidth;
132 qreal yPos = height;
132 qreal yPos = height;
133 for (int set=0; set < m_series->barsetCount(); set++) {
133 for (int set=0; set < m_series->barsetCount(); set++) {
134 qreal barHeight = m_series->valueAt(set, category) * scale;
134 qreal barHeight = m_series->valueAt(set, category) * scale;
135 BarValue* value = m_floatingValues.at(itemIndex);
135 BarValue* value = m_floatingValues.at(itemIndex);
136
136
137 QBarSet* barSet = m_series->barsetAt(set);
137 QBarSet* barSet = m_series->barsetAt(set);
138 value->resize(100, 50); // TODO: proper layout for this.
138 value->resize(100, 50); // TODO: proper layout for this.
139 value->setPos(xPos, yPos-barHeight / 2);
139 value->setPos(xPos, yPos-barHeight / 2);
140 value->setPen(barSet->floatingValuePen());
140 value->setPen(barSet->floatingValuePen());
141
141
142 if (m_series->valueAt(set,category) != 0) {
142 if (!qFuzzyIsNull(m_series->valueAt(set,category))) {
143 value->setValueString(QString::number(m_series->valueAt(set, category)));
143 value->setValueString(QString::number(m_series->valueAt(set, category)));
144 } else {
144 } else {
145 value->setValueString(QString(""));
145 value->setValueString(QString(""));
146 }
146 }
147
147
148 itemIndex++;
148 itemIndex++;
149 xPos += barWidth;
149 xPos += barWidth;
150 }
150 }
151 }
151 }
152
152
153 return layout;
153 return layout;
154 }
154 }
155
155
156 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
156 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
157 {
157 {
158 if (animator())
158 if (animator())
159 animator()->updateLayout(this, m_layout, layout);
159 animator()->updateLayout(this, m_layout, layout);
160 else
160 else
161 setLayout(layout);
161 setLayout(layout);
162 }
162 }
163
163
164 void BarChartItem::setLayout(const QVector<QRectF> &layout)
164 void BarChartItem::setLayout(const QVector<QRectF> &layout)
165 {
165 {
166 m_layout = layout;
166 m_layout = layout;
167
167
168 for (int i=0; i < m_bars.count(); i++)
168 for (int i=0; i < m_bars.count(); i++)
169 m_bars.at(i)->setRect(layout.at(i));
169 m_bars.at(i)->setRect(layout.at(i));
170
170
171 update();
171 update();
172 }
172 }
173
173
174 //handlers
174 //handlers
175
175
176 void BarChartItem::handleModelChanged(int index)
176 void BarChartItem::handleModelChanged(int index)
177 {
177 {
178 Q_UNUSED(index)
178 Q_UNUSED(index)
179 dataChanged();
179 dataChanged();
180 }
180 }
181
181
182 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
182 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
183 {
183 {
184 m_domainMinX = minX;
184 m_domainMinX = minX;
185 m_domainMaxX = maxX;
185 m_domainMaxX = maxX;
186 m_domainMinY = minY;
186 m_domainMinY = minY;
187 m_domainMaxY = maxY;
187 m_domainMaxY = maxY;
188 handleLayoutChanged();
188 handleLayoutChanged();
189 }
189 }
190
190
191 void BarChartItem::handleGeometryChanged(const QRectF &rect)
191 void BarChartItem::handleGeometryChanged(const QRectF &rect)
192 {
192 {
193 m_rect = rect;
193 m_rect = rect;
194 handleLayoutChanged();
194 handleLayoutChanged();
195 m_layoutSet = true;
195 m_layoutSet = true;
196 setPos(rect.topLeft());
196 setPos(rect.topLeft());
197 }
197 }
198
198
199 void BarChartItem::handleLayoutChanged()
199 void BarChartItem::handleLayoutChanged()
200 {
200 {
201 QVector<QRectF> layout = calculateLayout();
201 QVector<QRectF> layout = calculateLayout();
202 applyLayout(layout);
202 applyLayout(layout);
203 update();
203 update();
204 }
204 }
205
205
206
206
207 void BarChartItem::showToolTip(QPoint pos, QString tip)
207 void BarChartItem::showToolTip(QPoint pos, QString tip)
208 {
208 {
209 // TODO: cool tooltip instead of default
209 // TODO: cool tooltip instead of default
210 QToolTip::showText(pos, tip);
210 QToolTip::showText(pos, tip);
211 }
211 }
212
212
213 #include "moc_barchartitem_p.cpp"
213 #include "moc_barchartitem_p.cpp"
214
214
215 QTCOMMERCIALCHART_END_NAMESPACE
215 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,81
1 #include "percentbarchartitem_p.h"
1 #include "percentbarchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
9 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
10 BarChartItem(series, presenter)
10 BarChartItem(series, presenter)
11 {
11 {
12 }
12 }
13
13
14 QVector<QRectF> PercentBarChartItem::calculateLayout()
14 QVector<QRectF> PercentBarChartItem::calculateLayout()
15 {
15 {
16 QVector<QRectF> layout;
16 QVector<QRectF> layout;
17
17
18 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
18 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
19 qreal width = geometry().width();
19 qreal width = geometry().width();
20 qreal height = geometry().height();
20 qreal height = geometry().height();
21
21
22 qreal categoryCount = m_series->categoryCount();
22 qreal categoryCount = m_series->categoryCount();
23 qreal barWidth = width / (m_series->categoryCount() * 2);
23 qreal barWidth = width / (m_series->categoryCount() * 2);
24 qreal xStep = width / categoryCount;
24 qreal xStep = width / categoryCount;
25 qreal xPos = xStep / 2 - barWidth / 2;
25 qreal xPos = xStep / 2 - barWidth / 2;
26
26
27 int itemIndex(0);
27 int itemIndex(0);
28 for (int category = 0; category < categoryCount; category++) {
28 for (int category = 0; category < categoryCount; category++) {
29 qreal colSum = m_series->categorySum(category);
29 qreal colSum = m_series->categorySum(category);
30 qreal scale = (height / colSum);
30 qreal scale = (height / colSum);
31 qreal yPos = height;
31 qreal yPos = height;
32 for (int set=0; set < m_series->barsetCount(); set++) {
32 for (int set=0; set < m_series->barsetCount(); set++) {
33 qreal barHeight = m_series->valueAt(set, category) * scale;
33 qreal barHeight = m_series->valueAt(set, category) * scale;
34 Bar* bar = m_bars.at(itemIndex);
34 Bar* bar = m_bars.at(itemIndex);
35 bar->setPen(m_series->barsetAt(set)->pen());
35 bar->setPen(m_series->barsetAt(set)->pen());
36 bar->setBrush(m_series->barsetAt(set)->brush());
36 bar->setBrush(m_series->barsetAt(set)->brush());
37 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
37 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
38 layout.append(rect);
38 layout.append(rect);
39 itemIndex++;
39 itemIndex++;
40 yPos -= barHeight;
40 yPos -= barHeight;
41 }
41 }
42 xPos += xStep;
42 xPos += xStep;
43 }
43 }
44
44
45 // Position floating values
45 // Position floating values
46 itemIndex = 0;
46 itemIndex = 0;
47 xPos = (width/categoryCount);
47 xPos = (width/categoryCount);
48 for (int category=0; category < m_series->categoryCount(); category++) {
48 for (int category=0; category < m_series->categoryCount(); category++) {
49 qreal yPos = height;
49 qreal yPos = height;
50 qreal colSum = m_series->categorySum(category);
50 qreal colSum = m_series->categorySum(category);
51 qreal scale = (height / colSum);
51 qreal scale = (height / colSum);
52 for (int set=0; set < m_series->barsetCount(); set++) {
52 for (int set=0; set < m_series->barsetCount(); set++) {
53 qreal barHeight = m_series->valueAt(set,category) * scale;
53 qreal barHeight = m_series->valueAt(set,category) * scale;
54 BarValue* value = m_floatingValues.at(itemIndex);
54 BarValue* value = m_floatingValues.at(itemIndex);
55
55
56 QBarSet* barSet = m_series->barsetAt(set);
56 QBarSet* barSet = m_series->barsetAt(set);
57 value->resize(100, 50); // TODO: proper layout for this.
57 value->resize(100, 50); // TODO: proper layout for this.
58 value->setPos(xPos, yPos-barHeight / 2);
58 value->setPos(xPos, yPos-barHeight / 2);
59 value->setPen(barSet->floatingValuePen());
59 value->setPen(barSet->floatingValuePen());
60
60
61 if (m_series->valueAt(set,category) != 0) {
61 if (!qFuzzyIsNull(m_series->valueAt(set,category))) {
62 int p = m_series->percentageAt(set,category) * 100;
62 int p = m_series->percentageAt(set,category) * 100;
63 QString vString(QString::number(p));
63 QString vString(QString::number(p));
64 vString.truncate(3);
64 vString.truncate(3);
65 vString.append("%");
65 vString.append("%");
66 value->setValueString(vString);
66 value->setValueString(vString);
67 } else {
67 } else {
68 value->setValueString(QString(""));
68 value->setValueString(QString(""));
69 }
69 }
70
70
71 itemIndex++;
71 itemIndex++;
72 yPos -= barHeight;
72 yPos -= barHeight;
73 }
73 }
74 xPos += xStep;
74 xPos += xStep;
75 }
75 }
76 return layout;
76 return layout;
77 }
77 }
78
78
79 #include "moc_percentbarchartitem_p.cpp"
79 #include "moc_percentbarchartitem_p.cpp"
80
80
81 QTCOMMERCIALCHART_END_NAMESPACE
81 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,83 +1,83
1 #include "stackedbarchartitem_p.h"
1 #include "stackedbarchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
9 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
10 BarChartItem(series, presenter)
10 BarChartItem(series, presenter)
11 {
11 {
12 }
12 }
13
13
14 StackedBarChartItem::~StackedBarChartItem()
14 StackedBarChartItem::~StackedBarChartItem()
15 {
15 {
16 }
16 }
17
17
18 QVector<QRectF> StackedBarChartItem::calculateLayout()
18 QVector<QRectF> StackedBarChartItem::calculateLayout()
19 {
19 {
20 QVector<QRectF> layout;
20 QVector<QRectF> layout;
21 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
21 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
22
22
23 qreal maxSum = m_series->maxCategorySum();
23 qreal maxSum = m_series->maxCategorySum();
24 // Domain:
24 // Domain:
25 if (m_domainMaxY > maxSum) {
25 if (m_domainMaxY > maxSum) {
26 maxSum = m_domainMaxY;
26 maxSum = m_domainMaxY;
27 }
27 }
28
28
29 qreal height = geometry().height();
29 qreal height = geometry().height();
30 qreal width = geometry().width();
30 qreal width = geometry().width();
31 qreal scale = (height / m_series->maxCategorySum());
31 qreal scale = (height / m_series->maxCategorySum());
32 qreal categotyCount = m_series->categoryCount();
32 qreal categotyCount = m_series->categoryCount();
33 qreal barWidth = width / (categotyCount * 2);
33 qreal barWidth = width / (categotyCount * 2);
34 qreal xStep = width / categotyCount;
34 qreal xStep = width / categotyCount;
35 qreal xPos = xStep / 2 - barWidth / 2;
35 qreal xPos = xStep / 2 - barWidth / 2;
36
36
37 int itemIndex(0);
37 int itemIndex(0);
38 for (int category = 0; category < categotyCount; category++) {
38 for (int category = 0; category < categotyCount; category++) {
39 qreal yPos = height;
39 qreal yPos = height;
40 for (int set=0; set < m_series->barsetCount(); set++) {
40 for (int set=0; set < m_series->barsetCount(); set++) {
41 qreal barHeight = m_series->valueAt(set, category) * scale;
41 qreal barHeight = m_series->valueAt(set, category) * scale;
42 Bar* bar = m_bars.at(itemIndex);
42 Bar* bar = m_bars.at(itemIndex);
43 bar->setPen(m_series->barsetAt(set)->pen());
43 bar->setPen(m_series->barsetAt(set)->pen());
44 bar->setBrush(m_series->barsetAt(set)->brush());
44 bar->setBrush(m_series->barsetAt(set)->brush());
45 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
45 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
46 layout.append(rect);
46 layout.append(rect);
47 itemIndex++;
47 itemIndex++;
48 yPos -= barHeight;
48 yPos -= barHeight;
49 }
49 }
50 xPos += xStep;
50 xPos += xStep;
51 }
51 }
52
52
53 // Position floating values
53 // Position floating values
54 itemIndex = 0;
54 itemIndex = 0;
55 xPos = (width/categotyCount);
55 xPos = (width/categotyCount);
56 for (int category=0; category < m_series->categoryCount(); category++) {
56 for (int category=0; category < m_series->categoryCount(); category++) {
57 qreal yPos = height;
57 qreal yPos = height;
58 for (int set=0; set < m_series->barsetCount(); set++) {
58 for (int set=0; set < m_series->barsetCount(); set++) {
59 qreal barHeight = m_series->valueAt(set, category) * scale;
59 qreal barHeight = m_series->valueAt(set, category) * scale;
60 BarValue* value = m_floatingValues.at(itemIndex);
60 BarValue* value = m_floatingValues.at(itemIndex);
61
61
62 QBarSet* barSet = m_series->barsetAt(set);
62 QBarSet* barSet = m_series->barsetAt(set);
63 value->resize(100, 50); // TODO: proper layout for this.
63 value->resize(100, 50); // TODO: proper layout for this.
64 value->setPos(xPos, yPos-barHeight / 2);
64 value->setPos(xPos, yPos-barHeight / 2);
65 value->setPen(barSet->floatingValuePen());
65 value->setPen(barSet->floatingValuePen());
66
66
67 if (m_series->valueAt(set, category) != 0) {
67 if (!qFuzzyIsNull(m_series->valueAt(set, category))) {
68 value->setValueString(QString::number(m_series->valueAt(set,category)));
68 value->setValueString(QString::number(m_series->valueAt(set,category)));
69 } else {
69 } else {
70 value->setValueString(QString(""));
70 value->setValueString(QString(""));
71 }
71 }
72
72
73 itemIndex++;
73 itemIndex++;
74 yPos -= barHeight;
74 yPos -= barHeight;
75 }
75 }
76 xPos += xStep;
76 xPos += xStep;
77 }
77 }
78 return layout;
78 return layout;
79 }
79 }
80
80
81 #include "moc_stackedbarchartitem_p.cpp"
81 #include "moc_stackedbarchartitem_p.cpp"
82
82
83 QTCOMMERCIALCHART_END_NAMESPACE
83 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,257 +1,257
1 #include "domain_p.h"
1 #include "domain_p.h"
2 #include <cmath>
2 #include <cmath>
3
3
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
5
6 Domain::Domain(QObject* parent):QObject(parent),
6 Domain::Domain(QObject* parent):QObject(parent),
7 m_minX(0),
7 m_minX(0),
8 m_maxX(0),
8 m_maxX(0),
9 m_minY(0),
9 m_minY(0),
10 m_maxY(0),
10 m_maxY(0),
11 m_tickXCount(5),
11 m_tickXCount(5),
12 m_tickYCount(5),
12 m_tickYCount(5),
13 m_niceNumbers(false)
13 m_niceNumbers(false)
14 {
14 {
15 }
15 }
16
16
17 Domain::~Domain()
17 Domain::~Domain()
18 {
18 {
19 }
19 }
20
20
21 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
21 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
22 {
22 {
23 setRange(minX, maxX, minY, maxY,m_tickXCount,m_tickYCount);
23 setRange(minX, maxX, minY, maxY,m_tickXCount,m_tickYCount);
24 }
24 }
25
25
26 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY,int tickXCount,int tickYCount)
26 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY,int tickXCount,int tickYCount)
27 {
27 {
28 bool domainChanged = false;
28 bool domainChanged = false;
29 bool tickXChanged = false;
29 bool tickXChanged = false;
30 bool tickYChanged = false;
30 bool tickYChanged = false;
31
31
32 if(m_tickXCount!=tickXCount) {
32 if(m_tickXCount!=tickXCount) {
33 m_tickXCount=tickXCount;
33 m_tickXCount=tickXCount;
34 tickXChanged=true;
34 tickXChanged=true;
35 }
35 }
36
36
37 if(m_tickYCount!=tickYCount) {
37 if(m_tickYCount!=tickYCount) {
38 m_tickYCount=tickYCount;
38 m_tickYCount=tickYCount;
39 tickYChanged=true;
39 tickYChanged=true;
40 }
40 }
41
41
42 if(m_minX!=minX || m_maxX!=maxX) {
42 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
43 if(m_niceNumbers) looseNiceNumbers(minX, maxX, m_tickXCount);
43 if(m_niceNumbers) looseNiceNumbers(minX, maxX, m_tickXCount);
44 m_minX=minX;
44 m_minX=minX;
45 m_maxX=maxX;
45 m_maxX=maxX;
46 domainChanged=true;
46 domainChanged=true;
47 tickXChanged=false;
47 tickXChanged=false;
48 emit rangeXChanged(minX,maxX, m_tickXCount);
48 emit rangeXChanged(minX,maxX, m_tickXCount);
49 }
49 }
50
50
51 if(m_minY!=minY || m_maxY!=maxY) {
51 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
52 if(m_niceNumbers) looseNiceNumbers(minY, maxY, m_tickYCount);
52 if(m_niceNumbers) looseNiceNumbers(minY, maxY, m_tickYCount);
53 m_minY=minY;
53 m_minY=minY;
54 m_maxY=maxY;
54 m_maxY=maxY;
55 domainChanged=true;
55 domainChanged=true;
56 tickYChanged=false;
56 tickYChanged=false;
57 emit rangeYChanged(minY,maxY, m_tickYCount);
57 emit rangeYChanged(minY,maxY, m_tickYCount);
58 }
58 }
59
59
60 if(domainChanged) {
60 if(domainChanged) {
61 emit this->domainChanged(m_minX, m_maxX, m_minY, m_maxY);
61 emit this->domainChanged(m_minX, m_maxX, m_minY, m_maxY);
62 }
62 }
63
63
64 if(tickXChanged) {
64 if(tickXChanged) {
65 emit rangeXChanged(minX,maxX, m_tickXCount);
65 emit rangeXChanged(minX,maxX, m_tickXCount);
66 }
66 }
67
67
68 if(tickYChanged) {
68 if(tickYChanged) {
69 emit rangeYChanged(minY,maxY, m_tickYCount);
69 emit rangeYChanged(minY,maxY, m_tickYCount);
70 }
70 }
71 }
71 }
72
72
73 void Domain::setRangeX(qreal min, qreal max)
73 void Domain::setRangeX(qreal min, qreal max)
74 {
74 {
75 setRange(min,max,m_minY, m_maxY);
75 setRange(min,max,m_minY, m_maxY);
76 }
76 }
77
77
78 void Domain::setRangeX(qreal min, qreal max, int tickCount)
78 void Domain::setRangeX(qreal min, qreal max, int tickCount)
79 {
79 {
80 setRange(min,max,m_minY, m_maxY,tickCount,m_tickYCount);
80 setRange(min,max,m_minY, m_maxY,tickCount,m_tickYCount);
81 }
81 }
82
82
83 void Domain::setRangeY(qreal min, qreal max)
83 void Domain::setRangeY(qreal min, qreal max)
84 {
84 {
85 setRange(m_minX, m_maxX, min, max);
85 setRange(m_minX, m_maxX, min, max);
86 }
86 }
87
87
88 void Domain::setRangeY(qreal min, qreal max,int tickCount)
88 void Domain::setRangeY(qreal min, qreal max,int tickCount)
89 {
89 {
90 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickCount);
90 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickCount);
91 }
91 }
92
92
93 void Domain::setMinX(qreal min)
93 void Domain::setMinX(qreal min)
94 {
94 {
95 setRange(min, m_maxX, m_minY, m_maxY);
95 setRange(min, m_maxX, m_minY, m_maxY);
96 }
96 }
97
97
98 void Domain::setMaxX(qreal max)
98 void Domain::setMaxX(qreal max)
99 {
99 {
100 setRange(m_minX, max, m_minY, m_maxY);
100 setRange(m_minX, max, m_minY, m_maxY);
101 }
101 }
102
102
103 void Domain::setMinY(qreal min)
103 void Domain::setMinY(qreal min)
104 {
104 {
105 setRange(m_minX, m_maxX, min, m_maxY);
105 setRange(m_minX, m_maxX, min, m_maxY);
106 }
106 }
107
107
108 void Domain::setMaxY(qreal max)
108 void Domain::setMaxY(qreal max)
109 {
109 {
110 setRange(m_minX, m_maxX, m_minY, max);
110 setRange(m_minX, m_maxX, m_minY, max);
111 }
111 }
112
112
113 qreal Domain::spanX() const
113 qreal Domain::spanX() const
114 {
114 {
115 Q_ASSERT(m_maxX >= m_minX);
115 Q_ASSERT(m_maxX >= m_minX);
116 return m_maxX - m_minX;
116 return m_maxX - m_minX;
117 }
117 }
118
118
119 qreal Domain::spanY() const
119 qreal Domain::spanY() const
120 {
120 {
121 Q_ASSERT(m_maxY >= m_minY);
121 Q_ASSERT(m_maxY >= m_minY);
122 return m_maxY - m_minY;
122 return m_maxY - m_minY;
123 }
123 }
124
124
125 bool Domain::isEmpty() const
125 bool Domain::isEmpty() const
126 {
126 {
127 return spanX()==0 || spanY()==0;
127 return qFuzzyIsNull(spanX()) || qFuzzyIsNull(spanY());
128 }
128 }
129
129
130 void Domain::zoomIn(const QRectF& rect, const QSizeF& size)
130 void Domain::zoomIn(const QRectF& rect, const QSizeF& size)
131 {
131 {
132 qreal dx = spanX() / size.width();
132 qreal dx = spanX() / size.width();
133 qreal dy = spanY() / size.height();
133 qreal dy = spanY() / size.height();
134
134
135 m_maxX = m_minX + dx * rect.right();
135 m_maxX = m_minX + dx * rect.right();
136 m_minX = m_minX + dx * rect.left();
136 m_minX = m_minX + dx * rect.left();
137 m_minY = m_maxY - dy * rect.bottom();
137 m_minY = m_maxY - dy * rect.bottom();
138 m_maxY = m_maxY - dy * rect.top();
138 m_maxY = m_maxY - dy * rect.top();
139
139
140 if(m_niceNumbers) {
140 if(m_niceNumbers) {
141 looseNiceNumbers(m_minX, m_maxX, m_tickXCount);
141 looseNiceNumbers(m_minX, m_maxX, m_tickXCount);
142 looseNiceNumbers(m_minY, m_maxY, m_tickYCount);
142 looseNiceNumbers(m_minY, m_maxY, m_tickYCount);
143 }
143 }
144
144
145 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
145 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
146 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
146 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
147 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
147 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
148 }
148 }
149
149
150 void Domain::zoomOut(const QRectF& rect, const QSizeF& size)
150 void Domain::zoomOut(const QRectF& rect, const QSizeF& size)
151 {
151 {
152 qreal dx = spanX() / rect.width();
152 qreal dx = spanX() / rect.width();
153 qreal dy = spanY() / rect.height();
153 qreal dy = spanY() / rect.height();
154
154
155 m_minX = m_maxX - dx * rect.right();
155 m_minX = m_maxX - dx * rect.right();
156 m_maxX = m_minX + dx * size.width();
156 m_maxX = m_minX + dx * size.width();
157 m_maxY = m_minY + dy * rect.bottom();
157 m_maxY = m_minY + dy * rect.bottom();
158 m_minY = m_maxY - dy * size.height();
158 m_minY = m_maxY - dy * size.height();
159
159
160 if(m_niceNumbers) {
160 if(m_niceNumbers) {
161 looseNiceNumbers(m_minX, m_maxX, m_tickXCount);
161 looseNiceNumbers(m_minX, m_maxX, m_tickXCount);
162 looseNiceNumbers(m_minY, m_maxY, m_tickYCount);
162 looseNiceNumbers(m_minY, m_maxY, m_tickYCount);
163 }
163 }
164
164
165 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
165 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
166 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
166 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
167 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
167 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
168 }
168 }
169
169
170 void Domain::move(int dx,int dy,const QSizeF& size)
170 void Domain::move(int dx,int dy,const QSizeF& size)
171 {
171 {
172 qreal x = spanX() / size.width();
172 qreal x = spanX() / size.width();
173 qreal y = spanY() / size.height();
173 qreal y = spanY() / size.height();
174
174
175 if(dx!=0) {
175 if(dx!=0) {
176 m_minX = m_minX + x * dx;
176 m_minX = m_minX + x * dx;
177 m_maxX = m_maxX + x * dx;
177 m_maxX = m_maxX + x * dx;
178 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
178 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
179 }
179 }
180 if(dy!=0) {
180 if(dy!=0) {
181 m_minY = m_minY + y * dy;
181 m_minY = m_minY + y * dy;
182 m_maxY = m_maxY + y * dy;
182 m_maxY = m_maxY + y * dy;
183 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
183 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
184 }
184 }
185
185
186 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
186 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
187 }
187 }
188
188
189 void Domain::handleAxisXChanged(qreal min,qreal max,int tickXCount,bool niceNumbers)
189 void Domain::handleAxisXChanged(qreal min,qreal max,int tickXCount,bool niceNumbers)
190 {
190 {
191 m_niceNumbers=niceNumbers;
191 m_niceNumbers=niceNumbers;
192 setRange(min,max,m_minY, m_maxY,tickXCount,m_tickYCount);
192 setRange(min,max,m_minY, m_maxY,tickXCount,m_tickYCount);
193 }
193 }
194
194
195 void Domain::handleAxisYChanged(qreal min,qreal max,int tickYCount,bool niceNumbers)
195 void Domain::handleAxisYChanged(qreal min,qreal max,int tickYCount,bool niceNumbers)
196 {
196 {
197 m_niceNumbers=niceNumbers;
197 m_niceNumbers=niceNumbers;
198 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickYCount);
198 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickYCount);
199 }
199 }
200
200
201 //algorithm defined by Paul S.Heckbert GraphicalGems I
201 //algorithm defined by Paul S.Heckbert GraphicalGems I
202
202
203 void Domain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
203 void Domain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
204 {
204 {
205 qreal range = niceNumber(max-min,true); //range with ceiling
205 qreal range = niceNumber(max-min,true); //range with ceiling
206 qreal step = niceNumber(range/(ticksCount-1),false);
206 qreal step = niceNumber(range/(ticksCount-1),false);
207 min = floor(min/step);
207 min = floor(min/step);
208 max = ceil(max/step);
208 max = ceil(max/step);
209 ticksCount = int(max-min) +1;
209 ticksCount = int(max-min) +1;
210 min*=step;
210 min*=step;
211 max*=step;
211 max*=step;
212 }
212 }
213
213
214 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
214 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
215
215
216 qreal Domain::niceNumber(qreal x,bool ceiling)
216 qreal Domain::niceNumber(qreal x,bool ceiling)
217 {
217 {
218 qreal z = pow(10,floor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
218 qreal z = pow(10,floor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
219 qreal q = x/z;//q<10 && q>=1;
219 qreal q = x/z;//q<10 && q>=1;
220
220
221 if(ceiling) {
221 if(ceiling) {
222 if(q <= 1.0) q=1;
222 if(q <= 1.0) q=1;
223 else if(q <= 2.0) q=2;
223 else if(q <= 2.0) q=2;
224 else if(q <= 5.0) q=5;
224 else if(q <= 5.0) q=5;
225 else q=10;
225 else q=10;
226 }
226 }
227 else {
227 else {
228 if(q < 1.5) q=1;
228 if(q < 1.5) q=1;
229 else if(q < 3.0) q=2;
229 else if(q < 3.0) q=2;
230 else if(q < 7.0) q=5;
230 else if(q < 7.0) q=5;
231 else q=10;
231 else q=10;
232 }
232 }
233 return q*z;
233 return q*z;
234 }
234 }
235
235
236 bool operator== (const Domain &domain1, const Domain &domain2)
236 bool operator== (const Domain &domain1, const Domain &domain2)
237 {
237 {
238 return (domain1.m_maxX == domain2.m_maxX &&
238 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
239 domain1.m_maxY == domain2.m_maxY &&
239 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
240 domain1.m_minX == domain2.m_minX &&
240 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
241 domain1.m_minY == domain2.m_minY);
241 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
242 }
242 }
243
243
244 bool operator!= (const Domain &domain1, const Domain &domain2)
244 bool operator!= (const Domain &domain1, const Domain &domain2)
245 {
245 {
246 return !(domain1 == domain2);
246 return !(domain1 == domain2);
247 }
247 }
248
248
249 QDebug operator<<(QDebug dbg, const Domain &domain)
249 QDebug operator<<(QDebug dbg, const Domain &domain)
250 {
250 {
251 dbg.nospace() << "Domain("<<domain.m_minX<<','<<domain.m_maxX<<','<<domain.m_minY<<','<<domain.m_maxY<<')' << domain.m_tickXCount << "," << domain.m_tickYCount ;
251 dbg.nospace() << "Domain("<<domain.m_minX<<','<<domain.m_maxX<<','<<domain.m_minY<<','<<domain.m_maxY<<')' << domain.m_tickXCount << "," << domain.m_tickYCount ;
252 return dbg.maybeSpace();
252 return dbg.maybeSpace();
253 }
253 }
254
254
255 #include "moc_domain_p.cpp"
255 #include "moc_domain_p.cpp"
256
256
257 QTCOMMERCIALCHART_END_NAMESPACE
257 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 (!qFuzzyIsNull(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 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
67 !qFuzzyIsNull(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 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
73 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
74 m_labelPen != other.m_labelPen)
74 m_labelPen != other.m_labelPen)
75 return true;
75 return true;
76
76
77 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
77 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
78 m_center != other.m_center ||
78 m_center != other.m_center ||
79 !qFuzzyIsNull(m_radius - other.m_radius) ||
79 !qFuzzyIsNull(m_radius - other.m_radius) ||
80 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
80 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
81 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
81 !qFuzzyIsNull(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_labelPen;
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,98 +1,98
1 #include "qscatterseries.h"
1 #include "qscatterseries.h"
2 #include "qchart.h"
2 #include "qchart.h"
3
3
4 /*!
4 /*!
5 \class QScatterSeries
5 \class QScatterSeries
6 \brief The QScatterSeries class is used for making scatter charts.
6 \brief The QScatterSeries class is used for making scatter charts.
7
7
8 \mainclass
8 \mainclass
9
9
10 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
10 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
11 and the vertical axis.
11 and the vertical axis.
12
12
13 \image scatterchart.png
13 \image scatterchart.png
14
14
15 Creating basic scatter chart is simple:
15 Creating basic scatter chart is simple:
16 \code
16 \code
17 QScatterSeries* series = new QScatterSeries();
17 QScatterSeries* series = new QScatterSeries();
18 series->add(0, 6);
18 series->add(0, 6);
19 series->add(2, 4);
19 series->add(2, 4);
20 ...
20 ...
21 chartView->addSeries(series);
21 chartView->addSeries(series);
22 \endcode
22 \endcode
23 */
23 */
24
24
25 /*!
25 /*!
26 \enum QScatterSeries::MarkerShape
26 \enum QScatterSeries::MarkerShape
27
27
28 This enum describes the shape used when rendering marker items.
28 This enum describes the shape used when rendering marker items.
29
29
30 \value MarkerShapeCircle
30 \value MarkerShapeCircle
31 \value MarkerShapeRectangle
31 \value MarkerShapeRectangle
32 */
32 */
33
33
34 /*!
34 /*!
35 \fn QChartSeriesType QScatterSeries::type() const
35 \fn QChartSeriesType QScatterSeries::type() const
36 \brief Returns QChartSeries::SeriesTypeScatter.
36 \brief Returns QChartSeries::SeriesTypeScatter.
37 \sa QSeries, QSeriesType
37 \sa QSeries, QSeriesType
38 */
38 */
39
39
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41
41
42 /*!
42 /*!
43 Constructs a series object which is a child of \a parent.
43 Constructs a series object which is a child of \a parent.
44 */
44 */
45 QScatterSeries::QScatterSeries(QObject *parent) :
45 QScatterSeries::QScatterSeries(QObject *parent) :
46 QXYSeries(parent),
46 QXYSeries(parent),
47 m_shape(QScatterSeries::MarkerShapeCircle),
47 m_shape(QScatterSeries::MarkerShapeCircle),
48 m_size(15.0)
48 m_size(15.0)
49 {
49 {
50 }
50 }
51
51
52 /*!
52 /*!
53 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
53 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
54 */
54 */
55 QScatterSeries::~QScatterSeries()
55 QScatterSeries::~QScatterSeries()
56 {
56 {
57 }
57 }
58
58
59 /*!
59 /*!
60 Returns the shape used for drawing markers.
60 Returns the shape used for drawing markers.
61 */
61 */
62 QScatterSeries::MarkerShape QScatterSeries::shape() const
62 QScatterSeries::MarkerShape QScatterSeries::shape() const
63 {
63 {
64 return m_shape;
64 return m_shape;
65 }
65 }
66
66
67 /*!
67 /*!
68 Overrides the default shape of the marker items with a user defined \a shape. The default shape
68 Overrides the default shape of the marker items with a user defined \a shape. The default shape
69 is defined by chart theme setting.
69 is defined by chart theme setting.
70 */
70 */
71 void QScatterSeries::setShape(MarkerShape shape)
71 void QScatterSeries::setShape(MarkerShape shape)
72 {
72 {
73 if (m_shape != shape) {
73 if (m_shape != shape) {
74 m_shape = shape;
74 m_shape = shape;
75 emit QXYSeries::updated();
75 emit QXYSeries::updated();
76 }
76 }
77 }
77 }
78
78
79 /*!
79 /*!
80 Returns the size of the marker items.
80 Returns the size of the marker items.
81 */
81 */
82 qreal QScatterSeries::size() const
82 qreal QScatterSeries::size() const
83 {
83 {
84 return m_size;
84 return m_size;
85 }
85 }
86
86
87 /*!
87 /*!
88 Set the \a size of the marker items. The default size is 9.0.
88 Set the \a size of the marker items. The default size is 9.0.
89 */
89 */
90 void QScatterSeries::setSize(qreal size)
90 void QScatterSeries::setSize(qreal size)
91 {
91 {
92 if (m_size != size) {
92 if (!qFuzzyIsNull(m_size - size)) {
93 m_size = size;
93 m_size = size;
94 emit updated();
94 emit updated();
95 }
95 }
96 }
96 }
97
97
98 QTCOMMERCIALCHART_END_NAMESPACE
98 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,156 +1,156
1 #include "xychartitem_p.h"
1 #include "xychartitem_p.h"
2 #include "qxyseries.h"
2 #include "qxyseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartanimator_p.h"
4 #include "chartanimator_p.h"
5 #include <QPainter>
5 #include <QPainter>
6 #include <QGraphicsSceneMouseEvent>
6 #include <QGraphicsSceneMouseEvent>
7
7
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 //TODO: optimize : remove points which are not visible
11 //TODO: optimize : remove points which are not visible
12
12
13 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
13 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
14 m_minX(0),
14 m_minX(0),
15 m_maxX(0),
15 m_maxX(0),
16 m_minY(0),
16 m_minY(0),
17 m_maxY(0),
17 m_maxY(0),
18 m_series(series)
18 m_series(series)
19 {
19 {
20 connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
20 connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
21 connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
21 connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
22 connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
22 connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
23 connect(this,SIGNAL(clicked(const QPointF&)),series,SIGNAL(clicked(const QPointF&)));
23 connect(this,SIGNAL(clicked(const QPointF&)),series,SIGNAL(clicked(const QPointF&)));
24 }
24 }
25
25
26 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
26 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
27 {
27 {
28 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
28 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
29 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
29 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
30 qreal x = (point.x() - m_minX)* deltaX;
30 qreal x = (point.x() - m_minX)* deltaX;
31 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
31 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
32 return QPointF(x,y);
32 return QPointF(x,y);
33 }
33 }
34
34
35
35
36 QPointF XYChartItem::calculateGeometryPoint(int index) const
36 QPointF XYChartItem::calculateGeometryPoint(int index) const
37 {
37 {
38 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
38 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
39 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
39 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
40 qreal x = (m_series->x(index) - m_minX)* deltaX;
40 qreal x = (m_series->x(index) - m_minX)* deltaX;
41 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
41 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
42 return QPointF(x,y);
42 return QPointF(x,y);
43 }
43 }
44
44
45 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
45 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
46 {
46 {
47 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
47 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
48 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
48 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
49
49
50 QVector<QPointF> points;
50 QVector<QPointF> points;
51 points.reserve(m_series->count());
51 points.reserve(m_series->count());
52 for (int i = 0; i < m_series->count(); ++i) {
52 for (int i = 0; i < m_series->count(); ++i) {
53 qreal x = (m_series->x(i) - m_minX)* deltaX;
53 qreal x = (m_series->x(i) - m_minX)* deltaX;
54 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
54 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
55 points << QPointF(x,y);
55 points << QPointF(x,y);
56 }
56 }
57 return points;
57 return points;
58 }
58 }
59
59
60 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
60 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
61 {
61 {
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
64 qreal x = point.x()/deltaX +m_minX;
64 qreal x = point.x()/deltaX +m_minX;
65 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
65 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
66 return QPointF(x,y);
66 return QPointF(x,y);
67 }
67 }
68
68
69 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
69 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
70 {
70 {
71 if (animator()) {
71 if (animator()) {
72 animator()->updateLayout(this,oldPoints,newPoints,index);
72 animator()->updateLayout(this,oldPoints,newPoints,index);
73 } else {
73 } else {
74 setLayout(newPoints);
74 setLayout(newPoints);
75 }
75 }
76 }
76 }
77
77
78 void XYChartItem::setLayout(QVector<QPointF> &points)
78 void XYChartItem::setLayout(QVector<QPointF> &points)
79 {
79 {
80 m_points = points;
80 m_points = points;
81 update();
81 update();
82 }
82 }
83
83
84 //handlers
84 //handlers
85
85
86 void XYChartItem::handlePointAdded(int index)
86 void XYChartItem::handlePointAdded(int index)
87 {
87 {
88 Q_ASSERT(index<m_series->count());
88 Q_ASSERT(index<m_series->count());
89 Q_ASSERT(index>=0);
89 Q_ASSERT(index>=0);
90 QPointF point = calculateGeometryPoint(index);
90 QPointF point = calculateGeometryPoint(index);
91 QVector<QPointF> points = m_points;
91 QVector<QPointF> points = m_points;
92 points.insert(index,point);
92 points.insert(index,point);
93 updateLayout(m_points,points,index);
93 updateLayout(m_points,points,index);
94 update();
94 update();
95 }
95 }
96 void XYChartItem::handlePointRemoved(int index)
96 void XYChartItem::handlePointRemoved(int index)
97 {
97 {
98 Q_ASSERT(index<m_series->count() + 1);
98 Q_ASSERT(index<m_series->count() + 1);
99 Q_ASSERT(index>=0);
99 Q_ASSERT(index>=0);
100 QVector<QPointF> points = m_points;
100 QVector<QPointF> points = m_points;
101 points.remove(index);
101 points.remove(index);
102 updateLayout(m_points,points,index);
102 updateLayout(m_points,points,index);
103 update();
103 update();
104 }
104 }
105
105
106 void XYChartItem::handlePointReplaced(int index)
106 void XYChartItem::handlePointReplaced(int index)
107 {
107 {
108 Q_ASSERT(index<m_series->count());
108 Q_ASSERT(index<m_series->count());
109 Q_ASSERT(index>=0);
109 Q_ASSERT(index>=0);
110 QPointF point = calculateGeometryPoint(index);
110 QPointF point = calculateGeometryPoint(index);
111 QVector<QPointF> points = m_points;
111 QVector<QPointF> points = m_points;
112 points.replace(index,point);
112 points.replace(index,point);
113 updateLayout(m_points,points,index);
113 updateLayout(m_points,points,index);
114 update();
114 update();
115 }
115 }
116
116
117 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
117 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
118 {
118 {
119 m_minX=minX;
119 m_minX=minX;
120 m_maxX=maxX;
120 m_maxX=maxX;
121 m_minY=minY;
121 m_minY=minY;
122 m_maxY=maxY;
122 m_maxY=maxY;
123
123
124 if (isEmpty()) return;
124 if (isEmpty()) return;
125 QVector<QPointF> points = calculateGeometryPoints();
125 QVector<QPointF> points = calculateGeometryPoints();
126 updateLayout(m_points,points);
126 updateLayout(m_points,points);
127 update();
127 update();
128 }
128 }
129
129
130 void XYChartItem::handleGeometryChanged(const QRectF &rect)
130 void XYChartItem::handleGeometryChanged(const QRectF &rect)
131 {
131 {
132 Q_ASSERT(rect.isValid());
132 Q_ASSERT(rect.isValid());
133 m_size=rect.size();
133 m_size=rect.size();
134 m_clipRect=rect.translated(-rect.topLeft());
134 m_clipRect=rect.translated(-rect.topLeft());
135 setPos(rect.topLeft());
135 setPos(rect.topLeft());
136
136
137 if (isEmpty()) return;
137 if (isEmpty()) return;
138 QVector<QPointF> points = calculateGeometryPoints();
138 QVector<QPointF> points = calculateGeometryPoints();
139 updateLayout(m_points,points);
139 updateLayout(m_points,points);
140 update();
140 update();
141 }
141 }
142
142
143
143
144 bool XYChartItem::isEmpty()
144 bool XYChartItem::isEmpty()
145 {
145 {
146 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
146 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
147 }
147 }
148
148
149 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
149 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
150 {
150 {
151 emit clicked(calculateDomainPoint(event->pos()));
151 emit clicked(calculateDomainPoint(event->pos()));
152 }
152 }
153
153
154 #include "moc_xychartitem_p.cpp"
154 #include "moc_xychartitem_p.cpp"
155
155
156 QTCOMMERCIALCHART_END_NAMESPACE
156 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,579 +1,579
1 #include <QtTest/QtTest>
1 #include <QtTest/QtTest>
2 #include <private/domain_p.h>
2 #include <private/domain_p.h>
3 #include <qchartaxis.h>
3 #include <qchartaxis.h>
4
4
5 QTCOMMERCIALCHART_USE_NAMESPACE
5 QTCOMMERCIALCHART_USE_NAMESPACE
6
6
7 Q_DECLARE_METATYPE(Domain*)
7 Q_DECLARE_METATYPE(Domain*)
8 Q_DECLARE_METATYPE(QSizeF)
8 Q_DECLARE_METATYPE(QSizeF)
9
9
10 class tst_Domain : public QObject
10 class tst_Domain : public QObject
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13
13
14 public slots:
14 public slots:
15 void initTestCase();
15 void initTestCase();
16 void cleanupTestCase();
16 void cleanupTestCase();
17 void init();
17 void init();
18 void cleanup();
18 void cleanup();
19
19
20 private slots:
20 private slots:
21 void domain();
21 void domain();
22 void handleAxisRangeXChanged_data();
22 void handleAxisRangeXChanged_data();
23 void handleAxisRangeXChanged();
23 void handleAxisRangeXChanged();
24 void handleAxisRangeYChanged_data();
24 void handleAxisRangeYChanged_data();
25 void handleAxisRangeYChanged();
25 void handleAxisRangeYChanged();
26 void isEmpty_data();
26 void isEmpty_data();
27 void isEmpty();
27 void isEmpty();
28 void maxX_data();
28 void maxX_data();
29 void maxX();
29 void maxX();
30 void maxY_data();
30 void maxY_data();
31 void maxY();
31 void maxY();
32 void minX_data();
32 void minX_data();
33 void minX();
33 void minX();
34 void minY_data();
34 void minY_data();
35 void minY();
35 void minY();
36 void operatorEquals_data();
36 void operatorEquals_data();
37 void operatorEquals();
37 void operatorEquals();
38 void setRange_data();
38 void setRange_data();
39 void setRange();
39 void setRange();
40 void setRangeX_data();
40 void setRangeX_data();
41 void setRangeX();
41 void setRangeX();
42 void setRangeY_data();
42 void setRangeY_data();
43 void setRangeY();
43 void setRangeY();
44 void spanX_data();
44 void spanX_data();
45 void spanX();
45 void spanX();
46 void spanY_data();
46 void spanY_data();
47 void spanY();
47 void spanY();
48 void zoom_data();
48 void zoom_data();
49 void zoom();
49 void zoom();
50 };
50 };
51
51
52 void tst_Domain::initTestCase()
52 void tst_Domain::initTestCase()
53 {
53 {
54 }
54 }
55
55
56 void tst_Domain::cleanupTestCase()
56 void tst_Domain::cleanupTestCase()
57 {
57 {
58 }
58 }
59
59
60 void tst_Domain::init()
60 void tst_Domain::init()
61 {
61 {
62 }
62 }
63
63
64 void tst_Domain::cleanup()
64 void tst_Domain::cleanup()
65 {
65 {
66 }
66 }
67
67
68 void tst_Domain::domain()
68 void tst_Domain::domain()
69 {
69 {
70 Domain domain;
70 Domain domain;
71
71
72 QCOMPARE(domain.isEmpty(), true);
72 QCOMPARE(domain.isEmpty(), true);
73 QCOMPARE(domain.maxX(), 0.0);
73 QCOMPARE(domain.maxX(), 0.0);
74 QCOMPARE(domain.maxY(), 0.0);
74 QCOMPARE(domain.maxY(), 0.0);
75 QCOMPARE(domain.minX(), 0.0);
75 QCOMPARE(domain.minX(), 0.0);
76 QCOMPARE(domain.minY(), 0.0);
76 QCOMPARE(domain.minY(), 0.0);
77 }
77 }
78
78
79 void tst_Domain::handleAxisRangeXChanged_data()
79 void tst_Domain::handleAxisRangeXChanged_data()
80 {
80 {
81 QTest::addColumn<qreal>("min");
81 QTest::addColumn<qreal>("min");
82 QTest::addColumn<qreal>("max");
82 QTest::addColumn<qreal>("max");
83 QTest::newRow("-1 1") << -1.0 << 1.0;
83 QTest::newRow("-1 1") << -1.0 << 1.0;
84 QTest::newRow("0 1") << 0.0 << 1.0;
84 QTest::newRow("0 1") << 0.0 << 1.0;
85 QTest::newRow("-1 0") << -1.0 << 0.0;
85 QTest::newRow("-1 0") << -1.0 << 0.0;
86 }
86 }
87
87
88 void tst_Domain::handleAxisRangeXChanged()
88 void tst_Domain::handleAxisRangeXChanged()
89 {
89 {
90 QFETCH(qreal, min);
90 QFETCH(qreal, min);
91 QFETCH(qreal, max);
91 QFETCH(qreal, max);
92
92
93 Domain domain;
93 Domain domain;
94
94
95 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
95 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
96 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
96 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
97 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
97 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
98
98
99 domain.handleAxisXChanged(min, max);
99 domain.handleAxisXChanged(min, max);
100
100
101 QList<QVariant> arg0 = spy0.first();
101 QList<QVariant> arg0 = spy0.first();
102 QVERIFY(arg0.at(0).toReal() == min);
102 QVERIFY(qFuzzyIsNull(arg0.at(0).toReal() - min));
103 QVERIFY(arg0.at(1).toReal() == max);
103 QVERIFY(qFuzzyIsNull(arg0.at(1).toReal() - max));
104
104
105 QList<QVariant> arg1 = spy1.first();
105 QList<QVariant> arg1 = spy1.first();
106 QVERIFY(arg1.at(0).toReal() == min);
106 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
107 QVERIFY(arg1.at(1).toReal() == max);
107 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
108
108
109 QCOMPARE(spy0.count(), 1);
109 QCOMPARE(spy0.count(), 1);
110 QCOMPARE(spy1.count(), 1);
110 QCOMPARE(spy1.count(), 1);
111 QCOMPARE(spy2.count(), 0);
111 QCOMPARE(spy2.count(), 0);
112
112
113 }
113 }
114
114
115 void tst_Domain::handleAxisRangeYChanged_data()
115 void tst_Domain::handleAxisRangeYChanged_data()
116 {
116 {
117 QTest::addColumn<qreal>("min");
117 QTest::addColumn<qreal>("min");
118 QTest::addColumn<qreal>("max");
118 QTest::addColumn<qreal>("max");
119 QTest::newRow("-1 1") << -1.0 << 1.0;
119 QTest::newRow("-1 1") << -1.0 << 1.0;
120 QTest::newRow("0 1") << 0.0 << 1.0;
120 QTest::newRow("0 1") << 0.0 << 1.0;
121 QTest::newRow("-1 0") << -1.0 << 0.0;
121 QTest::newRow("-1 0") << -1.0 << 0.0;
122 }
122 }
123
123
124
124
125 void tst_Domain::handleAxisRangeYChanged()
125 void tst_Domain::handleAxisRangeYChanged()
126 {
126 {
127 QFETCH(qreal, min);
127 QFETCH(qreal, min);
128 QFETCH(qreal, max);
128 QFETCH(qreal, max);
129
129
130 Domain domain;
130 Domain domain;
131
131
132 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
132 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
133 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
133 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
134 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
134 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
135
135
136 domain.handleAxisYChanged(min, max,5);
136 domain.handleAxisYChanged(min, max,5);
137
137
138 QList<QVariant> arg0 = spy0.first();
138 QList<QVariant> arg0 = spy0.first();
139 QVERIFY(arg0.at(2).toReal() == min);
139 QVERIFY(qFuzzyIsNull(arg0.at(2).toReal() - min));
140 QVERIFY(arg0.at(3).toReal() == max);
140 QVERIFY(qFuzzyIsNull(arg0.at(3).toReal() - max));
141
141
142 QList<QVariant> arg1 = spy2.first();
142 QList<QVariant> arg1 = spy2.first();
143 QVERIFY(arg1.at(0).toReal() == min);
143 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
144 QVERIFY(arg1.at(1).toReal() == max);
144 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
145
145
146 QCOMPARE(spy0.count(), 1);
146 QCOMPARE(spy0.count(), 1);
147 QCOMPARE(spy1.count(), 0);
147 QCOMPARE(spy1.count(), 0);
148 QCOMPARE(spy2.count(), 1);
148 QCOMPARE(spy2.count(), 1);
149 }
149 }
150
150
151 void tst_Domain::isEmpty_data()
151 void tst_Domain::isEmpty_data()
152 {
152 {
153 QTest::addColumn<qreal>("minX");
153 QTest::addColumn<qreal>("minX");
154 QTest::addColumn<qreal>("maxX");
154 QTest::addColumn<qreal>("maxX");
155 QTest::addColumn<qreal>("minY");
155 QTest::addColumn<qreal>("minY");
156 QTest::addColumn<qreal>("maxY");
156 QTest::addColumn<qreal>("maxY");
157 QTest::addColumn<bool>("isEmpty");
157 QTest::addColumn<bool>("isEmpty");
158 QTest::newRow("0 0 0 0") << 0.0 << 0.0 << 0.0 << 0.0 << true;
158 QTest::newRow("0 0 0 0") << 0.0 << 0.0 << 0.0 << 0.0 << true;
159 QTest::newRow("0 1 0 0") << 0.0 << 1.0 << 0.0 << 0.0 << true;
159 QTest::newRow("0 1 0 0") << 0.0 << 1.0 << 0.0 << 0.0 << true;
160 QTest::newRow("0 0 0 1") << 0.0 << 1.0 << 0.0 << 0.0 << true;
160 QTest::newRow("0 0 0 1") << 0.0 << 1.0 << 0.0 << 0.0 << true;
161 QTest::newRow("0 1 0 1") << 0.0 << 1.0 << 0.0 << 1.0 << false;
161 QTest::newRow("0 1 0 1") << 0.0 << 1.0 << 0.0 << 1.0 << false;
162 }
162 }
163
163
164 void tst_Domain::isEmpty()
164 void tst_Domain::isEmpty()
165 {
165 {
166 QFETCH(qreal, minX);
166 QFETCH(qreal, minX);
167 QFETCH(qreal, maxX);
167 QFETCH(qreal, maxX);
168 QFETCH(qreal, minY);
168 QFETCH(qreal, minY);
169 QFETCH(qreal, maxY);
169 QFETCH(qreal, maxY);
170 QFETCH(bool, isEmpty);
170 QFETCH(bool, isEmpty);
171
171
172 Domain domain;
172 Domain domain;
173 domain.setRange(minX,maxX,minY,maxY);
173 domain.setRange(minX,maxX,minY,maxY);
174 QCOMPARE(domain.isEmpty(), isEmpty);
174 QCOMPARE(domain.isEmpty(), isEmpty);
175 }
175 }
176
176
177 void tst_Domain::maxX_data()
177 void tst_Domain::maxX_data()
178 {
178 {
179 QTest::addColumn<qreal>("maxX1");
179 QTest::addColumn<qreal>("maxX1");
180 QTest::addColumn<qreal>("maxX2");
180 QTest::addColumn<qreal>("maxX2");
181 QTest::addColumn<int>("count");
181 QTest::addColumn<int>("count");
182 QTest::newRow("1") << 0.0 << 1.0 << 1;
182 QTest::newRow("1") << 0.0 << 1.0 << 1;
183 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
183 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
184 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
184 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
185 }
185 }
186
186
187 void tst_Domain::maxX()
187 void tst_Domain::maxX()
188 {
188 {
189 QFETCH(qreal, maxX1);
189 QFETCH(qreal, maxX1);
190 QFETCH(qreal, maxX2);
190 QFETCH(qreal, maxX2);
191 QFETCH(int, count);
191 QFETCH(int, count);
192
192
193 Domain domain;
193 Domain domain;
194
194
195 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
195 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
196 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
196 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
197 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
197 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
198
198
199 domain.setMaxX(maxX1);
199 domain.setMaxX(maxX1);
200 QCOMPARE(domain.maxX(), maxX1);
200 QCOMPARE(domain.maxX(), maxX1);
201 domain.setMaxX(maxX2);
201 domain.setMaxX(maxX2);
202 QCOMPARE(domain.maxX(), maxX2);
202 QCOMPARE(domain.maxX(), maxX2);
203
203
204
204
205 QCOMPARE(spy0.count(), count);
205 QCOMPARE(spy0.count(), count);
206 QCOMPARE(spy1.count(), count);
206 QCOMPARE(spy1.count(), count);
207 QCOMPARE(spy2.count(), 0);
207 QCOMPARE(spy2.count(), 0);
208
208
209 }
209 }
210
210
211 void tst_Domain::maxY_data()
211 void tst_Domain::maxY_data()
212 {
212 {
213 QTest::addColumn<qreal>("maxY1");
213 QTest::addColumn<qreal>("maxY1");
214 QTest::addColumn<qreal>("maxY2");
214 QTest::addColumn<qreal>("maxY2");
215 QTest::addColumn<int>("count");
215 QTest::addColumn<int>("count");
216 QTest::newRow("1") << 0.0 << 1.0 << 1;
216 QTest::newRow("1") << 0.0 << 1.0 << 1;
217 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
217 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
218 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
218 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
219 }
219 }
220
220
221
221
222 void tst_Domain::maxY()
222 void tst_Domain::maxY()
223 {
223 {
224 QFETCH(qreal, maxY1);
224 QFETCH(qreal, maxY1);
225 QFETCH(qreal, maxY2);
225 QFETCH(qreal, maxY2);
226 QFETCH(int, count);
226 QFETCH(int, count);
227
227
228 Domain domain;
228 Domain domain;
229
229
230 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
230 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
231 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
231 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
232 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
232 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
233
233
234 domain.setMaxY(maxY1);
234 domain.setMaxY(maxY1);
235 QCOMPARE(domain.maxY(), maxY1);
235 QCOMPARE(domain.maxY(), maxY1);
236 domain.setMaxY(maxY2);
236 domain.setMaxY(maxY2);
237 QCOMPARE(domain.maxY(), maxY2);
237 QCOMPARE(domain.maxY(), maxY2);
238
238
239 QCOMPARE(spy0.count(), count);
239 QCOMPARE(spy0.count(), count);
240 QCOMPARE(spy1.count(), 0);
240 QCOMPARE(spy1.count(), 0);
241 QCOMPARE(spy2.count(), count);
241 QCOMPARE(spy2.count(), count);
242 }
242 }
243
243
244 void tst_Domain::minX_data()
244 void tst_Domain::minX_data()
245 {
245 {
246 QTest::addColumn<qreal>("minX1");
246 QTest::addColumn<qreal>("minX1");
247 QTest::addColumn<qreal>("minX2");
247 QTest::addColumn<qreal>("minX2");
248 QTest::addColumn<int>("count");
248 QTest::addColumn<int>("count");
249 QTest::newRow("1") << 0.0 << 1.0 << 1;
249 QTest::newRow("1") << 0.0 << 1.0 << 1;
250 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
250 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
251 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
251 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
252 }
252 }
253
253
254
254
255 void tst_Domain::minX()
255 void tst_Domain::minX()
256 {
256 {
257 QFETCH(qreal, minX1);
257 QFETCH(qreal, minX1);
258 QFETCH(qreal, minX2);
258 QFETCH(qreal, minX2);
259 QFETCH(int, count);
259 QFETCH(int, count);
260
260
261 Domain domain;
261 Domain domain;
262
262
263 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
263 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
264 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
264 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
265 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
265 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
266
266
267 domain.setMinX(minX1);
267 domain.setMinX(minX1);
268 QCOMPARE(domain.minX(), minX1);
268 QCOMPARE(domain.minX(), minX1);
269 domain.setMinX(minX2);
269 domain.setMinX(minX2);
270 QCOMPARE(domain.minX(), minX2);
270 QCOMPARE(domain.minX(), minX2);
271
271
272 QCOMPARE(spy0.count(), count);
272 QCOMPARE(spy0.count(), count);
273 QCOMPARE(spy1.count(), count);
273 QCOMPARE(spy1.count(), count);
274 QCOMPARE(spy2.count(), 0);
274 QCOMPARE(spy2.count(), 0);
275 }
275 }
276
276
277 void tst_Domain::minY_data()
277 void tst_Domain::minY_data()
278 {
278 {
279 QTest::addColumn<qreal>("minY1");
279 QTest::addColumn<qreal>("minY1");
280 QTest::addColumn<qreal>("minY2");
280 QTest::addColumn<qreal>("minY2");
281 QTest::addColumn<int>("count");
281 QTest::addColumn<int>("count");
282 QTest::newRow("1") << 0.0 << 1.0 << 1;
282 QTest::newRow("1") << 0.0 << 1.0 << 1;
283 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
283 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
284 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
284 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
285 }
285 }
286
286
287 void tst_Domain::minY()
287 void tst_Domain::minY()
288 {
288 {
289 QFETCH(qreal, minY1);
289 QFETCH(qreal, minY1);
290 QFETCH(qreal, minY2);
290 QFETCH(qreal, minY2);
291 QFETCH(int, count);
291 QFETCH(int, count);
292
292
293 Domain domain;
293 Domain domain;
294
294
295 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
295 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
296 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
296 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
297 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
297 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
298
298
299 domain.setMinY(minY1);
299 domain.setMinY(minY1);
300 QCOMPARE(domain.minY(), minY1);
300 QCOMPARE(domain.minY(), minY1);
301 domain.setMinY(minY2);
301 domain.setMinY(minY2);
302 QCOMPARE(domain.minY(), minY2);
302 QCOMPARE(domain.minY(), minY2);
303
303
304 QCOMPARE(spy0.count(), count);
304 QCOMPARE(spy0.count(), count);
305 QCOMPARE(spy1.count(), 0);
305 QCOMPARE(spy1.count(), 0);
306 QCOMPARE(spy2.count(), count);
306 QCOMPARE(spy2.count(), count);
307 }
307 }
308
308
309 void tst_Domain::operatorEquals_data()
309 void tst_Domain::operatorEquals_data()
310 {
310 {
311
311
312 QTest::addColumn<Domain*>("domain1");
312 QTest::addColumn<Domain*>("domain1");
313 QTest::addColumn<Domain*>("domain2");
313 QTest::addColumn<Domain*>("domain2");
314 QTest::addColumn<bool>("equals");
314 QTest::addColumn<bool>("equals");
315 QTest::addColumn<bool>("notEquals");
315 QTest::addColumn<bool>("notEquals");
316 Domain* a;
316 Domain* a;
317 Domain* b;
317 Domain* b;
318 a = new Domain();
318 a = new Domain();
319 a->setRange(0,100,0,100);
319 a->setRange(0,100,0,100);
320 b = new Domain();
320 b = new Domain();
321 b->setRange(0,100,0,100);
321 b->setRange(0,100,0,100);
322 QTest::newRow("equals") << a << b << true <<false;
322 QTest::newRow("equals") << a << b << true <<false;
323 a = new Domain();
323 a = new Domain();
324 a->setRange(0,100,0,100);
324 a->setRange(0,100,0,100);
325 b = new Domain();
325 b = new Domain();
326 b->setRange(0,100,0,1);
326 b->setRange(0,100,0,1);
327 QTest::newRow("equals") << a << b << false << true;
327 QTest::newRow("equals") << a << b << false << true;
328 a = new Domain();
328 a = new Domain();
329 a->setRange(0,100,0,100);
329 a->setRange(0,100,0,100);
330 b = new Domain();
330 b = new Domain();
331 b->setRange(0,1,0,100);
331 b->setRange(0,1,0,100);
332 QTest::newRow("equals") << a << b << false << true;
332 QTest::newRow("equals") << a << b << false << true;
333
333
334 }
334 }
335
335
336 void tst_Domain::operatorEquals()
336 void tst_Domain::operatorEquals()
337 {
337 {
338 QFETCH(Domain*, domain1);
338 QFETCH(Domain*, domain1);
339 QFETCH(Domain*, domain2);
339 QFETCH(Domain*, domain2);
340 QFETCH(bool, equals);
340 QFETCH(bool, equals);
341 QFETCH(bool, notEquals);
341 QFETCH(bool, notEquals);
342
342
343 Domain domain;
343 Domain domain;
344
344
345 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
345 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
346 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
346 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
347 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
347 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
348
348
349 QCOMPARE(*domain1==*domain2, equals);
349 QCOMPARE(*domain1==*domain2, equals);
350 QCOMPARE(*domain1!=*domain2, notEquals);
350 QCOMPARE(*domain1!=*domain2, notEquals);
351
351
352 QCOMPARE(spy0.count(), 0);
352 QCOMPARE(spy0.count(), 0);
353 QCOMPARE(spy1.count(), 0);
353 QCOMPARE(spy1.count(), 0);
354 QCOMPARE(spy2.count(), 0);
354 QCOMPARE(spy2.count(), 0);
355 }
355 }
356
356
357 void tst_Domain::setRange_data()
357 void tst_Domain::setRange_data()
358 {
358 {
359 QTest::addColumn<qreal>("minX");
359 QTest::addColumn<qreal>("minX");
360 QTest::addColumn<qreal>("maxX");
360 QTest::addColumn<qreal>("maxX");
361 QTest::addColumn<qreal>("minY");
361 QTest::addColumn<qreal>("minY");
362 QTest::addColumn<qreal>("maxY");
362 QTest::addColumn<qreal>("maxY");
363 QTest::newRow("1,2,1,2") << 1.0 << 2.0 << 1.0 << 2.0;
363 QTest::newRow("1,2,1,2") << 1.0 << 2.0 << 1.0 << 2.0;
364 QTest::newRow("1,3,1,3") << 1.0 << 3.0 << 1.0 << 3.0;
364 QTest::newRow("1,3,1,3") << 1.0 << 3.0 << 1.0 << 3.0;
365 QTest::newRow("-1,5,-2,-1") << -1.0 << 5.0 << -2.0 << -1.0;
365 QTest::newRow("-1,5,-2,-1") << -1.0 << 5.0 << -2.0 << -1.0;
366 }
366 }
367
367
368 void tst_Domain::setRange()
368 void tst_Domain::setRange()
369 {
369 {
370 QFETCH(qreal, minX);
370 QFETCH(qreal, minX);
371 QFETCH(qreal, maxX);
371 QFETCH(qreal, maxX);
372 QFETCH(qreal, minY);
372 QFETCH(qreal, minY);
373 QFETCH(qreal, maxY);
373 QFETCH(qreal, maxY);
374
374
375 Domain domain;
375 Domain domain;
376
376
377 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
377 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
378 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
378 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
379 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
379 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
380
380
381 domain.setRange(minX, maxX, minY, maxY);
381 domain.setRange(minX, maxX, minY, maxY);
382
382
383 QCOMPARE(domain.minX(), minX);
383 QCOMPARE(domain.minX(), minX);
384 QCOMPARE(domain.maxX(), maxX);
384 QCOMPARE(domain.maxX(), maxX);
385 QCOMPARE(domain.minY(), minY);
385 QCOMPARE(domain.minY(), minY);
386 QCOMPARE(domain.maxY(), maxY);
386 QCOMPARE(domain.maxY(), maxY);
387
387
388 QCOMPARE(spy0.count(), 1);
388 QCOMPARE(spy0.count(), 1);
389 QCOMPARE(spy1.count(), 1);
389 QCOMPARE(spy1.count(), 1);
390 QCOMPARE(spy2.count(), 1);
390 QCOMPARE(spy2.count(), 1);
391
391
392
392
393 }
393 }
394
394
395 void tst_Domain::setRangeX_data()
395 void tst_Domain::setRangeX_data()
396 {
396 {
397 QTest::addColumn<qreal>("min");
397 QTest::addColumn<qreal>("min");
398 QTest::addColumn<qreal>("max");
398 QTest::addColumn<qreal>("max");
399 QTest::newRow("-1 1") << -1.0 << 1.0;
399 QTest::newRow("-1 1") << -1.0 << 1.0;
400 QTest::newRow("0 1") << 0.0 << 1.0;
400 QTest::newRow("0 1") << 0.0 << 1.0;
401 QTest::newRow("-1 0") << -1.0 << 0.0;
401 QTest::newRow("-1 0") << -1.0 << 0.0;
402 }
402 }
403
403
404 void tst_Domain::setRangeX()
404 void tst_Domain::setRangeX()
405 {
405 {
406 QFETCH(qreal, min);
406 QFETCH(qreal, min);
407 QFETCH(qreal, max);
407 QFETCH(qreal, max);
408
408
409 Domain domain;
409 Domain domain;
410
410
411 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
411 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
412 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
412 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
413 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
413 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
414
414
415 domain.setRangeX(min, max);
415 domain.setRangeX(min, max);
416
416
417 QList<QVariant> arg0 = spy0.first();
417 QList<QVariant> arg0 = spy0.first();
418 QVERIFY(arg0.at(0).toReal() == min);
418 QVERIFY(qFuzzyIsNull(arg0.at(0).toReal() - min));
419 QVERIFY(arg0.at(1).toReal() == max);
419 QVERIFY(qFuzzyIsNull(arg0.at(1).toReal() - max));
420
420
421 QList<QVariant> arg1 = spy1.first();
421 QList<QVariant> arg1 = spy1.first();
422 QVERIFY(arg1.at(0).toReal() == min);
422 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
423 QVERIFY(arg1.at(1).toReal() == max);
423 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
424
424
425 QCOMPARE(spy0.count(), 1);
425 QCOMPARE(spy0.count(), 1);
426 QCOMPARE(spy1.count(), 1);
426 QCOMPARE(spy1.count(), 1);
427 QCOMPARE(spy2.count(), 0);
427 QCOMPARE(spy2.count(), 0);
428 }
428 }
429
429
430 void tst_Domain::setRangeY_data()
430 void tst_Domain::setRangeY_data()
431 {
431 {
432 QTest::addColumn<qreal>("min");
432 QTest::addColumn<qreal>("min");
433 QTest::addColumn<qreal>("max");
433 QTest::addColumn<qreal>("max");
434 QTest::newRow("-1 1") << -1.0 << 1.0;
434 QTest::newRow("-1 1") << -1.0 << 1.0;
435 QTest::newRow("0 1") << 0.0 << 1.0;
435 QTest::newRow("0 1") << 0.0 << 1.0;
436 QTest::newRow("-1 0") << -1.0 << 0.0;
436 QTest::newRow("-1 0") << -1.0 << 0.0;
437 }
437 }
438
438
439 void tst_Domain::setRangeY()
439 void tst_Domain::setRangeY()
440 {
440 {
441 QFETCH(qreal, min);
441 QFETCH(qreal, min);
442 QFETCH(qreal, max);
442 QFETCH(qreal, max);
443
443
444 Domain domain;
444 Domain domain;
445
445
446 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
446 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
447 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
447 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
448 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
448 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
449
449
450 domain.setRangeY(min, max);
450 domain.setRangeY(min, max);
451
451
452 QList<QVariant> arg0 = spy0.first();
452 QList<QVariant> arg0 = spy0.first();
453 QVERIFY(arg0.at(2).toReal() == min);
453 QVERIFY(qFuzzyIsNull(arg0.at(2).toReal() - min));
454 QVERIFY(arg0.at(3).toReal() == max);
454 QVERIFY(qFuzzyIsNull(arg0.at(3).toReal() - max));
455
455
456 QList<QVariant> arg1 = spy2.first();
456 QList<QVariant> arg1 = spy2.first();
457 QVERIFY(arg1.at(0).toReal() == min);
457 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
458 QVERIFY(arg1.at(1).toReal() == max);
458 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
459
459
460 QCOMPARE(spy0.count(), 1);
460 QCOMPARE(spy0.count(), 1);
461 QCOMPARE(spy1.count(), 0);
461 QCOMPARE(spy1.count(), 0);
462 QCOMPARE(spy2.count(), 1);
462 QCOMPARE(spy2.count(), 1);
463 }
463 }
464
464
465 void tst_Domain::spanX_data()
465 void tst_Domain::spanX_data()
466 {
466 {
467 QTest::addColumn<qreal>("minX");
467 QTest::addColumn<qreal>("minX");
468 QTest::addColumn<qreal>("maxX");
468 QTest::addColumn<qreal>("maxX");
469 QTest::addColumn<qreal>("spanX");
469 QTest::addColumn<qreal>("spanX");
470 QTest::newRow("1 2 1") << 1.0 << 2.0 << 1.0;
470 QTest::newRow("1 2 1") << 1.0 << 2.0 << 1.0;
471 QTest::newRow("0 2 2") << 1.0 << 2.0 << 1.0;
471 QTest::newRow("0 2 2") << 1.0 << 2.0 << 1.0;
472 }
472 }
473
473
474 void tst_Domain::spanX()
474 void tst_Domain::spanX()
475 {
475 {
476 QFETCH(qreal, minX);
476 QFETCH(qreal, minX);
477 QFETCH(qreal, maxX);
477 QFETCH(qreal, maxX);
478 QFETCH(qreal, spanX);
478 QFETCH(qreal, spanX);
479
479
480 Domain domain;
480 Domain domain;
481
481
482 domain.setRangeX(minX,maxX);
482 domain.setRangeX(minX,maxX);
483
483
484 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
484 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
485 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
485 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
486 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
486 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
487
487
488 QCOMPARE(domain.spanX(), spanX);
488 QCOMPARE(domain.spanX(), spanX);
489
489
490 QCOMPARE(spy0.count(), 0);
490 QCOMPARE(spy0.count(), 0);
491 QCOMPARE(spy1.count(), 0);
491 QCOMPARE(spy1.count(), 0);
492 QCOMPARE(spy2.count(), 0);
492 QCOMPARE(spy2.count(), 0);
493 }
493 }
494
494
495 void tst_Domain::spanY_data()
495 void tst_Domain::spanY_data()
496 {
496 {
497 QTest::addColumn<qreal>("minY");
497 QTest::addColumn<qreal>("minY");
498 QTest::addColumn<qreal>("maxY");
498 QTest::addColumn<qreal>("maxY");
499 QTest::addColumn<qreal>("spanY");
499 QTest::addColumn<qreal>("spanY");
500 QTest::newRow("1 2 1") << 1.0 << 2.0 << 1.0;
500 QTest::newRow("1 2 1") << 1.0 << 2.0 << 1.0;
501 QTest::newRow("0 2 2") << 1.0 << 2.0 << 1.0;
501 QTest::newRow("0 2 2") << 1.0 << 2.0 << 1.0;
502 }
502 }
503
503
504 void tst_Domain::spanY()
504 void tst_Domain::spanY()
505 {
505 {
506 QFETCH(qreal, minY);
506 QFETCH(qreal, minY);
507 QFETCH(qreal, maxY);
507 QFETCH(qreal, maxY);
508 QFETCH(qreal, spanY);
508 QFETCH(qreal, spanY);
509
509
510 Domain domain;
510 Domain domain;
511
511
512 domain.setRangeY(minY,maxY);
512 domain.setRangeY(minY,maxY);
513
513
514 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
514 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
515 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
515 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
516 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
516 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
517
517
518 QCOMPARE(domain.spanY(), spanY);
518 QCOMPARE(domain.spanY(), spanY);
519
519
520 QCOMPARE(spy0.count(), 0);
520 QCOMPARE(spy0.count(), 0);
521 QCOMPARE(spy1.count(), 0);
521 QCOMPARE(spy1.count(), 0);
522 QCOMPARE(spy2.count(), 0);
522 QCOMPARE(spy2.count(), 0);
523 }
523 }
524
524
525
525
526 void tst_Domain::zoom_data()
526 void tst_Domain::zoom_data()
527 {
527 {
528 QTest::addColumn<QRectF>("rect0");
528 QTest::addColumn<QRectF>("rect0");
529 QTest::addColumn<QSizeF>("size0");
529 QTest::addColumn<QSizeF>("size0");
530 QTest::addColumn<QRectF>("rect1");
530 QTest::addColumn<QRectF>("rect1");
531 QTest::addColumn<QSizeF>("size1");
531 QTest::addColumn<QSizeF>("size1");
532 QTest::addColumn<QRectF>("rect2");
532 QTest::addColumn<QRectF>("rect2");
533 QTest::addColumn<QSizeF>("size2");
533 QTest::addColumn<QSizeF>("size2");
534 QTest::newRow("first") << QRectF(10,10,100,100) << QSizeF(1000,1000) << QRectF(20,20,100,100) << QSizeF(1000,1000) << QRectF(50,50,100,100) << QSizeF(1000,1000);
534 QTest::newRow("first") << QRectF(10,10,100,100) << QSizeF(1000,1000) << QRectF(20,20,100,100) << QSizeF(1000,1000) << QRectF(50,50,100,100) << QSizeF(1000,1000);
535 QTest::newRow("scound") << QRectF(10,10,50,50) << QSizeF(1000,1000) << QRectF(20,20,100,100) << QSizeF(1000,1000) << QRectF(50,50,100,100) << QSizeF(1000,1000);
535 QTest::newRow("scound") << QRectF(10,10,50,50) << QSizeF(1000,1000) << QRectF(20,20,100,100) << QSizeF(1000,1000) << QRectF(50,50,100,100) << QSizeF(1000,1000);
536 QTest::newRow("third") << QRectF(10,10,10,10) << QSizeF(100,100) << QRectF(20,20,20,20) << QSizeF(100,100) << QRectF(50,50,50,50) << QSizeF(100,100);
536 QTest::newRow("third") << QRectF(10,10,10,10) << QSizeF(100,100) << QRectF(20,20,20,20) << QSizeF(100,100) << QRectF(50,50,50,50) << QSizeF(100,100);
537 }
537 }
538
538
539 void tst_Domain::zoom()
539 void tst_Domain::zoom()
540 {
540 {
541 QFETCH(QRectF, rect0);
541 QFETCH(QRectF, rect0);
542 QFETCH(QSizeF, size0);
542 QFETCH(QSizeF, size0);
543 QFETCH(QRectF, rect1);
543 QFETCH(QRectF, rect1);
544 QFETCH(QSizeF, size1);
544 QFETCH(QSizeF, size1);
545 QFETCH(QRectF, rect2);
545 QFETCH(QRectF, rect2);
546 QFETCH(QSizeF, size2);
546 QFETCH(QSizeF, size2);
547
547
548 Domain domain;
548 Domain domain;
549
549
550 domain.setRange(0,1000,0,1000);
550 domain.setRange(0,1000,0,1000);
551
551
552 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
552 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal, qreal, qreal, qreal)));
553 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
553 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal, qreal)));
554 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
554 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal, qreal)));
555
555
556 Domain domain0;
556 Domain domain0;
557 domain0.setRange(domain.minX(),domain.maxX(),domain.minY(),domain.maxY());
557 domain0.setRange(domain.minX(),domain.maxX(),domain.minY(),domain.maxY());
558 domain.zoomIn(rect0, size0);
558 domain.zoomIn(rect0, size0);
559 Domain domain1;
559 Domain domain1;
560 domain1.setRange(domain.minX(),domain.maxX(),domain.minY(),domain.maxY());
560 domain1.setRange(domain.minX(),domain.maxX(),domain.minY(),domain.maxY());
561 domain.zoomIn(rect1, size1);
561 domain.zoomIn(rect1, size1);
562 Domain domain2;
562 Domain domain2;
563 domain2.setRange(domain.minX(),domain.maxX(),domain.minY(),domain.maxY());
563 domain2.setRange(domain.minX(),domain.maxX(),domain.minY(),domain.maxY());
564 domain.zoomIn(rect2, size2);
564 domain.zoomIn(rect2, size2);
565 domain.zoomOut(rect2, size2);
565 domain.zoomOut(rect2, size2);
566 QCOMPARE(domain == domain2,true);
566 QCOMPARE(domain == domain2,true);
567 domain.zoomOut(rect1, size1);
567 domain.zoomOut(rect1, size1);
568 QCOMPARE(domain == domain1,true);
568 QCOMPARE(domain == domain1,true);
569 domain.zoomOut(rect0, size0);
569 domain.zoomOut(rect0, size0);
570 QCOMPARE(domain == domain0,true);
570 QCOMPARE(domain == domain0,true);
571 QCOMPARE(spy0.count(), 6);
571 QCOMPARE(spy0.count(), 6);
572 QCOMPARE(spy1.count(), 6);
572 QCOMPARE(spy1.count(), 6);
573 QCOMPARE(spy2.count(), 6);
573 QCOMPARE(spy2.count(), 6);
574
574
575 }
575 }
576
576
577 QTEST_MAIN(tst_Domain)
577 QTEST_MAIN(tst_Domain)
578 #include "tst_domain.moc"
578 #include "tst_domain.moc"
579
579
General Comments 0
You need to be logged in to leave comments. Login now