##// END OF EJS Templates
legend refactoring.
sauimone -
r792:f33d64d30a1c
parent child
Show More
@@ -1,349 +1,348
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:BSD$
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
10 ** You may use this file under the terms of the BSD license as follows:
11 **
11 **
12 ** "Redistribution and use in source and binary forms, with or without
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
13 ** modification, are permitted provided that the following conditions are
14 ** met:
14 ** met:
15 ** * Redistributions of source code must retain the above copyright
15 ** * Redistributions of source code must retain the above copyright
16 ** notice, this list of conditions and the following disclaimer.
16 ** notice, this list of conditions and the following disclaimer.
17 ** * Redistributions in binary form must reproduce the above copyright
17 ** * Redistributions in binary form must reproduce the above copyright
18 ** notice, this list of conditions and the following disclaimer in
18 ** notice, this list of conditions and the following disclaimer in
19 ** the documentation and/or other materials provided with the
19 ** the documentation and/or other materials provided with the
20 ** distribution.
20 ** distribution.
21 ** * Neither the name of Digia nor the names of its contributors
21 ** * Neither the name of Digia nor the names of its contributors
22 ** may be used to endorse or promote products derived from this
22 ** may be used to endorse or promote products derived from this
23 ** software without specific prior written permission.
23 ** software without specific prior written permission.
24 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 ** $QT_END_LICENSE$
36 ** $QT_END_LICENSE$
37 **
37 **
38 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
38 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
39 **
39 **
40 ****************************************************************************/
40 ****************************************************************************/
41
41
42 #include "themewidget.h"
42 #include "themewidget.h"
43
43
44 #include <QChartView>
44 #include <QChartView>
45 #include <QPieSeries>
45 #include <QPieSeries>
46 #include <QPieSlice>
46 #include <QPieSlice>
47 #include <QBarSeries>
47 #include <QBarSeries>
48 #include <QPercentBarSeries>
48 #include <QPercentBarSeries>
49 #include <QStackedBarSeries>
49 #include <QStackedBarSeries>
50 #include <QBarSet>
50 #include <QBarSet>
51 #include <QLineSeries>
51 #include <QLineSeries>
52 #include <QSplineSeries>
52 #include <QSplineSeries>
53 #include <QScatterSeries>
53 #include <QScatterSeries>
54 #include <QAreaSeries>
54 #include <QAreaSeries>
55 #include <QGridLayout>
55 #include <QGridLayout>
56 #include <QFormLayout>
56 #include <QFormLayout>
57 #include <QComboBox>
57 #include <QComboBox>
58 #include <QSpinBox>
58 #include <QSpinBox>
59 #include <QCheckBox>
59 #include <QCheckBox>
60 #include <QGroupBox>
60 #include <QGroupBox>
61 #include <QLabel>
61 #include <QLabel>
62 #include <QTime>
62 #include <QTime>
63
63
64 ThemeWidget::ThemeWidget(QWidget* parent) :
64 ThemeWidget::ThemeWidget(QWidget* parent) :
65 QWidget(parent),
65 QWidget(parent),
66 m_listCount(3),
66 m_listCount(3),
67 m_valueMax(100),
67 m_valueMax(100),
68 m_valueCount(11),
68 m_valueCount(11),
69 m_dataTable(generateRandomData(m_listCount,m_valueMax,m_valueCount)),
69 m_dataTable(generateRandomData(m_listCount,m_valueMax,m_valueCount)),
70 m_themeComboBox(createThemeBox()),
70 m_themeComboBox(createThemeBox()),
71 m_antialiasCheckBox(new QCheckBox("Anti aliasing")),
71 m_antialiasCheckBox(new QCheckBox("Anti aliasing")),
72 m_animatedComboBox(createAnimationBox())
72 m_animatedComboBox(createAnimationBox())
73 {
73 {
74
74
75 connectSignals();
75 connectSignals();
76 // create layout
76 // create layout
77 QGridLayout* baseLayout = new QGridLayout();
77 QGridLayout* baseLayout = new QGridLayout();
78 QHBoxLayout *settingsLayout = new QHBoxLayout();
78 QHBoxLayout *settingsLayout = new QHBoxLayout();
79 settingsLayout->addWidget(new QLabel("Theme:"));
79 settingsLayout->addWidget(new QLabel("Theme:"));
80 settingsLayout->addWidget(m_themeComboBox);
80 settingsLayout->addWidget(m_themeComboBox);
81 settingsLayout->addWidget(new QLabel("Animation:"));
81 settingsLayout->addWidget(new QLabel("Animation:"));
82 settingsLayout->addWidget(m_animatedComboBox);
82 settingsLayout->addWidget(m_animatedComboBox);
83 settingsLayout->addWidget(m_antialiasCheckBox);
83 settingsLayout->addWidget(m_antialiasCheckBox);
84 settingsLayout->addStretch();
84 settingsLayout->addStretch();
85 baseLayout->addLayout(settingsLayout, 0, 0, 1, 3);
85 baseLayout->addLayout(settingsLayout, 0, 0, 1, 3);
86
86
87 //create charts
87 //create charts
88
88
89 QChartView *chartView;
89 QChartView *chartView;
90
90
91 chartView = new QChartView(createAreaChart());
91 chartView = new QChartView(createAreaChart());
92 baseLayout->addWidget(chartView, 1, 0);
92 baseLayout->addWidget(chartView, 1, 0);
93 m_charts << chartView;
93 m_charts << chartView;
94
94
95 chartView = new QChartView(createBarChart(m_valueCount));
95 chartView = new QChartView(createBarChart(m_valueCount));
96 baseLayout->addWidget(chartView, 1, 1);
96 baseLayout->addWidget(chartView, 1, 1);
97 m_charts << chartView;
97 m_charts << chartView;
98
98
99 chartView = new QChartView(createLineChart());
99 chartView = new QChartView(createLineChart());
100 baseLayout->addWidget(chartView, 1, 2);
100 baseLayout->addWidget(chartView, 1, 2);
101 m_charts << chartView;
101 m_charts << chartView;
102
102
103 chartView = new QChartView(createPieChart());
103 chartView = new QChartView(createPieChart());
104 chartView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // funny things happen if the pie slice labels no not fit the screen...
104 chartView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // funny things happen if the pie slice labels no not fit the screen...
105 baseLayout->addWidget(chartView, 2, 0);
105 baseLayout->addWidget(chartView, 2, 0);
106 m_charts << chartView;
106 m_charts << chartView;
107
107
108 chartView = new QChartView(createSplineChart());
108 chartView = new QChartView(createSplineChart());
109 baseLayout->addWidget(chartView, 2, 1);
109 baseLayout->addWidget(chartView, 2, 1);
110 m_charts << chartView;
110 m_charts << chartView;
111
111
112 chartView = new QChartView(createScatterChart());
112 chartView = new QChartView(createScatterChart());
113 baseLayout->addWidget(chartView, 2, 2);
113 baseLayout->addWidget(chartView, 2, 2);
114 m_charts << chartView;
114 m_charts << chartView;
115
115
116 setLayout(baseLayout);
116 setLayout(baseLayout);
117 }
117 }
118
118
119 ThemeWidget::~ThemeWidget()
119 ThemeWidget::~ThemeWidget()
120 {
120 {
121 }
121 }
122
122
123 void ThemeWidget::connectSignals()
123 void ThemeWidget::connectSignals()
124 {
124 {
125 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
125 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
126 connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI()));
126 connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI()));
127 connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
127 connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()));
128 }
128 }
129
129
130 DataTable ThemeWidget::generateRandomData(int listCount,int valueMax,int valueCount) const
130 DataTable ThemeWidget::generateRandomData(int listCount,int valueMax,int valueCount) const
131 {
131 {
132 DataTable dataTable;
132 DataTable dataTable;
133
133
134 // set seed for random stuff
134 // set seed for random stuff
135 qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
135 qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
136
136
137 // generate random data
137 // generate random data
138 for (int i(0); i < listCount; i++) {
138 for (int i(0); i < listCount; i++) {
139 DataList dataList;
139 DataList dataList;
140 for (int j(0); j < valueCount; j++) {
140 for (int j(0); j < valueCount; j++) {
141 QPointF value(j + (qreal) rand() / (qreal) RAND_MAX, qrand() % valueMax);
141 QPointF value(j + (qreal) rand() / (qreal) RAND_MAX, qrand() % valueMax);
142 QString label = "Item " + QString::number(i) + ":" + QString::number(j);
142 QString label = "Item " + QString::number(i) + ":" + QString::number(j);
143 dataList << Data(value, label);
143 dataList << Data(value, label);
144 }
144 }
145 dataTable << dataList;
145 dataTable << dataList;
146 }
146 }
147
147
148 return dataTable;
148 return dataTable;
149 }
149 }
150
150
151 QComboBox* ThemeWidget::createThemeBox() const
151 QComboBox* ThemeWidget::createThemeBox() const
152 {
152 {
153 // settings layout
153 // settings layout
154 QComboBox* themeComboBox = new QComboBox();
154 QComboBox* themeComboBox = new QComboBox();
155 themeComboBox->addItem("Default", QChart::ChartThemeDefault);
155 themeComboBox->addItem("Default", QChart::ChartThemeDefault);
156 themeComboBox->addItem("Light", QChart::ChartThemeLight);
156 themeComboBox->addItem("Light", QChart::ChartThemeLight);
157 themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);
157 themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);
158 themeComboBox->addItem("Dark", QChart::ChartThemeDark);
158 themeComboBox->addItem("Dark", QChart::ChartThemeDark);
159 themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);
159 themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);
160 themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);
160 themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);
161 themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
161 themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
162 themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
162 themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
163 return themeComboBox;
163 return themeComboBox;
164 }
164 }
165
165
166 QComboBox* ThemeWidget::createAnimationBox() const
166 QComboBox* ThemeWidget::createAnimationBox() const
167 {
167 {
168 // settings layout
168 // settings layout
169 QComboBox* animationComboBox = new QComboBox();
169 QComboBox* animationComboBox = new QComboBox();
170 animationComboBox->addItem("No Animations", QChart::NoAnimation);
170 animationComboBox->addItem("No Animations", QChart::NoAnimation);
171 animationComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations);
171 animationComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations);
172 animationComboBox->addItem("Series Animations", QChart::SeriesAnimations);
172 animationComboBox->addItem("Series Animations", QChart::SeriesAnimations);
173 animationComboBox->addItem("All Animations", QChart::AllAnimations);
173 animationComboBox->addItem("All Animations", QChart::AllAnimations);
174 return animationComboBox;
174 return animationComboBox;
175 }
175 }
176
176
177 QChart* ThemeWidget::createAreaChart() const
177 QChart* ThemeWidget::createAreaChart() const
178 {
178 {
179 // area chart
179 // area chart
180 QChart *chart = new QChart();
180 QChart *chart = new QChart();
181 chart->setTitle("Area chart");
181 chart->setTitle("Area chart");
182 {
182 {
183 QString name("Series ");
183 QString name("Series ");
184 int nameIndex = 0;
184 int nameIndex = 0;
185 for (int i(0); i < m_dataTable.count(); i++) {
185 for (int i(0); i < m_dataTable.count(); i++) {
186 QLineSeries *series1 = new QLineSeries(chart);
186 QLineSeries *series1 = new QLineSeries(chart);
187 QLineSeries *series2 = new QLineSeries(chart);
187 QLineSeries *series2 = new QLineSeries(chart);
188 series1->setName(name + QString::number(nameIndex) + QString(" lo"));
189 series2->setName(name + QString::number(nameIndex) + QString(" hi"));
190 nameIndex++;
191 foreach (Data data, m_dataTable[i]) {
188 foreach (Data data, m_dataTable[i]) {
192 series1->add(data.first);
189 series1->add(data.first);
193 series2->add(QPointF(data.first.x(), 0.0));
190 series2->add(QPointF(data.first.x(), 0.0));
194 }
191 }
195 QAreaSeries *area = new QAreaSeries(series1, series2);
192 QAreaSeries *area = new QAreaSeries(series1, series2);
193 area->setName(name + QString::number(nameIndex));
194 nameIndex++;
196 chart->addSeries(area);
195 chart->addSeries(area);
197 }
196 }
198 }
197 }
199 return chart;
198 return chart;
200 }
199 }
201
200
202 QChart* ThemeWidget::createBarChart(int valueCount) const
201 QChart* ThemeWidget::createBarChart(int valueCount) const
203 {
202 {
204 // bar chart
203 // bar chart
205 QChart* chart = new QChart();
204 QChart* chart = new QChart();
206 chart->setTitle("Bar chart");
205 chart->setTitle("Bar chart");
207 {
206 {
208 QBarCategories categories;
207 QBarCategories categories;
209 // TODO: categories
208 // TODO: categories
210 for (int i(0); i < valueCount; i++)
209 for (int i(0); i < valueCount; i++)
211 categories << QString::number(i);
210 categories << QString::number(i);
212 // QBarSeries* series = new QBarSeries(categories, chart);
211 // QBarSeries* series = new QBarSeries(categories, chart);
213 // QPercentBarSeries* series = new QPercentBarSeries(categories, chart);
212 // QPercentBarSeries* series = new QPercentBarSeries(categories, chart);
214 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
213 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
215 for (int i(0); i < m_dataTable.count(); i++) {
214 for (int i(0); i < m_dataTable.count(); i++) {
216 QBarSet *set = new QBarSet("Set" + QString::number(i));
215 QBarSet *set = new QBarSet("Set" + QString::number(i));
217 foreach (Data data, m_dataTable[i])
216 foreach (Data data, m_dataTable[i])
218 *set << data.first.y();
217 *set << data.first.y();
219 series->appendBarSet(set);
218 series->appendBarSet(set);
220 }
219 }
221 chart->addSeries(series);
220 chart->addSeries(series);
222 }
221 }
223 return chart;
222 return chart;
224 }
223 }
225
224
226 QChart* ThemeWidget::createLineChart() const
225 QChart* ThemeWidget::createLineChart() const
227 {
226 {
228 // line chart
227 // line chart
229 QChart* chart = new QChart();
228 QChart* chart = new QChart();
230 chart->setTitle("Line chart");
229 chart->setTitle("Line chart");
231 QString name("Series ");
230 QString name("Series ");
232 int nameIndex = 0;
231 int nameIndex = 0;
233 foreach (DataList list, m_dataTable) {
232 foreach (DataList list, m_dataTable) {
234 QLineSeries *series = new QLineSeries(chart);
233 QLineSeries *series = new QLineSeries(chart);
235 foreach (Data data, list)
234 foreach (Data data, list)
236 series->add(data.first);
235 series->add(data.first);
237 series->setName(name + QString::number(nameIndex));
236 series->setName(name + QString::number(nameIndex));
238 nameIndex++;
237 nameIndex++;
239 chart->addSeries(series);
238 chart->addSeries(series);
240 }
239 }
241 return chart;
240 return chart;
242 }
241 }
243
242
244 QChart* ThemeWidget::createPieChart() const
243 QChart* ThemeWidget::createPieChart() const
245 {
244 {
246 // pie chart
245 // pie chart
247 QChart* chart = new QChart();
246 QChart* chart = new QChart();
248 chart->setTitle("Pie chart");
247 chart->setTitle("Pie chart");
249 qreal pieSize = 1.0 / m_dataTable.count();
248 qreal pieSize = 1.0 / m_dataTable.count();
250 for (int i = 0; i < m_dataTable.count(); i++) {
249 for (int i = 0; i < m_dataTable.count(); i++) {
251 QPieSeries *series = new QPieSeries(chart);
250 QPieSeries *series = new QPieSeries(chart);
252 foreach (Data data, m_dataTable[i]) {
251 foreach (Data data, m_dataTable[i]) {
253 QPieSlice *slice = series->add(data.first.y(), data.second);
252 QPieSlice *slice = series->add(data.first.y(), data.second);
254 if (data == m_dataTable[i].first()) {
253 if (data == m_dataTable[i].first()) {
255 slice->setLabelVisible();
254 slice->setLabelVisible();
256 slice->setExploded();
255 slice->setExploded();
257 }
256 }
258 }
257 }
259 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
258 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
260 series->setPieSize(pieSize);
259 series->setPieSize(pieSize);
261 series->setPiePosition(hPos, 0.5);
260 series->setPiePosition(hPos, 0.5);
262 chart->addSeries(series);
261 chart->addSeries(series);
263 }
262 }
264
263
265 return chart;
264 return chart;
266 }
265 }
267
266
268 QChart* ThemeWidget::createSplineChart() const
267 QChart* ThemeWidget::createSplineChart() const
269 { // spine chart
268 { // spine chart
270 QChart* chart = new QChart();
269 QChart* chart = new QChart();
271 chart->setTitle("Spline chart");
270 chart->setTitle("Spline chart");
272 QString name("Series ");
271 QString name("Series ");
273 int nameIndex = 0;
272 int nameIndex = 0;
274 foreach (DataList list, m_dataTable) {
273 foreach (DataList list, m_dataTable) {
275 QSplineSeries *series = new QSplineSeries(chart);
274 QSplineSeries *series = new QSplineSeries(chart);
276 foreach (Data data, list)
275 foreach (Data data, list)
277 series->add(data.first);
276 series->add(data.first);
278 series->setName(name + QString::number(nameIndex));
277 series->setName(name + QString::number(nameIndex));
279 nameIndex++;
278 nameIndex++;
280 chart->addSeries(series);
279 chart->addSeries(series);
281 }
280 }
282 return chart;
281 return chart;
283 }
282 }
284
283
285 QChart* ThemeWidget::createScatterChart() const
284 QChart* ThemeWidget::createScatterChart() const
286 { // scatter chart
285 { // scatter chart
287 QChart* chart = new QChart();
286 QChart* chart = new QChart();
288 chart->setTitle("Scatter chart");
287 chart->setTitle("Scatter chart");
289 QString name("Series ");
288 QString name("Series ");
290 int nameIndex = 0;
289 int nameIndex = 0;
291 foreach (DataList list, m_dataTable) {
290 foreach (DataList list, m_dataTable) {
292 QScatterSeries *series = new QScatterSeries(chart);
291 QScatterSeries *series = new QScatterSeries(chart);
293 foreach (Data data, list)
292 foreach (Data data, list)
294 series->add(data.first);
293 series->add(data.first);
295 series->setName(name + QString::number(nameIndex));
294 series->setName(name + QString::number(nameIndex));
296 nameIndex++;
295 nameIndex++;
297 chart->addSeries(series);
296 chart->addSeries(series);
298 }
297 }
299 return chart;
298 return chart;
300 }
299 }
301
300
302 void ThemeWidget::updateUI()
301 void ThemeWidget::updateUI()
303 {
302 {
304 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
303 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
305
304
306 if (m_charts.at(0)->chart()->theme() != theme) {
305 if (m_charts.at(0)->chart()->theme() != theme) {
307 foreach (QChartView *chartView, m_charts)
306 foreach (QChartView *chartView, m_charts)
308 chartView->chart()->setTheme(theme);
307 chartView->chart()->setTheme(theme);
309
308
310 QPalette pal = window()->palette();
309 QPalette pal = window()->palette();
311 if (theme == QChart::ChartThemeLight) {
310 if (theme == QChart::ChartThemeLight) {
312 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
311 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
313 pal.setColor(QPalette::WindowText, QRgb(0x404044));
312 pal.setColor(QPalette::WindowText, QRgb(0x404044));
314 } else if (theme == QChart::ChartThemeDark) {
313 } else if (theme == QChart::ChartThemeDark) {
315 pal.setColor(QPalette::Window, QRgb(0x121218));
314 pal.setColor(QPalette::Window, QRgb(0x121218));
316 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
315 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
317 } else if (theme == QChart::ChartThemeBlueCerulean) {
316 } else if (theme == QChart::ChartThemeBlueCerulean) {
318 pal.setColor(QPalette::Window, QRgb(0x40434a));
317 pal.setColor(QPalette::Window, QRgb(0x40434a));
319 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
318 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
320 } else if (theme == QChart::ChartThemeBrownSand) {
319 } else if (theme == QChart::ChartThemeBrownSand) {
321 pal.setColor(QPalette::Window, QRgb(0x9e8965));
320 pal.setColor(QPalette::Window, QRgb(0x9e8965));
322 pal.setColor(QPalette::WindowText, QRgb(0x404044));
321 pal.setColor(QPalette::WindowText, QRgb(0x404044));
323 } else if (theme == QChart::ChartThemeBlueNcs) {
322 } else if (theme == QChart::ChartThemeBlueNcs) {
324 pal.setColor(QPalette::Window, QRgb(0x018bba));
323 pal.setColor(QPalette::Window, QRgb(0x018bba));
325 pal.setColor(QPalette::WindowText, QRgb(0x404044));
324 pal.setColor(QPalette::WindowText, QRgb(0x404044));
326 } else if (theme == QChart::ChartThemeHighContrast) {
325 } else if (theme == QChart::ChartThemeHighContrast) {
327 pal.setColor(QPalette::Window, QRgb(0xffab03));
326 pal.setColor(QPalette::Window, QRgb(0xffab03));
328 pal.setColor(QPalette::WindowText, QRgb(0x181818));
327 pal.setColor(QPalette::WindowText, QRgb(0x181818));
329 } else if (theme == QChart::ChartThemeBlueIcy) {
328 } else if (theme == QChart::ChartThemeBlueIcy) {
330 pal.setColor(QPalette::Window, QRgb(0xcee7f0));
329 pal.setColor(QPalette::Window, QRgb(0xcee7f0));
331 pal.setColor(QPalette::WindowText, QRgb(0x404044));
330 pal.setColor(QPalette::WindowText, QRgb(0x404044));
332 } else {
331 } else {
333 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
332 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
334 pal.setColor(QPalette::WindowText, QRgb(0x404044));
333 pal.setColor(QPalette::WindowText, QRgb(0x404044));
335 }
334 }
336 window()->setPalette(pal);
335 window()->setPalette(pal);
337 }
336 }
338
337
339 bool checked = m_antialiasCheckBox->isChecked();
338 bool checked = m_antialiasCheckBox->isChecked();
340 foreach (QChartView *chart, m_charts)
339 foreach (QChartView *chart, m_charts)
341 chart->setRenderHint(QPainter::Antialiasing, checked);
340 chart->setRenderHint(QPainter::Antialiasing, checked);
342
341
343 QChart::AnimationOptions options(m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt());
342 QChart::AnimationOptions options(m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt());
344 if (m_charts.at(0)->chart()->animationOptions() != options) {
343 if (m_charts.at(0)->chart()->animationOptions() != options) {
345 foreach (QChartView *chartView, m_charts)
344 foreach (QChartView *chartView, m_charts)
346 chartView->chart()->setAnimationOptions(options);
345 chartView->chart()->setAnimationOptions(options);
347 }
346 }
348 }
347 }
349
348
@@ -1,386 +1,385
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qlegend.h"
2 #include "qlegend.h"
3 #include "qchartaxis.h"
3 #include "qchartaxis.h"
4 #include "chartpresenter_p.h"
4 #include "chartpresenter_p.h"
5 #include "chartdataset_p.h"
5 #include "chartdataset_p.h"
6 #include "charttheme_p.h"
6 #include "charttheme_p.h"
7 #include "chartanimator_p.h"
7 #include "chartanimator_p.h"
8 //series
8 //series
9 #include "qbarseries.h"
9 #include "qbarseries.h"
10 #include "qstackedbarseries.h"
10 #include "qstackedbarseries.h"
11 #include "qpercentbarseries.h"
11 #include "qpercentbarseries.h"
12 #include "qlineseries.h"
12 #include "qlineseries.h"
13 #include "qareaseries.h"
13 #include "qareaseries.h"
14 #include "qpieseries.h"
14 #include "qpieseries.h"
15 #include "qscatterseries.h"
15 #include "qscatterseries.h"
16 #include "qsplineseries.h"
16 #include "qsplineseries.h"
17 //items
17 //items
18 #include "axisitem_p.h"
18 #include "axisitem_p.h"
19 #include "areachartitem_p.h"
19 #include "areachartitem_p.h"
20 #include "barchartitem_p.h"
20 #include "barchartitem_p.h"
21 #include "stackedbarchartitem_p.h"
21 #include "stackedbarchartitem_p.h"
22 #include "percentbarchartitem_p.h"
22 #include "percentbarchartitem_p.h"
23 #include "linechartitem_p.h"
23 #include "linechartitem_p.h"
24 #include "piechartitem_p.h"
24 #include "piechartitem_p.h"
25 #include "scatterchartitem_p.h"
25 #include "scatterchartitem_p.h"
26 #include "splinechartitem_p.h"
26 #include "splinechartitem_p.h"
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
31 m_chart(chart),
31 m_chart(chart),
32 m_animator(0),
32 m_animator(0),
33 m_dataset(dataset),
33 m_dataset(dataset),
34 m_chartTheme(0),
34 m_chartTheme(0),
35 m_rect(QRectF(QPoint(0,0),m_chart->size())),
35 m_rect(QRectF(QPoint(0,0),m_chart->size())),
36 m_options(QChart::NoAnimation),
36 m_options(QChart::NoAnimation),
37 m_themeForce(false),
37 m_themeForce(false),
38 m_padding(50),
38 m_padding(50),
39 m_backgroundPadding(10)
39 m_backgroundPadding(10)
40 {
40 {
41 createConnections();
41 createConnections();
42 setTheme(QChart::ChartThemeDefault,false);
42 setTheme(QChart::ChartThemeDefault,false);
43 }
43 }
44
44
45 ChartPresenter::~ChartPresenter()
45 ChartPresenter::~ChartPresenter()
46 {
46 {
47 delete m_chartTheme;
47 delete m_chartTheme;
48 }
48 }
49
49
50 void ChartPresenter::createConnections()
50 void ChartPresenter::createConnections()
51 {
51 {
52 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
52 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
53 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
53 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
54 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
54 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
55 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
55 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
56 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
56 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
57 }
57 }
58
58
59 void ChartPresenter::handleGeometryChanged()
59 void ChartPresenter::handleGeometryChanged()
60 {
60 {
61 qDebug() << "legend h:" << m_chart->legend()->size().height();
62 QRectF rect(QPoint(0,0),m_chart->size());
61 QRectF rect(QPoint(0,0),m_chart->size());
63 rect.adjust(m_padding,
62 rect.adjust(m_padding,
64 m_padding + m_chart->legend()->size().height(),
63 m_padding + m_chart->legend()->size().height(),
65 -m_padding,
64 -m_padding,
66 -m_padding);
65 -m_padding);
67
66
68 //rewrite zoom stack
67 //rewrite zoom stack
69 /*
68 /*
70 for(int i=0;i<m_zoomStack.count();i++){
69 for(int i=0;i<m_zoomStack.count();i++){
71 QRectF r = m_zoomStack[i];
70 QRectF r = m_zoomStack[i];
72 qreal w = rect.width()/m_rect.width();
71 qreal w = rect.width()/m_rect.width();
73 qreal h = rect.height()/m_rect.height();
72 qreal h = rect.height()/m_rect.height();
74 QPointF tl = r.topLeft();
73 QPointF tl = r.topLeft();
75 tl.setX(tl.x()*w);
74 tl.setX(tl.x()*w);
76 tl.setY(tl.y()*h);
75 tl.setY(tl.y()*h);
77 QPointF br = r.bottomRight();
76 QPointF br = r.bottomRight();
78 br.setX(br.x()*w);
77 br.setX(br.x()*w);
79 br.setY(br.y()*h);
78 br.setY(br.y()*h);
80 r.setTopLeft(tl);
79 r.setTopLeft(tl);
81 r.setBottomRight(br);
80 r.setBottomRight(br);
82 m_zoomStack[i]=r;
81 m_zoomStack[i]=r;
83 }
82 }
84 */
83 */
85 m_rect = rect;
84 m_rect = rect;
86 Q_ASSERT(m_rect.isValid());
85 Q_ASSERT(m_rect.isValid());
87 emit geometryChanged(m_rect);
86 emit geometryChanged(m_rect);
88 }
87 }
89
88
90 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
89 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
91 {
90 {
92 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
91 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
93
92
94 if(m_options.testFlag(QChart::GridAxisAnimations)){
93 if(m_options.testFlag(QChart::GridAxisAnimations)){
95 m_animator->addAnimation(item);
94 m_animator->addAnimation(item);
96 }
95 }
97
96
98 if(axis==m_dataset->axisX()){
97 if(axis==m_dataset->axisX()){
99 m_chartTheme->decorate(axis,true,m_themeForce);
98 m_chartTheme->decorate(axis,true,m_themeForce);
100 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
99 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
101 //initialize
100 //initialize
102 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
101 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
103
102
104 }
103 }
105 else{
104 else{
106 m_chartTheme->decorate(axis,false,m_themeForce);
105 m_chartTheme->decorate(axis,false,m_themeForce);
107 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
106 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
108 //initialize
107 //initialize
109 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
108 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
110 }
109 }
111
110
112 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
111 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
113 //initialize
112 //initialize
114 item->handleGeometryChanged(m_rect);
113 item->handleGeometryChanged(m_rect);
115 m_axisItems.insert(axis, item);
114 m_axisItems.insert(axis, item);
116 }
115 }
117
116
118 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
117 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
119 {
118 {
120 Axis* item = m_axisItems.take(axis);
119 Axis* item = m_axisItems.take(axis);
121 Q_ASSERT(item);
120 Q_ASSERT(item);
122 if(m_animator) m_animator->removeAnimation(item);
121 if(m_animator) m_animator->removeAnimation(item);
123 delete item;
122 delete item;
124 }
123 }
125
124
126
125
127 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
126 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
128 {
127 {
129 Chart *item = 0 ;
128 Chart *item = 0 ;
130
129
131 switch(series->type())
130 switch(series->type())
132 {
131 {
133 case QSeries::SeriesTypeLine: {
132 case QSeries::SeriesTypeLine: {
134
133
135 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
134 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
136 LineChartItem* line = new LineChartItem(lineSeries,this);
135 LineChartItem* line = new LineChartItem(lineSeries,this);
137 if(m_options.testFlag(QChart::SeriesAnimations)) {
136 if(m_options.testFlag(QChart::SeriesAnimations)) {
138 m_animator->addAnimation(line);
137 m_animator->addAnimation(line);
139 }
138 }
140 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
139 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
141 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
140 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
142 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
141 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
143 item = line;
142 item = line;
144 break;
143 break;
145 }
144 }
146
145
147 case QSeries::SeriesTypeArea: {
146 case QSeries::SeriesTypeArea: {
148
147
149 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
148 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
150 AreaChartItem* area = new AreaChartItem(areaSeries,this);
149 AreaChartItem* area = new AreaChartItem(areaSeries,this);
151 if(m_options.testFlag(QChart::SeriesAnimations)) {
150 if(m_options.testFlag(QChart::SeriesAnimations)) {
152 m_animator->addAnimation(area->upperLineItem());
151 m_animator->addAnimation(area->upperLineItem());
153 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
152 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
154 }
153 }
155 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
154 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
156 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
155 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
157 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
156 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
158 item=area;
157 item=area;
159 break;
158 break;
160 }
159 }
161
160
162 case QSeries::SeriesTypeBar: {
161 case QSeries::SeriesTypeBar: {
163 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
162 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
164 BarChartItem* bar = new BarChartItem(barSeries,this);
163 BarChartItem* bar = new BarChartItem(barSeries,this);
165 if(m_options.testFlag(QChart::SeriesAnimations)) {
164 if(m_options.testFlag(QChart::SeriesAnimations)) {
166 m_animator->addAnimation(bar);
165 m_animator->addAnimation(bar);
167 }
166 }
168 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
167 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
169 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
168 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
170 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
169 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
171 item=bar;
170 item=bar;
172 break;
171 break;
173 }
172 }
174
173
175 case QSeries::SeriesTypeStackedBar: {
174 case QSeries::SeriesTypeStackedBar: {
176 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
175 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
177 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
176 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
178 if(m_options.testFlag(QChart::SeriesAnimations)) {
177 if(m_options.testFlag(QChart::SeriesAnimations)) {
179 m_animator->addAnimation(bar);
178 m_animator->addAnimation(bar);
180 }
179 }
181 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
180 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
182 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
181 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
183 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
182 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
184 item=bar;
183 item=bar;
185 break;
184 break;
186 }
185 }
187
186
188 case QSeries::SeriesTypePercentBar: {
187 case QSeries::SeriesTypePercentBar: {
189 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
188 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
190 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
189 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
191 if(m_options.testFlag(QChart::SeriesAnimations)) {
190 if(m_options.testFlag(QChart::SeriesAnimations)) {
192 m_animator->addAnimation(bar);
191 m_animator->addAnimation(bar);
193 }
192 }
194 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
193 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
195 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
194 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
196 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
195 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
197 item=bar;
196 item=bar;
198 break;
197 break;
199 }
198 }
200
199
201 case QSeries::SeriesTypeScatter: {
200 case QSeries::SeriesTypeScatter: {
202 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
201 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
203 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
202 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
204 if(m_options.testFlag(QChart::SeriesAnimations)) {
203 if(m_options.testFlag(QChart::SeriesAnimations)) {
205 m_animator->addAnimation(scatter);
204 m_animator->addAnimation(scatter);
206 }
205 }
207 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
206 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
208 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
207 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
209 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
208 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
210 item = scatter;
209 item = scatter;
211 break;
210 break;
212 }
211 }
213
212
214 case QSeries::SeriesTypePie: {
213 case QSeries::SeriesTypePie: {
215 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
214 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
216 PieChartItem* pie = new PieChartItem(pieSeries, this);
215 PieChartItem* pie = new PieChartItem(pieSeries, this);
217 if(m_options.testFlag(QChart::SeriesAnimations)) {
216 if(m_options.testFlag(QChart::SeriesAnimations)) {
218 m_animator->addAnimation(pie);
217 m_animator->addAnimation(pie);
219 }
218 }
220 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
219 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
221 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
220 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
222 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
221 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
223 // Hide all from background when there is only piechart
222 // Hide all from background when there is only piechart
224 // TODO: refactor this ugly code... should be one setting for this
223 // TODO: refactor this ugly code... should be one setting for this
225 if (m_chartItems.count() == 0) {
224 if (m_chartItems.count() == 0) {
226 m_chart->axisX()->hide();
225 m_chart->axisX()->hide();
227 m_chart->axisY()->hide();
226 m_chart->axisY()->hide();
228 }
227 }
229 item=pie;
228 item=pie;
230 break;
229 break;
231 }
230 }
232
231
233 case QSeries::SeriesTypeSpline: {
232 case QSeries::SeriesTypeSpline: {
234 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
233 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
235 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
234 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
236 if(m_options.testFlag(QChart::SeriesAnimations)) {
235 if(m_options.testFlag(QChart::SeriesAnimations)) {
237 m_animator->addAnimation(spline);
236 m_animator->addAnimation(spline);
238 }
237 }
239 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
238 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
240 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
239 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
241 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
240 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
242 item=spline;
241 item=spline;
243 break;
242 break;
244 }
243 }
245 default: {
244 default: {
246 qDebug()<< "Series type" << series->type() << "not implemented.";
245 qDebug()<< "Series type" << series->type() << "not implemented.";
247 break;
246 break;
248 }
247 }
249 }
248 }
250
249
251 //initialize
250 //initialize
252 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
251 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
253 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
252 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
254 m_chartItems.insert(series,item);
253 m_chartItems.insert(series,item);
255 }
254 }
256
255
257 void ChartPresenter::handleSeriesRemoved(QSeries* series)
256 void ChartPresenter::handleSeriesRemoved(QSeries* series)
258 {
257 {
259 Chart* item = m_chartItems.take(series);
258 Chart* item = m_chartItems.take(series);
260 Q_ASSERT(item);
259 Q_ASSERT(item);
261 if(m_animator) {
260 if(m_animator) {
262 //small hack to handle area animations
261 //small hack to handle area animations
263 if(series->type()==QSeries::SeriesTypeArea){
262 if(series->type()==QSeries::SeriesTypeArea){
264 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
263 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
265 AreaChartItem* area = static_cast<AreaChartItem*>(item);
264 AreaChartItem* area = static_cast<AreaChartItem*>(item);
266 m_animator->removeAnimation(area->upperLineItem());
265 m_animator->removeAnimation(area->upperLineItem());
267 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
266 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
268 }else
267 }else
269 m_animator->removeAnimation(item);
268 m_animator->removeAnimation(item);
270 }
269 }
271 delete item;
270 delete item;
272 }
271 }
273
272
274 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
273 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
275 {
274 {
276 if(m_chartTheme && m_chartTheme->id() == theme) return;
275 if(m_chartTheme && m_chartTheme->id() == theme) return;
277 delete m_chartTheme;
276 delete m_chartTheme;
278 m_themeForce = force;
277 m_themeForce = force;
279 m_chartTheme = ChartTheme::createTheme(theme);
278 m_chartTheme = ChartTheme::createTheme(theme);
280 m_chartTheme->decorate(m_chart,m_themeForce);
279 m_chartTheme->decorate(m_chart,m_themeForce);
281 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
280 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
282 resetAllElements();
281 resetAllElements();
283 }
282 }
284
283
285 QChart::ChartTheme ChartPresenter::theme()
284 QChart::ChartTheme ChartPresenter::theme()
286 {
285 {
287 return m_chartTheme->id();
286 return m_chartTheme->id();
288 }
287 }
289
288
290 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
289 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
291 {
290 {
292 if(m_options!=options) {
291 if(m_options!=options) {
293
292
294 m_options=options;
293 m_options=options;
295
294
296 if(m_options!=QChart::NoAnimation && !m_animator) {
295 if(m_options!=QChart::NoAnimation && !m_animator) {
297 m_animator= new ChartAnimator(this);
296 m_animator= new ChartAnimator(this);
298
297
299 }
298 }
300 resetAllElements();
299 resetAllElements();
301 }
300 }
302
301
303 }
302 }
304
303
305 void ChartPresenter::resetAllElements()
304 void ChartPresenter::resetAllElements()
306 {
305 {
307 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
306 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
308 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
307 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
309
308
310 foreach(QChartAxis* axis, axisList) {
309 foreach(QChartAxis* axis, axisList) {
311 handleAxisRemoved(axis);
310 handleAxisRemoved(axis);
312 handleAxisAdded(axis,m_dataset->domain(axis));
311 handleAxisAdded(axis,m_dataset->domain(axis));
313 }
312 }
314 foreach(QSeries* series, seriesList) {
313 foreach(QSeries* series, seriesList) {
315 handleSeriesRemoved(series);
314 handleSeriesRemoved(series);
316 handleSeriesAdded(series,m_dataset->domain(series));
315 handleSeriesAdded(series,m_dataset->domain(series));
317 }
316 }
318 }
317 }
319
318
320 void ChartPresenter::zoomIn()
319 void ChartPresenter::zoomIn()
321 {
320 {
322 QRectF rect = geometry();
321 QRectF rect = geometry();
323 rect.setWidth(rect.width()/2);
322 rect.setWidth(rect.width()/2);
324 rect.setHeight(rect.height()/2);
323 rect.setHeight(rect.height()/2);
325 rect.moveCenter(geometry().center());
324 rect.moveCenter(geometry().center());
326 zoomIn(rect);
325 zoomIn(rect);
327 }
326 }
328
327
329 void ChartPresenter::zoomIn(const QRectF& rect)
328 void ChartPresenter::zoomIn(const QRectF& rect)
330 {
329 {
331 QRectF r = rect.normalized();
330 QRectF r = rect.normalized();
332 r.translate(-m_padding, -m_padding);
331 r.translate(-m_padding, -m_padding);
333 if(m_animator) {
332 if(m_animator) {
334
333
335 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
334 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
336 m_animator->setState(ChartAnimator::ZoomInState,point);
335 m_animator->setState(ChartAnimator::ZoomInState,point);
337 }
336 }
338 m_dataset->zoomInDomain(r,geometry().size());
337 m_dataset->zoomInDomain(r,geometry().size());
339 if(m_animator) {
338 if(m_animator) {
340 m_animator->setState(ChartAnimator::ShowState);
339 m_animator->setState(ChartAnimator::ShowState);
341 }
340 }
342 }
341 }
343
342
344 void ChartPresenter::zoomOut()
343 void ChartPresenter::zoomOut()
345 {
344 {
346 if(m_animator)
345 if(m_animator)
347 {
346 {
348 m_animator->setState(ChartAnimator::ZoomOutState);
347 m_animator->setState(ChartAnimator::ZoomOutState);
349 }
348 }
350
349
351 QSizeF size = geometry().size();
350 QSizeF size = geometry().size();
352 QRectF rect = geometry();
351 QRectF rect = geometry();
353 rect.translate(-m_padding, -m_padding);
352 rect.translate(-m_padding, -m_padding);
354 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
353 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
355 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
354 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
356
355
357 if(m_animator){
356 if(m_animator){
358 m_animator->setState(ChartAnimator::ShowState);
357 m_animator->setState(ChartAnimator::ShowState);
359 }
358 }
360 }
359 }
361
360
362 void ChartPresenter::scroll(int dx,int dy)
361 void ChartPresenter::scroll(int dx,int dy)
363 {
362 {
364 if(m_animator){
363 if(m_animator){
365 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
364 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
366 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
365 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
367 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
366 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
368 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
367 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
369 }
368 }
370
369
371 m_dataset->scrollDomain(dx,dy,geometry().size());
370 m_dataset->scrollDomain(dx,dy,geometry().size());
372
371
373 if(m_animator){
372 if(m_animator){
374 m_animator->setState(ChartAnimator::ShowState);
373 m_animator->setState(ChartAnimator::ShowState);
375 }
374 }
376 }
375 }
377
376
378 QChart::AnimationOptions ChartPresenter::animationOptions() const
377 QChart::AnimationOptions ChartPresenter::animationOptions() const
379 {
378 {
380 return m_options;
379 return m_options;
381 }
380 }
382
381
383
382
384 #include "moc_chartpresenter_p.cpp"
383 #include "moc_chartpresenter_p.cpp"
385
384
386 QTCOMMERCIALCHART_END_NAMESPACE
385 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,175 +1,190
1 #include "qchartglobal.h"
1 #include "qchartglobal.h"
2 #include "legendmarker_p.h"
2 #include "legendmarker_p.h"
3 #include <qpieslice.h>
3 #include <qpieslice.h>
4 #include <qbarset.h>
4 #include <qbarset.h>
5 #include <qxyseries.h>
5 #include <qxyseries.h>
6 #include <qareaseries.h>
6 #include <QPainter>
7 #include <QPainter>
7 #include <QGraphicsSceneEvent>
8 #include <QGraphicsSceneEvent>
8 #include <QGraphicsSimpleTextItem>
9 #include <QGraphicsSimpleTextItem>
9
10
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
12
12 LegendMarker::LegendMarker(QSeries *series, QGraphicsItem *parent) : QGraphicsObject(parent),
13 LegendMarker::LegendMarker(QSeries *series, QGraphicsItem *parent) : QGraphicsObject(parent),
13 m_pos(0,0),
14 m_pos(0,0),
14 m_size(0,0),
15 m_size(0,0),
15 m_boundingRect(0,0,0,0),
16 m_boundingRect(0,0,0,0),
16 m_markerBoundingRect(0,0,0,0),
17 m_markerBoundingRect(0,0,0,0),
17 m_series(series),
18 m_series(series),
18 m_barset(0),
19 m_barset(0),
19 m_pieslice(0),
20 m_pieslice(0),
20 m_type(LegendMarkerTypeSeries),
21 m_textItem(new QGraphicsSimpleTextItem(this))
21 m_textItem(new QGraphicsSimpleTextItem(this))
22 {
22 {
23 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
23 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
24 }
24 }
25
25
26 LegendMarker::LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent) : QGraphicsObject(parent),
26 LegendMarker::LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent) : QGraphicsObject(parent),
27 m_pos(0,0),
27 m_pos(0,0),
28 m_size(0,0),
28 m_size(0,0),
29 m_boundingRect(0,0,0,0),
29 m_boundingRect(0,0,0,0),
30 m_markerBoundingRect(0,0,0,0),
30 m_markerBoundingRect(0,0,0,0),
31 m_series(series),
31 m_series(series),
32 m_barset(barset),
32 m_barset(barset),
33 m_pieslice(0),
33 m_pieslice(0),
34 m_type(LegendMarkerTypeBarset),
35 m_textItem(new QGraphicsSimpleTextItem(this))
34 m_textItem(new QGraphicsSimpleTextItem(this))
36 {
35 {
37 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
36 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
38 }
37 }
39
38
40 LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent) : QGraphicsObject(parent),
39 LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent) : QGraphicsObject(parent),
41 m_pos(0,0),
40 m_pos(0,0),
42 m_size(0,0),
41 m_size(0,0),
43 m_boundingRect(0,0,0,0),
42 m_boundingRect(0,0,0,0),
44 m_markerBoundingRect(0,0,0,0),
43 m_markerBoundingRect(0,0,0,0),
45 m_series(series),
44 m_series(series),
46 m_barset(0),
45 m_barset(0),
47 m_pieslice(pieslice),
46 m_pieslice(pieslice),
48 m_type(LegendMarkerTypePieslice),
49 m_textItem(new QGraphicsSimpleTextItem(this))
47 m_textItem(new QGraphicsSimpleTextItem(this))
50 {
48 {
51 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
49 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
52 }
50 }
53
51
54 void LegendMarker::setPos(qreal x, qreal y)
52 void LegendMarker::setPos(qreal x, qreal y)
55 {
53 {
56 m_pos = QPointF(x,y);
54 m_pos = QPointF(x,y);
57 layoutChanged();
55 layoutChanged();
58 }
56 }
59
57
60 void LegendMarker::setPen(const QPen &pen)
58 void LegendMarker::setPen(const QPen &pen)
61 {
59 {
62 m_pen = pen;
60 m_pen = pen;
63 }
61 }
64
62
65 QPen LegendMarker::pen() const
63 QPen LegendMarker::pen() const
66 {
64 {
67 return m_pen;
65 return m_pen;
68 }
66 }
69
67
70 void LegendMarker::setBrush(const QBrush &brush)
68 void LegendMarker::setBrush(const QBrush &brush)
71 {
69 {
72 m_brush = brush;
70 m_brush = brush;
73 }
71 }
74
72
75 QBrush LegendMarker::brush() const
73 QBrush LegendMarker::brush() const
76 {
74 {
77 return m_brush;
75 return m_brush;
78 }
76 }
79
77
80 void LegendMarker::setName(const QString name)
78 void LegendMarker::setName(const QString name)
81 {
79 {
82 m_textItem->setText(name);
80 m_textItem->setText(name);
83 layoutChanged();
81 layoutChanged();
84 }
82 }
85
83
86 QString LegendMarker::name() const
84 QString LegendMarker::name() const
87 {
85 {
88 return m_textItem->text();
86 return m_textItem->text();
89 }
87 }
90
88
91 QSeries* LegendMarker::series() const
89 QSeries* LegendMarker::series() const
92 {
90 {
93 return m_series;
91 return m_series;
94 }
92 }
95
93
96 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
94 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
97 {
95 {
98 Q_UNUSED(option)
96 Q_UNUSED(option)
99 Q_UNUSED(widget)
97 Q_UNUSED(widget)
100
98
101 painter->setPen(m_pen);
99 painter->setPen(m_pen);
102 painter->setBrush(m_brush);
100 painter->setBrush(m_brush);
103 painter->drawRect(m_markerBoundingRect);
101 painter->drawRect(m_markerBoundingRect);
104 }
102 }
105
103
106 QRectF LegendMarker::boundingRect() const
104 QRectF LegendMarker::boundingRect() const
107 {
105 {
108 return m_boundingRect;
106 return m_boundingRect;
109 }
107 }
110
108
111 void LegendMarker::layoutChanged()
109 void LegendMarker::layoutChanged()
112 {
110 {
113 QSizeF markerSize(10,10);
111 QSizeF markerSize(10,10);
114 qreal margin = 2;
112 qreal margin = 2;
115
113
116 m_size.setHeight(markerSize.height() + 2 * margin);
114 m_size.setHeight(markerSize.height() + 2 * margin);
117 m_size.setWidth(m_textItem->boundingRect().width() + markerSize.width() + 3 * margin);
115 m_size.setWidth(m_textItem->boundingRect().width() + markerSize.width() + 3 * margin);
118
116
119 m_boundingRect = QRectF(m_pos.x(),m_pos.y(),m_size.width(),m_size.height());
117 m_boundingRect = QRectF(m_pos.x(),m_pos.y(),m_size.width(),m_size.height());
120
118
121 m_markerBoundingRect = QRectF(m_pos.x() + margin, m_pos.y() + margin, markerSize.width(),markerSize.height());
119 m_markerBoundingRect = QRectF(m_pos.x() + margin, m_pos.y() + margin, markerSize.width(),markerSize.height());
122
120
123 m_textItem->setPos(m_pos.x() + markerSize.width() + 2 * margin, m_pos.y() + margin);
121 m_textItem->setPos(m_pos.x() + markerSize.width() + 2 * margin, m_pos.y() + margin);
124 }
122 }
125
123
126 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
124 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
127 {
125 {
128 switch (m_type)
126 switch (m_series->type()) {
129 {
127 case QSeries::SeriesTypeLine:
130 case LegendMarkerTypeSeries: {
128 case QSeries::SeriesTypeArea:
129 case QSeries::SeriesTypeScatter:
130 case QSeries::SeriesTypeSpline: {
131 emit clicked(m_series,event->button());
131 emit clicked(m_series,event->button());
132 break;
132 break;
133 }
133 }
134 case LegendMarkerTypeBarset: {
134 case QSeries::SeriesTypeBar:
135 case QSeries::SeriesTypeStackedBar:
136 case QSeries::SeriesTypePercentBar: {
135 emit clicked(m_barset,event->button());
137 emit clicked(m_barset,event->button());
136 break;
138 break;
137 }
139 }
138 case LegendMarkerTypePieslice: {
140 case QSeries::SeriesTypePie: {
139 emit clicked(m_pieslice,event->button());
141 emit clicked(m_pieslice,event->button());
140 break;
142 break;
141 }
143 }
142 default: {
144 default: {
143 break;
145 break;
144 }
146 }
145 }
147 }
146 }
148 }
147
149
148 void LegendMarker::changed()
150 void LegendMarker::changed()
149 {
151 {
150 switch (m_type)
152 switch (m_series->type()) {
151 {
153 case QSeries::SeriesTypeArea: {
152 case LegendMarkerTypeSeries: {
154 QAreaSeries* s = static_cast<QAreaSeries*> (m_series);
153 QXYSeries* s = static_cast<QXYSeries*> (m_series);
154 setPen(s->pen());
155 setPen(s->pen());
155 setBrush(s->brush());
156 setBrush(s->brush());
156 setName(s->name());
157 setName(s->name());
157 break;
158 break;
158 }
159 }
159 case LegendMarkerTypeBarset: {
160 case QSeries::SeriesTypeLine:
161 case QSeries::SeriesTypeScatter:
162 case QSeries::SeriesTypeSpline: {
163 QXYSeries* s = static_cast<QXYSeries*> (m_series);
164 setPen(s->pen());
165 setBrush(s->brush());
166 setName(s->name());
167 break;
168 }
169 case QSeries::SeriesTypeBar:
170 case QSeries::SeriesTypeStackedBar:
171 case QSeries::SeriesTypePercentBar: {
160 setPen(m_barset->pen());
172 setPen(m_barset->pen());
161 setBrush(m_barset->brush());
173 setBrush(m_barset->brush());
162 setName(m_barset->name());
174 setName(m_barset->name());
163 break;
175 break;
164 }
176 }
165 case LegendMarkerTypePieslice: {
177 case QSeries::SeriesTypePie: {
166 setBrush(m_pieslice->brush());
178 setBrush(m_pieslice->brush());
167 setName(m_pieslice->label());
179 setName(m_pieslice->label());
168 break;
180 break;
169 }
181 }
182 default: {
183 break;
184 }
170 }
185 }
171 }
186 }
172
187
173 #include "moc_legendmarker_p.cpp"
188 #include "moc_legendmarker_p.cpp"
174
189
175 QTCOMMERCIALCHART_END_NAMESPACE
190 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,74
1 #ifndef LEGENDMARKER_P_H
1 #ifndef LEGENDMARKER_P_H
2 #define LEGENDMARKER_P_H
2 #define LEGENDMARKER_P_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QGraphicsObject>
5 #include <QGraphicsObject>
6 #include <QBrush>
6 #include <QBrush>
7 #include <QPen>
7 #include <QPen>
8 #include <QGraphicsSimpleTextItem>
8 #include <QGraphicsSimpleTextItem>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class QSeries;
12 class QSeries;
13 class QBarSet;
13 class QBarSet;
14 class QPieSlice;
14 class QPieSlice;
15
15
16 // TODO: split this to 3 different markers for series, barset and pieslice. Current implementation is easier to misuse...
16 // TODO: split this to 3 different markers for series, barset and pieslice. Current implementation is easier to misuse...
17 class LegendMarker : public QGraphicsObject
17 class LegendMarker : public QGraphicsObject
18 {
18 {
19 Q_OBJECT
19 Q_OBJECT
20
20
21 enum LegendMarkerType {
22 LegendMarkerTypeSeries,
23 LegendMarkerTypeBarset,
24 LegendMarkerTypePieslice
25 };
26
27 public:
21 public:
28 LegendMarker(QSeries *series, QGraphicsItem *parent = 0);
22 LegendMarker(QSeries *series, QGraphicsItem *parent = 0);
29 LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent = 0);
23 LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent = 0);
30 LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent = 0);
24 LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent = 0);
31
25
32 void setPos(qreal x, qreal y);
26 void setPos(qreal x, qreal y);
33
27
34 void setPen(const QPen &pen);
28 void setPen(const QPen &pen);
35 QPen pen() const;
29 QPen pen() const;
36
30
37 void setBrush(const QBrush &brush);
31 void setBrush(const QBrush &brush);
38 QBrush brush() const;
32 QBrush brush() const;
39
33
40 void setName(const QString name);
34 void setName(const QString name);
41 QString name() const;
35 QString name() const;
42
36
43 QSeries* series() const;
37 QSeries* series() const;
44
38
45 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
39 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
46
40
47 QRectF boundingRect() const;
41 QRectF boundingRect() const;
48
42
49 void layoutChanged();
43 void layoutChanged();
50
44
51 public:
45 public:
52 // From QGraphicsObject
46 // From QGraphicsObject
53 void mousePressEvent(QGraphicsSceneMouseEvent *event);
47 void mousePressEvent(QGraphicsSceneMouseEvent *event);
54
48
55 Q_SIGNALS:
49 Q_SIGNALS:
56 void clicked(QSeries *series, Qt::MouseButton button);
50 void clicked(QSeries *series, Qt::MouseButton button);
57 void clicked(QBarSet *barset, Qt::MouseButton button);
51 void clicked(QBarSet *barset, Qt::MouseButton button);
58 void clicked(QPieSlice *pieslice, Qt::MouseButton button);
52 void clicked(QPieSlice *pieslice, Qt::MouseButton button);
59
53
60 public Q_SLOTS:
54 public Q_SLOTS:
61 void changed();
55 void changed();
62
56
63 private:
57 private:
64 QPointF m_pos;
58 QPointF m_pos;
65 QSize m_size;
59 QSize m_size;
66 QRectF m_boundingRect;
60 QRectF m_boundingRect;
67 QRectF m_markerBoundingRect;
61 QRectF m_markerBoundingRect;
68 QBrush m_brush;
62 QBrush m_brush;
69 QPen m_pen;
63 QPen m_pen;
70
64
71 QSeries *m_series;
65 QSeries *m_series;
72 QBarSet *m_barset;
66 QBarSet *m_barset;
73 QPieSlice *m_pieslice;
67 QPieSlice *m_pieslice;
74
68
75 LegendMarkerType m_type;
76 QGraphicsSimpleTextItem *m_textItem;
69 QGraphicsSimpleTextItem *m_textItem;
77
70
78 };
71 };
79
72
80 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
81 #endif // LEGENDMARKER_P_H
74 #endif // LEGENDMARKER_P_H
@@ -1,693 +1,683
1 #include "qlegend.h"
1 #include "qlegend.h"
2 #include "qchart_p.h"
2 #include "qchart_p.h"
3 #include "qseries.h"
3 #include "qseries.h"
4 #include "legendmarker_p.h"
4 #include "legendmarker_p.h"
5 #include "legendscrollbutton_p.h"
5 #include "legendscrollbutton_p.h"
6 #include "qxyseries.h"
6 #include "qxyseries.h"
7 #include "qlineseries.h"
7 #include "qlineseries.h"
8 #include "qareaseries.h"
8 #include "qareaseries.h"
9 #include "qscatterseries.h"
9 #include "qscatterseries.h"
10 #include "qsplineseries.h"
10 #include "qsplineseries.h"
11 #include "qbarseries.h"
11 #include "qbarseries.h"
12 #include "qstackedbarseries.h"
12 #include "qstackedbarseries.h"
13 #include "qpercentbarseries.h"
13 #include "qpercentbarseries.h"
14 #include "qbarset.h"
14 #include "qbarset.h"
15 #include "qpieseries.h"
15 #include "qpieseries.h"
16 #include "qpieslice.h"
16 #include "qpieslice.h"
17 #include "chartpresenter_p.h"
17 #include "chartpresenter_p.h"
18 #include <QPainter>
18 #include <QPainter>
19 #include <QPen>
19 #include <QPen>
20
20
21 #include <QGraphicsSceneEvent>
21 #include <QGraphicsSceneEvent>
22
22
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24
24
25 /*!
25 /*!
26 \class QLegend
26 \class QLegend
27 \brief part of QtCommercial chart API.
27 \brief part of QtCommercial chart API.
28
28
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
31 handle the drawing manually.
31 handle the drawing manually.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
33
33
34 \mainclass
34 \mainclass
35
35
36 \sa QChart, QSeries
36 \sa QChart, QSeries
37 */
37 */
38
38
39 /*!
39 /*!
40 \enum QLegend::Layout
40 \enum QLegend::Layout
41
41
42 This enum describes the possible position for legend inside chart.
42 This enum describes the possible position for legend inside chart.
43
43
44 \value LayoutTop
44 \value LayoutTop
45 \value LayoutBottom
45 \value LayoutBottom
46 \value LayoutLeft
46 \value LayoutLeft
47 \value LayoutRight
47 \value LayoutRight
48 */
48 */
49
49
50
50
51 /*!
51 /*!
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
53 \brief Notifies when series has been clicked on legend \a series \a button
53 \brief Notifies when series has been clicked on legend \a series \a button
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
58 \brief Notifies when barset has been clicked on legend \a barset \a button
58 \brief Notifies when barset has been clicked on legend \a barset \a button
59 */
59 */
60
60
61 /*!
61 /*!
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs the legend object and sets the parent to \a parent
67 Constructs the legend object and sets the parent to \a parent
68 */
68 */
69 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
69 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
70 m_margin(5),
70 m_margin(5),
71 m_pos(0,0),
71 m_pos(0,0),
72 m_minimumSize(50,20), // TODO: magic numbers
72 m_minimumSize(50,20), // TODO: magic numbers
73 m_maximumSize(150,100),
73 m_maximumSize(150,100),
74 m_size(m_minimumSize),
74 m_size(m_minimumSize),
75 m_brush(Qt::darkGray), // TODO: default should come from theme
75 m_brush(Qt::darkGray), // TODO: default should come from theme
76 m_alignment(QLegend::LayoutTop),
76 m_alignment(QLegend::LayoutTop),
77 mFirstMarker(0)
77 mFirstMarker(0)
78 {
78 {
79 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
79 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
80 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
80 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
81 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
81 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
82 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
82 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
83 setZValue(ChartPresenter::LegendZValue);
83 setZValue(ChartPresenter::LegendZValue);
84 }
84 }
85
85
86 /*!
86 /*!
87 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
87 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
88 */
88 */
89 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
89 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
90 {
90 {
91 Q_UNUSED(option)
91 Q_UNUSED(option)
92 Q_UNUSED(widget)
92 Q_UNUSED(widget)
93
93
94 painter->setOpacity(opacity());
94 painter->setOpacity(opacity());
95 painter->setPen(m_pen);
95 painter->setPen(m_pen);
96 painter->setBrush(m_brush);
96 painter->setBrush(m_brush);
97 // painter->drawRect(boundingRect());
97 // painter->drawRect(boundingRect());
98 }
98 }
99
99
100 /*!
100 /*!
101 Bounding rect of legend.
101 Bounding rect of legend.
102 */
102 */
103 QRectF QLegend::boundingRect() const
103 QRectF QLegend::boundingRect() const
104 {
104 {
105 return QRectF(m_pos,m_size);
105 return QRectF(m_pos,m_size);
106 }
106 }
107
107
108 /*!
108 /*!
109 Sets the \a brush of legend. Brush affects the background of legend.
109 Sets the \a brush of legend. Brush affects the background of legend.
110 */
110 */
111 void QLegend::setBrush(const QBrush &brush)
111 void QLegend::setBrush(const QBrush &brush)
112 {
112 {
113 if (m_brush != brush) {
113 if (m_brush != brush) {
114 m_brush = brush;
114 m_brush = brush;
115 update();
115 update();
116 }
116 }
117 }
117 }
118
118
119 /*!
119 /*!
120 Returns the brush used by legend.
120 Returns the brush used by legend.
121 */
121 */
122 QBrush QLegend::brush() const
122 QBrush QLegend::brush() const
123 {
123 {
124 return m_brush;
124 return m_brush;
125 }
125 }
126
126
127 /*!
127 /*!
128 Sets the \a pen of legend. Pen affects the legend borders.
128 Sets the \a pen of legend. Pen affects the legend borders.
129 */
129 */
130 void QLegend::setPen(const QPen &pen)
130 void QLegend::setPen(const QPen &pen)
131 {
131 {
132 if (m_pen != pen) {
132 if (m_pen != pen) {
133 m_pen = pen;
133 m_pen = pen;
134 update();
134 update();
135 }
135 }
136 }
136 }
137
137
138 /*!
138 /*!
139 Returns the pen used by legend
139 Returns the pen used by legend
140 */
140 */
141
141
142 QPen QLegend::pen() const
142 QPen QLegend::pen() const
143 {
143 {
144 return m_pen;
144 return m_pen;
145 }
145 }
146
146
147 /*!
147 /*!
148 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
148 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
149 \sa QLegend::Layout
149 \sa QLegend::Layout
150 */
150 */
151 void QLegend::setAlignmnent(QLegend::Layout alignment)
151 void QLegend::setAlignmnent(QLegend::Layout alignment)
152 {
152 {
153 m_alignment = alignment;
153 m_alignment = alignment;
154 updateLayout();
154 updateLayout();
155 }
155 }
156
156
157 /*!
157 /*!
158 Returns the preferred layout for legend
158 Returns the preferred layout for legend
159 */
159 */
160 QLegend::Layout QLegend::alignment() const
160 QLegend::Layout QLegend::alignment() const
161 {
161 {
162 return m_alignment;
162 return m_alignment;
163 }
163 }
164
164
165 /*!
165 /*!
166 Returns the maximum size of legend.
166 Returns the maximum size of legend.
167 */
167 */
168 QSizeF QLegend::maximumSize() const
168 QSizeF QLegend::maximumSize() const
169 {
169 {
170 return m_maximumSize;
170 return m_maximumSize;
171 }
171 }
172
172
173 /*!
173 /*!
174 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
174 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
175 more series than legend can fit to this size, scroll buttons are displayed.
175 more series than legend can fit to this size, scroll buttons are displayed.
176 */
176 */
177 void QLegend::setMaximumSize(const QSizeF size)
177 void QLegend::setMaximumSize(const QSizeF size)
178 {
178 {
179 m_maximumSize = size;
179 m_maximumSize = size;
180 updateLayout();
180 updateLayout();
181 }
181 }
182
182
183 /*!
183 /*!
184 Returns the current size of legend.
184 Returns the current size of legend.
185 */
185 */
186 QSizeF QLegend::size() const
186 QSizeF QLegend::size() const
187 {
187 {
188 return m_size;
188 return m_size;
189 }
189 }
190
190
191 /*!
191 /*!
192 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
192 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
193 \sa setMmaximumSize()
193 \sa setMmaximumSize()
194 */
194 */
195 void QLegend::setSize(const QSizeF size)
195 void QLegend::setSize(const QSizeF size)
196 {
196 {
197 m_size = size;
197 m_size = size;
198 if (m_size.width() > m_maximumSize.width()) {
198 if (m_size.width() > m_maximumSize.width()) {
199 m_size.setWidth(m_maximumSize.width());
199 m_size.setWidth(m_maximumSize.width());
200 }
200 }
201 if (m_size.height() > m_maximumSize.height()) {
201 if (m_size.height() > m_maximumSize.height()) {
202 m_size.setHeight(m_maximumSize.height());
202 m_size.setHeight(m_maximumSize.height());
203 }
203 }
204 }
204 }
205
205
206 /*!
206 /*!
207 Sets position of legend to \a pos
207 Sets position of legend to \a pos
208 */
208 */
209 void QLegend::setPos(const QPointF &pos)
209 void QLegend::setPos(const QPointF &pos)
210 {
210 {
211 m_pos = pos;
211 m_pos = pos;
212 updateLayout();
212 updateLayout();
213 }
213 }
214
214
215 /*!
215 /*!
216 \internal \a series \a domain Should be called when series is added to chart.
216 \internal \a series \a domain Should be called when series is added to chart.
217 */
217 */
218 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
218 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
219 {
219 {
220 Q_UNUSED(domain)
220 Q_UNUSED(domain)
221
221
222 createMarkers(series);
222 switch (series->type())
223 connectSeries(series);
223 {
224 case QSeries::SeriesTypeLine: {
225 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
226 appendMarkers(lineSeries);
227 break;
228 }
229 case QSeries::SeriesTypeArea: {
230 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
231 appendMarkers(areaSeries);
232 break;
233 }
234 case QSeries::SeriesTypeBar: {
235 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
236 appendMarkers(barSeries);
237 break;
238 }
239 case QSeries::SeriesTypeStackedBar: {
240 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
241 appendMarkers(stackedBarSeries);
242 break;
243 }
244 case QSeries::SeriesTypePercentBar: {
245 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
246 appendMarkers(percentBarSeries);
247 break;
248 }
249 case QSeries::SeriesTypeScatter: {
250 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
251 appendMarkers(scatterSeries);
252 break;
253 }
254 case QSeries::SeriesTypePie: {
255 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
256 appendMarkers(pieSeries);
257 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
258 break;
259 }
260 case QSeries::SeriesTypeSpline: {
261 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
262 appendMarkers(splineSeries);
263 break;
264 }
265 default: {
266 qWarning()<< "QLegend::handleSeriesAdded" << series->type() << "unknown series type.";
267 break;
268 }
269 }
270
224 updateLayout();
271 updateLayout();
225 }
272 }
226
273
227 /*!
274 /*!
228 \internal \a series Should be called when series is removed from chart.
275 \internal \a series Should be called when series is removed from chart.
229 */
276 */
230 void QLegend::handleSeriesRemoved(QSeries *series)
277 void QLegend::handleSeriesRemoved(QSeries *series)
231 {
278 {
232 disconnectSeries(series);
279 switch (series->type())
233
280 {
234 if (series->type() == QSeries::SeriesTypeArea) {
281 case QSeries::SeriesTypeArea: {
235 // This is special case. Area series has upper and lower series, which each have markers
282 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
236 QAreaSeries* s = static_cast<QAreaSeries *> (series);
283 deleteMarkers(areaSeries);
237 deleteMarkers(s->upperSeries());
284 break;
238 deleteMarkers(s->lowerSeries());
285 }
239 } else {
286 case QSeries::SeriesTypePie: {
287 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
288 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
240 deleteMarkers(series);
289 deleteMarkers(series);
290 break;
291 }
292 default: {
293 // All other types
294 deleteMarkers(series);
295 break;
296 }
241 }
297 }
242
298
243 updateLayout();
299 updateLayout();
244 }
300 }
245
301
246 /*!
302 /*!
247 \internal \a slices Should be called when slices are added to pie chart.
303 \internal \a slices Should be called when slices are added to pie chart.
248 */
304 */
249 void QLegend::handleAdded(QList<QPieSlice *> slices)
305 void QLegend::handleAdded(QList<QPieSlice *> slices)
250 {
306 {
251 QPieSeries* series = static_cast<QPieSeries *> (sender());
307 QPieSeries* series = static_cast<QPieSeries *> (sender());
252 foreach(QPieSlice* s, slices) {
308 foreach(QPieSlice* s, slices) {
253 LegendMarker* marker = new LegendMarker(series, s, this);
309 LegendMarker* marker = new LegendMarker(series, s, this);
254 marker->setName(s->label());
310 marker->setName(s->label());
255 marker->setBrush(s->brush());
311 marker->setBrush(s->brush());
256 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
312 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
257 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
313 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
258 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
314 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
259 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
315 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
260 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
316 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
261 m_markers.append(marker);
317 m_markers.append(marker);
262 childItems().append(marker);
318 childItems().append(marker);
263 }
319 }
264 updateLayout();
320 updateLayout();
265 }
321 }
266
322
267 /*!
323 /*!
268 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
324 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
269 because removed slices are also deleted and we listen destroyed signal
325 because removed slices are also deleted and we listen destroyed signal
270 */
326 */
271 void QLegend::handleRemoved(QList<QPieSlice *> slices)
327 void QLegend::handleRemoved(QList<QPieSlice *> slices)
272 {
328 {
273 Q_UNUSED(slices)
329 Q_UNUSED(slices)
274 }
330 }
275
331
276
332
277 /*!
333 /*!
278 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
334 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
279 */
335 */
280 void QLegend::handleMarkerDestroyed()
336 void QLegend::handleMarkerDestroyed()
281 {
337 {
282 LegendMarker* m = static_cast<LegendMarker *> (sender());
338 LegendMarker* m = static_cast<LegendMarker *> (sender());
283 m_markers.removeOne(m);
339 m_markers.removeOne(m);
284 updateLayout();
340 updateLayout();
285 }
341 }
286
342
287 /*!
343 /*!
288 \internal \a event Handles clicked signals from scroll buttons
344 \internal \a event Handles clicked signals from scroll buttons
289 */
345 */
290 void QLegend::scrollButtonClicked(LegendScrollButton *scrollButton)
346 void QLegend::scrollButtonClicked(LegendScrollButton *scrollButton)
291 {
347 {
292 Q_ASSERT(scrollButton);
348 Q_ASSERT(scrollButton);
293
349
294 switch (scrollButton->id()) {
350 switch (scrollButton->id()) {
295 case LegendScrollButton::ScrollButtonIdLeft:
351 case LegendScrollButton::ScrollButtonIdLeft:
296 case LegendScrollButton::ScrollButtonIdUp: {
352 case LegendScrollButton::ScrollButtonIdUp: {
297 // Lower limit is same in these cases
353 // Lower limit is same in these cases
298 mFirstMarker--;
354 mFirstMarker--;
299 checkFirstMarkerBounds();
355 checkFirstMarkerBounds();
300 break;
356 break;
301 }
357 }
302 case LegendScrollButton::ScrollButtonIdRight:
358 case LegendScrollButton::ScrollButtonIdRight:
303 case LegendScrollButton::ScrollButtonIdDown: {
359 case LegendScrollButton::ScrollButtonIdDown: {
304 mFirstMarker++;
360 mFirstMarker++;
305 checkFirstMarkerBounds();
361 checkFirstMarkerBounds();
306 break;
362 break;
307 }
363 }
308 default: {
364 default: {
309 break;
365 break;
310 }
366 }
311 }
367 }
312 updateLayout();
368 updateLayout();
313 }
369 }
314
370
315 /*!
371 /*!
316 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
372 \internal Helper function. Appends markers from \a series to legend.
317 Not all series notify about events
318 */
319 void QLegend::connectSeries(QSeries *series)
320 {
321 // Connect relevant signals from series. Currently only pie series has interesting signals
322 // TODO: bar chart may have
323 if (series->type() == QSeries::SeriesTypePie) {
324 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
325 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
326 }
327 }
328
329 /*!
330 \internal Disconnects \a series from legend. No more status updates from series to legend.
331 */
332 void QLegend::disconnectSeries(QSeries *series)
333 {
334 if (series->type() == QSeries::SeriesTypePie) {
335 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
336 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
337 }
338 }
339
340 /*!
341 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
342 With pie chart, created markers depend on pie slices.
343 With bar chart, created markers depend on bar sets.
344 */
373 */
345 void QLegend::createMarkers(QSeries *series)
374 void QLegend::appendMarkers(QAreaSeries* series)
346 {
375 {
347 switch (series->type())
376 LegendMarker* marker = new LegendMarker(series,this);
348 {
377 marker->setName(series->name());
349 case QSeries::SeriesTypeLine: {
378 marker->setPen(series->pen());
350 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
379 marker->setBrush(series->brush());
351 appendMarkers(lineSeries);
380 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
352 break;
381 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
353 }
382 connect(series,SIGNAL(updated()),marker,SLOT(changed()));
354 case QSeries::SeriesTypeArea: {
383 m_markers.append(marker);
355 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
384 childItems().append(marker);
356 appendMarkers(areaSeries->upperSeries());
357 if(areaSeries->lowerSeries())
358 appendMarkers(areaSeries->lowerSeries());
359 break;
360 }
361 case QSeries::SeriesTypeBar: {
362 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
363 appendMarkers(barSeries);
364 break;
365 }
366 case QSeries::SeriesTypeStackedBar: {
367 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
368 appendMarkers(stackedBarSeries);
369 break;
370 }
371 case QSeries::SeriesTypePercentBar: {
372 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
373 appendMarkers(percentBarSeries);
374 break;
375 }
376 case QSeries::SeriesTypeScatter: {
377 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
378 appendMarkers(scatterSeries);
379 break;
380 }
381 case QSeries::SeriesTypePie: {
382 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
383 appendMarkers(pieSeries);
384 break;
385 }
386 case QSeries::SeriesTypeSpline: {
387 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
388 appendMarkers(splineSeries);
389 break;
390 }
391 default: {
392 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
393 break;
394 }
395 }
396 }
385 }
397
386
398 /*!
387 /*!
399 \internal Helper function. Appends markers from \a series to legend.
388 \internal Helper function. Appends markers from \a series to legend.
400 */
389 */
401 void QLegend::appendMarkers(QXYSeries* series)
390 void QLegend::appendMarkers(QXYSeries* series)
402 {
391 {
403 LegendMarker* marker = new LegendMarker(series,this);
392 LegendMarker* marker = new LegendMarker(series,this);
404 marker->setName(series->name());
393 marker->setName(series->name());
405 marker->setPen(series->pen());
394 marker->setPen(series->pen());
406 marker->setBrush(series->brush());
395 marker->setBrush(series->brush());
407 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
396 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
408 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
397 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
398 connect(series,SIGNAL(updated()),marker,SLOT(changed()));
409 m_markers.append(marker);
399 m_markers.append(marker);
410 childItems().append(marker);
400 childItems().append(marker);
411 }
401 }
412
402
413 /*!
403 /*!
414 \internal Helper function. Appends markers from \a series to legend.
404 \internal Helper function. Appends markers from \a series to legend.
415 */
405 */
416 void QLegend::appendMarkers(QBarSeries *series)
406 void QLegend::appendMarkers(QBarSeries *series)
417 {
407 {
418 foreach(QBarSet* set, series->barSets()) {
408 foreach(QBarSet* set, series->barSets()) {
419 LegendMarker* marker = new LegendMarker(series, set, this);
409 LegendMarker* marker = new LegendMarker(series, set, this);
420 marker->setName(set->name());
410 marker->setName(set->name());
421 marker->setPen(set->pen());
411 marker->setPen(set->pen());
422 marker->setBrush(set->brush());
412 marker->setBrush(set->brush());
423 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
413 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
424 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
414 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
425 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
415 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
426 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
416 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
427 m_markers.append(marker);
417 m_markers.append(marker);
428 childItems().append(marker);
418 childItems().append(marker);
429 }
419 }
430 }
420 }
431
421
432 /*!
422 /*!
433 \internal Helper function. Appends markers from \a series to legend.
423 \internal Helper function. Appends markers from \a series to legend.
434 */
424 */
435 void QLegend::appendMarkers(QPieSeries *series)
425 void QLegend::appendMarkers(QPieSeries *series)
436 {
426 {
437 foreach(QPieSlice* slice, series->slices()) {
427 foreach(QPieSlice* slice, series->slices()) {
438 LegendMarker* marker = new LegendMarker(series, slice, this);
428 LegendMarker* marker = new LegendMarker(series, slice, this);
439 marker->setName(slice->label());
429 marker->setName(slice->label());
440 marker->setPen(slice->pen());
430 marker->setPen(slice->pen());
441 marker->setBrush(slice->brush());
431 marker->setBrush(slice->brush());
442 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
432 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
443 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
433 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
444 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
434 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
445 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
435 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
446 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
436 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
447 m_markers.append(marker);
437 m_markers.append(marker);
448 childItems().append(marker);
438 childItems().append(marker);
449 }
439 }
450 }
440 }
451
441
452 /*!
442 /*!
453 \internal Deletes all markers that are created from \a series
443 \internal Deletes all markers that are created from \a series
454 */
444 */
455 void QLegend::deleteMarkers(QSeries *series)
445 void QLegend::deleteMarkers(QSeries *series)
456 {
446 {
457 // Search all markers that belong to given series and delete them.
447 // Search all markers that belong to given series and delete them.
458 foreach (LegendMarker *m, m_markers) {
448 foreach (LegendMarker *m, m_markers) {
459 if (m->series() == series) {
449 if (m->series() == series) {
460 m_markers.removeOne(m);
450 m_markers.removeOne(m);
461 delete m;
451 delete m;
462 }
452 }
463 }
453 }
464 }
454 }
465
455
466 /*!
456 /*!
467 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
457 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
468 If items don't fit, sets the visibility of scroll buttons accordingly.
458 If items don't fit, sets the visibility of scroll buttons accordingly.
469 Causes legend to be resized.
459 Causes legend to be resized.
470 */
460 */
471 void QLegend::updateLayout()
461 void QLegend::updateLayout()
472 {
462 {
473 // Calculate layout for markers and text
463 // Calculate layout for markers and text
474 if (m_markers.count() <= 0) {
464 if (m_markers.count() <= 0) {
475 // Nothing to do
465 // Nothing to do
476 return;
466 return;
477 }
467 }
478
468
479 // Find out widest item.
469 // Find out widest item.
480 QSizeF markerMaxSize = maximumMarkerSize();
470 QSizeF markerMaxSize = maximumMarkerSize();
481 checkFirstMarkerBounds();
471 checkFirstMarkerBounds();
482
472
483 // Use max height as scroll button size
473 // Use max height as scroll button size
484 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
474 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
485
475
486 qreal totalWidth = 0;
476 qreal totalWidth = 0;
487 qreal totalHeight = 0;
477 qreal totalHeight = 0;
488 switch (m_alignment)
478 switch (m_alignment)
489 {
479 {
490 // Both cases organise items horizontally
480 // Both cases organise items horizontally
491 case QLegend::LayoutBottom:
481 case QLegend::LayoutBottom:
492 case QLegend::LayoutTop: {
482 case QLegend::LayoutTop: {
493
483
494 qreal xStep = markerMaxSize.width();
484 qreal xStep = markerMaxSize.width();
495 qreal x = m_pos.x() + m_margin;
485 qreal x = m_pos.x() + m_margin;
496 qreal y = m_pos.y() + m_margin;
486 qreal y = m_pos.y() + m_margin;
497 int column = 0;
487 int column = 0;
498 int maxColumns = 1;
488 int maxColumns = 1;
499 qreal scrollButtonWidth = 0;
489 qreal scrollButtonWidth = 0;
500
490
501 // Set correct visibility for scroll scrollbuttons
491 // Set correct visibility for scroll scrollbuttons
502 if (scrollButtonsVisible()) {
492 if (scrollButtonsVisible()) {
503 m_scrollButtonLeft->setVisible(true);
493 m_scrollButtonLeft->setVisible(true);
504 m_scrollButtonRight->setVisible(true);
494 m_scrollButtonRight->setVisible(true);
505 // scrollbuttons visible, so add their width to total width
495 // scrollbuttons visible, so add their width to total width
506 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
496 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
507 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
497 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
508 // start position changes by scrollbutton width
498 // start position changes by scrollbutton width
509 x += scrollButtonWidth;
499 x += scrollButtonWidth;
510 } else {
500 } else {
511 m_scrollButtonLeft->setVisible(false);
501 m_scrollButtonLeft->setVisible(false);
512 m_scrollButtonRight->setVisible(false);
502 m_scrollButtonRight->setVisible(false);
513 }
503 }
514 m_scrollButtonUp->setVisible(false);
504 m_scrollButtonUp->setVisible(false);
515 m_scrollButtonDown->setVisible(false);
505 m_scrollButtonDown->setVisible(false);
516
506
517 for (int i=0; i < m_markers.count(); i++) {
507 for (int i=0; i < m_markers.count(); i++) {
518 LegendMarker *m = m_markers.at(i);
508 LegendMarker *m = m_markers.at(i);
519 if (i < mFirstMarker) {
509 if (i < mFirstMarker) {
520 // Markers before first are not visible.
510 // Markers before first are not visible.
521 m->setVisible(false);
511 m->setVisible(false);
522 } else {
512 } else {
523 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
513 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
524 // This marker would go outside legend rect.
514 // This marker would go outside legend rect.
525 m->setVisible(false);
515 m->setVisible(false);
526 } else {
516 } else {
527 // This marker is ok
517 // This marker is ok
528 m->setVisible(true);
518 m->setVisible(true);
529 m->setPos(x, y);
519 m->setPos(x, y);
530 x += xStep;
520 x += xStep;
531 column++;
521 column++;
532 }
522 }
533 }
523 }
534 maxColumns = column;
524 maxColumns = column;
535 }
525 }
536
526
537 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
527 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
538 m_scrollButtonRight->setPos(x + m_margin, y);
528 m_scrollButtonRight->setPos(x + m_margin, y);
539
529
540 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
530 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
541 totalHeight = markerMaxSize.height() + m_margin * 2;
531 totalHeight = markerMaxSize.height() + m_margin * 2;
542
532
543 break;
533 break;
544 }
534 }
545 // Both cases organize items vertically
535 // Both cases organize items vertically
546 case QLegend::LayoutLeft:
536 case QLegend::LayoutLeft:
547 case QLegend::LayoutRight: {
537 case QLegend::LayoutRight: {
548 qreal yStep = markerMaxSize.height();
538 qreal yStep = markerMaxSize.height();
549 qreal x = m_pos.x() + m_margin;
539 qreal x = m_pos.x() + m_margin;
550 qreal y = m_pos.y() + m_margin;
540 qreal y = m_pos.y() + m_margin;
551 int row = 1;
541 int row = 1;
552 int maxRows = 1;
542 int maxRows = 1;
553 qreal scrollButtonHeight = 0;
543 qreal scrollButtonHeight = 0;
554
544
555 // Set correct visibility for scroll scrollbuttons
545 // Set correct visibility for scroll scrollbuttons
556 if (scrollButtonsVisible()) {
546 if (scrollButtonsVisible()) {
557 m_scrollButtonUp->setVisible(true);
547 m_scrollButtonUp->setVisible(true);
558 m_scrollButtonDown->setVisible(true);
548 m_scrollButtonDown->setVisible(true);
559 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
549 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
560 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
550 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
561 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
551 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
562 } else {
552 } else {
563 m_scrollButtonUp->setVisible(false);
553 m_scrollButtonUp->setVisible(false);
564 m_scrollButtonDown->setVisible(false);
554 m_scrollButtonDown->setVisible(false);
565 }
555 }
566 m_scrollButtonLeft->setVisible(false);
556 m_scrollButtonLeft->setVisible(false);
567 m_scrollButtonRight->setVisible(false);
557 m_scrollButtonRight->setVisible(false);
568
558
569 for (int i=0; i < m_markers.count(); i++) {
559 for (int i=0; i < m_markers.count(); i++) {
570 LegendMarker* m = m_markers.at(i);
560 LegendMarker* m = m_markers.at(i);
571 if (i < mFirstMarker) {
561 if (i < mFirstMarker) {
572 // Markers before first are not visible.
562 // Markers before first are not visible.
573 m->setVisible(false);
563 m->setVisible(false);
574 } else {
564 } else {
575 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
565 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
576 // This marker would go outside legend rect.
566 // This marker would go outside legend rect.
577 m->setVisible(false);
567 m->setVisible(false);
578 } else {
568 } else {
579 // This marker is ok
569 // This marker is ok
580 m->setVisible(true);
570 m->setVisible(true);
581 m->setPos(x, y);
571 m->setPos(x, y);
582 y += yStep;
572 y += yStep;
583 row++;
573 row++;
584 }
574 }
585 }
575 }
586 maxRows = row;
576 maxRows = row;
587 }
577 }
588
578
589 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
579 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
590 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
580 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
591
581
592 totalWidth += markerMaxSize.width() + m_margin * 2;
582 totalWidth += markerMaxSize.width() + m_margin * 2;
593 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
583 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
594 break;
584 break;
595 }
585 }
596 default: {
586 default: {
597 break;
587 break;
598 }
588 }
599 }
589 }
600
590
601 m_size.setWidth(totalWidth);
591 m_size.setWidth(totalWidth);
602 m_size.setHeight(totalHeight);
592 m_size.setHeight(totalHeight);
603
593
604 update();
594 update();
605 }
595 }
606
596
607 /*!
597 /*!
608 \internal Sets the size of scroll buttons to \a size
598 \internal Sets the size of scroll buttons to \a size
609 */
599 */
610 void QLegend::rescaleScrollButtons(const QSize &size)
600 void QLegend::rescaleScrollButtons(const QSize &size)
611 {
601 {
612 QPolygonF left;
602 QPolygonF left;
613 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
603 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
614 QPolygonF right;
604 QPolygonF right;
615 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
605 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
616 QPolygonF up;
606 QPolygonF up;
617 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
607 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
618 QPolygonF down;
608 QPolygonF down;
619 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
609 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
620
610
621 m_scrollButtonLeft->setPolygon(left);
611 m_scrollButtonLeft->setPolygon(left);
622 m_scrollButtonRight->setPolygon(right);
612 m_scrollButtonRight->setPolygon(right);
623 m_scrollButtonUp->setPolygon(up);
613 m_scrollButtonUp->setPolygon(up);
624 m_scrollButtonDown->setPolygon(down);
614 m_scrollButtonDown->setPolygon(down);
625 }
615 }
626
616
627 /*!
617 /*!
628 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
618 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
629 */
619 */
630 QSizeF QLegend::maximumMarkerSize()
620 QSizeF QLegend::maximumMarkerSize()
631 {
621 {
632 QSizeF max(0,0);
622 QSizeF max(0,0);
633 foreach (LegendMarker* m, m_markers) {
623 foreach (LegendMarker* m, m_markers) {
634 if (m->boundingRect().width() > max.width())
624 if (m->boundingRect().width() > max.width())
635 max.setWidth(m->boundingRect().width());
625 max.setWidth(m->boundingRect().width());
636 if (m->boundingRect().height() > max.height())
626 if (m->boundingRect().height() > max.height())
637 max.setHeight(m->boundingRect().height());
627 max.setHeight(m->boundingRect().height());
638 }
628 }
639 return max;
629 return max;
640 }
630 }
641
631
642 /*!
632 /*!
643 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
633 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
644 If scrollbuttons are visible, they affect the number of visible markers.
634 If scrollbuttons are visible, they affect the number of visible markers.
645 */
635 */
646 void QLegend::checkFirstMarkerBounds()
636 void QLegend::checkFirstMarkerBounds()
647 {
637 {
648 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
638 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
649 // Bounds limited by height.
639 // Bounds limited by height.
650 int max;
640 int max;
651 if (scrollButtonsVisible()) {
641 if (scrollButtonsVisible()) {
652 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
642 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
653 } else {
643 } else {
654 max = m_maximumSize.height() / maximumMarkerSize().height();
644 max = m_maximumSize.height() / maximumMarkerSize().height();
655 }
645 }
656
646
657 if (mFirstMarker > m_markers.count() - max)
647 if (mFirstMarker > m_markers.count() - max)
658 mFirstMarker = m_markers.count() - max;
648 mFirstMarker = m_markers.count() - max;
659 } else {
649 } else {
660 // Bounds limited by width
650 // Bounds limited by width
661 int max;
651 int max;
662 if (scrollButtonsVisible()) {
652 if (scrollButtonsVisible()) {
663 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
653 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
664 } else {
654 } else {
665 max = m_maximumSize.width() / maximumMarkerSize().width();
655 max = m_maximumSize.width() / maximumMarkerSize().width();
666 }
656 }
667
657
668 if (mFirstMarker > m_markers.count() - max)
658 if (mFirstMarker > m_markers.count() - max)
669 mFirstMarker = m_markers.count() - max;
659 mFirstMarker = m_markers.count() - max;
670 }
660 }
671
661
672 if (mFirstMarker < 0)
662 if (mFirstMarker < 0)
673 mFirstMarker = 0;
663 mFirstMarker = 0;
674 }
664 }
675
665
676 /*!
666 /*!
677 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
667 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
678 */
668 */
679 bool QLegend::scrollButtonsVisible()
669 bool QLegend::scrollButtonsVisible()
680 {
670 {
681 // Just a helper to clarify, what the magic below means :)
671 // Just a helper to clarify, what the magic below means :)
682 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
672 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
683 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
673 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
684 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
674 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
685 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
675 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
686 }
676 }
687
677
688 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
678 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
689 }
679 }
690
680
691 #include "moc_qlegend.cpp"
681 #include "moc_qlegend.cpp"
692
682
693 QTCOMMERCIALCHART_END_NAMESPACE
683 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,116 +1,115
1 #ifndef QLEGEND_H
1 #ifndef QLEGEND_H
2 #define QLEGEND_H
2 #define QLEGEND_H
3
3
4 #include <QChartGlobal>
4 #include <QChartGlobal>
5 #include <QGraphicsWidget>
5 #include <QGraphicsWidget>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class Domain;
11 class Domain;
12 class LegendMarker;
12 class LegendMarker;
13 class QPieSlice;
13 class QPieSlice;
14 class QXYSeries;
14 class QXYSeries;
15 class QBarSet;
15 class QBarSet;
16 class QBarSeries;
16 class QBarSeries;
17 class QPieSeries;
17 class QPieSeries;
18 class QAreaSeries;
18 class LegendScrollButton;
19 class LegendScrollButton;
19 class QSeries;
20 class QSeries;
20 class QChart;
21 class QChart;
21
22
22 // TODO: This as widget
23 // TODO: This as widget
23 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
24 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
24 {
25 {
25 Q_OBJECT
26 Q_OBJECT
26 public:
27 public:
27
28
28 // We only support these alignments (for now)
29 // We only support these alignments (for now)
29 enum Layout {
30 enum Layout {
30 LayoutTop = Qt::AlignTop,
31 LayoutTop = Qt::AlignTop,
31 LayoutBottom = Qt::AlignBottom,
32 LayoutBottom = Qt::AlignBottom,
32 LayoutLeft = Qt::AlignLeft,
33 LayoutLeft = Qt::AlignLeft,
33 LayoutRight = Qt::AlignRight
34 LayoutRight = Qt::AlignRight
34 };
35 };
35 private:
36 private:
36 explicit QLegend(QChart *chart);
37 explicit QLegend(QChart *chart);
37
38
38 public:
39 public:
39 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
40 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
40 QRectF boundingRect() const;
41 QRectF boundingRect() const;
41
42
42 void setBrush(const QBrush &brush);
43 void setBrush(const QBrush &brush);
43 QBrush brush() const;
44 QBrush brush() const;
44
45
45 void setPen(const QPen &pen);
46 void setPen(const QPen &pen);
46 QPen pen() const;
47 QPen pen() const;
47
48
48 void setAlignmnent(QLegend::Layout alignment);
49 void setAlignmnent(QLegend::Layout alignment);
49 QLegend::Layout alignment() const;
50 QLegend::Layout alignment() const;
50
51
51 QSizeF maximumSize() const;
52 QSizeF maximumSize() const;
52 void setMaximumSize(const QSizeF size);
53 void setMaximumSize(const QSizeF size);
53
54
54 QSizeF size() const;
55 QSizeF size() const;
55 void setSize(const QSizeF size);
56 void setSize(const QSizeF size);
56 void setPos(const QPointF &pos);
57 void setPos(const QPointF &pos);
57
58
58 void scrollButtonClicked(LegendScrollButton *scrollButton);
59 void scrollButtonClicked(LegendScrollButton *scrollButton);
59
60
60 Q_SIGNALS:
61 Q_SIGNALS:
61 // for interactions.
62 // for interactions.
62 void clicked(QSeries *series, Qt::MouseButton button);
63 void clicked(QSeries *series, Qt::MouseButton button);
63 void clicked(QBarSet *barset, Qt::MouseButton button);
64 void clicked(QBarSet *barset, Qt::MouseButton button);
64 void clicked(QPieSlice *slice, Qt::MouseButton button);
65 void clicked(QPieSlice *slice, Qt::MouseButton button);
65
66
66 public Q_SLOTS:
67 public Q_SLOTS:
67 // PIMPL --->
68 // PIMPL --->
68 void handleSeriesAdded(QSeries *series, Domain *domain);
69 void handleSeriesAdded(QSeries *series, Domain *domain);
69 void handleSeriesRemoved(QSeries *series);
70 void handleSeriesRemoved(QSeries *series);
70 void handleAdded(QList<QPieSlice *> slices);
71 void handleAdded(QList<QPieSlice *> slices);
71 void handleRemoved(QList<QPieSlice *> slices);
72 void handleRemoved(QList<QPieSlice *> slices);
72 void handleMarkerDestroyed();
73 void handleMarkerDestroyed();
73
74
74 // PIMPL <---
75 // PIMPL <---
75
76
76 private:
77 private:
77 // PIMPL --->
78 // PIMPL --->
78 void connectSeries(QSeries *series);
79 void appendMarkers(QAreaSeries *series);
79 void disconnectSeries(QSeries *series);
80 void appendMarkers(QXYSeries *series);
80 void createMarkers(QSeries *series);
81 void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now
82 void appendMarkers(QBarSeries *series);
81 void appendMarkers(QBarSeries *series);
83 void appendMarkers(QPieSeries *series);
82 void appendMarkers(QPieSeries *series);
84 void deleteMarkers(QSeries *series);
83 void deleteMarkers(QSeries *series);
85 void updateLayout();
84 void updateLayout();
86 void rescaleScrollButtons(const QSize &size);
85 void rescaleScrollButtons(const QSize &size);
87 QSizeF maximumMarkerSize();
86 QSizeF maximumMarkerSize();
88 void checkFirstMarkerBounds();
87 void checkFirstMarkerBounds();
89 bool scrollButtonsVisible();
88 bool scrollButtonsVisible();
90
89
91 qreal m_margin;
90 qreal m_margin;
92 QPointF m_pos;
91 QPointF m_pos;
93 QSizeF m_minimumSize;
92 QSizeF m_minimumSize;
94 QSizeF m_maximumSize;
93 QSizeF m_maximumSize;
95 QSizeF m_size;
94 QSizeF m_size;
96
95
97 QList<LegendMarker *> m_markers;
96 QList<LegendMarker *> m_markers;
98
97
99 QBrush m_brush;
98 QBrush m_brush;
100 QPen m_pen;
99 QPen m_pen;
101 QLegend::Layout m_alignment;
100 QLegend::Layout m_alignment;
102
101
103 int mFirstMarker;
102 int mFirstMarker;
104
103
105 LegendScrollButton *m_scrollButtonLeft;
104 LegendScrollButton *m_scrollButtonLeft;
106 LegendScrollButton *m_scrollButtonRight;
105 LegendScrollButton *m_scrollButtonRight;
107 LegendScrollButton *m_scrollButtonUp;
106 LegendScrollButton *m_scrollButtonUp;
108 LegendScrollButton *m_scrollButtonDown;
107 LegendScrollButton *m_scrollButtonDown;
109
108
110 friend class QChart;
109 friend class QChart;
111 // <--- PIMPL
110 // <--- PIMPL
112 };
111 };
113
112
114 QTCOMMERCIALCHART_END_NAMESPACE
113 QTCOMMERCIALCHART_END_NAMESPACE
115
114
116 #endif // QLEGEND_H
115 #endif // QLEGEND_H
General Comments 0
You need to be logged in to leave comments. Login now