##// END OF EJS Templates
updated theme example. minor fix to legend
sauimone -
r786:3f886841e62a
parent child
Show More
@@ -1,332 +1,349
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 ");
184 int nameIndex = 0;
183 for (int i(0); i < m_dataTable.count(); i++) {
185 for (int i(0); i < m_dataTable.count(); i++) {
184 QLineSeries *series1 = new QLineSeries(chart);
186 QLineSeries *series1 = new QLineSeries(chart);
185 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++;
186 foreach (Data data, m_dataTable[i]) {
191 foreach (Data data, m_dataTable[i]) {
187 series1->add(data.first);
192 series1->add(data.first);
188 series2->add(QPointF(data.first.x(), 0.0));
193 series2->add(QPointF(data.first.x(), 0.0));
189 }
194 }
190 QAreaSeries *area = new QAreaSeries(series1, series2);
195 QAreaSeries *area = new QAreaSeries(series1, series2);
191 chart->addSeries(area);
196 chart->addSeries(area);
192 }
197 }
193 }
198 }
194 return chart;
199 return chart;
195 }
200 }
196
201
197 QChart* ThemeWidget::createBarChart(int valueCount) const
202 QChart* ThemeWidget::createBarChart(int valueCount) const
198 {
203 {
199 // bar chart
204 // bar chart
200 QChart* chart = new QChart();
205 QChart* chart = new QChart();
201 chart->setTitle("Bar chart");
206 chart->setTitle("Bar chart");
202 {
207 {
203 QBarCategories categories;
208 QBarCategories categories;
204 // TODO: categories
209 // TODO: categories
205 for (int i(0); i < valueCount; i++)
210 for (int i(0); i < valueCount; i++)
206 categories << QString::number(i);
211 categories << QString::number(i);
207 // QBarSeries* series = new QBarSeries(categories, chart);
212 // QBarSeries* series = new QBarSeries(categories, chart);
208 // QPercentBarSeries* series = new QPercentBarSeries(categories, chart);
213 // QPercentBarSeries* series = new QPercentBarSeries(categories, chart);
209 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
214 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
210 for (int i(0); i < m_dataTable.count(); i++) {
215 for (int i(0); i < m_dataTable.count(); i++) {
211 QBarSet *set = new QBarSet("Set" + QString::number(i));
216 QBarSet *set = new QBarSet("Set" + QString::number(i));
212 foreach (Data data, m_dataTable[i])
217 foreach (Data data, m_dataTable[i])
213 *set << data.first.y();
218 *set << data.first.y();
214 series->appendBarSet(set);
219 series->appendBarSet(set);
215 }
220 }
216 chart->addSeries(series);
221 chart->addSeries(series);
217 }
222 }
218 return chart;
223 return chart;
219 }
224 }
220
225
221 QChart* ThemeWidget::createLineChart() const
226 QChart* ThemeWidget::createLineChart() const
222 {
227 {
223 // line chart
228 // line chart
224 QChart* chart = new QChart();
229 QChart* chart = new QChart();
225 chart->setTitle("Line chart");
230 chart->setTitle("Line chart");
231 QString name("Series ");
232 int nameIndex = 0;
226 foreach (DataList list, m_dataTable) {
233 foreach (DataList list, m_dataTable) {
227 QLineSeries *series = new QLineSeries(chart);
234 QLineSeries *series = new QLineSeries(chart);
228 foreach (Data data, list)
235 foreach (Data data, list)
229 series->add(data.first);
236 series->add(data.first);
237 series->setName(name + QString::number(nameIndex));
238 nameIndex++;
230 chart->addSeries(series);
239 chart->addSeries(series);
231 }
240 }
232 return chart;
241 return chart;
233 }
242 }
234
243
235 QChart* ThemeWidget::createPieChart() const
244 QChart* ThemeWidget::createPieChart() const
236 {
245 {
237 // pie chart
246 // pie chart
238 QChart* chart = new QChart();
247 QChart* chart = new QChart();
239 chart->setTitle("Pie chart");
248 chart->setTitle("Pie chart");
240 qreal pieSize = 1.0 / m_dataTable.count();
249 qreal pieSize = 1.0 / m_dataTable.count();
241 for (int i = 0; i < m_dataTable.count(); i++) {
250 for (int i = 0; i < m_dataTable.count(); i++) {
242 QPieSeries *series = new QPieSeries(chart);
251 QPieSeries *series = new QPieSeries(chart);
243 foreach (Data data, m_dataTable[i]) {
252 foreach (Data data, m_dataTable[i]) {
244 QPieSlice *slice = series->add(data.first.y(), data.second);
253 QPieSlice *slice = series->add(data.first.y(), data.second);
245 if (data == m_dataTable[i].first()) {
254 if (data == m_dataTable[i].first()) {
246 slice->setLabelVisible();
255 slice->setLabelVisible();
247 slice->setExploded();
256 slice->setExploded();
248 }
257 }
249 }
258 }
250 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
259 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
251 series->setPieSize(pieSize);
260 series->setPieSize(pieSize);
252 series->setPiePosition(hPos, 0.5);
261 series->setPiePosition(hPos, 0.5);
253 chart->addSeries(series);
262 chart->addSeries(series);
254 }
263 }
255
264
256 return chart;
265 return chart;
257 }
266 }
258
267
259 QChart* ThemeWidget::createSplineChart() const
268 QChart* ThemeWidget::createSplineChart() const
260 { // spine chart
269 { // spine chart
261 QChart* chart = new QChart();
270 QChart* chart = new QChart();
262 chart->setTitle("Spline chart");
271 chart->setTitle("Spline chart");
272 QString name("Series ");
273 int nameIndex = 0;
263 foreach (DataList list, m_dataTable) {
274 foreach (DataList list, m_dataTable) {
264 QSplineSeries *series = new QSplineSeries(chart);
275 QSplineSeries *series = new QSplineSeries(chart);
265 foreach (Data data, list)
276 foreach (Data data, list)
266 series->add(data.first);
277 series->add(data.first);
278 series->setName(name + QString::number(nameIndex));
279 nameIndex++;
267 chart->addSeries(series);
280 chart->addSeries(series);
268 }
281 }
269 return chart;
282 return chart;
270 }
283 }
271
284
272 QChart* ThemeWidget::createScatterChart() const
285 QChart* ThemeWidget::createScatterChart() const
273 { // scatter chart
286 { // scatter chart
274 QChart* chart = new QChart();
287 QChart* chart = new QChart();
275 chart->setTitle("Scatter chart");
288 chart->setTitle("Scatter chart");
289 QString name("Series ");
290 int nameIndex = 0;
276 foreach (DataList list, m_dataTable) {
291 foreach (DataList list, m_dataTable) {
277 QScatterSeries *series = new QScatterSeries(chart);
292 QScatterSeries *series = new QScatterSeries(chart);
278 foreach (Data data, list)
293 foreach (Data data, list)
279 series->add(data.first);
294 series->add(data.first);
295 series->setName(name + QString::number(nameIndex));
296 nameIndex++;
280 chart->addSeries(series);
297 chart->addSeries(series);
281 }
298 }
282 return chart;
299 return chart;
283 }
300 }
284
301
285 void ThemeWidget::updateUI()
302 void ThemeWidget::updateUI()
286 {
303 {
287 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
304 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
288
305
289 if (m_charts.at(0)->chart()->theme() != theme) {
306 if (m_charts.at(0)->chart()->theme() != theme) {
290 foreach (QChartView *chartView, m_charts)
307 foreach (QChartView *chartView, m_charts)
291 chartView->chart()->setTheme(theme);
308 chartView->chart()->setTheme(theme);
292
309
293 QPalette pal = window()->palette();
310 QPalette pal = window()->palette();
294 if (theme == QChart::ChartThemeLight) {
311 if (theme == QChart::ChartThemeLight) {
295 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
312 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
296 pal.setColor(QPalette::WindowText, QRgb(0x404044));
313 pal.setColor(QPalette::WindowText, QRgb(0x404044));
297 } else if (theme == QChart::ChartThemeDark) {
314 } else if (theme == QChart::ChartThemeDark) {
298 pal.setColor(QPalette::Window, QRgb(0x121218));
315 pal.setColor(QPalette::Window, QRgb(0x121218));
299 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
316 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
300 } else if (theme == QChart::ChartThemeBlueCerulean) {
317 } else if (theme == QChart::ChartThemeBlueCerulean) {
301 pal.setColor(QPalette::Window, QRgb(0x40434a));
318 pal.setColor(QPalette::Window, QRgb(0x40434a));
302 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
319 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
303 } else if (theme == QChart::ChartThemeBrownSand) {
320 } else if (theme == QChart::ChartThemeBrownSand) {
304 pal.setColor(QPalette::Window, QRgb(0x9e8965));
321 pal.setColor(QPalette::Window, QRgb(0x9e8965));
305 pal.setColor(QPalette::WindowText, QRgb(0x404044));
322 pal.setColor(QPalette::WindowText, QRgb(0x404044));
306 } else if (theme == QChart::ChartThemeBlueNcs) {
323 } else if (theme == QChart::ChartThemeBlueNcs) {
307 pal.setColor(QPalette::Window, QRgb(0x018bba));
324 pal.setColor(QPalette::Window, QRgb(0x018bba));
308 pal.setColor(QPalette::WindowText, QRgb(0x404044));
325 pal.setColor(QPalette::WindowText, QRgb(0x404044));
309 } else if (theme == QChart::ChartThemeHighContrast) {
326 } else if (theme == QChart::ChartThemeHighContrast) {
310 pal.setColor(QPalette::Window, QRgb(0xffab03));
327 pal.setColor(QPalette::Window, QRgb(0xffab03));
311 pal.setColor(QPalette::WindowText, QRgb(0x181818));
328 pal.setColor(QPalette::WindowText, QRgb(0x181818));
312 } else if (theme == QChart::ChartThemeBlueIcy) {
329 } else if (theme == QChart::ChartThemeBlueIcy) {
313 pal.setColor(QPalette::Window, QRgb(0xcee7f0));
330 pal.setColor(QPalette::Window, QRgb(0xcee7f0));
314 pal.setColor(QPalette::WindowText, QRgb(0x404044));
331 pal.setColor(QPalette::WindowText, QRgb(0x404044));
315 } else {
332 } else {
316 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
333 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
317 pal.setColor(QPalette::WindowText, QRgb(0x404044));
334 pal.setColor(QPalette::WindowText, QRgb(0x404044));
318 }
335 }
319 window()->setPalette(pal);
336 window()->setPalette(pal);
320 }
337 }
321
338
322 bool checked = m_antialiasCheckBox->isChecked();
339 bool checked = m_antialiasCheckBox->isChecked();
323 foreach (QChartView *chart, m_charts)
340 foreach (QChartView *chart, m_charts)
324 chart->setRenderHint(QPainter::Antialiasing, checked);
341 chart->setRenderHint(QPainter::Antialiasing, checked);
325
342
326 QChart::AnimationOptions options(m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt());
343 QChart::AnimationOptions options(m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt());
327 if (m_charts.at(0)->chart()->animationOptions() != options) {
344 if (m_charts.at(0)->chart()->animationOptions() != options) {
328 foreach (QChartView *chartView, m_charts)
345 foreach (QChartView *chartView, m_charts)
329 chartView->chart()->setAnimationOptions(options);
346 chartView->chart()->setAnimationOptions(options);
330 }
347 }
331 }
348 }
332
349
@@ -1,173 +1,175
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 <QPainter>
6 #include <QPainter>
7 #include <QGraphicsSceneEvent>
7 #include <QGraphicsSceneEvent>
8 #include <QGraphicsSimpleTextItem>
8 #include <QGraphicsSimpleTextItem>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 LegendMarker::LegendMarker(QSeries *series, QGraphicsItem *parent) : QGraphicsObject(parent),
12 LegendMarker::LegendMarker(QSeries *series, QGraphicsItem *parent) : QGraphicsObject(parent),
13 m_pos(0,0),
13 m_pos(0,0),
14 m_size(0,0),
14 m_size(0,0),
15 m_boundingRect(0,0,0,0),
15 m_boundingRect(0,0,0,0),
16 m_markerBoundingRect(0,0,0,0),
16 m_markerBoundingRect(0,0,0,0),
17 m_series(series),
17 m_series(series),
18 m_barset(0),
18 m_barset(0),
19 m_pieslice(0),
19 m_pieslice(0),
20 m_type(LegendMarkerTypeSeries),
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),
34 m_type(LegendMarkerTypeBarset),
35 m_textItem(new QGraphicsSimpleTextItem(this))
35 m_textItem(new QGraphicsSimpleTextItem(this))
36 {
36 {
37 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
37 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
38 }
38 }
39
39
40 LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent) : QGraphicsObject(parent),
40 LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent) : QGraphicsObject(parent),
41 m_pos(0,0),
41 m_pos(0,0),
42 m_size(0,0),
42 m_size(0,0),
43 m_boundingRect(0,0,0,0),
43 m_boundingRect(0,0,0,0),
44 m_markerBoundingRect(0,0,0,0),
44 m_markerBoundingRect(0,0,0,0),
45 m_series(series),
45 m_series(series),
46 m_barset(0),
46 m_barset(0),
47 m_pieslice(pieslice),
47 m_pieslice(pieslice),
48 m_type(LegendMarkerTypePieslice),
48 m_type(LegendMarkerTypePieslice),
49 m_textItem(new QGraphicsSimpleTextItem(this))
49 m_textItem(new QGraphicsSimpleTextItem(this))
50 {
50 {
51 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
51 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
52 }
52 }
53
53
54 void LegendMarker::setPos(qreal x, qreal y)
54 void LegendMarker::setPos(qreal x, qreal y)
55 {
55 {
56 m_pos = QPointF(x,y);
56 m_pos = QPointF(x,y);
57 layoutChanged();
57 layoutChanged();
58 }
58 }
59
59
60 void LegendMarker::setPen(const QPen &pen)
60 void LegendMarker::setPen(const QPen &pen)
61 {
61 {
62 m_pen = pen;
62 m_pen = pen;
63 }
63 }
64
64
65 QPen LegendMarker::pen() const
65 QPen LegendMarker::pen() const
66 {
66 {
67 return m_pen;
67 return m_pen;
68 }
68 }
69
69
70 void LegendMarker::setBrush(const QBrush &brush)
70 void LegendMarker::setBrush(const QBrush &brush)
71 {
71 {
72 m_brush = brush;
72 m_brush = brush;
73 }
73 }
74
74
75 QBrush LegendMarker::brush() const
75 QBrush LegendMarker::brush() const
76 {
76 {
77 return m_brush;
77 return m_brush;
78 }
78 }
79
79
80 void LegendMarker::setName(const QString name)
80 void LegendMarker::setName(const QString name)
81 {
81 {
82 m_textItem->setText(name);
82 m_textItem->setText(name);
83 layoutChanged();
83 layoutChanged();
84 }
84 }
85
85
86 QString LegendMarker::name() const
86 QString LegendMarker::name() const
87 {
87 {
88 return m_textItem->text();
88 return m_textItem->text();
89 }
89 }
90
90
91 QSeries* LegendMarker::series() const
91 QSeries* LegendMarker::series() const
92 {
92 {
93 return m_series;
93 return m_series;
94 }
94 }
95
95
96 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
96 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
97 {
97 {
98 Q_UNUSED(option)
98 Q_UNUSED(option)
99 Q_UNUSED(widget)
99 Q_UNUSED(widget)
100
100
101 painter->setPen(m_pen);
101 painter->setPen(m_pen);
102 painter->setBrush(m_brush);
102 painter->setBrush(m_brush);
103 painter->drawRect(m_markerBoundingRect);
103 painter->drawRect(m_markerBoundingRect);
104 }
104 }
105
105
106 QRectF LegendMarker::boundingRect() const
106 QRectF LegendMarker::boundingRect() const
107 {
107 {
108 return m_boundingRect;
108 return m_boundingRect;
109 }
109 }
110
110
111 void LegendMarker::layoutChanged()
111 void LegendMarker::layoutChanged()
112 {
112 {
113 QSizeF markerSize(10,10);
113 QSizeF markerSize(10,10);
114 qreal margin = 2;
114 qreal margin = 2;
115
115
116 m_size.setHeight(markerSize.height() + 2 * margin);
116 m_size.setHeight(markerSize.height() + 2 * margin);
117 m_size.setWidth(m_textItem->boundingRect().width() + markerSize.width() + 3 * margin);
117 m_size.setWidth(m_textItem->boundingRect().width() + markerSize.width() + 3 * margin);
118
118
119 m_boundingRect = QRectF(m_pos.x(),m_pos.y(),m_size.width(),m_size.height());
119 m_boundingRect = QRectF(m_pos.x(),m_pos.y(),m_size.width(),m_size.height());
120
120
121 m_markerBoundingRect = QRectF(m_pos.x() + margin, m_pos.y() + margin, markerSize.width(),markerSize.height());
121 m_markerBoundingRect = QRectF(m_pos.x() + margin, m_pos.y() + margin, markerSize.width(),markerSize.height());
122
122
123 m_textItem->setPos(m_pos.x() + markerSize.width() + 2 * margin, m_pos.y() + margin);
123 m_textItem->setPos(m_pos.x() + markerSize.width() + 2 * margin, m_pos.y() + margin);
124 }
124 }
125
125
126 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
126 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
127 {
127 {
128 switch (m_type)
128 switch (m_type)
129 {
129 {
130 case LegendMarkerTypeSeries: {
130 case LegendMarkerTypeSeries: {
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 LegendMarkerTypeBarset: {
135 emit clicked(m_barset,event->button());
135 emit clicked(m_barset,event->button());
136 break;
136 break;
137 }
137 }
138 case LegendMarkerTypePieslice: {
138 case LegendMarkerTypePieslice: {
139 emit clicked(m_pieslice,event->button());
139 emit clicked(m_pieslice,event->button());
140 break;
140 break;
141 }
141 }
142 default: {
142 default: {
143 break;
143 break;
144 }
144 }
145 }
145 }
146 }
146 }
147
147
148 void LegendMarker::changed()
148 void LegendMarker::changed()
149 {
149 {
150 switch (m_type)
150 switch (m_type)
151 {
151 {
152 case LegendMarkerTypeSeries: {
152 case LegendMarkerTypeSeries: {
153 QXYSeries* s = static_cast<QXYSeries*> (m_series);
153 QXYSeries* s = static_cast<QXYSeries*> (m_series);
154 setPen(s->pen());
154 setBrush(s->brush());
155 setBrush(s->brush());
155 setName(s->name());
156 setName(s->name());
156 break;
157 break;
157 }
158 }
158 case LegendMarkerTypeBarset: {
159 case LegendMarkerTypeBarset: {
160 setPen(m_barset->pen());
159 setBrush(m_barset->brush());
161 setBrush(m_barset->brush());
160 setName(m_barset->name());
162 setName(m_barset->name());
161 break;
163 break;
162 }
164 }
163 case LegendMarkerTypePieslice: {
165 case LegendMarkerTypePieslice: {
164 setBrush(m_pieslice->brush());
166 setBrush(m_pieslice->brush());
165 setName(m_pieslice->label());
167 setName(m_pieslice->label());
166 break;
168 break;
167 }
169 }
168 }
170 }
169 }
171 }
170
172
171 #include "moc_legendmarker_p.cpp"
173 #include "moc_legendmarker_p.cpp"
172
174
173 QTCOMMERCIALCHART_END_NAMESPACE
175 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,706 +1,706
1 #include "qchartglobal.h"
1 #include "qchartglobal.h"
2 #include "qlegend.h"
2 #include "qlegend.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(QGraphicsItem *parent) : QGraphicsObject(parent),
69 QLegend::QLegend(QGraphicsItem *parent) : QGraphicsObject(parent),
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
83
84 connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
84 connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
85 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
85 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
86 connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
86 connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
87 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
87 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
88 connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
88 connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
89 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
89 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
90 connect(m_scrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
90 connect(m_scrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
91 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
91 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
92
92
93 setZValue(ChartPresenter::LegendZValue);
93 setZValue(ChartPresenter::LegendZValue);
94 }
94 }
95
95
96 /*!
96 /*!
97 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
97 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
98 */
98 */
99 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
99 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
100 {
100 {
101 Q_UNUSED(option)
101 Q_UNUSED(option)
102 Q_UNUSED(widget)
102 Q_UNUSED(widget)
103
103
104 painter->setOpacity(opacity());
104 painter->setOpacity(opacity());
105 painter->setPen(m_pen);
105 painter->setPen(m_pen);
106 painter->setBrush(m_brush);
106 painter->setBrush(m_brush);
107 // painter->drawRect(boundingRect());
107 // painter->drawRect(boundingRect());
108 }
108 }
109
109
110 /*!
110 /*!
111 Bounding rect of legend.
111 Bounding rect of legend.
112 */
112 */
113 QRectF QLegend::boundingRect() const
113 QRectF QLegend::boundingRect() const
114 {
114 {
115 return QRectF(m_pos,m_size);
115 return QRectF(m_pos,m_size);
116 }
116 }
117
117
118 /*!
118 /*!
119 Sets the \a brush of legend. Brush affects the background of legend.
119 Sets the \a brush of legend. Brush affects the background of legend.
120 */
120 */
121 void QLegend::setBrush(const QBrush &brush)
121 void QLegend::setBrush(const QBrush &brush)
122 {
122 {
123 if (m_brush != brush) {
123 if (m_brush != brush) {
124 m_brush = brush;
124 m_brush = brush;
125 update();
125 update();
126 }
126 }
127 }
127 }
128
128
129 /*!
129 /*!
130 Returns the brush used by legend.
130 Returns the brush used by legend.
131 */
131 */
132 QBrush QLegend::brush() const
132 QBrush QLegend::brush() const
133 {
133 {
134 return m_brush;
134 return m_brush;
135 }
135 }
136
136
137 /*!
137 /*!
138 Sets the \a pen of legend. Pen affects the legend borders.
138 Sets the \a pen of legend. Pen affects the legend borders.
139 */
139 */
140 void QLegend::setPen(const QPen &pen)
140 void QLegend::setPen(const QPen &pen)
141 {
141 {
142 if (m_pen != pen) {
142 if (m_pen != pen) {
143 m_pen = pen;
143 m_pen = pen;
144 update();
144 update();
145 }
145 }
146 }
146 }
147
147
148 /*!
148 /*!
149 Returns the pen used by legend
149 Returns the pen used by legend
150 */
150 */
151
151
152 QPen QLegend::pen() const
152 QPen QLegend::pen() const
153 {
153 {
154 return m_pen;
154 return m_pen;
155 }
155 }
156
156
157 /*!
157 /*!
158 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
158 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
159 \sa QLegend::Layout
159 \sa QLegend::Layout
160 */
160 */
161 void QLegend::setAlignmnent(QLegend::Layout alignment)
161 void QLegend::setAlignmnent(QLegend::Layout alignment)
162 {
162 {
163 m_alignment = alignment;
163 m_alignment = alignment;
164 updateLayout();
164 updateLayout();
165 }
165 }
166
166
167 /*!
167 /*!
168 Returns the preferred layout for legend
168 Returns the preferred layout for legend
169 */
169 */
170 QLegend::Layout QLegend::alignment() const
170 QLegend::Layout QLegend::alignment() const
171 {
171 {
172 return m_alignment;
172 return m_alignment;
173 }
173 }
174
174
175 /*!
175 /*!
176 Returns the maximum size of legend.
176 Returns the maximum size of legend.
177 */
177 */
178 QSizeF QLegend::maximumSize() const
178 QSizeF QLegend::maximumSize() const
179 {
179 {
180 return m_maximumSize;
180 return m_maximumSize;
181 }
181 }
182
182
183 /*!
183 /*!
184 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
184 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
185 more series than legend can fit to this size, scroll buttons are displayed.
185 more series than legend can fit to this size, scroll buttons are displayed.
186 */
186 */
187 void QLegend::setMaximumSize(const QSizeF size)
187 void QLegend::setMaximumSize(const QSizeF size)
188 {
188 {
189 m_maximumSize = size;
189 m_maximumSize = size;
190 updateLayout();
190 updateLayout();
191 }
191 }
192
192
193 /*!
193 /*!
194 Returns the current size of legend.
194 Returns the current size of legend.
195 */
195 */
196 QSizeF QLegend::size() const
196 QSizeF QLegend::size() const
197 {
197 {
198 return m_size;
198 return m_size;
199 }
199 }
200
200
201 /*!
201 /*!
202 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
202 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
203 \sa setMmaximumSize()
203 \sa setMmaximumSize()
204 */
204 */
205 void QLegend::setSize(const QSizeF size)
205 void QLegend::setSize(const QSizeF size)
206 {
206 {
207 m_size = size;
207 m_size = size;
208 if (m_size.width() > m_maximumSize.width()) {
208 if (m_size.width() > m_maximumSize.width()) {
209 m_size.setWidth(m_maximumSize.width());
209 m_size.setWidth(m_maximumSize.width());
210 }
210 }
211 if (m_size.height() > m_maximumSize.height()) {
211 if (m_size.height() > m_maximumSize.height()) {
212 m_size.setHeight(m_maximumSize.height());
212 m_size.setHeight(m_maximumSize.height());
213 }
213 }
214 }
214 }
215
215
216 /*!
216 /*!
217 Sets position of legend to \a pos
217 Sets position of legend to \a pos
218 */
218 */
219 void QLegend::setPos(const QPointF &pos)
219 void QLegend::setPos(const QPointF &pos)
220 {
220 {
221 m_pos = pos;
221 m_pos = pos;
222 updateLayout();
222 updateLayout();
223 }
223 }
224
224
225 /*!
225 /*!
226 \internal \a series \a domain Should be called when series is added to chart.
226 \internal \a series \a domain Should be called when series is added to chart.
227 */
227 */
228 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
228 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
229 {
229 {
230 Q_UNUSED(domain)
230 Q_UNUSED(domain)
231
231
232 createMarkers(series);
232 createMarkers(series);
233 connectSeries(series);
233 connectSeries(series);
234 updateLayout();
234 updateLayout();
235 }
235 }
236
236
237 /*!
237 /*!
238 \internal \a series Should be called when series is removed from chart.
238 \internal \a series Should be called when series is removed from chart.
239 */
239 */
240 void QLegend::handleSeriesRemoved(QSeries *series)
240 void QLegend::handleSeriesRemoved(QSeries *series)
241 {
241 {
242 disconnectSeries(series);
242 disconnectSeries(series);
243
243
244 if (series->type() == QSeries::SeriesTypeArea) {
244 if (series->type() == QSeries::SeriesTypeArea) {
245 // This is special case. Area series has upper and lower series, which each have markers
245 // This is special case. Area series has upper and lower series, which each have markers
246 QAreaSeries* s = static_cast<QAreaSeries *> (series);
246 QAreaSeries* s = static_cast<QAreaSeries *> (series);
247 deleteMarkers(s->upperSeries());
247 deleteMarkers(s->upperSeries());
248 deleteMarkers(s->lowerSeries());
248 deleteMarkers(s->lowerSeries());
249 } else {
249 } else {
250 deleteMarkers(series);
250 deleteMarkers(series);
251 }
251 }
252
252
253 updateLayout();
253 updateLayout();
254 }
254 }
255
255
256 /*!
256 /*!
257 \internal \a slices Should be called when slices are added to pie chart.
257 \internal \a slices Should be called when slices are added to pie chart.
258 */
258 */
259 void QLegend::handleAdded(QList<QPieSlice *> slices)
259 void QLegend::handleAdded(QList<QPieSlice *> slices)
260 {
260 {
261 QPieSeries* series = static_cast<QPieSeries *> (sender());
261 QPieSeries* series = static_cast<QPieSeries *> (sender());
262 foreach(QPieSlice* s, slices) {
262 foreach(QPieSlice* s, slices) {
263 LegendMarker* marker = new LegendMarker(series, s, this);
263 LegendMarker* marker = new LegendMarker(series, s, this);
264 marker->setName(s->label());
264 marker->setName(s->label());
265 marker->setBrush(s->brush());
265 marker->setBrush(s->brush());
266 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
266 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
267 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
267 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
268 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
268 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
269 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
269 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
270 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
270 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
271 m_markers.append(marker);
271 m_markers.append(marker);
272 childItems().append(marker);
272 childItems().append(marker);
273 }
273 }
274 updateLayout();
274 updateLayout();
275 }
275 }
276
276
277 /*!
277 /*!
278 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
278 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
279 because removed slices are also deleted and we listen destroyed signal
279 because removed slices are also deleted and we listen destroyed signal
280 */
280 */
281 void QLegend::handleRemoved(QList<QPieSlice *> slices)
281 void QLegend::handleRemoved(QList<QPieSlice *> slices)
282 {
282 {
283 Q_UNUSED(slices)
283 Q_UNUSED(slices)
284 }
284 }
285
285
286
286
287 /*!
287 /*!
288 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
288 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
289 */
289 */
290 void QLegend::handleMarkerDestroyed()
290 void QLegend::handleMarkerDestroyed()
291 {
291 {
292 LegendMarker* m = static_cast<LegendMarker *> (sender());
292 LegendMarker* m = static_cast<LegendMarker *> (sender());
293 m_markers.removeOne(m);
293 m_markers.removeOne(m);
294 updateLayout();
294 updateLayout();
295 }
295 }
296
296
297 /*!
297 /*!
298 \internal \a event Handles clicked signals from scroll buttons
298 \internal \a event Handles clicked signals from scroll buttons
299 */
299 */
300 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
300 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
301 {
301 {
302 Q_UNUSED(event); // Maybe later something happens with right click...
302 Q_UNUSED(event); // Maybe later something happens with right click...
303
303
304 LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender());
304 LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender());
305 Q_ASSERT(scrollButton);
305 Q_ASSERT(scrollButton);
306
306
307 switch (scrollButton->id()) {
307 switch (scrollButton->id()) {
308 case LegendScrollButton::ScrollButtonIdLeft:
308 case LegendScrollButton::ScrollButtonIdLeft:
309 case LegendScrollButton::ScrollButtonIdUp: {
309 case LegendScrollButton::ScrollButtonIdUp: {
310 // Lower limit is same in these cases
310 // Lower limit is same in these cases
311 mFirstMarker--;
311 mFirstMarker--;
312 checkFirstMarkerBounds();
312 checkFirstMarkerBounds();
313 break;
313 break;
314 }
314 }
315 case LegendScrollButton::ScrollButtonIdRight:
315 case LegendScrollButton::ScrollButtonIdRight:
316 case LegendScrollButton::ScrollButtonIdDown: {
316 case LegendScrollButton::ScrollButtonIdDown: {
317 mFirstMarker++;
317 mFirstMarker++;
318 checkFirstMarkerBounds();
318 checkFirstMarkerBounds();
319 break;
319 break;
320 }
320 }
321 default: {
321 default: {
322 break;
322 break;
323 }
323 }
324 }
324 }
325 updateLayout();
325 updateLayout();
326 }
326 }
327
327
328 /*!
328 /*!
329 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
329 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
330 Not all series notify about events
330 Not all series notify about events
331 */
331 */
332 void QLegend::connectSeries(QSeries *series)
332 void QLegend::connectSeries(QSeries *series)
333 {
333 {
334 // Connect relevant signals from series. Currently only pie series has interesting signals
334 // Connect relevant signals from series. Currently only pie series has interesting signals
335 // TODO: bar chart may have
335 // TODO: bar chart may have
336 if (series->type() == QSeries::SeriesTypePie) {
336 if (series->type() == QSeries::SeriesTypePie) {
337 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
337 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
338 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
338 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
339 }
339 }
340 }
340 }
341
341
342 /*!
342 /*!
343 \internal Disconnects \a series from legend. No more status updates from series to legend.
343 \internal Disconnects \a series from legend. No more status updates from series to legend.
344 */
344 */
345 void QLegend::disconnectSeries(QSeries *series)
345 void QLegend::disconnectSeries(QSeries *series)
346 {
346 {
347 if (series->type() == QSeries::SeriesTypePie) {
347 if (series->type() == QSeries::SeriesTypePie) {
348 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
348 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
349 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
349 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
350 }
350 }
351 }
351 }
352
352
353 /*!
353 /*!
354 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
354 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
355 With pie chart, created markers depend on pie slices.
355 With pie chart, created markers depend on pie slices.
356 With bar chart, created markers depend on bar sets.
356 With bar chart, created markers depend on bar sets.
357 */
357 */
358 void QLegend::createMarkers(QSeries *series)
358 void QLegend::createMarkers(QSeries *series)
359 {
359 {
360 switch (series->type())
360 switch (series->type())
361 {
361 {
362 case QSeries::SeriesTypeLine: {
362 case QSeries::SeriesTypeLine: {
363 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
363 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
364 appendMarkers(lineSeries);
364 appendMarkers(lineSeries);
365 break;
365 break;
366 }
366 }
367 case QSeries::SeriesTypeArea: {
367 case QSeries::SeriesTypeArea: {
368 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
368 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
369 appendMarkers(areaSeries->upperSeries());
369 appendMarkers(areaSeries->upperSeries());
370 if(areaSeries->lowerSeries())
370 if(areaSeries->lowerSeries())
371 appendMarkers(areaSeries->lowerSeries());
371 appendMarkers(areaSeries->lowerSeries());
372 break;
372 break;
373 }
373 }
374 case QSeries::SeriesTypeBar: {
374 case QSeries::SeriesTypeBar: {
375 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
375 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
376 appendMarkers(barSeries);
376 appendMarkers(barSeries);
377 break;
377 break;
378 }
378 }
379 case QSeries::SeriesTypeStackedBar: {
379 case QSeries::SeriesTypeStackedBar: {
380 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
380 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
381 appendMarkers(stackedBarSeries);
381 appendMarkers(stackedBarSeries);
382 break;
382 break;
383 }
383 }
384 case QSeries::SeriesTypePercentBar: {
384 case QSeries::SeriesTypePercentBar: {
385 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
385 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
386 appendMarkers(percentBarSeries);
386 appendMarkers(percentBarSeries);
387 break;
387 break;
388 }
388 }
389 case QSeries::SeriesTypeScatter: {
389 case QSeries::SeriesTypeScatter: {
390 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
390 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
391 appendMarkers(scatterSeries);
391 appendMarkers(scatterSeries);
392 break;
392 break;
393 }
393 }
394 case QSeries::SeriesTypePie: {
394 case QSeries::SeriesTypePie: {
395 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
395 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
396 appendMarkers(pieSeries);
396 appendMarkers(pieSeries);
397 break;
397 break;
398 }
398 }
399 case QSeries::SeriesTypeSpline: {
399 case QSeries::SeriesTypeSpline: {
400 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
400 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
401 appendMarkers(splineSeries);
401 appendMarkers(splineSeries);
402 break;
402 break;
403 }
403 }
404 default: {
404 default: {
405 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
405 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
406 break;
406 break;
407 }
407 }
408 }
408 }
409 }
409 }
410
410
411 /*!
411 /*!
412 \internal Helper function. Appends markers from \a series to legend.
412 \internal Helper function. Appends markers from \a series to legend.
413 */
413 */
414 void QLegend::appendMarkers(QXYSeries* series)
414 void QLegend::appendMarkers(QXYSeries* series)
415 {
415 {
416 LegendMarker* marker = new LegendMarker(series,this);
416 LegendMarker* marker = new LegendMarker(series,this);
417 marker->setName(series->name());
417 marker->setName(series->name());
418 marker->setPen(series->pen());
418 marker->setPen(series->pen());
419 marker->setBrush(series->brush());
419 marker->setBrush(series->brush());
420 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
420 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
421 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
421 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
422 m_markers.append(marker);
422 m_markers.append(marker);
423 childItems().append(marker);
423 childItems().append(marker);
424 }
424 }
425
425
426 /*!
426 /*!
427 \internal Helper function. Appends markers from \a series to legend.
427 \internal Helper function. Appends markers from \a series to legend.
428 */
428 */
429 void QLegend::appendMarkers(QBarSeries *series)
429 void QLegend::appendMarkers(QBarSeries *series)
430 {
430 {
431 foreach(QBarSet* s, series->barSets()) {
431 foreach(QBarSet* set, series->barSets()) {
432 LegendMarker* marker = new LegendMarker(series, s, this);
432 LegendMarker* marker = new LegendMarker(series, set, this);
433 marker->setName(s->name());
433 marker->setName(set->name());
434 marker->setPen(s->pen());
434 marker->setPen(set->pen());
435 marker->setBrush(s->brush());
435 marker->setBrush(set->brush());
436 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
436 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
437 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
437 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
438 connect(s, SIGNAL(valueChanged()), marker, SLOT(changed()));
438 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
439 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
439 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
440 m_markers.append(marker);
440 m_markers.append(marker);
441 childItems().append(marker);
441 childItems().append(marker);
442 }
442 }
443 }
443 }
444
444
445 /*!
445 /*!
446 \internal Helper function. Appends markers from \a series to legend.
446 \internal Helper function. Appends markers from \a series to legend.
447 */
447 */
448 void QLegend::appendMarkers(QPieSeries *series)
448 void QLegend::appendMarkers(QPieSeries *series)
449 {
449 {
450 foreach(QPieSlice* s, series->slices()) {
450 foreach(QPieSlice* slice, series->slices()) {
451 LegendMarker* marker = new LegendMarker(series, s, this);
451 LegendMarker* marker = new LegendMarker(series, slice, this);
452 marker->setName(s->label());
452 marker->setName(slice->label());
453 marker->setPen(s->pen());
453 marker->setPen(slice->pen());
454 marker->setBrush(s->brush());
454 marker->setBrush(slice->brush());
455 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
455 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
456 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
456 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
457 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
457 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
458 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
458 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
459 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
459 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
460 m_markers.append(marker);
460 m_markers.append(marker);
461 childItems().append(marker);
461 childItems().append(marker);
462 }
462 }
463 }
463 }
464
464
465 /*!
465 /*!
466 \internal Deletes all markers that are created from \a series
466 \internal Deletes all markers that are created from \a series
467 */
467 */
468 void QLegend::deleteMarkers(QSeries *series)
468 void QLegend::deleteMarkers(QSeries *series)
469 {
469 {
470 // Search all markers that belong to given series and delete them.
470 // Search all markers that belong to given series and delete them.
471 foreach (LegendMarker *m, m_markers) {
471 foreach (LegendMarker *m, m_markers) {
472 if (m->series() == series) {
472 if (m->series() == series) {
473 m_markers.removeOne(m);
473 m_markers.removeOne(m);
474 delete m;
474 delete m;
475 }
475 }
476 }
476 }
477 }
477 }
478
478
479 /*!
479 /*!
480 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
480 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
481 If items don't fit, sets the visibility of scroll buttons accordingly.
481 If items don't fit, sets the visibility of scroll buttons accordingly.
482 Causes legend to be resized.
482 Causes legend to be resized.
483 */
483 */
484 void QLegend::updateLayout()
484 void QLegend::updateLayout()
485 {
485 {
486 // Calculate layout for markers and text
486 // Calculate layout for markers and text
487 if (m_markers.count() <= 0) {
487 if (m_markers.count() <= 0) {
488 // Nothing to do
488 // Nothing to do
489 return;
489 return;
490 }
490 }
491
491
492 // Find out widest item.
492 // Find out widest item.
493 QSizeF markerMaxSize = maximumMarkerSize();
493 QSizeF markerMaxSize = maximumMarkerSize();
494 checkFirstMarkerBounds();
494 checkFirstMarkerBounds();
495
495
496 // Use max height as scroll button size
496 // Use max height as scroll button size
497 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
497 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
498
498
499 qreal totalWidth = 0;
499 qreal totalWidth = 0;
500 qreal totalHeight = 0;
500 qreal totalHeight = 0;
501 switch (m_alignment)
501 switch (m_alignment)
502 {
502 {
503 // Both cases organise items horizontally
503 // Both cases organise items horizontally
504 case QLegend::LayoutBottom:
504 case QLegend::LayoutBottom:
505 case QLegend::LayoutTop: {
505 case QLegend::LayoutTop: {
506
506
507 qreal xStep = markerMaxSize.width();
507 qreal xStep = markerMaxSize.width();
508 qreal x = m_pos.x() + m_margin;
508 qreal x = m_pos.x() + m_margin;
509 qreal y = m_pos.y() + m_margin;
509 qreal y = m_pos.y() + m_margin;
510 int column = 0;
510 int column = 0;
511 int maxColumns = 1;
511 int maxColumns = 1;
512 qreal scrollButtonWidth = 0;
512 qreal scrollButtonWidth = 0;
513
513
514 // Set correct visibility for scroll scrollbuttons
514 // Set correct visibility for scroll scrollbuttons
515 if (scrollButtonsVisible()) {
515 if (scrollButtonsVisible()) {
516 m_scrollButtonLeft->setVisible(true);
516 m_scrollButtonLeft->setVisible(true);
517 m_scrollButtonRight->setVisible(true);
517 m_scrollButtonRight->setVisible(true);
518 // scrollbuttons visible, so add their width to total width
518 // scrollbuttons visible, so add their width to total width
519 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
519 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
520 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
520 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
521 // start position changes by scrollbutton width
521 // start position changes by scrollbutton width
522 x += scrollButtonWidth;
522 x += scrollButtonWidth;
523 } else {
523 } else {
524 m_scrollButtonLeft->setVisible(false);
524 m_scrollButtonLeft->setVisible(false);
525 m_scrollButtonRight->setVisible(false);
525 m_scrollButtonRight->setVisible(false);
526 }
526 }
527 m_scrollButtonUp->setVisible(false);
527 m_scrollButtonUp->setVisible(false);
528 m_scrollButtonDown->setVisible(false);
528 m_scrollButtonDown->setVisible(false);
529
529
530 for (int i=0; i < m_markers.count(); i++) {
530 for (int i=0; i < m_markers.count(); i++) {
531 LegendMarker *m = m_markers.at(i);
531 LegendMarker *m = m_markers.at(i);
532 if (i < mFirstMarker) {
532 if (i < mFirstMarker) {
533 // Markers before first are not visible.
533 // Markers before first are not visible.
534 m->setVisible(false);
534 m->setVisible(false);
535 } else {
535 } else {
536 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
536 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
537 // This marker would go outside legend rect.
537 // This marker would go outside legend rect.
538 m->setVisible(false);
538 m->setVisible(false);
539 } else {
539 } else {
540 // This marker is ok
540 // This marker is ok
541 m->setVisible(true);
541 m->setVisible(true);
542 m->setPos(x, y);
542 m->setPos(x, y);
543 x += xStep;
543 x += xStep;
544 column++;
544 column++;
545 }
545 }
546 }
546 }
547 maxColumns = column;
547 maxColumns = column;
548 }
548 }
549
549
550 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
550 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
551 m_scrollButtonRight->setPos(x + m_margin, y);
551 m_scrollButtonRight->setPos(x + m_margin, y);
552
552
553 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
553 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
554 totalHeight = markerMaxSize.height() + m_margin * 2;
554 totalHeight = markerMaxSize.height() + m_margin * 2;
555
555
556 break;
556 break;
557 }
557 }
558 // Both cases organize items vertically
558 // Both cases organize items vertically
559 case QLegend::LayoutLeft:
559 case QLegend::LayoutLeft:
560 case QLegend::LayoutRight: {
560 case QLegend::LayoutRight: {
561 qreal yStep = markerMaxSize.height();
561 qreal yStep = markerMaxSize.height();
562 qreal x = m_pos.x() + m_margin;
562 qreal x = m_pos.x() + m_margin;
563 qreal y = m_pos.y() + m_margin;
563 qreal y = m_pos.y() + m_margin;
564 int row = 1;
564 int row = 1;
565 int maxRows = 1;
565 int maxRows = 1;
566 qreal scrollButtonHeight = 0;
566 qreal scrollButtonHeight = 0;
567
567
568 // Set correct visibility for scroll scrollbuttons
568 // Set correct visibility for scroll scrollbuttons
569 if (scrollButtonsVisible()) {
569 if (scrollButtonsVisible()) {
570 m_scrollButtonUp->setVisible(true);
570 m_scrollButtonUp->setVisible(true);
571 m_scrollButtonDown->setVisible(true);
571 m_scrollButtonDown->setVisible(true);
572 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
572 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
573 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
573 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
574 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
574 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
575 } else {
575 } else {
576 m_scrollButtonUp->setVisible(false);
576 m_scrollButtonUp->setVisible(false);
577 m_scrollButtonDown->setVisible(false);
577 m_scrollButtonDown->setVisible(false);
578 }
578 }
579 m_scrollButtonLeft->setVisible(false);
579 m_scrollButtonLeft->setVisible(false);
580 m_scrollButtonRight->setVisible(false);
580 m_scrollButtonRight->setVisible(false);
581
581
582 for (int i=0; i < m_markers.count(); i++) {
582 for (int i=0; i < m_markers.count(); i++) {
583 LegendMarker* m = m_markers.at(i);
583 LegendMarker* m = m_markers.at(i);
584 if (i < mFirstMarker) {
584 if (i < mFirstMarker) {
585 // Markers before first are not visible.
585 // Markers before first are not visible.
586 m->setVisible(false);
586 m->setVisible(false);
587 } else {
587 } else {
588 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
588 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
589 // This marker would go outside legend rect.
589 // This marker would go outside legend rect.
590 m->setVisible(false);
590 m->setVisible(false);
591 } else {
591 } else {
592 // This marker is ok
592 // This marker is ok
593 m->setVisible(true);
593 m->setVisible(true);
594 m->setPos(x, y);
594 m->setPos(x, y);
595 y += yStep;
595 y += yStep;
596 row++;
596 row++;
597 }
597 }
598 }
598 }
599 maxRows = row;
599 maxRows = row;
600 }
600 }
601
601
602 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
602 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
603 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
603 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
604
604
605 totalWidth += markerMaxSize.width() + m_margin * 2;
605 totalWidth += markerMaxSize.width() + m_margin * 2;
606 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
606 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
607 break;
607 break;
608 }
608 }
609 default: {
609 default: {
610 break;
610 break;
611 }
611 }
612 }
612 }
613
613
614 m_size.setWidth(totalWidth);
614 m_size.setWidth(totalWidth);
615 m_size.setHeight(totalHeight);
615 m_size.setHeight(totalHeight);
616
616
617 update();
617 update();
618 }
618 }
619
619
620 /*!
620 /*!
621 \internal Sets the size of scroll buttons to \a size
621 \internal Sets the size of scroll buttons to \a size
622 */
622 */
623 void QLegend::rescaleScrollButtons(const QSize &size)
623 void QLegend::rescaleScrollButtons(const QSize &size)
624 {
624 {
625 QPolygonF left;
625 QPolygonF left;
626 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
626 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
627 QPolygonF right;
627 QPolygonF right;
628 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
628 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
629 QPolygonF up;
629 QPolygonF up;
630 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
630 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
631 QPolygonF down;
631 QPolygonF down;
632 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
632 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
633
633
634 m_scrollButtonLeft->setPolygon(left);
634 m_scrollButtonLeft->setPolygon(left);
635 m_scrollButtonRight->setPolygon(right);
635 m_scrollButtonRight->setPolygon(right);
636 m_scrollButtonUp->setPolygon(up);
636 m_scrollButtonUp->setPolygon(up);
637 m_scrollButtonDown->setPolygon(down);
637 m_scrollButtonDown->setPolygon(down);
638 }
638 }
639
639
640 /*!
640 /*!
641 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
641 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
642 */
642 */
643 QSizeF QLegend::maximumMarkerSize()
643 QSizeF QLegend::maximumMarkerSize()
644 {
644 {
645 QSizeF max(0,0);
645 QSizeF max(0,0);
646 foreach (LegendMarker* m, m_markers) {
646 foreach (LegendMarker* m, m_markers) {
647 if (m->boundingRect().width() > max.width())
647 if (m->boundingRect().width() > max.width())
648 max.setWidth(m->boundingRect().width());
648 max.setWidth(m->boundingRect().width());
649 if (m->boundingRect().height() > max.height())
649 if (m->boundingRect().height() > max.height())
650 max.setHeight(m->boundingRect().height());
650 max.setHeight(m->boundingRect().height());
651 }
651 }
652 return max;
652 return max;
653 }
653 }
654
654
655 /*!
655 /*!
656 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
656 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
657 If scrollbuttons are visible, they affect the number of visible markers.
657 If scrollbuttons are visible, they affect the number of visible markers.
658 */
658 */
659 void QLegend::checkFirstMarkerBounds()
659 void QLegend::checkFirstMarkerBounds()
660 {
660 {
661 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
661 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
662 // Bounds limited by height.
662 // Bounds limited by height.
663 int max;
663 int max;
664 if (scrollButtonsVisible()) {
664 if (scrollButtonsVisible()) {
665 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
665 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
666 } else {
666 } else {
667 max = m_maximumSize.height() / maximumMarkerSize().height();
667 max = m_maximumSize.height() / maximumMarkerSize().height();
668 }
668 }
669
669
670 if (mFirstMarker > m_markers.count() - max)
670 if (mFirstMarker > m_markers.count() - max)
671 mFirstMarker = m_markers.count() - max;
671 mFirstMarker = m_markers.count() - max;
672 } else {
672 } else {
673 // Bounds limited by width
673 // Bounds limited by width
674 int max;
674 int max;
675 if (scrollButtonsVisible()) {
675 if (scrollButtonsVisible()) {
676 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
676 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
677 } else {
677 } else {
678 max = m_maximumSize.width() / maximumMarkerSize().width();
678 max = m_maximumSize.width() / maximumMarkerSize().width();
679 }
679 }
680
680
681 if (mFirstMarker > m_markers.count() - max)
681 if (mFirstMarker > m_markers.count() - max)
682 mFirstMarker = m_markers.count() - max;
682 mFirstMarker = m_markers.count() - max;
683 }
683 }
684
684
685 if (mFirstMarker < 0)
685 if (mFirstMarker < 0)
686 mFirstMarker = 0;
686 mFirstMarker = 0;
687 }
687 }
688
688
689 /*!
689 /*!
690 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
690 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
691 */
691 */
692 bool QLegend::scrollButtonsVisible()
692 bool QLegend::scrollButtonsVisible()
693 {
693 {
694 // Just a helper to clarify, what the magic below means :)
694 // Just a helper to clarify, what the magic below means :)
695 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
695 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
696 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
696 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
697 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
697 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
698 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
698 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
699 }
699 }
700
700
701 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
701 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
702 }
702 }
703
703
704 #include "moc_qlegend.cpp"
704 #include "moc_qlegend.cpp"
705
705
706 QTCOMMERCIALCHART_END_NAMESPACE
706 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now