##// END OF EJS Templates
legend layout with padding
sauimone -
r799:0ecf2967daa4
parent child
Show More
@@ -1,405 +1,450
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "qlegend.h"
22 #include "qlegend.h"
23 #include "qchartaxis.h"
23 #include "qchartaxis.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "chartdataset_p.h"
25 #include "chartdataset_p.h"
26 #include "charttheme_p.h"
26 #include "charttheme_p.h"
27 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
28 //series
28 //series
29 #include "qbarseries.h"
29 #include "qbarseries.h"
30 #include "qstackedbarseries.h"
30 #include "qstackedbarseries.h"
31 #include "qpercentbarseries.h"
31 #include "qpercentbarseries.h"
32 #include "qlineseries.h"
32 #include "qlineseries.h"
33 #include "qareaseries.h"
33 #include "qareaseries.h"
34 #include "qpieseries.h"
34 #include "qpieseries.h"
35 #include "qscatterseries.h"
35 #include "qscatterseries.h"
36 #include "qsplineseries.h"
36 #include "qsplineseries.h"
37 //items
37 //items
38 #include "axisitem_p.h"
38 #include "axisitem_p.h"
39 #include "areachartitem_p.h"
39 #include "areachartitem_p.h"
40 #include "barchartitem_p.h"
40 #include "barchartitem_p.h"
41 #include "stackedbarchartitem_p.h"
41 #include "stackedbarchartitem_p.h"
42 #include "percentbarchartitem_p.h"
42 #include "percentbarchartitem_p.h"
43 #include "linechartitem_p.h"
43 #include "linechartitem_p.h"
44 #include "piechartitem_p.h"
44 #include "piechartitem_p.h"
45 #include "scatterchartitem_p.h"
45 #include "scatterchartitem_p.h"
46 #include "splinechartitem_p.h"
46 #include "splinechartitem_p.h"
47
47
48 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48 QTCOMMERCIALCHART_BEGIN_NAMESPACE
49
49
50 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
50 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
51 m_chart(chart),
51 m_chart(chart),
52 m_animator(0),
52 m_animator(0),
53 m_dataset(dataset),
53 m_dataset(dataset),
54 m_chartTheme(0),
54 m_chartTheme(0),
55 m_rect(QRectF(QPoint(0,0),m_chart->size())),
55 m_rect(QRectF(QPoint(0,0),m_chart->size())),
56 m_options(QChart::NoAnimation),
56 m_options(QChart::NoAnimation),
57 m_themeForce(false),
57 m_themeForce(false),
58 m_padding(50),
58 m_padding(50),
59 m_backgroundPadding(10)
59 m_backgroundPadding(10)
60 {
60 {
61 createConnections();
61 createConnections();
62 setTheme(QChart::ChartThemeDefault,false);
62 setTheme(QChart::ChartThemeDefault,false);
63 }
63 }
64
64
65 ChartPresenter::~ChartPresenter()
65 ChartPresenter::~ChartPresenter()
66 {
66 {
67 delete m_chartTheme;
67 delete m_chartTheme;
68 }
68 }
69
69
70 void ChartPresenter::createConnections()
70 void ChartPresenter::createConnections()
71 {
71 {
72 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
72 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
73 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
73 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
74 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
74 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
75 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
75 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
76 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
76 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
77 }
77 }
78
78
79 void ChartPresenter::handleGeometryChanged()
79 void ChartPresenter::handleGeometryChanged()
80 {
80 {
81 QRectF rect(QPoint(0,0),m_chart->size());
81 QRectF rect(QPoint(0,0),m_chart->size());
82 rect.adjust(m_padding,
82 QLegend* legend = m_chart->legend();
83 m_padding + m_chart->legend()->size().height(),
83 if ((legend->attachedToChart()) && (legend->isVisible())) {
84 -m_padding,
84
85 -m_padding);
85 // Reserve some space for legend
86 switch (m_chart->legend()->alignment()) {
87 case QLegend::AlignmentTop: {
88 rect.adjust(m_padding,
89 m_padding + legend->size().height(),
90 -m_padding,
91 -m_padding);
92 break;
93 }
94 case QLegend::AlignmentBottom: {
95 rect.adjust(m_padding,
96 m_padding,
97 -m_padding,
98 -m_padding - legend->size().height());
99 break;
100 }
101 case QLegend::AlignmentLeft: {
102 rect.adjust(m_padding + legend->size().width(),
103 m_padding,
104 -m_padding,
105 -m_padding);
106 break;
107 }
108 case QLegend::AlignmentRight: {
109 rect.adjust(m_padding,
110 m_padding,
111 -m_padding - legend->size().width(),
112 -m_padding);
113 break;
114 }
115 default: {
116 rect.adjust(m_padding,
117 m_padding,
118 -m_padding,
119 -m_padding);
120 break;
121 }
122 }
123 } else {
124
125 // Legend is detached, or not visible
126 rect.adjust(m_padding,
127 m_padding,
128 -m_padding,
129 -m_padding);
130 }
86
131
87 //rewrite zoom stack
132 //rewrite zoom stack
88 /*
133 /*
89 for(int i=0;i<m_zoomStack.count();i++){
134 for(int i=0;i<m_zoomStack.count();i++){
90 QRectF r = m_zoomStack[i];
135 QRectF r = m_zoomStack[i];
91 qreal w = rect.width()/m_rect.width();
136 qreal w = rect.width()/m_rect.width();
92 qreal h = rect.height()/m_rect.height();
137 qreal h = rect.height()/m_rect.height();
93 QPointF tl = r.topLeft();
138 QPointF tl = r.topLeft();
94 tl.setX(tl.x()*w);
139 tl.setX(tl.x()*w);
95 tl.setY(tl.y()*h);
140 tl.setY(tl.y()*h);
96 QPointF br = r.bottomRight();
141 QPointF br = r.bottomRight();
97 br.setX(br.x()*w);
142 br.setX(br.x()*w);
98 br.setY(br.y()*h);
143 br.setY(br.y()*h);
99 r.setTopLeft(tl);
144 r.setTopLeft(tl);
100 r.setBottomRight(br);
145 r.setBottomRight(br);
101 m_zoomStack[i]=r;
146 m_zoomStack[i]=r;
102 }
147 }
103 */
148 */
104 m_rect = rect;
149 m_rect = rect;
105 Q_ASSERT(m_rect.isValid());
150 Q_ASSERT(m_rect.isValid());
106 emit geometryChanged(m_rect);
151 emit geometryChanged(m_rect);
107 }
152 }
108
153
109 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
154 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
110 {
155 {
111 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
156 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
112
157
113 if(m_options.testFlag(QChart::GridAxisAnimations)){
158 if(m_options.testFlag(QChart::GridAxisAnimations)){
114 m_animator->addAnimation(item);
159 m_animator->addAnimation(item);
115 }
160 }
116
161
117 if(axis==m_dataset->axisX()){
162 if(axis==m_dataset->axisX()){
118 m_chartTheme->decorate(axis,true,m_themeForce);
163 m_chartTheme->decorate(axis,true,m_themeForce);
119 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
164 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
120 //initialize
165 //initialize
121 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
166 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
122
167
123 }
168 }
124 else{
169 else{
125 m_chartTheme->decorate(axis,false,m_themeForce);
170 m_chartTheme->decorate(axis,false,m_themeForce);
126 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
171 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
127 //initialize
172 //initialize
128 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
173 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
129 }
174 }
130
175
131 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
176 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
132 //initialize
177 //initialize
133 item->handleGeometryChanged(m_rect);
178 item->handleGeometryChanged(m_rect);
134 m_axisItems.insert(axis, item);
179 m_axisItems.insert(axis, item);
135 }
180 }
136
181
137 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
182 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
138 {
183 {
139 Axis* item = m_axisItems.take(axis);
184 Axis* item = m_axisItems.take(axis);
140 Q_ASSERT(item);
185 Q_ASSERT(item);
141 if(m_animator) m_animator->removeAnimation(item);
186 if(m_animator) m_animator->removeAnimation(item);
142 delete item;
187 delete item;
143 }
188 }
144
189
145
190
146 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
191 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
147 {
192 {
148 Chart *item = 0 ;
193 Chart *item = 0 ;
149
194
150 switch(series->type())
195 switch(series->type())
151 {
196 {
152 case QSeries::SeriesTypeLine: {
197 case QSeries::SeriesTypeLine: {
153
198
154 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
199 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
155 LineChartItem* line = new LineChartItem(lineSeries,this);
200 LineChartItem* line = new LineChartItem(lineSeries,this);
156 if(m_options.testFlag(QChart::SeriesAnimations)) {
201 if(m_options.testFlag(QChart::SeriesAnimations)) {
157 m_animator->addAnimation(line);
202 m_animator->addAnimation(line);
158 }
203 }
159 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
204 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
160 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
205 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
161 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
206 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
162 item = line;
207 item = line;
163 break;
208 break;
164 }
209 }
165
210
166 case QSeries::SeriesTypeArea: {
211 case QSeries::SeriesTypeArea: {
167
212
168 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
213 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
169 AreaChartItem* area = new AreaChartItem(areaSeries,this);
214 AreaChartItem* area = new AreaChartItem(areaSeries,this);
170 if(m_options.testFlag(QChart::SeriesAnimations)) {
215 if(m_options.testFlag(QChart::SeriesAnimations)) {
171 m_animator->addAnimation(area->upperLineItem());
216 m_animator->addAnimation(area->upperLineItem());
172 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
217 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
173 }
218 }
174 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
219 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
175 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
220 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
176 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
221 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
177 item=area;
222 item=area;
178 break;
223 break;
179 }
224 }
180
225
181 case QSeries::SeriesTypeBar: {
226 case QSeries::SeriesTypeBar: {
182 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
227 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
183 BarChartItem* bar = new BarChartItem(barSeries,this);
228 BarChartItem* bar = new BarChartItem(barSeries,this);
184 if(m_options.testFlag(QChart::SeriesAnimations)) {
229 if(m_options.testFlag(QChart::SeriesAnimations)) {
185 m_animator->addAnimation(bar);
230 m_animator->addAnimation(bar);
186 }
231 }
187 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
232 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
188 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
233 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
189 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
234 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
190 item=bar;
235 item=bar;
191 break;
236 break;
192 }
237 }
193
238
194 case QSeries::SeriesTypeStackedBar: {
239 case QSeries::SeriesTypeStackedBar: {
195 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
240 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
196 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
241 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
197 if(m_options.testFlag(QChart::SeriesAnimations)) {
242 if(m_options.testFlag(QChart::SeriesAnimations)) {
198 m_animator->addAnimation(bar);
243 m_animator->addAnimation(bar);
199 }
244 }
200 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
245 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
201 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
246 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
202 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
247 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
203 item=bar;
248 item=bar;
204 break;
249 break;
205 }
250 }
206
251
207 case QSeries::SeriesTypePercentBar: {
252 case QSeries::SeriesTypePercentBar: {
208 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
253 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
209 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
254 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
210 if(m_options.testFlag(QChart::SeriesAnimations)) {
255 if(m_options.testFlag(QChart::SeriesAnimations)) {
211 m_animator->addAnimation(bar);
256 m_animator->addAnimation(bar);
212 }
257 }
213 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
258 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
214 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
259 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
215 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
260 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
216 item=bar;
261 item=bar;
217 break;
262 break;
218 }
263 }
219
264
220 case QSeries::SeriesTypeScatter: {
265 case QSeries::SeriesTypeScatter: {
221 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
266 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
222 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
267 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
223 if(m_options.testFlag(QChart::SeriesAnimations)) {
268 if(m_options.testFlag(QChart::SeriesAnimations)) {
224 m_animator->addAnimation(scatter);
269 m_animator->addAnimation(scatter);
225 }
270 }
226 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
271 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
227 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
272 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
228 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
273 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
229 item = scatter;
274 item = scatter;
230 break;
275 break;
231 }
276 }
232
277
233 case QSeries::SeriesTypePie: {
278 case QSeries::SeriesTypePie: {
234 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
279 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
235 PieChartItem* pie = new PieChartItem(pieSeries, this);
280 PieChartItem* pie = new PieChartItem(pieSeries, this);
236 if(m_options.testFlag(QChart::SeriesAnimations)) {
281 if(m_options.testFlag(QChart::SeriesAnimations)) {
237 m_animator->addAnimation(pie);
282 m_animator->addAnimation(pie);
238 }
283 }
239 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
284 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
240 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
285 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
241 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
286 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
242 // Hide all from background when there is only piechart
287 // Hide all from background when there is only piechart
243 // TODO: refactor this ugly code... should be one setting for this
288 // TODO: refactor this ugly code... should be one setting for this
244 if (m_chartItems.count() == 0) {
289 if (m_chartItems.count() == 0) {
245 m_chart->axisX()->hide();
290 m_chart->axisX()->hide();
246 m_chart->axisY()->hide();
291 m_chart->axisY()->hide();
247 }
292 }
248 item=pie;
293 item=pie;
249 break;
294 break;
250 }
295 }
251
296
252 case QSeries::SeriesTypeSpline: {
297 case QSeries::SeriesTypeSpline: {
253 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
298 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
254 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
299 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
255 if(m_options.testFlag(QChart::SeriesAnimations)) {
300 if(m_options.testFlag(QChart::SeriesAnimations)) {
256 m_animator->addAnimation(spline);
301 m_animator->addAnimation(spline);
257 }
302 }
258 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
303 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
259 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
304 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
260 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
305 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
261 item=spline;
306 item=spline;
262 break;
307 break;
263 }
308 }
264 default: {
309 default: {
265 qDebug()<< "Series type" << series->type() << "not implemented.";
310 qDebug()<< "Series type" << series->type() << "not implemented.";
266 break;
311 break;
267 }
312 }
268 }
313 }
269
314
270 //initialize
315 //initialize
271 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
316 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
272 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
317 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
273 m_chartItems.insert(series,item);
318 m_chartItems.insert(series,item);
274 }
319 }
275
320
276 void ChartPresenter::handleSeriesRemoved(QSeries* series)
321 void ChartPresenter::handleSeriesRemoved(QSeries* series)
277 {
322 {
278 Chart* item = m_chartItems.take(series);
323 Chart* item = m_chartItems.take(series);
279 Q_ASSERT(item);
324 Q_ASSERT(item);
280 if(m_animator) {
325 if(m_animator) {
281 //small hack to handle area animations
326 //small hack to handle area animations
282 if(series->type()==QSeries::SeriesTypeArea){
327 if(series->type()==QSeries::SeriesTypeArea){
283 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
328 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
284 AreaChartItem* area = static_cast<AreaChartItem*>(item);
329 AreaChartItem* area = static_cast<AreaChartItem*>(item);
285 m_animator->removeAnimation(area->upperLineItem());
330 m_animator->removeAnimation(area->upperLineItem());
286 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
331 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
287 }else
332 }else
288 m_animator->removeAnimation(item);
333 m_animator->removeAnimation(item);
289 }
334 }
290 delete item;
335 delete item;
291 }
336 }
292
337
293 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
338 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
294 {
339 {
295 if(m_chartTheme && m_chartTheme->id() == theme) return;
340 if(m_chartTheme && m_chartTheme->id() == theme) return;
296 delete m_chartTheme;
341 delete m_chartTheme;
297 m_themeForce = force;
342 m_themeForce = force;
298 m_chartTheme = ChartTheme::createTheme(theme);
343 m_chartTheme = ChartTheme::createTheme(theme);
299 m_chartTheme->decorate(m_chart,m_themeForce);
344 m_chartTheme->decorate(m_chart,m_themeForce);
300 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
345 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
301 resetAllElements();
346 resetAllElements();
302 }
347 }
303
348
304 QChart::ChartTheme ChartPresenter::theme()
349 QChart::ChartTheme ChartPresenter::theme()
305 {
350 {
306 return m_chartTheme->id();
351 return m_chartTheme->id();
307 }
352 }
308
353
309 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
354 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
310 {
355 {
311 if(m_options!=options) {
356 if(m_options!=options) {
312
357
313 m_options=options;
358 m_options=options;
314
359
315 if(m_options!=QChart::NoAnimation && !m_animator) {
360 if(m_options!=QChart::NoAnimation && !m_animator) {
316 m_animator= new ChartAnimator(this);
361 m_animator= new ChartAnimator(this);
317
362
318 }
363 }
319 resetAllElements();
364 resetAllElements();
320 }
365 }
321
366
322 }
367 }
323
368
324 void ChartPresenter::resetAllElements()
369 void ChartPresenter::resetAllElements()
325 {
370 {
326 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
371 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
327 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
372 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
328
373
329 foreach(QChartAxis* axis, axisList) {
374 foreach(QChartAxis* axis, axisList) {
330 handleAxisRemoved(axis);
375 handleAxisRemoved(axis);
331 handleAxisAdded(axis,m_dataset->domain(axis));
376 handleAxisAdded(axis,m_dataset->domain(axis));
332 }
377 }
333 foreach(QSeries* series, seriesList) {
378 foreach(QSeries* series, seriesList) {
334 handleSeriesRemoved(series);
379 handleSeriesRemoved(series);
335 handleSeriesAdded(series,m_dataset->domain(series));
380 handleSeriesAdded(series,m_dataset->domain(series));
336 }
381 }
337 }
382 }
338
383
339 void ChartPresenter::zoomIn()
384 void ChartPresenter::zoomIn()
340 {
385 {
341 QRectF rect = geometry();
386 QRectF rect = geometry();
342 rect.setWidth(rect.width()/2);
387 rect.setWidth(rect.width()/2);
343 rect.setHeight(rect.height()/2);
388 rect.setHeight(rect.height()/2);
344 rect.moveCenter(geometry().center());
389 rect.moveCenter(geometry().center());
345 zoomIn(rect);
390 zoomIn(rect);
346 }
391 }
347
392
348 void ChartPresenter::zoomIn(const QRectF& rect)
393 void ChartPresenter::zoomIn(const QRectF& rect)
349 {
394 {
350 QRectF r = rect.normalized();
395 QRectF r = rect.normalized();
351 r.translate(-m_padding, -m_padding);
396 r.translate(-m_padding, -m_padding);
352 if(m_animator) {
397 if(m_animator) {
353
398
354 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
399 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
355 m_animator->setState(ChartAnimator::ZoomInState,point);
400 m_animator->setState(ChartAnimator::ZoomInState,point);
356 }
401 }
357 m_dataset->zoomInDomain(r,geometry().size());
402 m_dataset->zoomInDomain(r,geometry().size());
358 if(m_animator) {
403 if(m_animator) {
359 m_animator->setState(ChartAnimator::ShowState);
404 m_animator->setState(ChartAnimator::ShowState);
360 }
405 }
361 }
406 }
362
407
363 void ChartPresenter::zoomOut()
408 void ChartPresenter::zoomOut()
364 {
409 {
365 if(m_animator)
410 if(m_animator)
366 {
411 {
367 m_animator->setState(ChartAnimator::ZoomOutState);
412 m_animator->setState(ChartAnimator::ZoomOutState);
368 }
413 }
369
414
370 QSizeF size = geometry().size();
415 QSizeF size = geometry().size();
371 QRectF rect = geometry();
416 QRectF rect = geometry();
372 rect.translate(-m_padding, -m_padding);
417 rect.translate(-m_padding, -m_padding);
373 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
418 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
374 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
419 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
375
420
376 if(m_animator){
421 if(m_animator){
377 m_animator->setState(ChartAnimator::ShowState);
422 m_animator->setState(ChartAnimator::ShowState);
378 }
423 }
379 }
424 }
380
425
381 void ChartPresenter::scroll(int dx,int dy)
426 void ChartPresenter::scroll(int dx,int dy)
382 {
427 {
383 if(m_animator){
428 if(m_animator){
384 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
429 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
385 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
430 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
386 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
431 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
387 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
432 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
388 }
433 }
389
434
390 m_dataset->scrollDomain(dx,dy,geometry().size());
435 m_dataset->scrollDomain(dx,dy,geometry().size());
391
436
392 if(m_animator){
437 if(m_animator){
393 m_animator->setState(ChartAnimator::ShowState);
438 m_animator->setState(ChartAnimator::ShowState);
394 }
439 }
395 }
440 }
396
441
397 QChart::AnimationOptions ChartPresenter::animationOptions() const
442 QChart::AnimationOptions ChartPresenter::animationOptions() const
398 {
443 {
399 return m_options;
444 return m_options;
400 }
445 }
401
446
402
447
403 #include "moc_chartpresenter_p.cpp"
448 #include "moc_chartpresenter_p.cpp"
404
449
405 QTCOMMERCIALCHART_END_NAMESPACE
450 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,439 +1,441
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include <QGraphicsScene>
23 #include <QGraphicsScene>
24 #include <QGraphicsSceneResizeEvent>
24 #include <QGraphicsSceneResizeEvent>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 /*!
28 /*!
29 \enum QChart::ChartTheme
29 \enum QChart::ChartTheme
30
30
31 This enum describes the theme used by the chart.
31 This enum describes the theme used by the chart.
32
32
33 \value ChartThemeDefault Follows the GUI style of the Operating System
33 \value ChartThemeDefault Follows the GUI style of the Operating System
34 \value ChartThemeLight
34 \value ChartThemeLight
35 \value ChartThemeBlueCerulean
35 \value ChartThemeBlueCerulean
36 \value ChartThemeDark
36 \value ChartThemeDark
37 \value ChartThemeBrownSand
37 \value ChartThemeBrownSand
38 \value ChartThemeBlueNcs
38 \value ChartThemeBlueNcs
39 \value ChartThemeHighContrast
39 \value ChartThemeHighContrast
40 \value ChartThemeBlueIcy
40 \value ChartThemeBlueIcy
41 \value ChartThemeCount Not really a theme; the total count of themes.
41 \value ChartThemeCount Not really a theme; the total count of themes.
42 */
42 */
43
43
44 /*!
44 /*!
45 \enum QChart::AnimationOption
45 \enum QChart::AnimationOption
46
46
47 For enabling/disabling animations. Defaults to NoAnimation.
47 For enabling/disabling animations. Defaults to NoAnimation.
48
48
49 \value NoAnimation
49 \value NoAnimation
50 \value GridAxisAnimations
50 \value GridAxisAnimations
51 \value SeriesAnimations
51 \value SeriesAnimations
52 \value AllAnimations
52 \value AllAnimations
53 */
53 */
54
54
55 /*!
55 /*!
56 \class QChart
56 \class QChart
57 \brief QtCommercial chart API.
57 \brief QtCommercial chart API.
58
58
59 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
59 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
60 representation of different types of QChartSeries and other chart related objects like
60 representation of different types of QChartSeries and other chart related objects like
61 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
61 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
62 convenience class QChartView instead of QChart.
62 convenience class QChartView instead of QChart.
63 \sa QChartView
63 \sa QChartView
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
67 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
68 */
68 */
69 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
69 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
70 d_ptr(new QChartPrivate(this))
70 d_ptr(new QChartPrivate(this))
71 {
71 {
72 //setMinimumSize(200,200);
72 //setMinimumSize(200,200);
73 d_ptr->m_legend = new QLegend(this);
73 d_ptr->m_legend = new QLegend(this);
74 d_ptr->m_dataset = new ChartDataSet(this);
74 d_ptr->m_dataset = new ChartDataSet(this);
75 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
75 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
76 int padding = d_ptr->m_presenter->padding();
76 int padding = d_ptr->m_presenter->padding();
77 setMinimumSize(3*padding,3*padding);
77 setMinimumSize(3*padding,3*padding);
78 connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
78 connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
79 connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*)));
79 connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*)));
80 }
80 }
81
81
82 /*!
82 /*!
83 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
83 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
84 */
84 */
85 QChart::~QChart()
85 QChart::~QChart()
86 {
86 {
87 //delete first presenter , since this is a root of all the graphical items
87 //delete first presenter , since this is a root of all the graphical items
88 delete d_ptr->m_presenter;
88 delete d_ptr->m_presenter;
89 d_ptr->m_presenter=0;
89 d_ptr->m_presenter=0;
90 }
90 }
91
91
92 /*!
92 /*!
93 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
93 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
94 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
94 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
95 the y axis).
95 the y axis).
96 */
96 */
97 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
97 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
98 {
98 {
99 d_ptr->m_dataset->addSeries(series, axisY);
99 d_ptr->m_dataset->addSeries(series, axisY);
100 }
100 }
101
101
102 /*!
102 /*!
103 Removes the \a series specified in a perameter from the QChartView.
103 Removes the \a series specified in a perameter from the QChartView.
104 It releses its ownership of the specified QChartSeries object.
104 It releses its ownership of the specified QChartSeries object.
105 It does not delete the pointed QChartSeries data object
105 It does not delete the pointed QChartSeries data object
106 \sa addSeries(), removeAllSeries()
106 \sa addSeries(), removeAllSeries()
107 */
107 */
108 void QChart::removeSeries(QSeries* series)
108 void QChart::removeSeries(QSeries* series)
109 {
109 {
110 d_ptr->m_dataset->removeSeries(series);
110 d_ptr->m_dataset->removeSeries(series);
111 }
111 }
112
112
113 /*!
113 /*!
114 Removes all the QChartSeries that have been added to the QChartView
114 Removes all the QChartSeries that have been added to the QChartView
115 It also deletes the pointed QChartSeries data objects
115 It also deletes the pointed QChartSeries data objects
116 \sa addSeries(), removeSeries()
116 \sa addSeries(), removeSeries()
117 */
117 */
118 void QChart::removeAllSeries()
118 void QChart::removeAllSeries()
119 {
119 {
120 d_ptr->m_dataset->removeAllSeries();
120 d_ptr->m_dataset->removeAllSeries();
121 }
121 }
122
122
123 /*!
123 /*!
124 Sets the \a brush that is used for painting the background of the chart area.
124 Sets the \a brush that is used for painting the background of the chart area.
125 */
125 */
126 void QChart::setBackgroundBrush(const QBrush& brush)
126 void QChart::setBackgroundBrush(const QBrush& brush)
127 {
127 {
128 d_ptr->createChartBackgroundItem();
128 d_ptr->createChartBackgroundItem();
129 d_ptr->m_backgroundItem->setBrush(brush);
129 d_ptr->m_backgroundItem->setBrush(brush);
130 d_ptr->m_backgroundItem->update();
130 d_ptr->m_backgroundItem->update();
131 }
131 }
132
132
133 QBrush QChart::backgroundBrush() const
133 QBrush QChart::backgroundBrush() const
134 {
134 {
135 if (!d_ptr->m_backgroundItem) return QBrush();
135 if (!d_ptr->m_backgroundItem) return QBrush();
136 return (d_ptr->m_backgroundItem)->brush();
136 return (d_ptr->m_backgroundItem)->brush();
137 }
137 }
138
138
139 /*!
139 /*!
140 Sets the \a pen that is used for painting the background of the chart area.
140 Sets the \a pen that is used for painting the background of the chart area.
141 */
141 */
142 void QChart::setBackgroundPen(const QPen& pen)
142 void QChart::setBackgroundPen(const QPen& pen)
143 {
143 {
144 d_ptr->createChartBackgroundItem();
144 d_ptr->createChartBackgroundItem();
145 d_ptr->m_backgroundItem->setPen(pen);
145 d_ptr->m_backgroundItem->setPen(pen);
146 d_ptr->m_backgroundItem->update();
146 d_ptr->m_backgroundItem->update();
147 }
147 }
148
148
149 QPen QChart::backgroundPen() const
149 QPen QChart::backgroundPen() const
150 {
150 {
151 if (!d_ptr->m_backgroundItem) return QPen();
151 if (!d_ptr->m_backgroundItem) return QPen();
152 return d_ptr->m_backgroundItem->pen();
152 return d_ptr->m_backgroundItem->pen();
153 }
153 }
154
154
155 /*!
155 /*!
156 Sets the chart \a title. The description text that is drawn above the chart.
156 Sets the chart \a title. The description text that is drawn above the chart.
157 */
157 */
158 void QChart::setTitle(const QString& title)
158 void QChart::setTitle(const QString& title)
159 {
159 {
160 d_ptr->createChartTitleItem();
160 d_ptr->createChartTitleItem();
161 d_ptr->m_titleItem->setText(title);
161 d_ptr->m_titleItem->setText(title);
162 d_ptr->updateLayout();
162 d_ptr->updateLayout();
163 }
163 }
164
164
165 /*!
165 /*!
166 Returns the chart title. The description text that is drawn above the chart.
166 Returns the chart title. The description text that is drawn above the chart.
167 */
167 */
168 QString QChart::title() const
168 QString QChart::title() const
169 {
169 {
170 if (d_ptr->m_titleItem)
170 if (d_ptr->m_titleItem)
171 return d_ptr->m_titleItem->text();
171 return d_ptr->m_titleItem->text();
172 else
172 else
173 return QString();
173 return QString();
174 }
174 }
175
175
176 /*!
176 /*!
177 Sets the \a font that is used for rendering the description text that is rendered above the chart.
177 Sets the \a font that is used for rendering the description text that is rendered above the chart.
178 */
178 */
179 void QChart::setTitleFont(const QFont& font)
179 void QChart::setTitleFont(const QFont& font)
180 {
180 {
181 d_ptr->createChartTitleItem();
181 d_ptr->createChartTitleItem();
182 d_ptr->m_titleItem->setFont(font);
182 d_ptr->m_titleItem->setFont(font);
183 d_ptr->updateLayout();
183 d_ptr->updateLayout();
184 }
184 }
185
185
186 /*!
186 /*!
187 Sets the \a brush used for rendering the title text.
187 Sets the \a brush used for rendering the title text.
188 */
188 */
189 void QChart::setTitleBrush(const QBrush &brush)
189 void QChart::setTitleBrush(const QBrush &brush)
190 {
190 {
191 d_ptr->createChartTitleItem();
191 d_ptr->createChartTitleItem();
192 d_ptr->m_titleItem->setBrush(brush);
192 d_ptr->m_titleItem->setBrush(brush);
193 d_ptr->updateLayout();
193 d_ptr->updateLayout();
194 }
194 }
195
195
196 /*!
196 /*!
197 Returns the brush used for rendering the title text.
197 Returns the brush used for rendering the title text.
198 */
198 */
199 QBrush QChart::titleBrush() const
199 QBrush QChart::titleBrush() const
200 {
200 {
201 if (!d_ptr->m_titleItem) return QBrush();
201 if (!d_ptr->m_titleItem) return QBrush();
202 return d_ptr->m_titleItem->brush();
202 return d_ptr->m_titleItem->brush();
203 }
203 }
204
204
205 /*!
205 /*!
206 Sets the \a theme used by the chart for rendering the graphical representation of the data
206 Sets the \a theme used by the chart for rendering the graphical representation of the data
207 \sa ChartTheme, chartTheme()
207 \sa ChartTheme, chartTheme()
208 */
208 */
209 void QChart::setTheme(QChart::ChartTheme theme)
209 void QChart::setTheme(QChart::ChartTheme theme)
210 {
210 {
211 d_ptr->m_presenter->setTheme(theme);
211 d_ptr->m_presenter->setTheme(theme);
212 }
212 }
213
213
214 /*!
214 /*!
215 Returns the theme enum used by the chart.
215 Returns the theme enum used by the chart.
216 \sa ChartTheme, setChartTheme()
216 \sa ChartTheme, setChartTheme()
217 */
217 */
218 QChart::ChartTheme QChart::theme() const
218 QChart::ChartTheme QChart::theme() const
219 {
219 {
220 return d_ptr->m_presenter->theme();
220 return d_ptr->m_presenter->theme();
221 }
221 }
222
222
223 /*!
223 /*!
224 Zooms in the view by a factor of 2
224 Zooms in the view by a factor of 2
225 */
225 */
226 void QChart::zoomIn()
226 void QChart::zoomIn()
227 {
227 {
228 d_ptr->m_presenter->zoomIn();
228 d_ptr->m_presenter->zoomIn();
229 }
229 }
230
230
231 /*!
231 /*!
232 Zooms in the view to a maximum level at which \a rect is still fully visible.
232 Zooms in the view to a maximum level at which \a rect is still fully visible.
233 */
233 */
234 void QChart::zoomIn(const QRectF& rect)
234 void QChart::zoomIn(const QRectF& rect)
235 {
235 {
236 if (!rect.isValid()) return;
236 if (!rect.isValid()) return;
237 d_ptr->m_presenter->zoomIn(rect);
237 d_ptr->m_presenter->zoomIn(rect);
238 }
238 }
239
239
240 /*!
240 /*!
241 Restores the view zoom level to the previous one.
241 Restores the view zoom level to the previous one.
242 */
242 */
243 void QChart::zoomOut()
243 void QChart::zoomOut()
244 {
244 {
245 d_ptr->m_presenter->zoomOut();
245 d_ptr->m_presenter->zoomOut();
246 }
246 }
247
247
248 /*!
248 /*!
249 Returns the pointer to the x axis object of the chart
249 Returns the pointer to the x axis object of the chart
250 */
250 */
251 QChartAxis* QChart::axisX() const
251 QChartAxis* QChart::axisX() const
252 {
252 {
253 return d_ptr->m_dataset->axisX();
253 return d_ptr->m_dataset->axisX();
254 }
254 }
255
255
256 /*!
256 /*!
257 Returns the pointer to the y axis object of the chart
257 Returns the pointer to the y axis object of the chart
258 */
258 */
259 QChartAxis* QChart::axisY() const
259 QChartAxis* QChart::axisY() const
260 {
260 {
261 return d_ptr->m_dataset->axisY();
261 return d_ptr->m_dataset->axisY();
262 }
262 }
263
263
264 /*!
264 /*!
265 Returns the legend object of the chart. Ownership stays in chart.
265 Returns the legend object of the chart. Ownership stays in chart.
266 */
266 */
267 QLegend* QChart::legend() const
267 QLegend* QChart::legend() const
268 {
268 {
269 return d_ptr->m_legend;
269 return d_ptr->m_legend;
270 }
270 }
271
271
272 /*!
272 /*!
273 Resizes and updates the chart area using the \a event data
273 Resizes and updates the chart area using the \a event data
274 */
274 */
275 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
275 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
276 {
276 {
277 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
277 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
278 d_ptr->updateLayout();
278 d_ptr->updateLayout();
279 QGraphicsWidget::resizeEvent(event);
279 QGraphicsWidget::resizeEvent(event);
280 update();
280 update();
281 }
281 }
282
282
283 /*!
283 /*!
284 Sets animation \a options for the chart
284 Sets animation \a options for the chart
285 */
285 */
286 void QChart::setAnimationOptions(AnimationOptions options)
286 void QChart::setAnimationOptions(AnimationOptions options)
287 {
287 {
288 d_ptr->m_presenter->setAnimationOptions(options);
288 d_ptr->m_presenter->setAnimationOptions(options);
289 }
289 }
290
290
291 /*!
291 /*!
292 Returns animation options for the chart
292 Returns animation options for the chart
293 */
293 */
294 QChart::AnimationOptions QChart::animationOptions() const
294 QChart::AnimationOptions QChart::animationOptions() const
295 {
295 {
296 return d_ptr->m_presenter->animationOptions();
296 return d_ptr->m_presenter->animationOptions();
297 }
297 }
298
298
299 void QChart::scrollLeft()
299 void QChart::scrollLeft()
300 {
300 {
301 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
301 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
302 }
302 }
303
303
304 void QChart::scrollRight()
304 void QChart::scrollRight()
305 {
305 {
306 d_ptr->m_presenter->scroll(d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
306 d_ptr->m_presenter->scroll(d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
307 }
307 }
308
308
309 void QChart::scrollUp()
309 void QChart::scrollUp()
310 {
310 {
311 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1));
311 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1));
312 }
312 }
313
313
314 void QChart::scrollDown()
314 void QChart::scrollDown()
315 {
315 {
316 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1));
316 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1));
317 }
317 }
318
318
319 void QChart::setBackgroundVisible(bool visible)
319 void QChart::setBackgroundVisible(bool visible)
320 {
320 {
321 d_ptr->createChartBackgroundItem();
321 d_ptr->createChartBackgroundItem();
322 d_ptr->m_backgroundItem->setVisible(visible);
322 d_ptr->m_backgroundItem->setVisible(visible);
323 }
323 }
324
324
325 bool QChart::isBackgroundVisible() const
325 bool QChart::isBackgroundVisible() const
326 {
326 {
327 if (!d_ptr->m_backgroundItem) return false;
327 if (!d_ptr->m_backgroundItem) return false;
328 return d_ptr->m_backgroundItem->isVisible();
328 return d_ptr->m_backgroundItem->isVisible();
329 }
329 }
330
330
331 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
331 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
332
332
333 QChartPrivate::QChartPrivate(QChart *parent):
333 QChartPrivate::QChartPrivate(QChart *parent):
334 q_ptr(parent),
334 q_ptr(parent),
335 m_backgroundItem(0),
335 m_backgroundItem(0),
336 m_titleItem(0),
336 m_titleItem(0),
337 m_legend(0),
337 m_legend(0),
338 m_dataset(0),
338 m_dataset(0),
339 m_presenter(0)
339 m_presenter(0)
340 {
340 {
341
341
342 }
342 }
343
343
344 QChartPrivate::~QChartPrivate()
344 QChartPrivate::~QChartPrivate()
345 {
345 {
346
346
347 }
347 }
348
348
349 void QChartPrivate::createChartBackgroundItem()
349 void QChartPrivate::createChartBackgroundItem()
350 {
350 {
351 if (!m_backgroundItem) {
351 if (!m_backgroundItem) {
352 m_backgroundItem = new ChartBackground(q_ptr);
352 m_backgroundItem = new ChartBackground(q_ptr);
353 m_backgroundItem->setPen(Qt::NoPen);
353 m_backgroundItem->setPen(Qt::NoPen);
354 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
354 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
355 }
355 }
356 }
356 }
357
357
358 void QChartPrivate::createChartTitleItem()
358 void QChartPrivate::createChartTitleItem()
359 {
359 {
360 if (!m_titleItem) {
360 if (!m_titleItem) {
361 m_titleItem = new QGraphicsSimpleTextItem(q_ptr);
361 m_titleItem = new QGraphicsSimpleTextItem(q_ptr);
362 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
362 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
363 }
363 }
364 }
364 }
365
365
366 void QChartPrivate::updateLegendLayout()
366 void QChartPrivate::updateLegendLayout()
367 {
367 {
368 int padding = m_presenter->padding();
368 int padding = m_presenter->padding();
369 QRectF plotRect = m_rect.adjusted(padding,padding,-padding,-padding);
369 QRectF plotRect = m_rect.adjusted(padding,padding,-padding,-padding);
370 QRectF legendRect;
370 QRectF legendRect;
371
371
372 switch (m_legend->alignment())
372 switch (m_legend->alignment())
373 {
373 {
374 case QLegend::LayoutTop: {
374 case QLegend::AlignmentTop: {
375 legendRect = plotRect.adjusted(0,0,0,-padding - plotRect.height());
375 legendRect = m_rect.adjusted(0,0,0,-padding - plotRect.height());
376 break;
376 break;
377 }
377 }
378 case QLegend::LayoutBottom: {
378 case QLegend::AlignmentBottom: {
379 legendRect = plotRect.adjusted(padding,padding + plotRect.height(),-padding,0);
379 legendRect = m_rect.adjusted(padding,padding + plotRect.height(),-padding,0);
380 break;
380 break;
381 }
381 }
382 case QLegend::LayoutLeft: {
382 case QLegend::AlignmentLeft: {
383 legendRect = plotRect.adjusted(0,padding,-padding - plotRect.width(),-padding);
383 legendRect = m_rect.adjusted(0,padding,-padding - plotRect.width(),-padding);
384 break;
384 break;
385 }
385 }
386 case QLegend::LayoutRight: {
386 case QLegend::AlignmentRight: {
387 legendRect = plotRect.adjusted(padding + plotRect.width(),padding,0,-padding);
387 legendRect = m_rect.adjusted(padding + plotRect.width(),padding,0,-padding);
388 break;
388 break;
389 }
389 }
390 default: {
390 default: {
391 legendRect = plotRect;
391 legendRect = plotRect;
392 break;
392 break;
393 }
393 }
394 }
394 }
395
395
396 m_legend->setMaximumSize(legendRect.size());
396 m_legend->setMaximumSize(legendRect.size());
397
397
398 qreal width = legendRect.width() - m_legend->size().width();
398 qreal width = legendRect.width() - m_legend->size().width();
399 qreal height = legendRect.height() - m_legend->size().height();
399 qreal height = legendRect.height() - m_legend->size().height();
400
400
401 QPointF pos = legendRect.topLeft();
401 QPointF pos = legendRect.topLeft();
402 if (width > 0) {
402 if (width > 0) {
403 pos.setX(pos.x() + width/2);
403 pos.setX(pos.x() + width/2);
404 }
404 }
405 if (height > 0) {
405 if (height > 0) {
406 pos.setY(pos.y() + height/2);
406 pos.setY(pos.y() + height/2);
407 }
407 }
408
409 qDebug() << "lenged topleft:" << pos;
408 m_legend->setPos(pos);
410 m_legend->setPos(pos);
409 }
411 }
410
412
411 void QChartPrivate::updateLayout()
413 void QChartPrivate::updateLayout()
412 {
414 {
413 if (!m_rect.isValid()) return;
415 if (!m_rect.isValid()) return;
414
416
415 int padding = m_presenter->padding();
417 int padding = m_presenter->padding();
416 int backgroundPadding = m_presenter->backgroundPadding();
418 int backgroundPadding = m_presenter->backgroundPadding();
417
419
418 // recalculate title position
420 // recalculate title position
419 if (m_titleItem) {
421 if (m_titleItem) {
420 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
422 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
421 m_titleItem->setPos(center.x(),m_rect.top()/2 + padding/2);
423 m_titleItem->setPos(center.x(),m_rect.top()/2 + padding/2);
422 }
424 }
423
425
424 //recalculate background gradient
426 //recalculate background gradient
425 if (m_backgroundItem) {
427 if (m_backgroundItem) {
426 m_backgroundItem->setRect(m_rect.adjusted(backgroundPadding,backgroundPadding, -backgroundPadding, -backgroundPadding));
428 m_backgroundItem->setRect(m_rect.adjusted(backgroundPadding,backgroundPadding, -backgroundPadding, -backgroundPadding));
427 }
429 }
428
430
429 // recalculate legend position
431 // recalculate legend position
430 if (m_legend) {
432 if (m_legend) {
431 if (m_legend->parentObject() == q_ptr) {
433 if ((m_legend->attachedToChart()) && (m_legend->parentObject() == q_ptr)) {
432 updateLegendLayout();
434 updateLegendLayout();
433 }
435 }
434 }
436 }
435 }
437 }
436
438
437 #include "moc_qchart.cpp"
439 #include "moc_qchart.cpp"
438
440
439 QTCOMMERCIALCHART_END_NAMESPACE
441 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,703 +1,728
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qlegend.h"
21 #include "qlegend.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include "qseries.h"
23 #include "qseries.h"
24 #include "legendmarker_p.h"
24 #include "legendmarker_p.h"
25 #include "legendscrollbutton_p.h"
25 #include "legendscrollbutton_p.h"
26 #include "qxyseries.h"
26 #include "qxyseries.h"
27 #include "qlineseries.h"
27 #include "qlineseries.h"
28 #include "qareaseries.h"
28 #include "qareaseries.h"
29 #include "qscatterseries.h"
29 #include "qscatterseries.h"
30 #include "qsplineseries.h"
30 #include "qsplineseries.h"
31 #include "qbarseries.h"
31 #include "qbarseries.h"
32 #include "qstackedbarseries.h"
32 #include "qstackedbarseries.h"
33 #include "qpercentbarseries.h"
33 #include "qpercentbarseries.h"
34 #include "qbarset.h"
34 #include "qbarset.h"
35 #include "qpieseries.h"
35 #include "qpieseries.h"
36 #include "qpieslice.h"
36 #include "qpieslice.h"
37 #include "chartpresenter_p.h"
37 #include "chartpresenter_p.h"
38 #include <QPainter>
38 #include <QPainter>
39 #include <QPen>
39 #include <QPen>
40
40
41 #include <QGraphicsSceneEvent>
41 #include <QGraphicsSceneEvent>
42
42
43 QTCOMMERCIALCHART_BEGIN_NAMESPACE
43 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44
44
45 /*!
45 /*!
46 \class QLegend
46 \class QLegend
47 \brief part of QtCommercial chart API.
47 \brief part of QtCommercial chart API.
48
48
49 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
49 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
50 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
50 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
51 handle the drawing manually.
51 handle the drawing manually.
52 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
52 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
53
53
54 \mainclass
54 \mainclass
55
55
56 \sa QChart, QSeries
56 \sa QChart, QSeries
57 */
57 */
58
58
59 /*!
59 /*!
60 \enum QLegend::Layout
60 \enum QLegend::Layout
61
61
62 This enum describes the possible position for legend inside chart.
62 This enum describes the possible position for legend inside chart.
63
63
64 \value LayoutTop
64 \value LayoutTop
65 \value LayoutBottom
65 \value LayoutBottom
66 \value LayoutLeft
66 \value LayoutLeft
67 \value LayoutRight
67 \value LayoutRight
68 */
68 */
69
69
70
70
71 /*!
71 /*!
72 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
72 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
73 \brief Notifies when series has been clicked on legend \a series \a button
73 \brief Notifies when series has been clicked on legend \a series \a button
74 */
74 */
75
75
76 /*!
76 /*!
77 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
77 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
78 \brief Notifies when barset has been clicked on legend \a barset \a button
78 \brief Notifies when barset has been clicked on legend \a barset \a button
79 */
79 */
80
80
81 /*!
81 /*!
82 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
82 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
83 \brief Notifies when pie slice has been clicked on legend \a slice \a button
83 \brief Notifies when pie slice has been clicked on legend \a slice \a button
84 */
84 */
85
85
86 /*!
86 /*!
87 Constructs the legend object and sets the parent to \a parent
87 Constructs the legend object and sets the parent to \a parent
88 */
88 */
89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
90 m_margin(5),
90 m_margin(5),
91 m_pos(0,0),
91 m_pos(0,0),
92 m_minimumSize(50,20), // TODO: magic numbers
92 m_minimumSize(50,20), // TODO: magic numbers
93 m_maximumSize(150,100),
93 m_maximumSize(150,100),
94 m_size(m_minimumSize),
94 m_size(m_minimumSize),
95 m_brush(Qt::darkGray), // TODO: default should come from theme
95 m_brush(Qt::darkGray), // TODO: default should come from theme
96 m_alignment(QLegend::LayoutTop),
96 m_alignment(QLegend::AlignmentRight),
97 mFirstMarker(0)
97 mFirstMarker(0),
98 m_attachedToChart(true)
98 {
99 {
99 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
100 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
100 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
101 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
101 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
102 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
102 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
103 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
103 setZValue(ChartPresenter::LegendZValue);
104 setZValue(ChartPresenter::LegendZValue);
104 }
105 }
105
106
106 /*!
107 /*!
107 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
108 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
108 */
109 */
109 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 {
111 {
111 Q_UNUSED(option)
112 Q_UNUSED(option)
112 Q_UNUSED(widget)
113 Q_UNUSED(widget)
113
114
114 painter->setOpacity(opacity());
115 painter->setOpacity(opacity());
115 painter->setPen(m_pen);
116 painter->setPen(m_pen);
116 painter->setBrush(m_brush);
117 painter->setBrush(m_brush);
117 // painter->drawRect(boundingRect());
118 // painter->drawRect(boundingRect());
118 }
119 }
119
120
120 /*!
121 /*!
121 Bounding rect of legend.
122 Bounding rect of legend.
122 */
123 */
123 QRectF QLegend::boundingRect() const
124 QRectF QLegend::boundingRect() const
124 {
125 {
125 return QRectF(m_pos,m_size);
126 return QRectF(m_pos,m_size);
126 }
127 }
127
128
128 /*!
129 /*!
129 Sets the \a brush of legend. Brush affects the background of legend.
130 Sets the \a brush of legend. Brush affects the background of legend.
130 */
131 */
131 void QLegend::setBrush(const QBrush &brush)
132 void QLegend::setBrush(const QBrush &brush)
132 {
133 {
133 if (m_brush != brush) {
134 if (m_brush != brush) {
134 m_brush = brush;
135 m_brush = brush;
135 update();
136 update();
136 }
137 }
137 }
138 }
138
139
139 /*!
140 /*!
140 Returns the brush used by legend.
141 Returns the brush used by legend.
141 */
142 */
142 QBrush QLegend::brush() const
143 QBrush QLegend::brush() const
143 {
144 {
144 return m_brush;
145 return m_brush;
145 }
146 }
146
147
147 /*!
148 /*!
148 Sets the \a pen of legend. Pen affects the legend borders.
149 Sets the \a pen of legend. Pen affects the legend borders.
149 */
150 */
150 void QLegend::setPen(const QPen &pen)
151 void QLegend::setPen(const QPen &pen)
151 {
152 {
152 if (m_pen != pen) {
153 if (m_pen != pen) {
153 m_pen = pen;
154 m_pen = pen;
154 update();
155 update();
155 }
156 }
156 }
157 }
157
158
158 /*!
159 /*!
159 Returns the pen used by legend
160 Returns the pen used by legend
160 */
161 */
161
162
162 QPen QLegend::pen() const
163 QPen QLegend::pen() const
163 {
164 {
164 return m_pen;
165 return m_pen;
165 }
166 }
166
167
167 /*!
168 /*!
168 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
169 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
169 \sa QLegend::Layout
170 \sa QLegend::Layout
170 */
171 */
171 void QLegend::setAlignmnent(QLegend::Layout alignment)
172 void QLegend::setAlignmnent(QLegend::Alignment alignment)
172 {
173 {
173 m_alignment = alignment;
174 m_alignment = alignment;
174 updateLayout();
175 updateLayout();
175 }
176 }
176
177
177 /*!
178 /*!
178 Returns the preferred layout for legend
179 Returns the preferred layout for legend
179 */
180 */
180 QLegend::Layout QLegend::alignment() const
181 QLegend::Alignment QLegend::alignment() const
181 {
182 {
182 return m_alignment;
183 return m_alignment;
183 }
184 }
184
185
185 /*!
186 /*!
186 Returns the maximum size of legend.
187 Returns the maximum size of legend.
187 */
188 */
188 QSizeF QLegend::maximumSize() const
189 QSizeF QLegend::maximumSize() const
189 {
190 {
190 return m_maximumSize;
191 return m_maximumSize;
191 }
192 }
192
193
193 /*!
194 /*!
194 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
195 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
195 more series than legend can fit to this size, scroll buttons are displayed.
196 more series than legend can fit to this size, scroll buttons are displayed.
196 */
197 */
197 void QLegend::setMaximumSize(const QSizeF size)
198 void QLegend::setMaximumSize(const QSizeF size)
198 {
199 {
199 m_maximumSize = size;
200 m_maximumSize = size;
200 updateLayout();
201 updateLayout();
201 }
202 }
202
203
203 /*!
204 /*!
204 Returns the current size of legend.
205 Returns the current size of legend.
205 */
206 */
206 QSizeF QLegend::size() const
207 QSizeF QLegend::size() const
207 {
208 {
208 return m_size;
209 return m_size;
209 }
210 }
210
211
211 /*!
212 /*!
212 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
213 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
213 \sa setMmaximumSize()
214 \sa setMmaximumSize()
214 */
215 */
215 void QLegend::setSize(const QSizeF size)
216 void QLegend::setSize(const QSizeF size)
216 {
217 {
217 m_size = size;
218 m_size = size;
218 if (m_size.width() > m_maximumSize.width()) {
219 if (m_size.width() > m_maximumSize.width()) {
219 m_size.setWidth(m_maximumSize.width());
220 m_size.setWidth(m_maximumSize.width());
220 }
221 }
221 if (m_size.height() > m_maximumSize.height()) {
222 if (m_size.height() > m_maximumSize.height()) {
222 m_size.setHeight(m_maximumSize.height());
223 m_size.setHeight(m_maximumSize.height());
223 }
224 }
224 }
225 }
225
226
226 /*!
227 /*!
227 Sets position of legend to \a pos
228 Sets position of legend to \a pos
228 */
229 */
229 void QLegend::setPos(const QPointF &pos)
230 void QLegend::setPos(const QPointF &pos)
230 {
231 {
231 m_pos = pos;
232 m_pos = pos;
232 updateLayout();
233 updateLayout();
233 }
234 }
234
235
235 /*!
236 /*!
236 \internal \a series \a domain Should be called when series is added to chart.
237 \internal \a series \a domain Should be called when series is added to chart.
237 */
238 */
238 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
239 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
239 {
240 {
240 Q_UNUSED(domain)
241 Q_UNUSED(domain)
241
242
242 switch (series->type())
243 switch (series->type())
243 {
244 {
244 case QSeries::SeriesTypeLine: {
245 case QSeries::SeriesTypeLine: {
245 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
246 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
246 appendMarkers(lineSeries);
247 appendMarkers(lineSeries);
247 break;
248 break;
248 }
249 }
249 case QSeries::SeriesTypeArea: {
250 case QSeries::SeriesTypeArea: {
250 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
251 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
251 appendMarkers(areaSeries);
252 appendMarkers(areaSeries);
252 break;
253 break;
253 }
254 }
254 case QSeries::SeriesTypeBar: {
255 case QSeries::SeriesTypeBar: {
255 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
256 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
256 appendMarkers(barSeries);
257 appendMarkers(barSeries);
257 break;
258 break;
258 }
259 }
259 case QSeries::SeriesTypeStackedBar: {
260 case QSeries::SeriesTypeStackedBar: {
260 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
261 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
261 appendMarkers(stackedBarSeries);
262 appendMarkers(stackedBarSeries);
262 break;
263 break;
263 }
264 }
264 case QSeries::SeriesTypePercentBar: {
265 case QSeries::SeriesTypePercentBar: {
265 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
266 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
266 appendMarkers(percentBarSeries);
267 appendMarkers(percentBarSeries);
267 break;
268 break;
268 }
269 }
269 case QSeries::SeriesTypeScatter: {
270 case QSeries::SeriesTypeScatter: {
270 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
271 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
271 appendMarkers(scatterSeries);
272 appendMarkers(scatterSeries);
272 break;
273 break;
273 }
274 }
274 case QSeries::SeriesTypePie: {
275 case QSeries::SeriesTypePie: {
275 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
276 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
276 appendMarkers(pieSeries);
277 appendMarkers(pieSeries);
277 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
278 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
278 break;
279 break;
279 }
280 }
280 case QSeries::SeriesTypeSpline: {
281 case QSeries::SeriesTypeSpline: {
281 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
282 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
282 appendMarkers(splineSeries);
283 appendMarkers(splineSeries);
283 break;
284 break;
284 }
285 }
285 default: {
286 default: {
286 qWarning()<< "QLegend::handleSeriesAdded" << series->type() << "unknown series type.";
287 qWarning()<< "QLegend::handleSeriesAdded" << series->type() << "unknown series type.";
287 break;
288 break;
288 }
289 }
289 }
290 }
290
291
291 updateLayout();
292 updateLayout();
292 }
293 }
293
294
294 /*!
295 /*!
295 \internal \a series Should be called when series is removed from chart.
296 \internal \a series Should be called when series is removed from chart.
296 */
297 */
297 void QLegend::handleSeriesRemoved(QSeries *series)
298 void QLegend::handleSeriesRemoved(QSeries *series)
298 {
299 {
299 switch (series->type())
300 switch (series->type())
300 {
301 {
301 case QSeries::SeriesTypeArea: {
302 case QSeries::SeriesTypeArea: {
302 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
303 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
303 deleteMarkers(areaSeries);
304 deleteMarkers(areaSeries);
304 break;
305 break;
305 }
306 }
306 case QSeries::SeriesTypePie: {
307 case QSeries::SeriesTypePie: {
307 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
308 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
308 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
309 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
309 deleteMarkers(series);
310 deleteMarkers(series);
310 break;
311 break;
311 }
312 }
312 default: {
313 default: {
313 // All other types
314 // All other types
314 deleteMarkers(series);
315 deleteMarkers(series);
315 break;
316 break;
316 }
317 }
317 }
318 }
318
319
319 updateLayout();
320 updateLayout();
320 }
321 }
321
322
322 /*!
323 /*!
323 \internal \a slices Should be called when slices are added to pie chart.
324 \internal \a slices Should be called when slices are added to pie chart.
324 */
325 */
325 void QLegend::handleAdded(QList<QPieSlice *> slices)
326 void QLegend::handleAdded(QList<QPieSlice *> slices)
326 {
327 {
327 QPieSeries* series = static_cast<QPieSeries *> (sender());
328 QPieSeries* series = static_cast<QPieSeries *> (sender());
328 foreach(QPieSlice* s, slices) {
329 foreach(QPieSlice* s, slices) {
329 LegendMarker* marker = new LegendMarker(series, s, this);
330 LegendMarker* marker = new LegendMarker(series, s, this);
330 marker->setName(s->label());
331 marker->setName(s->label());
331 marker->setBrush(s->brush());
332 marker->setBrush(s->brush());
332 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
333 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
333 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
334 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
334 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
335 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
335 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
336 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
336 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
337 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
337 m_markers.append(marker);
338 m_markers.append(marker);
338 childItems().append(marker);
339 childItems().append(marker);
339 }
340 }
340 updateLayout();
341 updateLayout();
341 }
342 }
342
343
343 /*!
344 /*!
344 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
345 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
345 because removed slices are also deleted and we listen destroyed signal
346 because removed slices are also deleted and we listen destroyed signal
346 */
347 */
347 void QLegend::handleRemoved(QList<QPieSlice *> slices)
348 void QLegend::handleRemoved(QList<QPieSlice *> slices)
348 {
349 {
349 Q_UNUSED(slices)
350 Q_UNUSED(slices)
350 }
351 }
351
352
352
353
353 /*!
354 /*!
354 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
355 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
355 */
356 */
356 void QLegend::handleMarkerDestroyed()
357 void QLegend::handleMarkerDestroyed()
357 {
358 {
358 LegendMarker* m = static_cast<LegendMarker *> (sender());
359 LegendMarker* m = static_cast<LegendMarker *> (sender());
359 m_markers.removeOne(m);
360 m_markers.removeOne(m);
360 updateLayout();
361 updateLayout();
361 }
362 }
362
363
363 /*!
364 /*!
364 \internal \a event Handles clicked signals from scroll buttons
365 \internal \a event Handles clicked signals from scroll buttons
365 */
366 */
366 void QLegend::scrollButtonClicked(LegendScrollButton *scrollButton)
367 void QLegend::scrollButtonClicked(LegendScrollButton *scrollButton)
367 {
368 {
368 Q_ASSERT(scrollButton);
369 Q_ASSERT(scrollButton);
369
370
370 switch (scrollButton->id()) {
371 switch (scrollButton->id()) {
371 case LegendScrollButton::ScrollButtonIdLeft:
372 case LegendScrollButton::ScrollButtonIdLeft:
372 case LegendScrollButton::ScrollButtonIdUp: {
373 case LegendScrollButton::ScrollButtonIdUp: {
373 // Lower limit is same in these cases
374 // Lower limit is same in these cases
374 mFirstMarker--;
375 mFirstMarker--;
375 checkFirstMarkerBounds();
376 checkFirstMarkerBounds();
376 break;
377 break;
377 }
378 }
378 case LegendScrollButton::ScrollButtonIdRight:
379 case LegendScrollButton::ScrollButtonIdRight:
379 case LegendScrollButton::ScrollButtonIdDown: {
380 case LegendScrollButton::ScrollButtonIdDown: {
380 mFirstMarker++;
381 mFirstMarker++;
381 checkFirstMarkerBounds();
382 checkFirstMarkerBounds();
382 break;
383 break;
383 }
384 }
384 default: {
385 default: {
385 break;
386 break;
386 }
387 }
387 }
388 }
388 updateLayout();
389 updateLayout();
389 }
390 }
390
391
391 /*!
392 /*!
393 Detaches the legend from chart. Chart won't change layout of the legend.
394 */
395 void QLegend::detachFromChart()
396 {
397 m_attachedToChart = false;
398 }
399
400 /*!
401 Attaches the legend to chart. Chart may change layout of the legend.
402 */
403 void QLegend::attachToChart()
404 {
405 m_attachedToChart = true;
406 }
407
408 /*!
409 Returns true, if legend is attached to chart.
410 */
411 bool QLegend::attachedToChart()
412 {
413 return m_attachedToChart;
414 }
415
416 /*!
392 \internal Helper function. Appends markers from \a series to legend.
417 \internal Helper function. Appends markers from \a series to legend.
393 */
418 */
394 void QLegend::appendMarkers(QAreaSeries* series)
419 void QLegend::appendMarkers(QAreaSeries* series)
395 {
420 {
396 LegendMarker* marker = new LegendMarker(series,this);
421 LegendMarker* marker = new LegendMarker(series,this);
397 marker->setName(series->name());
422 marker->setName(series->name());
398 marker->setPen(series->pen());
423 marker->setPen(series->pen());
399 marker->setBrush(series->brush());
424 marker->setBrush(series->brush());
400 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
425 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
401 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
426 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
402 connect(series,SIGNAL(updated()),marker,SLOT(changed()));
427 connect(series,SIGNAL(updated()),marker,SLOT(changed()));
403 m_markers.append(marker);
428 m_markers.append(marker);
404 childItems().append(marker);
429 childItems().append(marker);
405 }
430 }
406
431
407 /*!
432 /*!
408 \internal Helper function. Appends markers from \a series to legend.
433 \internal Helper function. Appends markers from \a series to legend.
409 */
434 */
410 void QLegend::appendMarkers(QXYSeries* series)
435 void QLegend::appendMarkers(QXYSeries* series)
411 {
436 {
412 LegendMarker* marker = new LegendMarker(series,this);
437 LegendMarker* marker = new LegendMarker(series,this);
413 marker->setName(series->name());
438 marker->setName(series->name());
414 marker->setPen(series->pen());
439 marker->setPen(series->pen());
415 marker->setBrush(series->brush());
440 marker->setBrush(series->brush());
416 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
441 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
417 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
442 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
418 connect(series,SIGNAL(updated()),marker,SLOT(changed()));
443 connect(series,SIGNAL(updated()),marker,SLOT(changed()));
419 m_markers.append(marker);
444 m_markers.append(marker);
420 childItems().append(marker);
445 childItems().append(marker);
421 }
446 }
422
447
423 /*!
448 /*!
424 \internal Helper function. Appends markers from \a series to legend.
449 \internal Helper function. Appends markers from \a series to legend.
425 */
450 */
426 void QLegend::appendMarkers(QBarSeries *series)
451 void QLegend::appendMarkers(QBarSeries *series)
427 {
452 {
428 foreach(QBarSet* set, series->barSets()) {
453 foreach(QBarSet* set, series->barSets()) {
429 LegendMarker* marker = new LegendMarker(series, set, this);
454 LegendMarker* marker = new LegendMarker(series, set, this);
430 marker->setName(set->name());
455 marker->setName(set->name());
431 marker->setPen(set->pen());
456 marker->setPen(set->pen());
432 marker->setBrush(set->brush());
457 marker->setBrush(set->brush());
433 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
458 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
434 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
459 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
435 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
460 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
436 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
461 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
437 m_markers.append(marker);
462 m_markers.append(marker);
438 childItems().append(marker);
463 childItems().append(marker);
439 }
464 }
440 }
465 }
441
466
442 /*!
467 /*!
443 \internal Helper function. Appends markers from \a series to legend.
468 \internal Helper function. Appends markers from \a series to legend.
444 */
469 */
445 void QLegend::appendMarkers(QPieSeries *series)
470 void QLegend::appendMarkers(QPieSeries *series)
446 {
471 {
447 foreach(QPieSlice* slice, series->slices()) {
472 foreach(QPieSlice* slice, series->slices()) {
448 LegendMarker* marker = new LegendMarker(series, slice, this);
473 LegendMarker* marker = new LegendMarker(series, slice, this);
449 marker->setName(slice->label());
474 marker->setName(slice->label());
450 marker->setPen(slice->pen());
475 marker->setPen(slice->pen());
451 marker->setBrush(slice->brush());
476 marker->setBrush(slice->brush());
452 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
477 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
453 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
478 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
454 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
479 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
455 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
480 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
456 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
481 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
457 m_markers.append(marker);
482 m_markers.append(marker);
458 childItems().append(marker);
483 childItems().append(marker);
459 }
484 }
460 }
485 }
461
486
462 /*!
487 /*!
463 \internal Deletes all markers that are created from \a series
488 \internal Deletes all markers that are created from \a series
464 */
489 */
465 void QLegend::deleteMarkers(QSeries *series)
490 void QLegend::deleteMarkers(QSeries *series)
466 {
491 {
467 // Search all markers that belong to given series and delete them.
492 // Search all markers that belong to given series and delete them.
468 foreach (LegendMarker *m, m_markers) {
493 foreach (LegendMarker *m, m_markers) {
469 if (m->series() == series) {
494 if (m->series() == series) {
470 m_markers.removeOne(m);
495 m_markers.removeOne(m);
471 delete m;
496 delete m;
472 }
497 }
473 }
498 }
474 }
499 }
475
500
476 /*!
501 /*!
477 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
502 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
478 If items don't fit, sets the visibility of scroll buttons accordingly.
503 If items don't fit, sets the visibility of scroll buttons accordingly.
479 Causes legend to be resized.
504 Causes legend to be resized.
480 */
505 */
481 void QLegend::updateLayout()
506 void QLegend::updateLayout()
482 {
507 {
483 // Calculate layout for markers and text
508 // Calculate layout for markers and text
484 if (m_markers.count() <= 0) {
509 if (m_markers.count() <= 0) {
485 // Nothing to do
510 // Nothing to do
486 return;
511 return;
487 }
512 }
488
513
489 // Find out widest item.
514 // Find out widest item.
490 QSizeF markerMaxSize = maximumMarkerSize();
515 QSizeF markerMaxSize = maximumMarkerSize();
491 checkFirstMarkerBounds();
516 checkFirstMarkerBounds();
492
517
493 // Use max height as scroll button size
518 // Use max height as scroll button size
494 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
519 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
495
520
496 qreal totalWidth = 0;
521 qreal totalWidth = 0;
497 qreal totalHeight = 0;
522 qreal totalHeight = 0;
498 switch (m_alignment)
523 switch (m_alignment)
499 {
524 {
500 // Both cases organise items horizontally
525 // Both cases organise items horizontally
501 case QLegend::LayoutBottom:
526 case QLegend::AlignmentBottom:
502 case QLegend::LayoutTop: {
527 case QLegend::AlignmentTop: {
503
528
504 qreal xStep = markerMaxSize.width();
529 qreal xStep = markerMaxSize.width();
505 qreal x = m_pos.x() + m_margin;
530 qreal x = m_pos.x() + m_margin;
506 qreal y = m_pos.y() + m_margin;
531 qreal y = m_pos.y() + m_margin;
507 int column = 0;
532 int column = 0;
508 int maxColumns = 1;
533 int maxColumns = 1;
509 qreal scrollButtonWidth = 0;
534 qreal scrollButtonWidth = 0;
510
535
511 // Set correct visibility for scroll scrollbuttons
536 // Set correct visibility for scroll scrollbuttons
512 if (scrollButtonsVisible()) {
537 if (scrollButtonsVisible()) {
513 m_scrollButtonLeft->setVisible(true);
538 m_scrollButtonLeft->setVisible(true);
514 m_scrollButtonRight->setVisible(true);
539 m_scrollButtonRight->setVisible(true);
515 // scrollbuttons visible, so add their width to total width
540 // scrollbuttons visible, so add their width to total width
516 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
541 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
517 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
542 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
518 // start position changes by scrollbutton width
543 // start position changes by scrollbutton width
519 x += scrollButtonWidth;
544 x += scrollButtonWidth;
520 } else {
545 } else {
521 m_scrollButtonLeft->setVisible(false);
546 m_scrollButtonLeft->setVisible(false);
522 m_scrollButtonRight->setVisible(false);
547 m_scrollButtonRight->setVisible(false);
523 }
548 }
524 m_scrollButtonUp->setVisible(false);
549 m_scrollButtonUp->setVisible(false);
525 m_scrollButtonDown->setVisible(false);
550 m_scrollButtonDown->setVisible(false);
526
551
527 for (int i=0; i < m_markers.count(); i++) {
552 for (int i=0; i < m_markers.count(); i++) {
528 LegendMarker *m = m_markers.at(i);
553 LegendMarker *m = m_markers.at(i);
529 if (i < mFirstMarker) {
554 if (i < mFirstMarker) {
530 // Markers before first are not visible.
555 // Markers before first are not visible.
531 m->setVisible(false);
556 m->setVisible(false);
532 } else {
557 } else {
533 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
558 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
534 // This marker would go outside legend rect.
559 // This marker would go outside legend rect.
535 m->setVisible(false);
560 m->setVisible(false);
536 } else {
561 } else {
537 // This marker is ok
562 // This marker is ok
538 m->setVisible(true);
563 m->setVisible(true);
539 m->setPos(x, y);
564 m->setPos(x, y);
540 x += xStep;
565 x += xStep;
541 column++;
566 column++;
542 }
567 }
543 }
568 }
544 maxColumns = column;
569 maxColumns = column;
545 }
570 }
546
571
547 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
572 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
548 m_scrollButtonRight->setPos(x + m_margin, y);
573 m_scrollButtonRight->setPos(x + m_margin, y);
549
574
550 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
575 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
551 totalHeight = markerMaxSize.height() + m_margin * 2;
576 totalHeight = markerMaxSize.height() + m_margin * 2;
552
577
553 break;
578 break;
554 }
579 }
555 // Both cases organize items vertically
580 // Both cases organize items vertically
556 case QLegend::LayoutLeft:
581 case QLegend::AlignmentLeft:
557 case QLegend::LayoutRight: {
582 case QLegend::AlignmentRight: {
558 qreal yStep = markerMaxSize.height();
583 qreal yStep = markerMaxSize.height();
559 qreal x = m_pos.x() + m_margin;
584 qreal x = m_pos.x() + m_margin;
560 qreal y = m_pos.y() + m_margin;
585 qreal y = m_pos.y() + m_margin;
561 int row = 1;
586 int row = 1;
562 int maxRows = 1;
587 int maxRows = 1;
563 qreal scrollButtonHeight = 0;
588 qreal scrollButtonHeight = 0;
564
589
565 // Set correct visibility for scroll scrollbuttons
590 // Set correct visibility for scroll scrollbuttons
566 if (scrollButtonsVisible()) {
591 if (scrollButtonsVisible()) {
567 m_scrollButtonUp->setVisible(true);
592 m_scrollButtonUp->setVisible(true);
568 m_scrollButtonDown->setVisible(true);
593 m_scrollButtonDown->setVisible(true);
569 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
594 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
570 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
595 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
571 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
596 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
572 } else {
597 } else {
573 m_scrollButtonUp->setVisible(false);
598 m_scrollButtonUp->setVisible(false);
574 m_scrollButtonDown->setVisible(false);
599 m_scrollButtonDown->setVisible(false);
575 }
600 }
576 m_scrollButtonLeft->setVisible(false);
601 m_scrollButtonLeft->setVisible(false);
577 m_scrollButtonRight->setVisible(false);
602 m_scrollButtonRight->setVisible(false);
578
603
579 for (int i=0; i < m_markers.count(); i++) {
604 for (int i=0; i < m_markers.count(); i++) {
580 LegendMarker* m = m_markers.at(i);
605 LegendMarker* m = m_markers.at(i);
581 if (i < mFirstMarker) {
606 if (i < mFirstMarker) {
582 // Markers before first are not visible.
607 // Markers before first are not visible.
583 m->setVisible(false);
608 m->setVisible(false);
584 } else {
609 } else {
585 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
610 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
586 // This marker would go outside legend rect.
611 // This marker would go outside legend rect.
587 m->setVisible(false);
612 m->setVisible(false);
588 } else {
613 } else {
589 // This marker is ok
614 // This marker is ok
590 m->setVisible(true);
615 m->setVisible(true);
591 m->setPos(x, y);
616 m->setPos(x, y);
592 y += yStep;
617 y += yStep;
593 row++;
618 row++;
594 }
619 }
595 }
620 }
596 maxRows = row;
621 maxRows = row;
597 }
622 }
598
623
599 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
624 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
600 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
625 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
601
626
602 totalWidth += markerMaxSize.width() + m_margin * 2;
627 totalWidth += markerMaxSize.width() + m_margin * 2;
603 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
628 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
604 break;
629 break;
605 }
630 }
606 default: {
631 default: {
607 break;
632 break;
608 }
633 }
609 }
634 }
610
635
611 m_size.setWidth(totalWidth);
636 m_size.setWidth(totalWidth);
612 m_size.setHeight(totalHeight);
637 m_size.setHeight(totalHeight);
613
638
614 update();
639 update();
615 }
640 }
616
641
617 /*!
642 /*!
618 \internal Sets the size of scroll buttons to \a size
643 \internal Sets the size of scroll buttons to \a size
619 */
644 */
620 void QLegend::rescaleScrollButtons(const QSize &size)
645 void QLegend::rescaleScrollButtons(const QSize &size)
621 {
646 {
622 QPolygonF left;
647 QPolygonF left;
623 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
648 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
624 QPolygonF right;
649 QPolygonF right;
625 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
650 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
626 QPolygonF up;
651 QPolygonF up;
627 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
652 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
628 QPolygonF down;
653 QPolygonF down;
629 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
654 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
630
655
631 m_scrollButtonLeft->setPolygon(left);
656 m_scrollButtonLeft->setPolygon(left);
632 m_scrollButtonRight->setPolygon(right);
657 m_scrollButtonRight->setPolygon(right);
633 m_scrollButtonUp->setPolygon(up);
658 m_scrollButtonUp->setPolygon(up);
634 m_scrollButtonDown->setPolygon(down);
659 m_scrollButtonDown->setPolygon(down);
635 }
660 }
636
661
637 /*!
662 /*!
638 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
663 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
639 */
664 */
640 QSizeF QLegend::maximumMarkerSize()
665 QSizeF QLegend::maximumMarkerSize()
641 {
666 {
642 QSizeF max(0,0);
667 QSizeF max(0,0);
643 foreach (LegendMarker* m, m_markers) {
668 foreach (LegendMarker* m, m_markers) {
644 if (m->boundingRect().width() > max.width())
669 if (m->boundingRect().width() > max.width())
645 max.setWidth(m->boundingRect().width());
670 max.setWidth(m->boundingRect().width());
646 if (m->boundingRect().height() > max.height())
671 if (m->boundingRect().height() > max.height())
647 max.setHeight(m->boundingRect().height());
672 max.setHeight(m->boundingRect().height());
648 }
673 }
649 return max;
674 return max;
650 }
675 }
651
676
652 /*!
677 /*!
653 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
678 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
654 If scrollbuttons are visible, they affect the number of visible markers.
679 If scrollbuttons are visible, they affect the number of visible markers.
655 */
680 */
656 void QLegend::checkFirstMarkerBounds()
681 void QLegend::checkFirstMarkerBounds()
657 {
682 {
658 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
683 if ((m_alignment == QLegend::AlignmentLeft) || (m_alignment == QLegend::AlignmentRight)) {
659 // Bounds limited by height.
684 // Bounds limited by height.
660 int max;
685 int max;
661 if (scrollButtonsVisible()) {
686 if (scrollButtonsVisible()) {
662 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
687 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
663 } else {
688 } else {
664 max = m_maximumSize.height() / maximumMarkerSize().height();
689 max = m_maximumSize.height() / maximumMarkerSize().height();
665 }
690 }
666
691
667 if (mFirstMarker > m_markers.count() - max)
692 if (mFirstMarker > m_markers.count() - max)
668 mFirstMarker = m_markers.count() - max;
693 mFirstMarker = m_markers.count() - max;
669 } else {
694 } else {
670 // Bounds limited by width
695 // Bounds limited by width
671 int max;
696 int max;
672 if (scrollButtonsVisible()) {
697 if (scrollButtonsVisible()) {
673 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
698 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
674 } else {
699 } else {
675 max = m_maximumSize.width() / maximumMarkerSize().width();
700 max = m_maximumSize.width() / maximumMarkerSize().width();
676 }
701 }
677
702
678 if (mFirstMarker > m_markers.count() - max)
703 if (mFirstMarker > m_markers.count() - max)
679 mFirstMarker = m_markers.count() - max;
704 mFirstMarker = m_markers.count() - max;
680 }
705 }
681
706
682 if (mFirstMarker < 0)
707 if (mFirstMarker < 0)
683 mFirstMarker = 0;
708 mFirstMarker = 0;
684 }
709 }
685
710
686 /*!
711 /*!
687 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
712 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
688 */
713 */
689 bool QLegend::scrollButtonsVisible()
714 bool QLegend::scrollButtonsVisible()
690 {
715 {
691 // Just a helper to clarify, what the magic below means :)
716 // Just a helper to clarify, what the magic below means :)
692 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
717 if ((m_alignment == QLegend::AlignmentTop) || (m_alignment == QLegend::AlignmentBottom)) {
693 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
718 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
694 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
719 } else if ((m_alignment == QLegend::AlignmentLeft) || (m_alignment == QLegend::AlignmentRight)) {
695 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
720 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
696 }
721 }
697
722
698 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
723 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
699 }
724 }
700
725
701 #include "moc_qlegend.cpp"
726 #include "moc_qlegend.cpp"
702
727
703 QTCOMMERCIALCHART_END_NAMESPACE
728 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,135 +1,140
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef QLEGEND_H
21 #ifndef QLEGEND_H
22 #define QLEGEND_H
22 #define QLEGEND_H
23
23
24 #include <QChartGlobal>
24 #include <QChartGlobal>
25 #include <QGraphicsWidget>
25 #include <QGraphicsWidget>
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 class Domain;
31 class Domain;
32 class LegendMarker;
32 class LegendMarker;
33 class QPieSlice;
33 class QPieSlice;
34 class QXYSeries;
34 class QXYSeries;
35 class QBarSet;
35 class QBarSet;
36 class QBarSeries;
36 class QBarSeries;
37 class QPieSeries;
37 class QPieSeries;
38 class QAreaSeries;
38 class QAreaSeries;
39 class LegendScrollButton;
39 class LegendScrollButton;
40 class QSeries;
40 class QSeries;
41 class QChart;
41 class QChart;
42
42
43 // TODO: This as widget
44 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
43 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
45 {
44 {
46 Q_OBJECT
45 Q_OBJECT
47 public:
46 public:
48
47
49 // We only support these alignments (for now)
48 // We only support these alignments (for now)
50 enum Layout {
49 enum Alignment {
51 LayoutTop = Qt::AlignTop,
50 AlignmentTop = Qt::AlignTop,
52 LayoutBottom = Qt::AlignBottom,
51 AlignmentBottom = Qt::AlignBottom,
53 LayoutLeft = Qt::AlignLeft,
52 AlignmentLeft = Qt::AlignLeft,
54 LayoutRight = Qt::AlignRight
53 AlignmentRight = Qt::AlignRight
55 };
54 };
56 private:
55 private:
57 explicit QLegend(QChart *chart);
56 explicit QLegend(QChart *chart);
58
57
59 public:
58 public:
60 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
59 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
61 QRectF boundingRect() const;
60 QRectF boundingRect() const;
62
61
63 void setBrush(const QBrush &brush);
62 void setBrush(const QBrush &brush);
64 QBrush brush() const;
63 QBrush brush() const;
65
64
66 void setPen(const QPen &pen);
65 void setPen(const QPen &pen);
67 QPen pen() const;
66 QPen pen() const;
68
67
69 void setAlignmnent(QLegend::Layout alignment);
68 void setAlignmnent(QLegend::Alignment alignment);
70 QLegend::Layout alignment() const;
69 QLegend::Alignment alignment() const;
71
70
72 QSizeF maximumSize() const;
71 QSizeF maximumSize() const;
73 void setMaximumSize(const QSizeF size);
72 void setMaximumSize(const QSizeF size);
74
73
75 QSizeF size() const;
74 QSizeF size() const;
76 void setSize(const QSizeF size);
75 void setSize(const QSizeF size);
77 void setPos(const QPointF &pos);
76 void setPos(const QPointF &pos);
78
77
79 void scrollButtonClicked(LegendScrollButton *scrollButton);
78 void scrollButtonClicked(LegendScrollButton *scrollButton);
80
79
80 void detachFromChart();
81 void attachToChart();
82 bool attachedToChart();
83
81 Q_SIGNALS:
84 Q_SIGNALS:
82 // for interactions.
85 // for interactions.
83 void clicked(QSeries *series, Qt::MouseButton button);
86 void clicked(QSeries *series, Qt::MouseButton button);
84 void clicked(QBarSet *barset, Qt::MouseButton button);
87 void clicked(QBarSet *barset, Qt::MouseButton button);
85 void clicked(QPieSlice *slice, Qt::MouseButton button);
88 void clicked(QPieSlice *slice, Qt::MouseButton button);
86
89
87 public Q_SLOTS:
90 public Q_SLOTS:
88 // PIMPL --->
91 // PIMPL --->
89 void handleSeriesAdded(QSeries *series, Domain *domain);
92 void handleSeriesAdded(QSeries *series, Domain *domain);
90 void handleSeriesRemoved(QSeries *series);
93 void handleSeriesRemoved(QSeries *series);
91 void handleAdded(QList<QPieSlice *> slices);
94 void handleAdded(QList<QPieSlice *> slices);
92 void handleRemoved(QList<QPieSlice *> slices);
95 void handleRemoved(QList<QPieSlice *> slices);
93 void handleMarkerDestroyed();
96 void handleMarkerDestroyed();
94
97
95 // PIMPL <---
98 // PIMPL <---
96
99
97 private:
100 private:
98 // PIMPL --->
101 // PIMPL --->
99 void appendMarkers(QAreaSeries *series);
102 void appendMarkers(QAreaSeries *series);
100 void appendMarkers(QXYSeries *series);
103 void appendMarkers(QXYSeries *series);
101 void appendMarkers(QBarSeries *series);
104 void appendMarkers(QBarSeries *series);
102 void appendMarkers(QPieSeries *series);
105 void appendMarkers(QPieSeries *series);
103 void deleteMarkers(QSeries *series);
106 void deleteMarkers(QSeries *series);
104 void updateLayout();
107 void updateLayout();
105 void rescaleScrollButtons(const QSize &size);
108 void rescaleScrollButtons(const QSize &size);
106 QSizeF maximumMarkerSize();
109 QSizeF maximumMarkerSize();
107 void checkFirstMarkerBounds();
110 void checkFirstMarkerBounds();
108 bool scrollButtonsVisible();
111 bool scrollButtonsVisible();
109
112
110 qreal m_margin;
113 qreal m_margin;
111 QPointF m_pos;
114 QPointF m_pos;
112 QSizeF m_minimumSize;
115 QSizeF m_minimumSize;
113 QSizeF m_maximumSize;
116 QSizeF m_maximumSize;
114 QSizeF m_size;
117 QSizeF m_size;
115
118
116 QList<LegendMarker *> m_markers;
119 QList<LegendMarker *> m_markers;
117
120
118 QBrush m_brush;
121 QBrush m_brush;
119 QPen m_pen;
122 QPen m_pen;
120 QLegend::Layout m_alignment;
123 QLegend::Alignment m_alignment;
121
124
122 int mFirstMarker;
125 int mFirstMarker;
123
126
124 LegendScrollButton *m_scrollButtonLeft;
127 LegendScrollButton *m_scrollButtonLeft;
125 LegendScrollButton *m_scrollButtonRight;
128 LegendScrollButton *m_scrollButtonRight;
126 LegendScrollButton *m_scrollButtonUp;
129 LegendScrollButton *m_scrollButtonUp;
127 LegendScrollButton *m_scrollButtonDown;
130 LegendScrollButton *m_scrollButtonDown;
128
131
132 bool m_attachedToChart;
133
129 friend class QChart;
134 friend class QChart;
130 // <--- PIMPL
135 // <--- PIMPL
131 };
136 };
132
137
133 QTCOMMERCIALCHART_END_NAMESPACE
138 QTCOMMERCIALCHART_END_NAMESPACE
134
139
135 #endif // QLEGEND_H
140 #endif // QLEGEND_H
General Comments 0
You need to be logged in to leave comments. Login now