##// END OF EJS Templates
Fixes and improvments to series API...
Michal Klocek -
r1057:d444309c9f1b
parent child
Show More
@@ -1,374 +1,375
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "themewidget.h"
21 #include "themewidget.h"
22
22
23 #include <QChartView>
23 #include <QChartView>
24 #include <QPieSeries>
24 #include <QPieSeries>
25 #include <QPieSlice>
25 #include <QPieSlice>
26 #include <QBarSeries>
26 #include <QBarSeries>
27 #include <QPercentBarSeries>
27 #include <QPercentBarSeries>
28 #include <QStackedBarSeries>
28 #include <QStackedBarSeries>
29 #include <QBarSet>
29 #include <QBarSet>
30 #include <QLineSeries>
30 #include <QLineSeries>
31 #include <QSplineSeries>
31 #include <QSplineSeries>
32 #include <QScatterSeries>
32 #include <QScatterSeries>
33 #include <QAreaSeries>
33 #include <QAreaSeries>
34 #include <QLegend>
34 #include <QLegend>
35 #include <QGridLayout>
35 #include <QGridLayout>
36 #include <QFormLayout>
36 #include <QFormLayout>
37 #include <QComboBox>
37 #include <QComboBox>
38 #include <QSpinBox>
38 #include <QSpinBox>
39 #include <QCheckBox>
39 #include <QCheckBox>
40 #include <QGroupBox>
40 #include <QGroupBox>
41 #include <QLabel>
41 #include <QLabel>
42 #include <QTime>
42 #include <QTime>
43
43
44 ThemeWidget::ThemeWidget(QWidget* parent) :
44 ThemeWidget::ThemeWidget(QWidget* parent) :
45 QWidget(parent),
45 QWidget(parent),
46 m_listCount(3),
46 m_listCount(3),
47 m_valueMax(10),
47 m_valueMax(10),
48 m_valueCount(7),
48 m_valueCount(7),
49 m_dataTable(generateRandomData(m_listCount,m_valueMax,m_valueCount)),
49 m_dataTable(generateRandomData(m_listCount,m_valueMax,m_valueCount)),
50 m_themeComboBox(createThemeBox()),
50 m_themeComboBox(createThemeBox()),
51 m_antialiasCheckBox(new QCheckBox("Anti-aliasing")),
51 m_antialiasCheckBox(new QCheckBox("Anti-aliasing")),
52 m_animatedComboBox(createAnimationBox()),
52 m_animatedComboBox(createAnimationBox()),
53 m_legendComboBox(createLegendBox())
53 m_legendComboBox(createLegendBox())
54 {
54 {
55 connectSignals();
55 connectSignals();
56 // create layout
56 // create layout
57 QGridLayout* baseLayout = new QGridLayout();
57 QGridLayout* baseLayout = new QGridLayout();
58 QHBoxLayout *settingsLayout = new QHBoxLayout();
58 QHBoxLayout *settingsLayout = new QHBoxLayout();
59 settingsLayout->addWidget(new QLabel("Theme:"));
59 settingsLayout->addWidget(new QLabel("Theme:"));
60 settingsLayout->addWidget(m_themeComboBox);
60 settingsLayout->addWidget(m_themeComboBox);
61 settingsLayout->addWidget(new QLabel("Animation:"));
61 settingsLayout->addWidget(new QLabel("Animation:"));
62 settingsLayout->addWidget(m_animatedComboBox);
62 settingsLayout->addWidget(m_animatedComboBox);
63 settingsLayout->addWidget(new QLabel("Legend:"));
63 settingsLayout->addWidget(new QLabel("Legend:"));
64 settingsLayout->addWidget(m_legendComboBox);
64 settingsLayout->addWidget(m_legendComboBox);
65 settingsLayout->addWidget(m_antialiasCheckBox);
65 settingsLayout->addWidget(m_antialiasCheckBox);
66 settingsLayout->addStretch();
66 settingsLayout->addStretch();
67 baseLayout->addLayout(settingsLayout, 0, 0, 1, 3);
67 baseLayout->addLayout(settingsLayout, 0, 0, 1, 3);
68
68
69 //create charts
69 //create charts
70
70
71 QChartView *chartView;
71 QChartView *chartView;
72
72
73 chartView = new QChartView(createAreaChart());
73 chartView = new QChartView(createAreaChart());
74 baseLayout->addWidget(chartView, 1, 0);
74 baseLayout->addWidget(chartView, 1, 0);
75 m_charts << chartView;
75 m_charts << chartView;
76
76
77 chartView = new QChartView(createBarChart(m_valueCount));
77 chartView = new QChartView(createBarChart(m_valueCount));
78 baseLayout->addWidget(chartView, 1, 1);
78 baseLayout->addWidget(chartView, 1, 1);
79 m_charts << chartView;
79 m_charts << chartView;
80
80
81 chartView = new QChartView(createLineChart());
81 chartView = new QChartView(createLineChart());
82 baseLayout->addWidget(chartView, 1, 2);
82 baseLayout->addWidget(chartView, 1, 2);
83 m_charts << chartView;
83 m_charts << chartView;
84
84
85 chartView = new QChartView(createPieChart());
85 chartView = new QChartView(createPieChart());
86 chartView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // funny things happen if the pie slice labels no not fit the screen...
86 chartView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // funny things happen if the pie slice labels no not fit the screen...
87 baseLayout->addWidget(chartView, 2, 0);
87 baseLayout->addWidget(chartView, 2, 0);
88 m_charts << chartView;
88 m_charts << chartView;
89
89
90 chartView = new QChartView(createSplineChart());
90 chartView = new QChartView(createSplineChart());
91 baseLayout->addWidget(chartView, 2, 1);
91 baseLayout->addWidget(chartView, 2, 1);
92 m_charts << chartView;
92 m_charts << chartView;
93
93
94 chartView = new QChartView(createScatterChart());
94 chartView = new QChartView(createScatterChart());
95 baseLayout->addWidget(chartView, 2, 2);
95 baseLayout->addWidget(chartView, 2, 2);
96 m_charts << chartView;
96 m_charts << chartView;
97
97
98 setLayout(baseLayout);
98 setLayout(baseLayout);
99
99
100 // Set defaults
100 // Set defaults
101 m_antialiasCheckBox->setChecked(true);
101 m_antialiasCheckBox->setChecked(true);
102 updateUI();
102 updateUI();
103 }
103 }
104
104
105 ThemeWidget::~ThemeWidget()
105 ThemeWidget::~ThemeWidget()
106 {
106 {
107 }
107 }
108
108
109 void ThemeWidget::connectSignals()
109 void ThemeWidget::connectSignals()
110 {
110 {
111 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
111 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
112 connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI()));
112 connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI()));
113 connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
113 connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
114 connect(m_legendComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
114 connect(m_legendComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
115 }
115 }
116
116
117 DataTable ThemeWidget::generateRandomData(int listCount,int valueMax,int valueCount) const
117 DataTable ThemeWidget::generateRandomData(int listCount,int valueMax,int valueCount) const
118 {
118 {
119 DataTable dataTable;
119 DataTable dataTable;
120
120
121 // set seed for random stuff
121 // set seed for random stuff
122 qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
122 qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
123
123
124 // generate random data
124 // generate random data
125 for (int i(0); i < listCount; i++) {
125 for (int i(0); i < listCount; i++) {
126 DataList dataList;
126 DataList dataList;
127 qreal yValue(0);
127 qreal yValue(0);
128 for (int j(0); j < valueCount; j++) {
128 for (int j(0); j < valueCount; j++) {
129 yValue = yValue + (qreal) (qrand() % valueMax) / (qreal) valueCount;
129 yValue = yValue + (qreal) (qrand() % valueMax) / (qreal) valueCount;
130 QPointF value((j + (qreal) rand() / (qreal) RAND_MAX) * ((qreal) m_valueMax / (qreal) valueCount),
130 QPointF value((j + (qreal) rand() / (qreal) RAND_MAX) * ((qreal) m_valueMax / (qreal) valueCount),
131 yValue);
131 yValue);
132 QString label = "Slice " + QString::number(i) + ":" + QString::number(j);
132 QString label = "Slice " + QString::number(i) + ":" + QString::number(j);
133 dataList << Data(value, label);
133 dataList << Data(value, label);
134 }
134 }
135 dataTable << dataList;
135 dataTable << dataList;
136 }
136 }
137
137
138 return dataTable;
138 return dataTable;
139 }
139 }
140
140
141 QComboBox* ThemeWidget::createThemeBox() const
141 QComboBox* ThemeWidget::createThemeBox() const
142 {
142 {
143 // settings layout
143 // settings layout
144 QComboBox* themeComboBox = new QComboBox();
144 QComboBox* themeComboBox = new QComboBox();
145 themeComboBox->addItem("Light", QChart::ChartThemeLight);
145 themeComboBox->addItem("Light", QChart::ChartThemeLight);
146 themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);
146 themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);
147 themeComboBox->addItem("Dark", QChart::ChartThemeDark);
147 themeComboBox->addItem("Dark", QChart::ChartThemeDark);
148 themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);
148 themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);
149 themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);
149 themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);
150 themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
150 themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
151 themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
151 themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
152 return themeComboBox;
152 return themeComboBox;
153 }
153 }
154
154
155 QComboBox* ThemeWidget::createAnimationBox() const
155 QComboBox* ThemeWidget::createAnimationBox() const
156 {
156 {
157 // settings layout
157 // settings layout
158 QComboBox* animationComboBox = new QComboBox();
158 QComboBox* animationComboBox = new QComboBox();
159 animationComboBox->addItem("No Animations", QChart::NoAnimation);
159 animationComboBox->addItem("No Animations", QChart::NoAnimation);
160 animationComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations);
160 animationComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations);
161 animationComboBox->addItem("Series Animations", QChart::SeriesAnimations);
161 animationComboBox->addItem("Series Animations", QChart::SeriesAnimations);
162 animationComboBox->addItem("All Animations", QChart::AllAnimations);
162 animationComboBox->addItem("All Animations", QChart::AllAnimations);
163 return animationComboBox;
163 return animationComboBox;
164 }
164 }
165
165
166 QComboBox* ThemeWidget::createLegendBox() const
166 QComboBox* ThemeWidget::createLegendBox() const
167 {
167 {
168 QComboBox* legendComboBox = new QComboBox();
168 QComboBox* legendComboBox = new QComboBox();
169 legendComboBox->addItem("No Legend ", 0);
169 legendComboBox->addItem("No Legend ", 0);
170 legendComboBox->addItem("Legend Top", QLegend::AlignmentTop);
170 legendComboBox->addItem("Legend Top", QLegend::AlignmentTop);
171 legendComboBox->addItem("Legend Bottom", QLegend::AlignmentBottom);
171 legendComboBox->addItem("Legend Bottom", QLegend::AlignmentBottom);
172 legendComboBox->addItem("Legend Left", QLegend::AlignmentLeft);
172 legendComboBox->addItem("Legend Left", QLegend::AlignmentLeft);
173 legendComboBox->addItem("Legend Right", QLegend::AlignmentRight);
173 legendComboBox->addItem("Legend Right", QLegend::AlignmentRight);
174 return legendComboBox;
174 return legendComboBox;
175 }
175 }
176
176
177 QChart* ThemeWidget::createAreaChart() const
177 QChart* ThemeWidget::createAreaChart() const
178 {
178 {
179 QChart *chart = new QChart();
179 QChart *chart = new QChart();
180 chart->axisX()->setNiceNumbersEnabled(true);
180 chart->axisX()->setNiceNumbersEnabled(true);
181 chart->axisY()->setNiceNumbersEnabled(true);
181 chart->axisY()->setNiceNumbersEnabled(true);
182 chart->setTitle("Area chart");
182 chart->setTitle("Area chart");
183
183
184 // The lower series initialized to zero values
184 // The lower series initialized to zero values
185 QLineSeries *lowerSeries = 0;
185 QLineSeries *lowerSeries = 0;
186 QString name("Series ");
186 QString name("Series ");
187 int nameIndex = 0;
187 int nameIndex = 0;
188 for (int i(0); i < m_dataTable.count(); i++) {
188 for (int i(0); i < m_dataTable.count(); i++) {
189 QLineSeries *upperSeries = new QLineSeries(chart);
189 QLineSeries *upperSeries = new QLineSeries(chart);
190 for (int j(0); j < m_dataTable[i].count(); j++) {
190 for (int j(0); j < m_dataTable[i].count(); j++) {
191 Data data = m_dataTable[i].at(j);
191 Data data = m_dataTable[i].at(j);
192 if (lowerSeries)
192 if (lowerSeries){
193 upperSeries->append(QPointF(j, lowerSeries->y(i) + data.first.y()));
193 const QList<QPointF>& points = lowerSeries->points();
194 else
194 upperSeries->append(QPointF(j, points[i].y() + data.first.y()));
195 }else
195 upperSeries->append(QPointF(j, data.first.y()));
196 upperSeries->append(QPointF(j, data.first.y()));
196 }
197 }
197 QAreaSeries *area = new QAreaSeries(upperSeries, lowerSeries);
198 QAreaSeries *area = new QAreaSeries(upperSeries, lowerSeries);
198 area->setName(name + QString::number(nameIndex));
199 area->setName(name + QString::number(nameIndex));
199 nameIndex++;
200 nameIndex++;
200 chart->addSeries(area);
201 chart->addSeries(area);
201 lowerSeries = upperSeries;
202 lowerSeries = upperSeries;
202 }
203 }
203
204
204 return chart;
205 return chart;
205 }
206 }
206
207
207 QChart* ThemeWidget::createBarChart(int valueCount) const
208 QChart* ThemeWidget::createBarChart(int valueCount) const
208 {
209 {
209 QChart* chart = new QChart();
210 QChart* chart = new QChart();
210 chart->axisX()->setNiceNumbersEnabled(true);
211 chart->axisX()->setNiceNumbersEnabled(true);
211 chart->axisY()->setNiceNumbersEnabled(true);
212 chart->axisY()->setNiceNumbersEnabled(true);
212 chart->setTitle("Bar chart");
213 chart->setTitle("Bar chart");
213
214
214 QBarCategories categories;
215 QBarCategories categories;
215 for (int i(0); i < valueCount; i++)
216 for (int i(0); i < valueCount; i++)
216 categories << QString::number(i);
217 categories << QString::number(i);
217
218
218 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
219 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
219 for (int i(0); i < m_dataTable.count(); i++) {
220 for (int i(0); i < m_dataTable.count(); i++) {
220 QBarSet *set = new QBarSet("Bar set " + QString::number(i));
221 QBarSet *set = new QBarSet("Bar set " + QString::number(i));
221 foreach (Data data, m_dataTable[i])
222 foreach (Data data, m_dataTable[i])
222 *set << data.first.y();
223 *set << data.first.y();
223 series->appendBarSet(set);
224 series->appendBarSet(set);
224 }
225 }
225 chart->addSeries(series);
226 chart->addSeries(series);
226
227
227 return chart;
228 return chart;
228 }
229 }
229
230
230 QChart* ThemeWidget::createLineChart() const
231 QChart* ThemeWidget::createLineChart() const
231 {
232 {
232 QChart* chart = new QChart();
233 QChart* chart = new QChart();
233 chart->axisX()->setNiceNumbersEnabled(true);
234 chart->axisX()->setNiceNumbersEnabled(true);
234 chart->axisY()->setNiceNumbersEnabled(true);
235 chart->axisY()->setNiceNumbersEnabled(true);
235 chart->setTitle("Line chart");
236 chart->setTitle("Line chart");
236
237
237 QString name("Series ");
238 QString name("Series ");
238 int nameIndex = 0;
239 int nameIndex = 0;
239 foreach (DataList list, m_dataTable) {
240 foreach (DataList list, m_dataTable) {
240 QLineSeries *series = new QLineSeries(chart);
241 QLineSeries *series = new QLineSeries(chart);
241 foreach (Data data, list)
242 foreach (Data data, list)
242 series->append(data.first);
243 series->append(data.first);
243 series->setName(name + QString::number(nameIndex));
244 series->setName(name + QString::number(nameIndex));
244 nameIndex++;
245 nameIndex++;
245 chart->addSeries(series);
246 chart->addSeries(series);
246 }
247 }
247
248
248 return chart;
249 return chart;
249 }
250 }
250
251
251 QChart* ThemeWidget::createPieChart() const
252 QChart* ThemeWidget::createPieChart() const
252 {
253 {
253 QChart* chart = new QChart();
254 QChart* chart = new QChart();
254 chart->setTitle("Pie chart");
255 chart->setTitle("Pie chart");
255
256
256 qreal pieSize = 1.0 / m_dataTable.count();
257 qreal pieSize = 1.0 / m_dataTable.count();
257 for (int i = 0; i < m_dataTable.count(); i++) {
258 for (int i = 0; i < m_dataTable.count(); i++) {
258 QPieSeries *series = new QPieSeries(chart);
259 QPieSeries *series = new QPieSeries(chart);
259 foreach (Data data, m_dataTable[i]) {
260 foreach (Data data, m_dataTable[i]) {
260 QPieSlice *slice = series->append(data.first.y(), data.second);
261 QPieSlice *slice = series->append(data.first.y(), data.second);
261 if (data == m_dataTable[i].first()) {
262 if (data == m_dataTable[i].first()) {
262 slice->setLabelVisible();
263 slice->setLabelVisible();
263 slice->setExploded();
264 slice->setExploded();
264 }
265 }
265 }
266 }
266 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
267 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
267 series->setPieSize(pieSize);
268 series->setPieSize(pieSize);
268 series->setHorizontalPosition(hPos);
269 series->setHorizontalPosition(hPos);
269 series->setVerticalPosition(0.5);
270 series->setVerticalPosition(0.5);
270 chart->addSeries(series);
271 chart->addSeries(series);
271 }
272 }
272
273
273 return chart;
274 return chart;
274 }
275 }
275
276
276 QChart* ThemeWidget::createSplineChart() const
277 QChart* ThemeWidget::createSplineChart() const
277 { // spine chart
278 { // spine chart
278 QChart* chart = new QChart();
279 QChart* chart = new QChart();
279 chart->axisX()->setNiceNumbersEnabled(true);
280 chart->axisX()->setNiceNumbersEnabled(true);
280 chart->axisY()->setNiceNumbersEnabled(true);
281 chart->axisY()->setNiceNumbersEnabled(true);
281 chart->setTitle("Spline chart");
282 chart->setTitle("Spline chart");
282 QString name("Series ");
283 QString name("Series ");
283 int nameIndex = 0;
284 int nameIndex = 0;
284 foreach (DataList list, m_dataTable) {
285 foreach (DataList list, m_dataTable) {
285 QSplineSeries *series = new QSplineSeries(chart);
286 QSplineSeries *series = new QSplineSeries(chart);
286 foreach (Data data, list)
287 foreach (Data data, list)
287 series->append(data.first);
288 series->append(data.first);
288 series->setName(name + QString::number(nameIndex));
289 series->setName(name + QString::number(nameIndex));
289 nameIndex++;
290 nameIndex++;
290 chart->addSeries(series);
291 chart->addSeries(series);
291 }
292 }
292 return chart;
293 return chart;
293 }
294 }
294
295
295 QChart* ThemeWidget::createScatterChart() const
296 QChart* ThemeWidget::createScatterChart() const
296 { // scatter chart
297 { // scatter chart
297 QChart* chart = new QChart();
298 QChart* chart = new QChart();
298 chart->axisX()->setNiceNumbersEnabled(true);
299 chart->axisX()->setNiceNumbersEnabled(true);
299 chart->axisY()->setNiceNumbersEnabled(true);
300 chart->axisY()->setNiceNumbersEnabled(true);
300 chart->setTitle("Scatter chart");
301 chart->setTitle("Scatter chart");
301 QString name("Series ");
302 QString name("Series ");
302 int nameIndex = 0;
303 int nameIndex = 0;
303 foreach (DataList list, m_dataTable) {
304 foreach (DataList list, m_dataTable) {
304 QScatterSeries *series = new QScatterSeries(chart);
305 QScatterSeries *series = new QScatterSeries(chart);
305 foreach (Data data, list)
306 foreach (Data data, list)
306 series->append(data.first);
307 series->append(data.first);
307 series->setName(name + QString::number(nameIndex));
308 series->setName(name + QString::number(nameIndex));
308 nameIndex++;
309 nameIndex++;
309 chart->addSeries(series);
310 chart->addSeries(series);
310 }
311 }
311 return chart;
312 return chart;
312 }
313 }
313
314
314 void ThemeWidget::updateUI()
315 void ThemeWidget::updateUI()
315 {
316 {
316 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
317 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
317
318
318 if (m_charts.at(0)->chart()->theme() != theme) {
319 if (m_charts.at(0)->chart()->theme() != theme) {
319 foreach (QChartView *chartView, m_charts)
320 foreach (QChartView *chartView, m_charts)
320 chartView->chart()->setTheme(theme);
321 chartView->chart()->setTheme(theme);
321
322
322 QPalette pal = window()->palette();
323 QPalette pal = window()->palette();
323 if (theme == QChart::ChartThemeLight) {
324 if (theme == QChart::ChartThemeLight) {
324 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
325 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
325 pal.setColor(QPalette::WindowText, QRgb(0x404044));
326 pal.setColor(QPalette::WindowText, QRgb(0x404044));
326 } else if (theme == QChart::ChartThemeDark) {
327 } else if (theme == QChart::ChartThemeDark) {
327 pal.setColor(QPalette::Window, QRgb(0x121218));
328 pal.setColor(QPalette::Window, QRgb(0x121218));
328 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
329 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
329 } else if (theme == QChart::ChartThemeBlueCerulean) {
330 } else if (theme == QChart::ChartThemeBlueCerulean) {
330 pal.setColor(QPalette::Window, QRgb(0x40434a));
331 pal.setColor(QPalette::Window, QRgb(0x40434a));
331 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
332 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
332 } else if (theme == QChart::ChartThemeBrownSand) {
333 } else if (theme == QChart::ChartThemeBrownSand) {
333 pal.setColor(QPalette::Window, QRgb(0x9e8965));
334 pal.setColor(QPalette::Window, QRgb(0x9e8965));
334 pal.setColor(QPalette::WindowText, QRgb(0x404044));
335 pal.setColor(QPalette::WindowText, QRgb(0x404044));
335 } else if (theme == QChart::ChartThemeBlueNcs) {
336 } else if (theme == QChart::ChartThemeBlueNcs) {
336 pal.setColor(QPalette::Window, QRgb(0x018bba));
337 pal.setColor(QPalette::Window, QRgb(0x018bba));
337 pal.setColor(QPalette::WindowText, QRgb(0x404044));
338 pal.setColor(QPalette::WindowText, QRgb(0x404044));
338 } else if (theme == QChart::ChartThemeHighContrast) {
339 } else if (theme == QChart::ChartThemeHighContrast) {
339 pal.setColor(QPalette::Window, QRgb(0xffab03));
340 pal.setColor(QPalette::Window, QRgb(0xffab03));
340 pal.setColor(QPalette::WindowText, QRgb(0x181818));
341 pal.setColor(QPalette::WindowText, QRgb(0x181818));
341 } else if (theme == QChart::ChartThemeBlueIcy) {
342 } else if (theme == QChart::ChartThemeBlueIcy) {
342 pal.setColor(QPalette::Window, QRgb(0xcee7f0));
343 pal.setColor(QPalette::Window, QRgb(0xcee7f0));
343 pal.setColor(QPalette::WindowText, QRgb(0x404044));
344 pal.setColor(QPalette::WindowText, QRgb(0x404044));
344 } else {
345 } else {
345 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
346 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
346 pal.setColor(QPalette::WindowText, QRgb(0x404044));
347 pal.setColor(QPalette::WindowText, QRgb(0x404044));
347 }
348 }
348 window()->setPalette(pal);
349 window()->setPalette(pal);
349 }
350 }
350
351
351 bool checked = m_antialiasCheckBox->isChecked();
352 bool checked = m_antialiasCheckBox->isChecked();
352 foreach (QChartView *chart, m_charts)
353 foreach (QChartView *chart, m_charts)
353 chart->setRenderHint(QPainter::Antialiasing, checked);
354 chart->setRenderHint(QPainter::Antialiasing, checked);
354
355
355 QChart::AnimationOptions options(m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt());
356 QChart::AnimationOptions options(m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt());
356 if (m_charts.at(0)->chart()->animationOptions() != options) {
357 if (m_charts.at(0)->chart()->animationOptions() != options) {
357 foreach (QChartView *chartView, m_charts)
358 foreach (QChartView *chartView, m_charts)
358 chartView->chart()->setAnimationOptions(options);
359 chartView->chart()->setAnimationOptions(options);
359 }
360 }
360
361
361 QLegend::Alignments alignment(m_legendComboBox->itemData(m_legendComboBox->currentIndex()).toInt());
362 QLegend::Alignments alignment(m_legendComboBox->itemData(m_legendComboBox->currentIndex()).toInt());
362
363
363 if (!alignment) {
364 if (!alignment) {
364 foreach (QChartView *chartView, m_charts) {
365 foreach (QChartView *chartView, m_charts) {
365 chartView->chart()->legend()->hide();
366 chartView->chart()->legend()->hide();
366 }
367 }
367 } else {
368 } else {
368 foreach (QChartView *chartView, m_charts) {
369 foreach (QChartView *chartView, m_charts) {
369 chartView->chart()->legend()->setAlignment(alignment);
370 chartView->chart()->legend()->setAlignment(alignment);
370 chartView->chart()->legend()->show();
371 chartView->chart()->legend()->show();
371 }
372 }
372 }
373 }
373 }
374 }
374
375
@@ -1,65 +1,66
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chart.h"
21 #include "chart.h"
22 #include <QAxis>
22 #include <QAxis>
23 #include <QSplineSeries>
23 #include <QSplineSeries>
24 #include <QTime>
24 #include <QTime>
25
25
26 Chart::Chart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
26 Chart::Chart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
27 :QChart(parent, wFlags),
27 :QChart(parent, wFlags),
28 m_step(1),
28 m_step(1),
29 m_x(0),
29 m_x(0),
30 m_y(1)
30 m_y(1)
31 {
31 {
32 qsrand((uint) QTime::currentTime().msec());
32 qsrand((uint) QTime::currentTime().msec());
33
33
34 QObject::connect(&m_timer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
34 QObject::connect(&m_timer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
35 m_timer.setInterval(1000);
35 m_timer.setInterval(1000);
36
36
37 m_series = new QSplineSeries(this);
37 m_series = new QSplineSeries(this);
38 QPen green(Qt::red);
38 QPen green(Qt::red);
39 green.setWidth(3);
39 green.setWidth(3);
40 m_series->setPen(green);
40 m_series->setPen(green);
41 m_series->append(m_x, m_y);
41 m_series->append(m_x, m_y);
42
42
43 addSeries(m_series);
43 addSeries(m_series);
44
44
45 axisY()->setRange(-5, 5);
45 axisY()->setRange(-5, 5);
46 axisX()->setRange(-9, 1);
46 axisX()->setRange(-9, 1);
47 axisX()->setTicksCount(11);
47 axisX()->setTicksCount(11);
48
48
49 m_timer.start();
49 m_timer.start();
50 }
50 }
51
51
52 Chart::~Chart()
52 Chart::~Chart()
53 {
53 {
54
54
55 }
55 }
56
56
57 void Chart::handleTimeout()
57 void Chart::handleTimeout()
58 {
58 {
59 m_x += m_step;
59 m_x += m_step;
60 qreal y = m_y;
60 m_y = qrand() % 5 - 2.5;
61 m_y = qrand() % 5 - 2.5;
61 m_series->append(m_x, m_y);
62 m_series->append(m_x, m_y);
62 if (m_x >= 10)
63 if (m_x >= 10)
63 m_series->remove(m_x - 10);
64 m_series->remove(m_x - 10,y);
64 scrollRight();
65 scrollRight();
65 }
66 }
@@ -1,281 +1,286
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qareaseries.h"
21 #include "qareaseries.h"
22 #include "qareaseries_p.h"
22 #include "qareaseries_p.h"
23 #include "qlineseries.h"
23 #include "qlineseries.h"
24 #include "areachartitem_p.h"
24 #include "areachartitem_p.h"
25 #include "legendmarker_p.h"
25 #include "legendmarker_p.h"
26 #include "domain_p.h"
26 #include "domain_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 /*!
33 /*!
34 \class QAreaSeries
34 \class QAreaSeries
35 \brief The QAreaSeries class is used for making area charts.
35 \brief The QAreaSeries class is used for making area charts.
36
36
37 \mainclass
37 \mainclass
38
38
39 An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line
39 An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line
40 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
40 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
41 which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X. Instead of axis X "lower" boundary can be specified by other line.
41 which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X. Instead of axis X "lower" boundary can be specified by other line.
42 In that case QAreaSeries should be initiated with two QLineSerie instances. Please note terms "upper" and "lower" boundary can be misleading in cases
42 In that case QAreaSeries should be initiated with two QLineSerie instances. Please note terms "upper" and "lower" boundary can be misleading in cases
43 where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary lines will be filled.
43 where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary lines will be filled.
44
44
45 See the \l {AreaChart Example} {area chart example} to learn how to create a simple area chart.
45 See the \l {AreaChart Example} {area chart example} to learn how to create a simple area chart.
46 \image examples_areachart.png
46 \image examples_areachart.png
47 */
47 */
48
48
49 /*!
49 /*!
50 \fn virtual QSeriesType QAreaSeries::type() const
50 \fn virtual QSeriesType QAreaSeries::type() const
51 \brief Returns type of series.
51 \brief Returns type of series.
52 \sa QAbstractSeries, QSeriesType
52 \sa QAbstractSeries, QSeriesType
53 */
53 */
54
54
55 /*!
55 /*!
56 \fn QLineSeries* QAreaSeries::upperSeries() const
56 \fn QLineSeries* QAreaSeries::upperSeries() const
57 \brief Returns upperSeries used to define one of area boundaries.
57 \brief Returns upperSeries used to define one of area boundaries.
58 */
58 */
59
59
60 /*!
60 /*!
61 \fn QLineSeries* QAreaSeries::lowerSeries() const
61 \fn QLineSeries* QAreaSeries::lowerSeries() const
62 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
62 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
63 this function return Null pointer.
63 this function return Null pointer.
64 */
64 */
65
65
66 /*!
66 /*!
67 \fn QPen QAreaSeries::pen() const
67 \fn QPen QAreaSeries::pen() const
68 \brief Returns the pen used to draw line for this series.
68 \brief Returns the pen used to draw line for this series.
69 \sa setPen()
69 \sa setPen()
70 */
70 */
71
71
72 /*!
72 /*!
73 \fn QPen QAreaSeries::brush() const
73 \fn QPen QAreaSeries::brush() const
74 \brief Returns the brush used to draw line for this series.
74 \brief Returns the brush used to draw line for this series.
75 \sa setBrush()
75 \sa setBrush()
76 */
76 */
77
77
78 /*!
78 /*!
79 \fn bool QAreaSeries::pointsVisible() const
79 \fn bool QAreaSeries::pointsVisible() const
80 \brief Returns if the points are drawn for this series.
80 \brief Returns if the points are drawn for this series.
81 \sa setPointsVisible()
81 \sa setPointsVisible()
82 */
82 */
83
83
84 /*!
84 /*!
85 \fn void QAreaSeries::clicked(const QPointF& point)
85 \fn void QAreaSeries::clicked(const QPointF& point)
86 \brief Signal is emitted when user clicks the \a point on area chart.
86 \brief Signal is emitted when user clicks the \a point on area chart.
87 */
87 */
88
88
89 /*!
89 /*!
90 \fn void QAreaSeries::selected()
90 \fn void QAreaSeries::selected()
91
91
92 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
92 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
93 implemented by the user of QAreaSeries API.
93 implemented by the user of QAreaSeries API.
94 */
94 */
95
95
96 /*!
96 /*!
97 \fn void QAreaSeriesPrivate::updated()
97 \fn void QAreaSeriesPrivate::updated()
98 \brief \internal
98 \brief \internal
99 */
99 */
100
100
101 /*!
101 /*!
102 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
102 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
103 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
103 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
104 When series object is added to QChartView or QChart instance ownerships is transferred.
104 When series object is added to QChartView or QChart instance ownerships is transferred.
105 */
105 */
106 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
106 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
107 : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
107 : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
108 {
108 {
109 }
109 }
110
110
111 /*!
111 /*!
112 Destroys the object. Series added to QChartView or QChart instances are owned by those,
112 Destroys the object. Series added to QChartView or QChart instances are owned by those,
113 and are deleted when mentioned object are destroyed.
113 and are deleted when mentioned object are destroyed.
114 */
114 */
115 QAreaSeries::~QAreaSeries()
115 QAreaSeries::~QAreaSeries()
116 {
116 {
117 }
117 }
118
118
119
119
120 QAbstractSeries::QSeriesType QAreaSeries::type() const
120 QAbstractSeries::QSeriesType QAreaSeries::type() const
121 {
121 {
122 return QAbstractSeries::SeriesTypeArea;
122 return QAbstractSeries::SeriesTypeArea;
123 }
123 }
124
124
125 QLineSeries* QAreaSeries::upperSeries() const
125 QLineSeries* QAreaSeries::upperSeries() const
126 {
126 {
127 Q_D(const QAreaSeries);
127 Q_D(const QAreaSeries);
128 return d->m_upperSeries;
128 return d->m_upperSeries;
129 }
129 }
130
130
131 QLineSeries* QAreaSeries::lowerSeries() const
131 QLineSeries* QAreaSeries::lowerSeries() const
132 {
132 {
133 Q_D(const QAreaSeries);
133 Q_D(const QAreaSeries);
134 return d->m_lowerSeries;
134 return d->m_lowerSeries;
135 }
135 }
136
136
137 /*!
137 /*!
138 Sets \a pen used for drawing area outline.
138 Sets \a pen used for drawing area outline.
139 */
139 */
140 void QAreaSeries::setPen(const QPen &pen)
140 void QAreaSeries::setPen(const QPen &pen)
141 {
141 {
142 Q_D(QAreaSeries);
142 Q_D(QAreaSeries);
143 if (d->m_pen != pen) {
143 if (d->m_pen != pen) {
144 d->m_pen = pen;
144 d->m_pen = pen;
145 emit d->updated();
145 emit d->updated();
146 }
146 }
147 }
147 }
148
148
149 QPen QAreaSeries::pen() const
149 QPen QAreaSeries::pen() const
150 {
150 {
151 Q_D(const QAreaSeries);
151 Q_D(const QAreaSeries);
152 return d->m_pen;
152 return d->m_pen;
153 }
153 }
154
154
155 /*!
155 /*!
156 Sets \a brush used for filling the area.
156 Sets \a brush used for filling the area.
157 */
157 */
158 void QAreaSeries::setBrush(const QBrush &brush)
158 void QAreaSeries::setBrush(const QBrush &brush)
159 {
159 {
160 Q_D(QAreaSeries);
160 Q_D(QAreaSeries);
161 if (d->m_brush != brush) {
161 if (d->m_brush != brush) {
162 d->m_brush = brush;
162 d->m_brush = brush;
163 emit d->updated();
163 emit d->updated();
164 }
164 }
165 }
165 }
166
166
167 QBrush QAreaSeries::brush() const
167 QBrush QAreaSeries::brush() const
168 {
168 {
169 Q_D(const QAreaSeries);
169 Q_D(const QAreaSeries);
170 return d->m_brush;
170 return d->m_brush;
171 }
171 }
172 /*!
172 /*!
173 Sets if data points are \a visible and should be drawn on line.
173 Sets if data points are \a visible and should be drawn on line.
174 */
174 */
175 void QAreaSeries::setPointsVisible(bool visible)
175 void QAreaSeries::setPointsVisible(bool visible)
176 {
176 {
177 Q_D(QAreaSeries);
177 Q_D(QAreaSeries);
178 if (d->m_pointsVisible != visible) {
178 if (d->m_pointsVisible != visible) {
179 d->m_pointsVisible = visible;
179 d->m_pointsVisible = visible;
180 emit d->updated();
180 emit d->updated();
181 }
181 }
182 }
182 }
183
183
184 bool QAreaSeries::pointsVisible() const
184 bool QAreaSeries::pointsVisible() const
185 {
185 {
186 Q_D(const QAreaSeries);
186 Q_D(const QAreaSeries);
187 return d->m_pointsVisible;
187 return d->m_pointsVisible;
188 }
188 }
189
189
190 /*!
190 /*!
191 Does nothing at present. Paremeter \a model is not used. Always returns false.
191 Does nothing at present. Paremeter \a model is not used. Always returns false.
192 To set the model for area series set the models for upperSeries, lowerSeries
192 To set the model for area series set the models for upperSeries, lowerSeries
193 */
193 */
194 bool QAreaSeries::setModel(QAbstractItemModel* model)
194 bool QAreaSeries::setModel(QAbstractItemModel* model)
195 {
195 {
196 Q_UNUSED(model);
196 Q_UNUSED(model);
197 qWarning()<<"Not implemented";
197 qWarning()<<"Not implemented";
198 return false;
198 return false;
199 }
199 }
200
200
201 /*!
201 /*!
202 Does nothing at present. Always returns 0;
202 Does nothing at present. Always returns 0;
203 To get the model set for area series call upperSeries->model(), lowerSeries->model()
203 To get the model set for area series call upperSeries->model(), lowerSeries->model()
204 */
204 */
205 QAbstractItemModel* QAreaSeries::model() const
205 QAbstractItemModel* QAreaSeries::model() const
206 {
206 {
207 return 0;
207 return 0;
208 }
208 }
209
209
210 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211
211
212 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
212 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
213 QAbstractSeriesPrivate(q),
213 QAbstractSeriesPrivate(q),
214 m_upperSeries(upperSeries),
214 m_upperSeries(upperSeries),
215 m_lowerSeries(lowerSeries),
215 m_lowerSeries(lowerSeries),
216 m_pointsVisible(false)
216 m_pointsVisible(false)
217 {
217 {
218 }
218 }
219
219
220 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
220 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
221 {
221 {
222 Q_Q(QAreaSeries);
222 Q_Q(QAreaSeries);
223
223
224 qreal minX(domain.minX());
224 qreal minX(domain.minX());
225 qreal minY(domain.minY());
225 qreal minY(domain.minY());
226 qreal maxX(domain.maxX());
226 qreal maxX(domain.maxX());
227 qreal maxY(domain.maxY());
227 qreal maxY(domain.maxY());
228 int tickXCount(domain.tickXCount());
228 int tickXCount(domain.tickXCount());
229 int tickYCount(domain.tickYCount());
229 int tickYCount(domain.tickYCount());
230
230
231 QLineSeries* upperSeries = q->upperSeries();
231 QLineSeries* upperSeries = q->upperSeries();
232 QLineSeries* lowerSeries = q->lowerSeries();
232 QLineSeries* lowerSeries = q->lowerSeries();
233
233
234 for (int i = 0; i < upperSeries->count(); i++)
234 const QList<QPointF>& points = upperSeries->points();
235
236 for (int i = 0; i < points.count(); i++)
235 {
237 {
236 qreal x = upperSeries->x(i);
238 qreal x = points[i].x();
237 qreal y = upperSeries->y(i);
239 qreal y = points[i].y();
238 minX = qMin(minX, x);
240 minX = qMin(minX, x);
239 minY = qMin(minY, y);
241 minY = qMin(minY, y);
240 maxX = qMax(maxX, x);
242 maxX = qMax(maxX, x);
241 maxY = qMax(maxY, y);
243 maxY = qMax(maxY, y);
242 }
244 }
243 if(lowerSeries) {
245 if(lowerSeries) {
244 for (int i = 0; i < lowerSeries->count(); i++)
246
247 const QList<QPointF>& points = upperSeries->points();
248
249 for (int i = 0; i < points.count(); i++)
245 {
250 {
246 qreal x = lowerSeries->x(i);
251 qreal x = points[i].x();
247 qreal y = lowerSeries->y(i);
252 qreal y = points[i].y();
248 minX = qMin(minX, x);
253 minX = qMin(minX, x);
249 minY = qMin(minY, y);
254 minY = qMin(minY, y);
250 maxX = qMax(maxX, x);
255 maxX = qMax(maxX, x);
251 maxY = qMax(maxY, y);
256 maxY = qMax(maxY, y);
252 }}
257 }}
253
258
254 domain.setRangeX(minX,maxX,tickXCount);
259 domain.setRangeX(minX,maxX,tickXCount);
255 domain.setRangeY(minY,maxY,tickYCount);
260 domain.setRangeY(minY,maxY,tickYCount);
256 }
261 }
257
262
258 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
263 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
259 {
264 {
260 Q_Q(QAreaSeries);
265 Q_Q(QAreaSeries);
261
266
262 AreaChartItem* area = new AreaChartItem(q,presenter);
267 AreaChartItem* area = new AreaChartItem(q,presenter);
263 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
268 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
264 presenter->animator()->addAnimation(area->upperLineItem());
269 presenter->animator()->addAnimation(area->upperLineItem());
265 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
270 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
266 }
271 }
267 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
272 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
268 return area;
273 return area;
269 }
274 }
270
275
271 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
276 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
272 {
277 {
273 Q_Q(QAreaSeries);
278 Q_Q(QAreaSeries);
274 QList<LegendMarker*> list;
279 QList<LegendMarker*> list;
275 return list << new AreaLegendMarker(q,legend);
280 return list << new AreaLegendMarker(q,legend);
276 }
281 }
277
282
278 #include "moc_qareaseries.cpp"
283 #include "moc_qareaseries.cpp"
279 #include "moc_qareaseries_p.cpp"
284 #include "moc_qareaseries_p.cpp"
280
285
281 QTCOMMERCIALCHART_END_NAMESPACE
286 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,191 +1,191
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "scatterchartitem_p.h"
21 #include "scatterchartitem_p.h"
22 #include "qscatterseries.h"
22 #include "qscatterseries.h"
23 #include "qscatterseries_p.h"
23 #include "qscatterseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsScene>
26 #include <QGraphicsScene>
27 #include <QDebug>
27 #include <QDebug>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter) :
31 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter) :
32 XYChartItem(series,presenter),
32 XYChartItem(series,presenter),
33 m_series(series),
33 m_series(series),
34 m_items(this),
34 m_items(this),
35 m_shape(QScatterSeries::MarkerShapeRectangle),
35 m_shape(QScatterSeries::MarkerShapeRectangle),
36 m_size(15)
36 m_size(15)
37
37
38 {
38 {
39 QObject::connect(m_series->d_func(),SIGNAL(updated()), this, SLOT(handleUpdated()));
39 QObject::connect(m_series->d_func(),SIGNAL(updated()), this, SLOT(handleUpdated()));
40
40
41 setZValue(ChartPresenter::ScatterSeriesZValue);
41 setZValue(ChartPresenter::ScatterSeriesZValue);
42 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
42 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
43
43
44 handleUpdated();
44 handleUpdated();
45
45
46 m_items.setHandlesChildEvents(false);
46 m_items.setHandlesChildEvents(false);
47
47
48 // TODO: how to draw a drop shadow?
48 // TODO: how to draw a drop shadow?
49 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
49 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
50 // dropShadow->setOffset(2.0);
50 // dropShadow->setOffset(2.0);
51 // dropShadow->setBlurRadius(2.0);
51 // dropShadow->setBlurRadius(2.0);
52 // setGraphicsEffect(dropShadow);
52 // setGraphicsEffect(dropShadow);
53 }
53 }
54
54
55
55
56 QRectF ScatterChartItem::boundingRect() const
56 QRectF ScatterChartItem::boundingRect() const
57 {
57 {
58 return m_rect;
58 return m_rect;
59 }
59 }
60
60
61 void ScatterChartItem::createPoints(int count)
61 void ScatterChartItem::createPoints(int count)
62 {
62 {
63 for (int i = 0; i < count; ++i) {
63 for (int i = 0; i < count; ++i) {
64
64
65 QGraphicsItem *item = 0;
65 QGraphicsItem *item = 0;
66
66
67 switch (m_shape) {
67 switch (m_shape) {
68 case QScatterSeries::MarkerShapeCircle:{
68 case QScatterSeries::MarkerShapeCircle:{
69 QGraphicsEllipseItem* i = new QGraphicsEllipseItem(0,0,m_size,m_size);
69 QGraphicsEllipseItem* i = new QGraphicsEllipseItem(0,0,m_size,m_size);
70 const QRectF& rect = i->boundingRect();
70 const QRectF& rect = i->boundingRect();
71 i->setPos(-rect.width()/2,-rect.height()/2);
71 i->setPos(-rect.width()/2,-rect.height()/2);
72 item = new Marker(i,this);
72 item = new Marker(i,this);
73 break;
73 break;
74 }
74 }
75 case QScatterSeries::MarkerShapeRectangle:{
75 case QScatterSeries::MarkerShapeRectangle:{
76 QGraphicsRectItem* i = new QGraphicsRectItem(0,0,m_size,m_size);
76 QGraphicsRectItem* i = new QGraphicsRectItem(0,0,m_size,m_size);
77 i->setPos(-m_size/2,-m_size/2);
77 i->setPos(-m_size/2,-m_size/2);
78 item = new Marker(i,this);
78 item = new Marker(i,this);
79 break;
79 break;
80 }
80 }
81 default:
81 default:
82 qWarning()<<"Unsupported marker type";
82 qWarning()<<"Unsupported marker type";
83 break;
83 break;
84
84
85 }
85 }
86 m_items.addToGroup(item);
86 m_items.addToGroup(item);
87 }
87 }
88 }
88 }
89
89
90 void ScatterChartItem::deletePoints(int count)
90 void ScatterChartItem::deletePoints(int count)
91 {
91 {
92 QList<QGraphicsItem *> items = m_items.childItems();
92 QList<QGraphicsItem *> items = m_items.childItems();
93
93
94 for (int i = 0; i < count; ++i) {
94 for (int i = 0; i < count; ++i) {
95 delete(items.takeLast());
95 delete(items.takeLast());
96 }
96 }
97 }
97 }
98
98
99 void ScatterChartItem::markerSelected(Marker *marker)
99 void ScatterChartItem::markerSelected(Marker *marker)
100 {
100 {
101 emit XYChartItem::clicked(QPointF(m_series->x(marker->index()), m_series->y(marker->index())));
101 emit XYChartItem::clicked(marker->point());
102 }
102 }
103
103
104 void ScatterChartItem::setLayout(QVector<QPointF>& points)
104 void ScatterChartItem::setLayout(QVector<QPointF>& points)
105 {
105 {
106 if(points.size()==0)
106 if(points.size()==0)
107 {
107 {
108 XYChartItem::setLayout(points);
108 XYChartItem::setLayout(points);
109 return;
109 return;
110 }
110 }
111
111
112 int diff = m_items.childItems().size() - points.size();
112 int diff = m_items.childItems().size() - points.size();
113
113
114 if(diff>0) {
114 if(diff>0) {
115 deletePoints(diff);
115 deletePoints(diff);
116 }
116 }
117 else if(diff<0) {
117 else if(diff<0) {
118 createPoints(-diff);
118 createPoints(-diff);
119 }
119 }
120
120
121 if(diff!=0) handleUpdated();
121 if(diff!=0) handleUpdated();
122
122
123 QList<QGraphicsItem*> items = m_items.childItems();
123 QList<QGraphicsItem*> items = m_items.childItems();
124
124
125 for (int i = 0; i < points.size(); i++) {
125 for (int i = 0; i < points.size(); i++) {
126 Marker* item = static_cast<Marker*>(items.at(i));
126 Marker* item = static_cast<Marker*>(items.at(i));
127 const QPointF& point = points.at(i);
127 const QPointF& point = points.at(i);
128 const QRectF& rect = item->boundingRect();
128 const QRectF& rect = item->boundingRect();
129 item->setIndex(i);
129 item->setPoint(point);
130 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
130 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
131 if(!clipRect().contains(point)) {
131 if(!clipRect().contains(point)) {
132 item->setVisible(false);
132 item->setVisible(false);
133 }
133 }
134 else {
134 else {
135 item->setVisible(true);
135 item->setVisible(true);
136 }
136 }
137 }
137 }
138
138
139 prepareGeometryChange();
139 prepareGeometryChange();
140 m_rect = clipRect();
140 m_rect = clipRect();
141 XYChartItem::setLayout(points);
141 XYChartItem::setLayout(points);
142 }
142 }
143
143
144
144
145 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
145 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
146 {
146 {
147 Q_UNUSED(painter)
147 Q_UNUSED(painter)
148 Q_UNUSED(option)
148 Q_UNUSED(option)
149 Q_UNUSED(widget)
149 Q_UNUSED(widget)
150 }
150 }
151
151
152 void ScatterChartItem::setPen(const QPen& pen)
152 void ScatterChartItem::setPen(const QPen& pen)
153 {
153 {
154 foreach(QGraphicsItem* item , m_items.childItems()) {
154 foreach(QGraphicsItem* item , m_items.childItems()) {
155 static_cast<Marker*>(item)->setPen(pen);
155 static_cast<Marker*>(item)->setPen(pen);
156 }
156 }
157 }
157 }
158
158
159 void ScatterChartItem::setBrush(const QBrush& brush)
159 void ScatterChartItem::setBrush(const QBrush& brush)
160 {
160 {
161 foreach(QGraphicsItem* item , m_items.childItems()) {
161 foreach(QGraphicsItem* item , m_items.childItems()) {
162 static_cast<Marker*>(item)->setBrush(brush);
162 static_cast<Marker*>(item)->setBrush(brush);
163 }
163 }
164 }
164 }
165
165
166 void ScatterChartItem::handleUpdated()
166 void ScatterChartItem::handleUpdated()
167 {
167 {
168
168
169 int count = m_items.childItems().count();
169 int count = m_items.childItems().count();
170
170
171 if(count==0) return;
171 if(count==0) return;
172
172
173 bool recreate = m_size != m_series->size() || m_shape != m_series->shape();
173 bool recreate = m_size != m_series->size() || m_shape != m_series->shape();
174
174
175 //TODO: only rewrite on size change
175 //TODO: only rewrite on size change
176
176
177 m_size = m_series->size();
177 m_size = m_series->size();
178 m_shape = m_series->shape();
178 m_shape = m_series->shape();
179
179
180 if(recreate){
180 if(recreate){
181 deletePoints(count);
181 deletePoints(count);
182 createPoints(count);
182 createPoints(count);
183 }
183 }
184
184
185 setPen(m_series->pen());
185 setPen(m_series->pen());
186 setBrush(m_series->brush());
186 setBrush(m_series->brush());
187 }
187 }
188
188
189 #include "moc_scatterchartitem_p.cpp"
189 #include "moc_scatterchartitem_p.cpp"
190
190
191 QTCOMMERCIALCHART_END_NAMESPACE
191 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,140 +1,140
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef SCATTERCHARTITEM_H
21 #ifndef SCATTERCHARTITEM_H
22 #define SCATTERCHARTITEM_H
22 #define SCATTERCHARTITEM_H
23
23
24 #include "qchartglobal.h"
24 #include "qchartglobal.h"
25 #include "xychartitem_p.h"
25 #include "xychartitem_p.h"
26 #include <QGraphicsEllipseItem>
26 #include <QGraphicsEllipseItem>
27 #include <QPen>
27 #include <QPen>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 class QScatterSeries;
31 class QScatterSeries;
32 class Marker;
32 class Marker;
33
33
34 class ScatterChartItem : public XYChartItem
34 class ScatterChartItem : public XYChartItem
35 {
35 {
36 Q_OBJECT
36 Q_OBJECT
37 public:
37 public:
38 explicit ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter);
38 explicit ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter);
39
39
40 public:
40 public:
41 //from QGraphicsItem
41 //from QGraphicsItem
42 QRectF boundingRect() const;
42 QRectF boundingRect() const;
43 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
43 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
44
44
45 void setPen(const QPen &pen);
45 void setPen(const QPen &pen);
46 void setBrush(const QBrush &brush);
46 void setBrush(const QBrush &brush);
47
47
48 void markerSelected(Marker *item);
48 void markerSelected(Marker *item);
49
49
50 public Q_SLOTS:
50 public Q_SLOTS:
51 void handleUpdated();
51 void handleUpdated();
52
52
53 private:
53 private:
54 void createPoints(int count);
54 void createPoints(int count);
55 void deletePoints(int count);
55 void deletePoints(int count);
56
56
57 protected:
57 protected:
58 void setLayout(QVector<QPointF> &points);
58 void setLayout(QVector<QPointF> &points);
59
59
60 private:
60 private:
61 QScatterSeries *m_series;
61 QScatterSeries *m_series;
62 QGraphicsItemGroup m_items;
62 QGraphicsItemGroup m_items;
63 int m_shape;
63 int m_shape;
64 int m_size;
64 int m_size;
65 QRectF m_rect;
65 QRectF m_rect;
66
66
67 };
67 };
68
68
69
69
70 class Marker: public QAbstractGraphicsShapeItem
70 class Marker: public QAbstractGraphicsShapeItem
71 {
71 {
72
72
73 public:
73 public:
74
74
75 Marker(QAbstractGraphicsShapeItem *item , ScatterChartItem *parent) : QAbstractGraphicsShapeItem(0) ,m_item(item), m_parent(parent), m_index(-1)
75 Marker(QAbstractGraphicsShapeItem *item , ScatterChartItem *parent) : QAbstractGraphicsShapeItem(0) ,m_item(item), m_parent(parent)
76 {
76 {
77 }
77 }
78
78
79 ~Marker()
79 ~Marker()
80 {
80 {
81 delete m_item;
81 delete m_item;
82 }
82 }
83
83
84 void setIndex(int index)
84 void setPoint(const QPointF& point)
85 {
85 {
86 m_index=index;
86 m_point=point;
87 }
87 }
88
88
89 int index() const
89 QPointF point() const
90 {
90 {
91 return m_index;
91 return m_point;
92 }
92 }
93
93
94 QPainterPath shape() const
94 QPainterPath shape() const
95 {
95 {
96 return m_item->shape();
96 return m_item->shape();
97 }
97 }
98
98
99 QRectF boundingRect() const
99 QRectF boundingRect() const
100 {
100 {
101 return m_item->boundingRect();
101 return m_item->boundingRect();
102 }
102 }
103
103
104 bool contains(const QPointF &point) const
104 bool contains(const QPointF &point) const
105 {
105 {
106 return m_item->contains(point);
106 return m_item->contains(point);
107 }
107 }
108
108
109 void setPen(const QPen &pen)
109 void setPen(const QPen &pen)
110 {
110 {
111 m_item->setPen(pen);
111 m_item->setPen(pen);
112 }
112 }
113
113
114 void setBrush(const QBrush &brush)
114 void setBrush(const QBrush &brush)
115 {
115 {
116 m_item->setBrush(brush);
116 m_item->setBrush(brush);
117 }
117 }
118
118
119 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
119 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
120 {
120 {
121 m_item->paint(painter,option,widget);
121 m_item->paint(painter,option,widget);
122 }
122 }
123
123
124 protected:
124 protected:
125
125
126 void mousePressEvent(QGraphicsSceneMouseEvent *event)
126 void mousePressEvent(QGraphicsSceneMouseEvent *event)
127 {
127 {
128 Q_UNUSED(event)
128 Q_UNUSED(event)
129 m_parent->markerSelected(this);
129 m_parent->markerSelected(this);
130 }
130 }
131
131
132 private:
132 private:
133 QAbstractGraphicsShapeItem* m_item;
133 QAbstractGraphicsShapeItem* m_item;
134 ScatterChartItem* m_parent;
134 ScatterChartItem* m_parent;
135 int m_index;
135 QPointF m_point;
136 };
136 };
137
137
138 QTCOMMERCIALCHART_END_NAMESPACE
138 QTCOMMERCIALCHART_END_NAMESPACE
139
139
140 #endif // SCATTERPRESENTER_H
140 #endif // SCATTERPRESENTER_H
@@ -1,210 +1,224
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qsplineseries.h"
21 #include "qsplineseries.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "splinechartitem_p.h"
23 #include "splinechartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27
27
28 /*!
28 /*!
29 \class QSplineSeries
29 \class QSplineSeries
30 \brief Series type used to store data needed to draw a spline.
30 \brief Series type used to store data needed to draw a spline.
31
31
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
34
34
35 \image examples_splinechart.png
35 \image examples_splinechart.png
36
36
37 Creating basic spline chart is simple:
37 Creating basic spline chart is simple:
38 \code
38 \code
39 QSplineSeries* series = new QSplineSeries();
39 QSplineSeries* series = new QSplineSeries();
40 series->append(0, 6);
40 series->append(0, 6);
41 series->append(2, 4);
41 series->append(2, 4);
42 ...
42 ...
43 chart->addSeries(series);
43 chart->addSeries(series);
44 \endcode
44 \endcode
45 */
45 */
46
46
47 /*!
47 /*!
48 \fn QSeriesType QSplineSeries::type() const
48 \fn QSeriesType QSplineSeries::type() const
49 Returns the type of the series
49 Returns the type of the series
50 */
50 */
51
51
52 /*!
52 /*!
53 \fn QSeriesType QSplineSeries::controlPoint(int index) const
53 \fn QSeriesType QSplineSeries::controlPoint(int index) const
54 Returns the control point specified by \a index
54 Returns the control point specified by \a index
55 */
55 */
56
56
57 QTCOMMERCIALCHART_BEGIN_NAMESPACE
57 QTCOMMERCIALCHART_BEGIN_NAMESPACE
58
58
59 /*!
59 /*!
60 Constructs empty series object which is a child of \a parent.
60 Constructs empty series object which is a child of \a parent.
61 When series object is added to QChartView or QChart instance then the ownerships is transferred.
61 When series object is added to QChartView or QChart instance then the ownerships is transferred.
62 */
62 */
63
63
64 QSplineSeries::QSplineSeries(QObject *parent) :
64 QSplineSeries::QSplineSeries(QObject *parent) :
65 QLineSeries(*new QSplineSeriesPrivate(this),parent)
65 QLineSeries(*new QSplineSeriesPrivate(this),parent)
66 {
66 {
67 }
67 }
68
68
69 QAbstractSeries::QSeriesType QSplineSeries::type() const
69 QAbstractSeries::QSeriesType QSplineSeries::type() const
70 {
70 {
71 return QAbstractSeries::SeriesTypeSpline;
71 return QAbstractSeries::SeriesTypeSpline;
72 }
72 }
73
73
74 QPointF QSplineSeries::controlPoint(int index) const
74 QPointF QSplineSeries::controlPoint(int index) const
75 {
75 {
76 Q_D(const QSplineSeries);
76 Q_D(const QSplineSeries);
77 return d->m_controlPoints[index];
77 return d->m_controlPoints[index];
78 }
78 }
79
79
80 /*!
80 /*!
81 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
81 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
82 as a data source for y coordinate. The \a orientation parameter specifies whether the data
82 as a data source for y coordinate. The \a orientation parameter specifies whether the data
83 is in columns or in rows.
83 is in columns or in rows.
84 \sa setModel()
84 \sa setModel()
85 */
85 */
86 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
86 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
87 {
87 {
88 Q_D(QSplineSeries);
88 Q_D(QSplineSeries);
89 QXYSeries::setModelMapping(modelX, modelY, orientation);
89 QXYSeries::setModelMapping(modelX, modelY, orientation);
90 d->calculateControlPoints();
90 d->calculateControlPoints();
91 }
91 }
92
92
93 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
94
94
95 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
95 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
96 {
96 {
97 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
97 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
98 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
98 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
100 };
100 };
101
101
102 /*!
102 /*!
103 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
103 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
104 */
104 */
105 void QSplineSeriesPrivate::calculateControlPoints()
105 void QSplineSeriesPrivate::calculateControlPoints()
106 {
106 {
107
107
108 Q_Q(QSplineSeries);
108 int n = m_points.count() - 1;
109
110 int n = q->count() - 1;
111
109
112 if (n == 1)
110 if (n == 1)
113 {
111 {
114 //for n==1
112 //for n==1
115 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
113 m_controlPoints[0].setX((2 * m_points[0].x() + m_points[1].x()) / 3);
116 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
114 m_controlPoints[0].setY((2 * m_points[0].y() + m_points[1].y()) / 3);
115 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - m_points[0].x());
116 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - m_points[0].y());
117 return;
117 return;
118 }
118 }
119
119
120 // Calculate first Bezier control points
120 // Calculate first Bezier control points
121 // Right hand side vector
121 // Right hand side vector
122 // Set of equations for P0 to Pn points.
122 // Set of equations for P0 to Pn points.
123 //
123 //
124 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
124 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
125 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
125 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
126 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
126 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
127 // | . . . . . . . . . . . . | | ... | | ... |
127 // | . . . . . . . . . . . . | | ... | | ... |
128 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
128 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
129 // | . . . . . . . . . . . . | | ... | | ... |
129 // | . . . . . . . . . . . . | | ... | | ... |
130 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
130 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
131 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
131 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
132 //
132 //
133 QList<qreal> points;
133 QVector<qreal> vector;
134 vector.resize(n);
135
136 vector[0] = m_points[0].x() + 2 * m_points[1].x();
134
137
135 points.append(q->x(0) + 2 * q->x(1));
136
138
139 for (int i = 1; i < n - 1; ++i){
140 vector[i] = 4 * m_points[i].x() + 2 * m_points[i + 1].x();
141 }
137
142
138 for (int i = 1; i < n - 1; ++i)
143 vector[n - 1] = (8 * m_points[n-1].x() + m_points[n].x()) / 2.0;
139 points.append(4 * q->x(i) + 2 * q->x(i + 1));
140
144
141 points.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
145 QVector<qreal> xControl = firstControlPoints(vector);
142
146
143 QList<qreal> xControl = firstControlPoints(points);
147 vector[0] = m_points[0].y() + 2 * m_points[1].y();
144 points[0] = q->y(0) + 2 * q->y(1);
145
148
146 for (int i = 1; i < n - 1; ++i) {
149 for (int i = 1; i < n - 1; ++i) {
147 points[i] = 4 * q->y(i) + 2 * q->y(i + 1);
150 vector[i] = 4 * m_points[i].y() + 2 * m_points[i + 1].y();
148 }
151 }
149
152
150 points[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
153 vector[n - 1] = (8 * m_points[n-1].y() + m_points[n].y()) / 2.0;
154
155 QVector<qreal> yControl = firstControlPoints(vector);
151
156
152 QList<qreal> yControl = firstControlPoints(points);
157 for (int i = 0,j =0; i < n; ++i, ++j) {
153
158
154 for (int i = 0; i < n; ++i) {
159 m_controlPoints[j].setX(xControl[i]);
160 m_controlPoints[j].setY(yControl[i]);
155
161
156 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
162 j++;
157
163
158 if (i < n - 1)
164 if (i < n - 1){
159 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
165 m_controlPoints[j].setX(2 * m_points[i+1].x() - xControl[i + 1]);
160 else
166 m_controlPoints[j].setY(2 * m_points[i+1].y() - yControl[i + 1]);
161 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
167 }else{
168 m_controlPoints[j].setX((m_points[n].x() + xControl[n - 1]) / 2);
169 m_controlPoints[j].setY((m_points[n].y() + yControl[n - 1]) / 2);
170 }
162 }
171 }
163 }
172 }
164
173
165 QList<qreal> QSplineSeriesPrivate::firstControlPoints(QList<qreal> list)
174 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
166 {
175 {
167 QList<qreal> result;
176 QVector<qreal> result;
168 QList<qreal> temp;
177
178 int count = vector.count();
179 result.resize(count);
180 result[0] = vector[0] / 2.0;
181
182 QVector<qreal> temp;
183 temp.resize(count);
184 temp[0] = 0;
169
185
170 qreal b = 2.0;
186 qreal b = 2.0;
171 result.append(list[0] / b);
187
172 temp.append(0);
188 for (int i = 1; i < count; i++) {
173 for (int i = 1; i < list.size(); i++) {
189 temp[i] = 1 / b;
174 temp.append(1 / b);
190 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
175 b = (i < list.size() - 1 ? 4.0 : 3.5) - temp[i];
191 result[i]=(vector[i] - result[i - 1]) / b;
176 result.append((list[i] - result[i - 1]) / b);
177 }
192 }
178 for (int i = 1; i < list.size(); i++)
193 for (int i = 1; i < count; i++)
179 result[list.size() - i - 1] -= temp[list.size() - i] * result[list.size() - i];
194 result[count - i - 1] -= temp[count - i] * result[count - i];
180
195
181 return result;
196 return result;
182 }
197 }
183
198
184 /*!
199 /*!
185 Updates the control points, besed on currently avaiable knots.
200 Updates the control points, besed on currently avaiable knots.
186 */
201 */
187 void QSplineSeriesPrivate::updateControlPoints()
202 void QSplineSeriesPrivate::updateControlPoints()
188 {
203 {
189 Q_Q(QSplineSeries);
204 if (m_points.count() > 1) {
190 if (q->count() > 1) {
205 m_controlPoints.resize(2*m_points.count()-2);
191 m_controlPoints.clear();
192 calculateControlPoints();
206 calculateControlPoints();
193 }
207 }
194 }
208 }
195
209
196 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
210 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
197 {
211 {
198 Q_Q(QSplineSeries);
212 Q_Q(QSplineSeries);
199 SplineChartItem* spline = new SplineChartItem(q,presenter);
213 SplineChartItem* spline = new SplineChartItem(q,presenter);
200 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
214 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
201 presenter->animator()->addAnimation(spline);
215 presenter->animator()->addAnimation(spline);
202 }
216 }
203 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
217 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
204 return spline;
218 return spline;
205 }
219 }
206
220
207 #include "moc_qsplineseries.cpp"
221 #include "moc_qsplineseries.cpp"
208 #include "moc_qsplineseries_p.cpp"
222 #include "moc_qsplineseries_p.cpp"
209
223
210 QTCOMMERCIALCHART_END_NAMESPACE
224 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,57 +1,60
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QSPLINESERIES_P_H
30 #ifndef QSPLINESERIES_P_H
31 #define QSPLINESERIES_P_H
31 #define QSPLINESERIES_P_H
32
32
33 #include "qlineseries_p.h"
33 #include "qlineseries_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37
37
38 class QSplineSeriesPrivate: public QLineSeriesPrivate
38 class QSplineSeriesPrivate: public QLineSeriesPrivate
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 Chart* createGraphics(ChartPresenter* presenter);
42 Chart* createGraphics(ChartPresenter* presenter);
43 QSplineSeriesPrivate(QSplineSeries* q);
43 QSplineSeriesPrivate(QSplineSeries* q);
44 void calculateControlPoints();
45 QList<qreal> firstControlPoints(QList<qreal> rhs);
46
44
47 public Q_SLOTS:
45 public Q_SLOTS:
48 void updateControlPoints();
46 void updateControlPoints();
47
48 private:
49 void calculateControlPoints();
50 QVector<qreal> firstControlPoints(const QVector<qreal>& vector);
51
49 public:
52 public:
50 QList<QPointF> m_controlPoints;
53 QVector<QPointF> m_controlPoints;
51 private:
54 private:
52 Q_DECLARE_PUBLIC(QSplineSeries)
55 Q_DECLARE_PUBLIC(QSplineSeries)
53 };
56 };
54
57
55 QTCOMMERCIALCHART_END_NAMESPACE
58 QTCOMMERCIALCHART_END_NAMESPACE
56
59
57 #endif
60 #endif
@@ -1,503 +1,455
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qxyseries.h"
21 #include "qxyseries.h"
22 #include "qxyseries_p.h"
22 #include "qxyseries_p.h"
23 #include "domain_p.h"
23 #include "domain_p.h"
24 #include "legendmarker_p.h"
24 #include "legendmarker_p.h"
25 #include <QAbstractItemModel>
25 #include <QAbstractItemModel>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 /*!
29 /*!
30 \class QXYSeries
30 \class QXYSeries
31 \brief The QXYSeries class is a base class for line, spline and scatter series.
31 \brief The QXYSeries class is a base class for line, spline and scatter series.
32 */
32 */
33
33
34 /*!
34 /*!
35 \fn QPen QXYSeries::pen() const
35 \fn QPen QXYSeries::pen() const
36 \brief Returns pen used to draw points for series.
36 \brief Returns pen used to draw points for series.
37 \sa setPen()
37 \sa setPen()
38 */
38 */
39
39
40 /*!
40 /*!
41 \fn QBrush QXYSeries::brush() const
41 \fn QBrush QXYSeries::brush() const
42 \brief Returns brush used to draw points for series.
42 \brief Returns brush used to draw points for series.
43 \sa setBrush()
43 \sa setBrush()
44 */
44 */
45
45
46 /*!
46 /*!
47 \fn void QXYSeries::clicked(const QPointF& point)
47 \fn void QXYSeries::clicked(const QPointF& point)
48 \brief Signal is emitted when user clicks the \a point on chart.
48 \brief Signal is emitted when user clicks the \a point on chart.
49 */
49 */
50
50
51 /*!
51 /*!
52 \fn void QXYSeries::selected()
52 \fn void QXYSeries::selected()
53
53
54 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
54 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
55 implemented by the user of QXYSeries API.
55 implemented by the user of QXYSeries API.
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn void QXYSeriesPrivate::pointReplaced(int index)
59 \fn void QXYSeriesPrivate::pointReplaced(int index)
60 \brief \internal \a index
60 \brief \internal \a index
61 */
61 */
62
62
63 /*!
63 /*!
64 \fn void QXYSeriesPrivate::pointAdded(int index)
64 \fn void QXYSeriesPrivate::pointAdded(int index)
65 \brief \internal \a index
65 \brief \internal \a index
66 */
66 */
67
67
68 /*!
68 /*!
69 \fn void QXYSeriesPrivate::pointRemoved(int index)
69 \fn void QXYSeriesPrivate::pointRemoved(int index)
70 \brief \internal \a index
70 \brief \internal \a index
71 */
71 */
72
72
73 /*!
73 /*!
74 \fn void QXYSeriesPrivate::updated()
74 \fn void QXYSeriesPrivate::updated()
75 \brief \internal
75 \brief \internal
76 */
76 */
77
77
78 /*!
78 /*!
79 \internal
79 \internal
80
80
81 Constructs empty series object which is a child of \a parent.
81 Constructs empty series object which is a child of \a parent.
82 When series object is added to QChartView or QChart instance ownerships is transferred.
82 When series object is added to QChartView or QChart instance ownerships is transferred.
83 */
83 */
84 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
84 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
85 {
85 {
86
86
87 }
87 }
88 /*!
88 /*!
89 Destroys the object. Series added to QChartView or QChart instances are owned by those,
89 Destroys the object. Series added to QChartView or QChart instances are owned by those,
90 and are deleted when mentioned object are destroyed.
90 and are deleted when mentioned object are destroyed.
91 */
91 */
92 QXYSeries::~QXYSeries()
92 QXYSeries::~QXYSeries()
93 {
93 {
94 }
94 }
95
95
96 /*!
96 /*!
97 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
97 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
98 */
98 */
99 void QXYSeries::append(qreal x,qreal y)
99 void QXYSeries::append(qreal x,qreal y)
100 {
100 {
101 Q_D(QXYSeries);
101 append(QPointF(x,y));
102 Q_ASSERT(d->m_x.size() == d->m_y.size());
103 d->m_x<<x;
104 d->m_y<<y;
105 emit d->pointAdded(d->m_x.size()-1);
106 }
102 }
107
103
108 /*!
104 /*!
109 This is an overloaded function.
105 This is an overloaded function.
110 Adds data \a point to the series. Points are connected with lines on the chart.
106 Adds data \a point to the series. Points are connected with lines on the chart.
111 */
107 */
112 void QXYSeries::append(const QPointF &point)
108 void QXYSeries::append(const QPointF &point)
113 {
109 {
114 append(point.x(),point.y());
110 Q_D(QXYSeries);
111 d->m_points<<point;
112 emit d->pointAdded(d->m_points.count()-1);
115 }
113 }
116
114
117 /*!
115 /*!
118 This is an overloaded function.
116 This is an overloaded function.
119 Adds list of data \a points to the series. Points are connected with lines on the chart.
117 Adds list of data \a points to the series. Points are connected with lines on the chart.
120 */
118 */
121 void QXYSeries::append(const QList<QPointF> points)
119 void QXYSeries::append(const QList<QPointF> &points)
122 {
120 {
123 foreach(const QPointF& point , points) {
121 foreach(const QPointF& point , points) {
124 append(point.x(),point.y());
122 append(point);
125 }
123 }
126 }
124 }
127
125
128 /*!
129 Modifies \a y value for given \a x a value.
130 */
131 void QXYSeries::replace(qreal x,qreal y)
132 {
133 Q_D(QXYSeries);
134 int index = d->m_x.indexOf(x);
135 d->m_x[index] = x;
136 d->m_y[index] = y;
137 emit d->pointReplaced(index);
138 }
139
126
140 /*!
127 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
141 This is an overloaded function.
142 Replaces current y value of for given \a point x value with \a point y value.
143 */
144 void QXYSeries::replace(const QPointF &point)
145 {
128 {
146 replace(point.x(),point.y());
129 replace(QPointF(oldX,oldY),QPointF(newX,newY));
147 }
130 }
148
131
149 /*!
132 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
150 Removes first \a x value and related y value.
151 */
152 void QXYSeries::remove(qreal x)
153 {
133 {
154 Q_D(QXYSeries);
134 Q_D(QXYSeries);
155 int index = d->m_x.indexOf(x);
135 int index = d->m_points.indexOf(oldPoint);
156
136 if(index==1) return;
157 if (index == -1) return;
137 d->m_points[index] = newPoint;
158
138 emit d->pointReplaced(index);
159 d->m_x.remove(index);
160 d->m_y.remove(index);
161
162 emit d->pointRemoved(index);
163 }
139 }
164
140
165 /*!
141 /*!
166 Removes current \a x and \a y value.
142 Removes current \a x and \a y value.
167 */
143 */
168 void QXYSeries::remove(qreal x,qreal y)
144 void QXYSeries::remove(qreal x,qreal y)
169 {
145 {
170 Q_D(QXYSeries);
146 remove(QPointF(x,y));
171 int index =-1;
172 do {
173 index = d->m_x.indexOf(x,index+1);
174 } while (index !=-1 && d->m_y.at(index)!=y);
175
176 if (index==-1) return;
177
178 d->m_x.remove(index);
179 d->m_y.remove(index);
180 emit d->pointRemoved(index);
181 }
147 }
182
148
183 /*!
149 /*!
184 Removes current \a point x value. Note \a point y value is ignored.
150 Removes current \a point x value. Note \a point y value is ignored.
185 */
151 */
186 void QXYSeries::remove(const QPointF &point)
152 void QXYSeries::remove(const QPointF &point)
187 {
153 {
188 remove(point.x(),point.y());
154 Q_D(QXYSeries);
155 int index = d->m_points.indexOf(point);
156 if(index==1) return;
157 d->m_points.remove(index);
158 emit d->pointRemoved(index);
189 }
159 }
190
160
191 /*!
161 /*!
192 Removes all data points from the series.
162 Removes all data points from the series.
193 */
163 */
194 void QXYSeries::removeAll()
164 void QXYSeries::removeAll()
195 {
165 {
196 Q_D(QXYSeries);
166 Q_D(QXYSeries);
197 d->m_x.clear();
167 foreach(const QPointF& point, d->m_points) {
198 d->m_y.clear();
168 remove(point);
169 }
199 }
170 }
200
171
201 /*!
172 /*!
202 \internal \a pos
173 \internal \a pos
203 */
174 */
204 qreal QXYSeries::x(int pos) const
175 QList<QPointF> QXYSeries::points() const
205 {
176 {
206 Q_D(const QXYSeries);
177 Q_D(const QXYSeries);
207 if (d->m_model) {
178 if (d->m_model) {
208 if (d->m_mapOrientation == Qt::Vertical)
179 QList<QPointF> result;
180 if (d->m_mapOrientation == Qt::Vertical){
209 // consecutive data is read from model's column
181 // consecutive data is read from model's column
210 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapX), Qt::DisplayRole).toDouble();
182
211 else
183 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
212 // consecutive data is read from model's row
184 qreal x = d->m_model->data(d->m_model->index(i, d->m_mapX), Qt::DisplayRole).toReal();
213 return d->m_model->data(d->m_model->index(d->m_mapX, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
185 qreal y = d->m_model->data(d->m_model->index(i, d->m_mapY), Qt::DisplayRole).toReal();
214 } else {
186 result << QPointF(x,y);
215 // model is not specified, return the data from series' internal data store
216 return d->m_x.at(pos);
217 }
187 }
188 return result;
218 }
189 }
219
190 else{
220 /*!
221 \internal \a pos
222 */
223 qreal QXYSeries::y(int pos) const
224 {
225 Q_D(const QXYSeries);
226 if (d->m_model) {
227 if (d->m_mapOrientation == Qt::Vertical)
228 // consecutive data is read from model's column
229 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapY), Qt::DisplayRole).toDouble();
230 else
231 // consecutive data is read from model's row
191 // consecutive data is read from model's row
232 return d->m_model->data(d->m_model->index(d->m_mapY, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
192 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
193 qreal x = d->m_model->data(d->m_model->index(d->m_mapX, i), Qt::DisplayRole).toReal();
194 qreal y = d->m_model->data(d->m_model->index(d->m_mapY, i), Qt::DisplayRole).toReal();
195 result << QPointF(x,y);
196 }
197 return result;
198 }
233 } else {
199 } else {
234 // model is not specified, return the data from series' internal data store
200 // model is not specified, return the data from series' internal data store
235 return d->m_y.at(pos);
201 return d->m_points.toList();
236 }
202 }
237 }
203 }
238
204
239 /*!
205 /*!
240 Returns number of data points within series.
206 Returns number of data points within series.
241 */
207 */
242 int QXYSeries::count() const
208 int QXYSeries::count() const
243 {
209 {
244 Q_D(const QXYSeries);
210 Q_D(const QXYSeries);
245
211
246 Q_ASSERT(d->m_x.size() == d->m_y.size());
247
248 if (d->m_model) {
212 if (d->m_model) {
249 if (d->m_mapOrientation == Qt::Vertical) {
213 if (d->m_mapOrientation == Qt::Vertical) {
250 // data is in a column. Return the number of mapped items if the model's column have enough items
214 // data is in a column. Return the number of mapped items if the model's column have enough items
251 // or the number of items that can be mapped
215 // or the number of items that can be mapped
252 if (d->m_mapCount != -1)
216 if (d->m_mapCount != -1)
253 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
217 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
254 else
218 else
255 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
219 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
256 } else {
220 } else {
257 // data is in a row. Return the number of mapped items if the model's row have enough items
221 // data is in a row. Return the number of mapped items if the model's row have enough items
258 // or the number of items that can be mapped
222 // or the number of items that can be mapped
259 if (d->m_mapCount != -1)
223 if (d->m_mapCount != -1)
260 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
224 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
261 else
225 else
262 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
226 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
263 }
227 }
264 }
228 }
265
229
266 // model is not specified, return the number of points in the series internal data store
230 // model is not specified, return the number of points in the series internal data store
267 return d->m_x.size();
231 return d->m_points.count();
268 }
269
270 /*!
271 Returns the data points of the series.
272 */
273 QList<QPointF> QXYSeries::data()
274 {
275 Q_D(QXYSeries);
276 QList<QPointF> data;
277 for (int i(0); i < d->m_x.count() && i < d->m_y.count(); i++)
278 data.append(QPointF(d->m_x.at(i), d->m_y.at(i)));
279 return data;
280 }
232 }
281
233
282
234
283 /*!
235 /*!
284 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
236 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
285 pen from chart theme is used.
237 pen from chart theme is used.
286 \sa QChart::setTheme()
238 \sa QChart::setTheme()
287 */
239 */
288 void QXYSeries::setPen(const QPen &pen)
240 void QXYSeries::setPen(const QPen &pen)
289 {
241 {
290 Q_D(QXYSeries);
242 Q_D(QXYSeries);
291 if (d->m_pen!=pen) {
243 if (d->m_pen!=pen) {
292 d->m_pen = pen;
244 d->m_pen = pen;
293 emit d->updated();
245 emit d->updated();
294 }
246 }
295 }
247 }
296
248
297 QPen QXYSeries::pen() const
249 QPen QXYSeries::pen() const
298 {
250 {
299 Q_D(const QXYSeries);
251 Q_D(const QXYSeries);
300 return d->m_pen;
252 return d->m_pen;
301 }
253 }
302
254
303 /*!
255 /*!
304 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
256 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
305 from chart theme setting is used.
257 from chart theme setting is used.
306 \sa QChart::setTheme()
258 \sa QChart::setTheme()
307 */
259 */
308 void QXYSeries::setBrush(const QBrush &brush)
260 void QXYSeries::setBrush(const QBrush &brush)
309 {
261 {
310 Q_D(QXYSeries);
262 Q_D(QXYSeries);
311 if (d->m_brush!=brush) {
263 if (d->m_brush!=brush) {
312 d->m_brush = brush;
264 d->m_brush = brush;
313 emit d->updated();
265 emit d->updated();
314 }
266 }
315 }
267 }
316
268
317 QBrush QXYSeries::brush() const
269 QBrush QXYSeries::brush() const
318 {
270 {
319 Q_D(const QXYSeries);
271 Q_D(const QXYSeries);
320 return d->m_brush;
272 return d->m_brush;
321 }
273 }
322
274
323
275
324 /*!
276 /*!
325 Sets if data points are \a visible and should be drawn on line.
277 Sets if data points are \a visible and should be drawn on line.
326 */
278 */
327 void QXYSeries::setPointsVisible(bool visible)
279 void QXYSeries::setPointsVisible(bool visible)
328 {
280 {
329 Q_D(QXYSeries);
281 Q_D(QXYSeries);
330 if (d->m_pointsVisible != visible){
282 if (d->m_pointsVisible != visible){
331 d->m_pointsVisible = visible;
283 d->m_pointsVisible = visible;
332 emit d->updated();
284 emit d->updated();
333 }
285 }
334 }
286 }
335
287
336 /*!
288 /*!
337 Returns true if drawing the data points of the series is enabled.
289 Returns true if drawing the data points of the series is enabled.
338 */
290 */
339 bool QXYSeries::pointsVisible() const
291 bool QXYSeries::pointsVisible() const
340 {
292 {
341 Q_D(const QXYSeries);
293 Q_D(const QXYSeries);
342 return d->m_pointsVisible;
294 return d->m_pointsVisible;
343 }
295 }
344
296
345
297
346 /*!
298 /*!
347 Stream operator for adding a data \a point to the series.
299 Stream operator for adding a data \a point to the series.
348 \sa append()
300 \sa append()
349 */
301 */
350 QXYSeries& QXYSeries::operator<< (const QPointF &point)
302 QXYSeries& QXYSeries::operator<< (const QPointF &point)
351 {
303 {
352 append(point);
304 append(point);
353 return *this;
305 return *this;
354 }
306 }
355
307
356
308
357 /*!
309 /*!
358 Stream operator for adding a list of \a points to the series.
310 Stream operator for adding a list of \a points to the series.
359 \sa append()
311 \sa append()
360 */
312 */
361
313
362 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
314 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
363 {
315 {
364 append(points);
316 append(points);
365 return *this;
317 return *this;
366 }
318 }
367
319
368 /*!
320 /*!
369 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
321 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
370 Sets the \a model to be used as a data source
322 Sets the \a model to be used as a data source
371 \sa setModelMapping()
323 \sa setModelMapping()
372 */
324 */
373 bool QXYSeries::setModel(QAbstractItemModel *model)
325 bool QXYSeries::setModel(QAbstractItemModel *model)
374 {
326 {
375 Q_D(QXYSeries);
327 Q_D(QXYSeries);
376 // disconnect signals from old model
328 // disconnect signals from old model
377 if (d->m_model) {
329 if (d->m_model) {
378 QObject::disconnect(d->m_model, 0, this, 0);
330 QObject::disconnect(d->m_model, 0, this, 0);
379 d->m_mapX = -1;
331 d->m_mapX = -1;
380 d->m_mapY = -1;
332 d->m_mapY = -1;
381 d->m_mapOrientation = Qt::Vertical;
333 d->m_mapOrientation = Qt::Vertical;
382 }
334 }
383
335
384 // set new model
336 // set new model
385 if (model) {
337 if (model) {
386 d->m_model = model;
338 d->m_model = model;
387 return true;
339 return true;
388 } else {
340 } else {
389 d->m_model = 0;
341 d->m_model = 0;
390 return false;
342 return false;
391 }
343 }
392 }
344 }
393
345
394 /*!
346 /*!
395 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
347 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
396 as a data source for y coordinate. The \a orientation parameter specifies whether the data
348 as a data source for y coordinate. The \a orientation parameter specifies whether the data
397 is in columns or in rows.
349 is in columns or in rows.
398 \sa setModel()
350 \sa setModel()
399 */
351 */
400 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
352 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
401 {
353 {
402 Q_D(QXYSeries);
354 Q_D(QXYSeries);
403 if (d->m_model == 0)
355 if (d->m_model == 0)
404 return;
356 return;
405 d->m_mapX = modelX;
357 d->m_mapX = modelX;
406 d->m_mapY = modelY;
358 d->m_mapY = modelY;
407 d->m_mapOrientation = orientation;
359 d->m_mapOrientation = orientation;
408
360
409 // connect the signals from the model
361 // connect the signals from the model
410 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
362 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
411 if (d->m_mapOrientation == Qt::Vertical) {
363 if (d->m_mapOrientation == Qt::Vertical) {
412 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
364 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
413 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
365 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
414 } else {
366 } else {
415 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
367 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
416 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
368 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
417 }
369 }
418 }
370 }
419
371
420 void QXYSeries::setModelMappingRange(int first, int count)
372 void QXYSeries::setModelMappingRange(int first, int count)
421 {
373 {
422 Q_D(QXYSeries);
374 Q_D(QXYSeries);
423 d->m_mapFirst = first;
375 d->m_mapFirst = first;
424 d->m_mapCount = count;
376 d->m_mapCount = count;
425 }
377 }
426
378
427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
428
380
429
381
430 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
382 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
431 m_mapX(-1),
383 m_mapX(-1),
432 m_mapY(-1),
384 m_mapY(-1),
433 m_pointsVisible(false)
385 m_pointsVisible(false)
434 {
386 {
435 }
387 }
436
388
437 void QXYSeriesPrivate::scaleDomain(Domain& domain)
389 void QXYSeriesPrivate::scaleDomain(Domain& domain)
438 {
390 {
439 qreal minX(domain.minX());
391 qreal minX(domain.minX());
440 qreal minY(domain.minY());
392 qreal minY(domain.minY());
441 qreal maxX(domain.maxX());
393 qreal maxX(domain.maxX());
442 qreal maxY(domain.maxY());
394 qreal maxY(domain.maxY());
443 int tickXCount(domain.tickXCount());
395 int tickXCount(domain.tickXCount());
444 int tickYCount(domain.tickYCount());
396 int tickYCount(domain.tickYCount());
445
397
446 Q_Q(QXYSeries);
398 for (int i = 0; i < m_points.count(); i++)
447 for (int i = 0; i < q->count(); i++)
448 {
399 {
449 qreal x = q->x(i);
400
450 qreal y = q->y(i);
401 qreal x = m_points[i].x();
402 qreal y = m_points[i].y();
451 minX = qMin(minX, x);
403 minX = qMin(minX, x);
452 minY = qMin(minY, y);
404 minY = qMin(minY, y);
453 maxX = qMax(maxX, x);
405 maxX = qMax(maxX, x);
454 maxY = qMax(maxY, y);
406 maxY = qMax(maxY, y);
455 }
407 }
456
408
457 domain.setRangeX(minX,maxX,tickXCount);
409 domain.setRangeX(minX,maxX,tickXCount);
458 domain.setRangeY(minY,maxY,tickYCount);
410 domain.setRangeY(minY,maxY,tickYCount);
459 }
411 }
460
412
461 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
413 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
462 {
414 {
463 Q_Q(QXYSeries);
415 Q_Q(QXYSeries);
464 QList<LegendMarker*> list;
416 QList<LegendMarker*> list;
465 return list << new XYLegendMarker(q,legend);
417 return list << new XYLegendMarker(q,legend);
466 }
418 }
467
419
468 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
420 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
469 {
421 {
470 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
422 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
471 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
423 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
472 if (m_mapOrientation == Qt::Vertical) {
424 if (m_mapOrientation == Qt::Vertical) {
473 if ((column == m_mapX || column == m_mapY) // modified item is in a mapped column
425 if ((column == m_mapX || column == m_mapY) // modified item is in a mapped column
474 && row >= m_mapFirst // modfied item in not before first item
426 && row >= m_mapFirst // modfied item in not before first item
475 && (m_mapCount == -1 || row < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
427 && (m_mapCount == -1 || row < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
476 emit pointReplaced(row - m_mapFirst);
428 emit pointReplaced(row - m_mapFirst);
477 } else {
429 } else {
478 if ((row == m_mapX || row == m_mapY) // modified item is in a mapped row
430 if ((row == m_mapX || row == m_mapY) // modified item is in a mapped row
479 && column >= m_mapFirst // modfied item in not before first item
431 && column >= m_mapFirst // modfied item in not before first item
480 && (m_mapCount == -1 || column < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
432 && (m_mapCount == -1 || column < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
481 emit pointReplaced(column - m_mapFirst);
433 emit pointReplaced(column - m_mapFirst);
482 }
434 }
483 }
435 }
484 }
436 }
485 }
437 }
486
438
487
439
488 void QXYSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
440 void QXYSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
489 {
441 {
490 Q_UNUSED(parent);
442 Q_UNUSED(parent);
491 emit pointsAdded(start, end);
443 emit pointsAdded(start, end);
492 }
444 }
493
445
494 void QXYSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
446 void QXYSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
495 {
447 {
496 Q_UNUSED(parent);
448 Q_UNUSED(parent);
497 emit pointsRemoved(start, end);
449 emit pointsRemoved(start, end);
498 }
450 }
499
451
500 #include "moc_qxyseries.cpp"
452 #include "moc_qxyseries.cpp"
501 #include "moc_qxyseries_p.cpp"
453 #include "moc_qxyseries_p.cpp"
502
454
503 QTCOMMERCIALCHART_END_NAMESPACE
455 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,90 +1,87
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef QXYSERIES_H
21 #ifndef QXYSERIES_H
22 #define QXYSERIES_H
22 #define QXYSERIES_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <qabstractseries.h>
25 #include <qabstractseries.h>
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28
28
29 class QModelIndex;
29 class QModelIndex;
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 class QXYSeriesPrivate;
33 class QXYSeriesPrivate;
34
34
35 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QAbstractSeries
35 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QAbstractSeries
36 {
36 {
37 Q_OBJECT
37 Q_OBJECT
38 protected:
38 protected:
39 explicit QXYSeries(QXYSeriesPrivate &d,QObject *parent = 0);
39 explicit QXYSeries(QXYSeriesPrivate &d,QObject *parent = 0);
40 ~QXYSeries();
40 ~QXYSeries();
41
41
42 public:
42 public:
43 void append(qreal x, qreal y);
43 void append(qreal x, qreal y);
44 void append(const QPointF &point);
44 void append(const QPointF &point);
45 void append(const QList<QPointF> points);
45 void append(const QList<QPointF> &points);
46 void replace(qreal x,qreal y);
46 void replace(qreal oldX,qreal oldY,qreal newX,qreal newY);
47 void replace(const QPointF &point);
47 void replace(const QPointF &oldPoint,const QPointF &newPoint);
48 void remove(qreal x);
49 void remove(qreal x, qreal y);
48 void remove(qreal x, qreal y);
50 void remove(const QPointF &point);
49 void remove(const QPointF &point);
51 void removeAll();
50 void removeAll();
52
51
53 int count() const;
52 int count() const;
54 qreal x(int pos) const;
53 QList<QPointF> points() const;
55 qreal y(int pos) const;
56 QList<QPointF> data();
57
54
58 QXYSeries& operator << (const QPointF &point);
55 QXYSeries& operator << (const QPointF &point);
59 QXYSeries& operator << (const QList<QPointF> points);
56 QXYSeries& operator << (const QList<QPointF> &points);
60
57
61 void setPen(const QPen &pen);
58 void setPen(const QPen &pen);
62 QPen pen() const;
59 QPen pen() const;
63
60
64 void setBrush(const QBrush &brush);
61 void setBrush(const QBrush &brush);
65 QBrush brush() const;
62 QBrush brush() const;
66
63
67 void setPointsVisible(bool visible = true);
64 void setPointsVisible(bool visible = true);
68 bool pointsVisible() const;
65 bool pointsVisible() const;
69
66
70 bool setModel(QAbstractItemModel *model);
67 bool setModel(QAbstractItemModel *model);
71 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
68 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
72 void setModelMappingRange(int first, int count = -1);
69 void setModelMappingRange(int first, int count = -1);
73
70
74 //private Q_SLOTS:
71 //private Q_SLOTS:
75 // void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
72 // void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
76
73
77 Q_SIGNALS:
74 Q_SIGNALS:
78 void clicked(const QPointF &point);
75 void clicked(const QPointF &point);
79 void selected();
76 void selected();
80
77
81 private:
78 private:
82 Q_DECLARE_PRIVATE(QXYSeries);
79 Q_DECLARE_PRIVATE(QXYSeries);
83 Q_DISABLE_COPY(QXYSeries);
80 Q_DISABLE_COPY(QXYSeries);
84 friend class XYLegendMarker;
81 friend class XYLegendMarker;
85 friend class XYChartItem;
82 friend class XYChartItem;
86 };
83 };
87
84
88 QTCOMMERCIALCHART_END_NAMESPACE
85 QTCOMMERCIALCHART_END_NAMESPACE
89
86
90 #endif
87 #endif
@@ -1,83 +1,82
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QXYSERIES_P_H
30 #ifndef QXYSERIES_P_H
31 #define QXYSERIES_P_H
31 #define QXYSERIES_P_H
32
32
33 #include "qabstractseries_p.h"
33 #include "qabstractseries_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 class QXYSeries;
37 class QXYSeries;
38
38
39 class QXYSeriesPrivate: public QAbstractSeriesPrivate
39 class QXYSeriesPrivate: public QAbstractSeriesPrivate
40 {
40 {
41 Q_OBJECT
41 Q_OBJECT
42
42
43 public:
43 public:
44 QXYSeriesPrivate(QXYSeries* q);
44 QXYSeriesPrivate(QXYSeries* q);
45
45
46 void scaleDomain(Domain& domain);
46 void scaleDomain(Domain& domain);
47 QList<LegendMarker*> createLegendMarker(QLegend* legend);
47 QList<LegendMarker*> createLegendMarker(QLegend* legend);
48
48
49 private Q_SLOTS:
49 private Q_SLOTS:
50 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
51 void modelDataAdded(QModelIndex parent, int start, int end);
51 void modelDataAdded(QModelIndex parent, int start, int end);
52 void modelDataRemoved(QModelIndex parent, int start, int end);
52 void modelDataRemoved(QModelIndex parent, int start, int end);
53
53
54 Q_SIGNALS:
54 Q_SIGNALS:
55 void updated();
55 void updated();
56 void pointReplaced(int index);
56 void pointReplaced(int index);
57 void pointRemoved(int index);
57 void pointRemoved(int index);
58 void pointsRemoved(int start, int end);
58 void pointsRemoved(int start, int end);
59 void pointAdded(int index);
59 void pointAdded(int index);
60 void pointsAdded(int start, int end);
60 void pointsAdded(int start, int end);
61
61
62
62
63
63
64 protected:
64 protected:
65 QVector<qreal> m_x;
65 QVector<QPointF> m_points;
66 QVector<qreal> m_y;
67
66
68 QPen m_pen;
67 QPen m_pen;
69 QBrush m_brush;
68 QBrush m_brush;
70
69
71 int m_mapX;
70 int m_mapX;
72 int m_mapY;
71 int m_mapY;
73 bool m_pointsVisible;
72 bool m_pointsVisible;
74
73
75 private:
74 private:
76 Q_DECLARE_PUBLIC(QXYSeries);
75 Q_DECLARE_PUBLIC(QXYSeries);
77 friend class QScatterSeries;
76 friend class QScatterSeries;
78
77
79 };
78 };
80
79
81 QTCOMMERCIALCHART_END_NAMESPACE
80 QTCOMMERCIALCHART_END_NAMESPACE
82
81
83 #endif
82 #endif
@@ -1,306 +1,309
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xychartitem_p.h"
21 #include "xychartitem_p.h"
22 #include "qxyseries.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
23 #include "qxyseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "chartanimator_p.h"
25 #include "chartanimator_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <QGraphicsSceneMouseEvent>
27 #include <QGraphicsSceneMouseEvent>
28 #include <QAbstractItemModel>
28 #include <QAbstractItemModel>
29
29
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 //TODO: optimize : remove points which are not visible
33 //TODO: optimize : remove points which are not visible
34
34
35 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
35 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
36 m_minX(0),
36 m_minX(0),
37 m_maxX(0),
37 m_maxX(0),
38 m_minY(0),
38 m_minY(0),
39 m_maxY(0),
39 m_maxY(0),
40 m_series(series)
40 m_series(series)
41 {
41 {
42 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
42 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
43 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
43 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
44 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
44 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
45 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
45 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
46 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
46 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
47 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
47 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
48 }
48 }
49
49
50 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
50 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
51 {
51 {
52 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
52 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
53 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
53 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
54 qreal x = (point.x() - m_minX)* deltaX;
54 qreal x = (point.x() - m_minX)* deltaX;
55 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
55 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
56 return QPointF(x,y);
56 return QPointF(x,y);
57 }
57 }
58
58
59
59
60 QPointF XYChartItem::calculateGeometryPoint(int index) const
60 QPointF XYChartItem::calculateGeometryPoint(int index) 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 = (m_series->x(index) - m_minX)* deltaX;
64 const QList<QPointF>& vector = m_series->points();
65 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
65 qreal x = (vector[index].x() - m_minX)* deltaX;
66 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
66 return QPointF(x,y);
67 return QPointF(x,y);
67 }
68 }
68
69
69 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
70 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
70 {
71 {
71 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
72 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
72 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
73 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
73
74
74 QVector<QPointF> points;
75 QVector<QPointF> result;
75 points.reserve(m_series->count());
76 result.resize(m_series->count());
77 const QList<QPointF>& vector = m_series->points();
76 for (int i = 0; i < m_series->count(); ++i) {
78 for (int i = 0; i < m_series->count(); ++i) {
77 qreal x = (m_series->x(i) - m_minX)* deltaX;
79 qreal x = (vector[i].x() - m_minX)* deltaX;
78 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
80 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
79 points << QPointF(x,y);
81 result[i].setX(x);
82 result[i].setY(y);
80 }
83 }
81 return points;
84 return result;
82 }
85 }
83
86
84 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
87 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
85 {
88 {
86 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
89 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
87 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
90 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
88 qreal x = point.x()/deltaX +m_minX;
91 qreal x = point.x()/deltaX +m_minX;
89 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
92 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
90 return QPointF(x,y);
93 return QPointF(x,y);
91 }
94 }
92
95
93 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
96 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
94 {
97 {
95 if (animator()) {
98 if (animator()) {
96 animator()->updateLayout(this,oldPoints,newPoints,index);
99 animator()->updateLayout(this,oldPoints,newPoints,index);
97 } else {
100 } else {
98 setLayout(newPoints);
101 setLayout(newPoints);
99 }
102 }
100 }
103 }
101
104
102 void XYChartItem::setLayout(QVector<QPointF> &points)
105 void XYChartItem::setLayout(QVector<QPointF> &points)
103 {
106 {
104 m_points = points;
107 m_points = points;
105 update();
108 update();
106 }
109 }
107
110
108 //handlers
111 //handlers
109
112
110 void XYChartItem::handlePointAdded(int index)
113 void XYChartItem::handlePointAdded(int index)
111 {
114 {
112 if (m_series->model() == 0) {
115 if (m_series->model() == 0) {
113 Q_ASSERT(index<m_series->count());
116 Q_ASSERT(index<m_series->count());
114 Q_ASSERT(index>=0);
117 Q_ASSERT(index>=0);
115 }
118 }
116 QVector<QPointF> points = m_points;
119 QVector<QPointF> points = m_points;
117 QPointF point;
120 QPointF point;
118 point = calculateGeometryPoint(index);
121 point = calculateGeometryPoint(index);
119 points.insert(index, point);
122 points.insert(index, point);
120 updateLayout(m_points, points, index);
123 updateLayout(m_points, points, index);
121 update();
124 update();
122 }
125 }
123
126
124 void XYChartItem::handlePointsAdded(int start, int end)
127 void XYChartItem::handlePointsAdded(int start, int end)
125 {
128 {
126 if (m_series->model() == 0) {
129 if (m_series->model() == 0) {
127 for (int i = start; i <= end; i++)
130 for (int i = start; i <= end; i++)
128 handlePointAdded(i);
131 handlePointAdded(i);
129 } else {
132 } else {
130 // series uses model as a data source
133 // series uses model as a data source
131 int first = m_series->mapFirst();
134 int first = m_series->mapFirst();
132 int count = m_series->mapCount();
135 int count = m_series->mapCount();
133 int addedCount = end - start + 1;
136 int addedCount = end - start + 1;
134 if (count != -1 && start >= first + count) {
137 if (count != -1 && start >= first + count) {
135 return;
138 return;
136 }
139 }
137
140
138 // adding items to unlimited map
141 // adding items to unlimited map
139 else if (count == -1 && start >= first) {
142 else if (count == -1 && start >= first) {
140 for (int i = start; i <= end; i++)
143 for (int i = start; i <= end; i++)
141 handlePointAdded(i - first);
144 handlePointAdded(i - first);
142 } else if (count == - 1 && start < first) {
145 } else if (count == - 1 && start < first) {
143 // not all newly added items
146 // not all newly added items
144 for (int i = first; i < first + addedCount; i++)
147 for (int i = first; i < first + addedCount; i++)
145 handlePointAdded(i - first);
148 handlePointAdded(i - first);
146 }
149 }
147 // commented out code below does the same thing, but its more confusing.
150 // commented out code below does the same thing, but its more confusing.
148 // } else if (count == -1) {
151 // } else if (count == -1) {
149 // int begin = qMax(start, first);
152 // int begin = qMax(start, first);
150 // for (int i = begin; i < begin + (end - start + 1); i++)
153 // for (int i = begin; i < begin + (end - start + 1); i++)
151 // handlePointAdded(i - first);
154 // handlePointAdded(i - first);
152 // }
155 // }
153
156
154 // adding items to limited map
157 // adding items to limited map
155 else if (start >= first) {
158 else if (start >= first) {
156 // remove the items that will no longer fit into the map
159 // remove the items that will no longer fit into the map
157 // int toRemove = addedCount - (count - points().size());
160 // int toRemove = addedCount - (count - points().size());
158 for (int i = start; i <= end; i++) {
161 for (int i = start; i <= end; i++) {
159 handlePointAdded(i - first);
162 handlePointAdded(i - first);
160 }
163 }
161 if (m_points.size() > count)
164 if (m_points.size() > count)
162 for (int i = m_points.size() - 1; i >= count; i--)
165 for (int i = m_points.size() - 1; i >= count; i--)
163 handlePointRemoved(i);
166 handlePointRemoved(i);
164 // update();
167 // update();
165 } else {
168 } else {
166 //
169 //
167 for (int i = first; i < first + addedCount; i++) {
170 for (int i = first; i < first + addedCount; i++) {
168 handlePointAdded(i - first);
171 handlePointAdded(i - first);
169 }
172 }
170 if (m_points.size() > count)
173 if (m_points.size() > count)
171 for (int i = m_points.size() - 1; i >= count; i--)
174 for (int i = m_points.size() - 1; i >= count; i--)
172 handlePointRemoved(i);
175 handlePointRemoved(i);
173 }
176 }
174 }
177 }
175 }
178 }
176
179
177 void XYChartItem::handlePointRemoved(int index)
180 void XYChartItem::handlePointRemoved(int index)
178 {
181 {
179 if (m_series->model() == 0) {
182 if (m_series->model() == 0) {
180 Q_ASSERT(index<m_series->count() + 1);
183 Q_ASSERT(index<m_series->count() + 1);
181 Q_ASSERT(index>=0);
184 Q_ASSERT(index>=0);
182 }
185 }
183 QVector<QPointF> points = m_points;
186 QVector<QPointF> points = m_points;
184 points.remove(index);
187 points.remove(index);
185 updateLayout(m_points, points, index);
188 updateLayout(m_points, points, index);
186 update();
189 update();
187 }
190 }
188
191
189 void XYChartItem::handlePointsRemoved(int start, int end)
192 void XYChartItem::handlePointsRemoved(int start, int end)
190 {
193 {
191 Q_UNUSED(start)
194 Q_UNUSED(start)
192 Q_UNUSED(end)
195 Q_UNUSED(end)
193 if (m_series->model() == 0) {
196 if (m_series->model() == 0) {
194 for (int i = end; i >= start; i--)
197 for (int i = end; i >= start; i--)
195 handlePointRemoved(i);
198 handlePointRemoved(i);
196 } else {
199 } else {
197 // series uses model as a data source
200 // series uses model as a data source
198 int first = m_series->mapFirst();
201 int first = m_series->mapFirst();
199 int count = m_series->mapCount();
202 int count = m_series->mapCount();
200 int removedCount = end - start + 1;
203 int removedCount = end - start + 1;
201 if (count != -1 && start >= first + count) {
204 if (count != -1 && start >= first + count) {
202 return;
205 return;
203 }
206 }
204
207
205 // removing items from unlimited map
208 // removing items from unlimited map
206 else if (count == -1 && start >= first) {
209 else if (count == -1 && start >= first) {
207 for (int i = end; i >= start; i--)
210 for (int i = end; i >= start; i--)
208 handlePointRemoved(i - first);
211 handlePointRemoved(i - first);
209 } else if (count == - 1 && start < first) {
212 } else if (count == - 1 && start < first) {
210 // not all removed items
213 // not all removed items
211 for (int i = first + removedCount - 1; i >= first; i--)
214 for (int i = first + removedCount - 1; i >= first; i--)
212 handlePointRemoved(i - first);
215 handlePointRemoved(i - first);
213 }
216 }
214
217
215 // removing items from limited map
218 // removing items from limited map
216 else if (start >= first) {
219 else if (start >= first) {
217 //
220 //
218 int lastExisting = qMin(first + m_points.size() - 1, end);
221 int lastExisting = qMin(first + m_points.size() - 1, end);
219 for (int i = lastExisting; i >= start; i--) {
222 for (int i = lastExisting; i >= start; i--) {
220 handlePointRemoved(i - first);
223 handlePointRemoved(i - first);
221 }
224 }
222
225
223 // the map is limited, so after removing the items some new items may have fall within the mapped area
226 // the map is limited, so after removing the items some new items may have fall within the mapped area
224 int itemsAvailable;
227 int itemsAvailable;
225 if (m_series->mapOrientation() == Qt::Vertical)
228 if (m_series->mapOrientation() == Qt::Vertical)
226 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
229 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
227 else
230 else
228 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
231 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
229 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
232 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
230 int currentSize = m_points.size();
233 int currentSize = m_points.size();
231 if (itemsAvailable > 0)
234 if (itemsAvailable > 0)
232 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
235 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
233 handlePointAdded(i);
236 handlePointAdded(i);
234 } else {
237 } else {
235 // first removed item lays before the mapped area
238 // first removed item lays before the mapped area
236 int toRemove = qMin(m_points.size() - 1, removedCount);
239 int toRemove = qMin(m_points.size() - 1, removedCount);
237 for (int i = first; i < first + toRemove; i++)
240 for (int i = first; i < first + toRemove; i++)
238 handlePointRemoved(0);
241 handlePointRemoved(0);
239
242
240 // the map is limited, so after removing the items some new items may have fall into the map
243 // the map is limited, so after removing the items some new items may have fall into the map
241 int itemsAvailable;
244 int itemsAvailable;
242 if (m_series->mapOrientation() == Qt::Vertical)
245 if (m_series->mapOrientation() == Qt::Vertical)
243 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
246 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
244 else
247 else
245 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
248 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
246 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
249 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
247 int currentSize = m_points.size();
250 int currentSize = m_points.size();
248 if (itemsAvailable > 0)
251 if (itemsAvailable > 0)
249 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
252 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
250 handlePointAdded(i);
253 handlePointAdded(i);
251 }
254 }
252 }
255 }
253
256
254 }
257 }
255
258
256 void XYChartItem::handlePointReplaced(int index)
259 void XYChartItem::handlePointReplaced(int index)
257 {
260 {
258 Q_ASSERT(index<m_series->count());
261 Q_ASSERT(index<m_series->count());
259 Q_ASSERT(index>=0);
262 Q_ASSERT(index>=0);
260 QPointF point = calculateGeometryPoint(index);
263 QPointF point = calculateGeometryPoint(index);
261 QVector<QPointF> points = m_points;
264 QVector<QPointF> points = m_points;
262 points.replace(index,point);
265 points.replace(index,point);
263 updateLayout(m_points,points,index);
266 updateLayout(m_points,points,index);
264 update();
267 update();
265 }
268 }
266
269
267 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
270 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
268 {
271 {
269 m_minX=minX;
272 m_minX=minX;
270 m_maxX=maxX;
273 m_maxX=maxX;
271 m_minY=minY;
274 m_minY=minY;
272 m_maxY=maxY;
275 m_maxY=maxY;
273
276
274 if (isEmpty()) return;
277 if (isEmpty()) return;
275 QVector<QPointF> points = calculateGeometryPoints();
278 QVector<QPointF> points = calculateGeometryPoints();
276 updateLayout(m_points,points);
279 updateLayout(m_points,points);
277 update();
280 update();
278 }
281 }
279
282
280 void XYChartItem::handleGeometryChanged(const QRectF &rect)
283 void XYChartItem::handleGeometryChanged(const QRectF &rect)
281 {
284 {
282 Q_ASSERT(rect.isValid());
285 Q_ASSERT(rect.isValid());
283 m_size=rect.size();
286 m_size=rect.size();
284 m_clipRect=rect.translated(-rect.topLeft());
287 m_clipRect=rect.translated(-rect.topLeft());
285 setPos(rect.topLeft());
288 setPos(rect.topLeft());
286
289
287 if (isEmpty()) return;
290 if (isEmpty()) return;
288 QVector<QPointF> points = calculateGeometryPoints();
291 QVector<QPointF> points = calculateGeometryPoints();
289 updateLayout(m_points,points);
292 updateLayout(m_points,points);
290 update();
293 update();
291 }
294 }
292
295
293
296
294 bool XYChartItem::isEmpty()
297 bool XYChartItem::isEmpty()
295 {
298 {
296 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
299 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
297 }
300 }
298
301
299 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
302 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
300 {
303 {
301 emit clicked(calculateDomainPoint(event->pos()));
304 emit clicked(calculateDomainPoint(event->pos()));
302 }
305 }
303
306
304 #include "moc_xychartitem_p.cpp"
307 #include "moc_xychartitem_p.cpp"
305
308
306 QTCOMMERCIALCHART_END_NAMESPACE
309 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,10 +1,10
1 !include( ../test.pri ) {
1 !include( ../test.pri ) {
2 error( "Couldn't find the test.pri file!" )
2 error( "Couldn't find the test.pri file!" )
3 }
3 }
4
4
5 TEMPLATE = subdirs
5 TEMPLATE = subdirs
6 SUBDIRS += qchartview qchart
6 SUBDIRS += qchartview qchart qlineseries
7
7
8 test_private:{
8 test_private:{
9 SUBDIRS += chartdataset domain
9 SUBDIRS += chartdataset domain
10 }
10 }
@@ -1,68 +1,68
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "wavechart.h"
21 #include "wavechart.h"
22 #include <cmath>
22 #include <cmath>
23
23
24 QTCOMMERCIALCHART_USE_NAMESPACE
24 QTCOMMERCIALCHART_USE_NAMESPACE
25
25
26 #define PI 3.14159265358979
26 #define PI 3.14159265358979
27 static const int numPoints =100;
27 static const int numPoints =100;
28
28
29 WaveChart::WaveChart(QChart* chart, QWidget* parent) :
29 WaveChart::WaveChart(QChart* chart, QWidget* parent) :
30 QChartView(chart, parent),
30 QChartView(chart, parent),
31 m_series(new QLineSeries()),
31 m_series(new QLineSeries()),
32 m_wave(0),
32 m_wave(0),
33 m_step(2 * PI / numPoints)
33 m_step(2 * PI / numPoints)
34 {
34 {
35 QPen blue(Qt::blue);
35 QPen blue(Qt::blue);
36 blue.setWidth(3);
36 blue.setWidth(3);
37 m_series->setPen(blue);
37 m_series->setPen(blue);
38
38
39 QTime now = QTime::currentTime();
39 QTime now = QTime::currentTime();
40 qsrand((uint) now.msec());
40 qsrand((uint) now.msec());
41
41
42 int fluctuate = 100;
42 int fluctuate = 100;
43
43
44 for (qreal x = 0; x <= 2 * PI; x += m_step) {
44 for (qreal x = 0; x <= 2 * PI; x += m_step) {
45 m_series->append(x, fabs(sin(x) * fluctuate));
45 m_series->append(x, fabs(sin(x) * fluctuate));
46 }
46 }
47
47
48 chart->addSeries(m_series);
48 chart->addSeries(m_series);
49
49
50 QObject::connect(&m_timer, SIGNAL(timeout()), this, SLOT(update()));
50 QObject::connect(&m_timer, SIGNAL(timeout()), this, SLOT(update()));
51 m_timer.setInterval(5000);
51 m_timer.setInterval(5000);
52 m_timer.start();
52 m_timer.start();
53
53
54 }
54 }
55 ;
55 ;
56
56
57 void WaveChart::update()
57 void WaveChart::update()
58 {
58 {
59
59
60 int fluctuate;
60 int fluctuate;
61
61 const QList<QPointF>& points = m_series->points();
62 for (qreal i = 0, x = 0; x <= 2 * PI; x += m_step, i++) {
62 for (qreal i = 0, x = 0; x <= 2 * PI; x += m_step, i++) {
63 fluctuate = qrand() % 100;
63 fluctuate = qrand() % 100;
64 m_series->replace(x, fabs(sin(x) * fluctuate));
64 m_series->replace(x,points[i].y(),x,fabs(sin(x) * fluctuate));
65
65
66 }
66 }
67
67
68 }
68 }
General Comments 0
You need to be logged in to leave comments. Login now