##// END OF EJS Templates
improved legend layout
sauimone -
r783:d2e48e985993
parent child
Show More
@@ -1,381 +1,386
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qlegend.h"
2 #include "qchartaxis.h"
3 #include "qchartaxis.h"
3 #include "chartpresenter_p.h"
4 #include "chartpresenter_p.h"
4 #include "chartdataset_p.h"
5 #include "chartdataset_p.h"
5 #include "charttheme_p.h"
6 #include "charttheme_p.h"
6 #include "chartanimator_p.h"
7 #include "chartanimator_p.h"
7 //series
8 //series
8 #include "qbarseries.h"
9 #include "qbarseries.h"
9 #include "qstackedbarseries.h"
10 #include "qstackedbarseries.h"
10 #include "qpercentbarseries.h"
11 #include "qpercentbarseries.h"
11 #include "qlineseries.h"
12 #include "qlineseries.h"
12 #include "qareaseries.h"
13 #include "qareaseries.h"
13 #include "qpieseries.h"
14 #include "qpieseries.h"
14 #include "qscatterseries.h"
15 #include "qscatterseries.h"
15 #include "qsplineseries.h"
16 #include "qsplineseries.h"
16 //items
17 //items
17 #include "axisitem_p.h"
18 #include "axisitem_p.h"
18 #include "areachartitem_p.h"
19 #include "areachartitem_p.h"
19 #include "barchartitem_p.h"
20 #include "barchartitem_p.h"
20 #include "stackedbarchartitem_p.h"
21 #include "stackedbarchartitem_p.h"
21 #include "percentbarchartitem_p.h"
22 #include "percentbarchartitem_p.h"
22 #include "linechartitem_p.h"
23 #include "linechartitem_p.h"
23 #include "piechartitem_p.h"
24 #include "piechartitem_p.h"
24 #include "scatterchartitem_p.h"
25 #include "scatterchartitem_p.h"
25 #include "splinechartitem_p.h"
26 #include "splinechartitem_p.h"
26
27
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
29
29 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 m_chart(chart),
31 m_chart(chart),
31 m_animator(0),
32 m_animator(0),
32 m_dataset(dataset),
33 m_dataset(dataset),
33 m_chartTheme(0),
34 m_chartTheme(0),
34 m_rect(QRectF(QPoint(0,0),m_chart->size())),
35 m_rect(QRectF(QPoint(0,0),m_chart->size())),
35 m_options(QChart::NoAnimation),
36 m_options(QChart::NoAnimation),
36 m_themeForce(false),
37 m_themeForce(false),
37 m_padding(50),
38 m_padding(50),
38 m_backgroundPadding(10)
39 m_backgroundPadding(10)
39 {
40 {
40 createConnections();
41 createConnections();
41 setTheme(QChart::ChartThemeDefault,false);
42 setTheme(QChart::ChartThemeDefault,false);
42 }
43 }
43
44
44 ChartPresenter::~ChartPresenter()
45 ChartPresenter::~ChartPresenter()
45 {
46 {
46 delete m_chartTheme;
47 delete m_chartTheme;
47 }
48 }
48
49
49 void ChartPresenter::createConnections()
50 void ChartPresenter::createConnections()
50 {
51 {
51 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
52 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
52 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
53 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
53 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
54 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
54 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
55 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
55 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
56 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
56 }
57 }
57
58
58 void ChartPresenter::handleGeometryChanged()
59 void ChartPresenter::handleGeometryChanged()
59 {
60 {
61 qDebug() << "legend h:" << m_chart->legend()->size().height();
60 QRectF rect(QPoint(0,0),m_chart->size());
62 QRectF rect(QPoint(0,0),m_chart->size());
61 rect.adjust(m_padding,m_padding,-m_padding,-m_padding);
63 rect.adjust(m_padding,
64 m_padding + m_chart->legend()->size().height(),
65 -m_padding,
66 -m_padding);
62
67
63 //rewrite zoom stack
68 //rewrite zoom stack
64 /*
69 /*
65 for(int i=0;i<m_zoomStack.count();i++){
70 for(int i=0;i<m_zoomStack.count();i++){
66 QRectF r = m_zoomStack[i];
71 QRectF r = m_zoomStack[i];
67 qreal w = rect.width()/m_rect.width();
72 qreal w = rect.width()/m_rect.width();
68 qreal h = rect.height()/m_rect.height();
73 qreal h = rect.height()/m_rect.height();
69 QPointF tl = r.topLeft();
74 QPointF tl = r.topLeft();
70 tl.setX(tl.x()*w);
75 tl.setX(tl.x()*w);
71 tl.setY(tl.y()*h);
76 tl.setY(tl.y()*h);
72 QPointF br = r.bottomRight();
77 QPointF br = r.bottomRight();
73 br.setX(br.x()*w);
78 br.setX(br.x()*w);
74 br.setY(br.y()*h);
79 br.setY(br.y()*h);
75 r.setTopLeft(tl);
80 r.setTopLeft(tl);
76 r.setBottomRight(br);
81 r.setBottomRight(br);
77 m_zoomStack[i]=r;
82 m_zoomStack[i]=r;
78 }
83 }
79 */
84 */
80 m_rect = rect;
85 m_rect = rect;
81 Q_ASSERT(m_rect.isValid());
86 Q_ASSERT(m_rect.isValid());
82 emit geometryChanged(m_rect);
87 emit geometryChanged(m_rect);
83 }
88 }
84
89
85 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
90 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
86 {
91 {
87 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
92 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
88
93
89 if(m_options.testFlag(QChart::GridAxisAnimations)){
94 if(m_options.testFlag(QChart::GridAxisAnimations)){
90 m_animator->addAnimation(item);
95 m_animator->addAnimation(item);
91 }
96 }
92
97
93 if(axis==m_dataset->axisX()){
98 if(axis==m_dataset->axisX()){
94 m_chartTheme->decorate(axis,true,m_themeForce);
99 m_chartTheme->decorate(axis,true,m_themeForce);
95 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
100 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
96 //initialize
101 //initialize
97 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
102 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
98
103
99 }
104 }
100 else{
105 else{
101 m_chartTheme->decorate(axis,false,m_themeForce);
106 m_chartTheme->decorate(axis,false,m_themeForce);
102 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
107 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
103 //initialize
108 //initialize
104 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
109 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
105 }
110 }
106
111
107 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
112 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
108 //initialize
113 //initialize
109 item->handleGeometryChanged(m_rect);
114 item->handleGeometryChanged(m_rect);
110 m_axisItems.insert(axis, item);
115 m_axisItems.insert(axis, item);
111 }
116 }
112
117
113 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
118 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
114 {
119 {
115 Axis* item = m_axisItems.take(axis);
120 Axis* item = m_axisItems.take(axis);
116 Q_ASSERT(item);
121 Q_ASSERT(item);
117 if(m_animator) m_animator->removeAnimation(item);
122 if(m_animator) m_animator->removeAnimation(item);
118 delete item;
123 delete item;
119 }
124 }
120
125
121
126
122 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
127 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
123 {
128 {
124 Chart *item = 0 ;
129 Chart *item = 0 ;
125
130
126 switch(series->type())
131 switch(series->type())
127 {
132 {
128 case QSeries::SeriesTypeLine: {
133 case QSeries::SeriesTypeLine: {
129
134
130 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
135 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
131 LineChartItem* line = new LineChartItem(lineSeries,this);
136 LineChartItem* line = new LineChartItem(lineSeries,this);
132 if(m_options.testFlag(QChart::SeriesAnimations)) {
137 if(m_options.testFlag(QChart::SeriesAnimations)) {
133 m_animator->addAnimation(line);
138 m_animator->addAnimation(line);
134 }
139 }
135 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
140 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
136 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
141 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
137 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
142 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
138 item = line;
143 item = line;
139 break;
144 break;
140 }
145 }
141
146
142 case QSeries::SeriesTypeArea: {
147 case QSeries::SeriesTypeArea: {
143
148
144 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
149 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
145 AreaChartItem* area = new AreaChartItem(areaSeries,this);
150 AreaChartItem* area = new AreaChartItem(areaSeries,this);
146 if(m_options.testFlag(QChart::SeriesAnimations)) {
151 if(m_options.testFlag(QChart::SeriesAnimations)) {
147 m_animator->addAnimation(area->upperLineItem());
152 m_animator->addAnimation(area->upperLineItem());
148 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
153 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
149 }
154 }
150 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
155 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
151 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
156 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
152 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
157 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
153 item=area;
158 item=area;
154 break;
159 break;
155 }
160 }
156
161
157 case QSeries::SeriesTypeBar: {
162 case QSeries::SeriesTypeBar: {
158 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
163 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
159 BarChartItem* bar = new BarChartItem(barSeries,this);
164 BarChartItem* bar = new BarChartItem(barSeries,this);
160 if(m_options.testFlag(QChart::SeriesAnimations)) {
165 if(m_options.testFlag(QChart::SeriesAnimations)) {
161 m_animator->addAnimation(bar);
166 m_animator->addAnimation(bar);
162 }
167 }
163 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
168 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
164 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
169 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
165 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
170 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
166 item=bar;
171 item=bar;
167 break;
172 break;
168 }
173 }
169
174
170 case QSeries::SeriesTypeStackedBar: {
175 case QSeries::SeriesTypeStackedBar: {
171 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
176 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
172 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
177 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
173 if(m_options.testFlag(QChart::SeriesAnimations)) {
178 if(m_options.testFlag(QChart::SeriesAnimations)) {
174 m_animator->addAnimation(bar);
179 m_animator->addAnimation(bar);
175 }
180 }
176 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
181 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
177 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
182 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
178 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
183 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
179 item=bar;
184 item=bar;
180 break;
185 break;
181 }
186 }
182
187
183 case QSeries::SeriesTypePercentBar: {
188 case QSeries::SeriesTypePercentBar: {
184 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
189 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
185 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
190 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
186 if(m_options.testFlag(QChart::SeriesAnimations)) {
191 if(m_options.testFlag(QChart::SeriesAnimations)) {
187 m_animator->addAnimation(bar);
192 m_animator->addAnimation(bar);
188 }
193 }
189 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
194 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
190 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
195 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
191 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
196 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
192 item=bar;
197 item=bar;
193 break;
198 break;
194 }
199 }
195
200
196 case QSeries::SeriesTypeScatter: {
201 case QSeries::SeriesTypeScatter: {
197 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
202 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
198 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
203 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
199 if(m_options.testFlag(QChart::SeriesAnimations)) {
204 if(m_options.testFlag(QChart::SeriesAnimations)) {
200 m_animator->addAnimation(scatter);
205 m_animator->addAnimation(scatter);
201 }
206 }
202 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
207 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
203 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
208 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
204 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
209 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
205 item = scatter;
210 item = scatter;
206 break;
211 break;
207 }
212 }
208
213
209 case QSeries::SeriesTypePie: {
214 case QSeries::SeriesTypePie: {
210 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
215 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
211 PieChartItem* pie = new PieChartItem(pieSeries, this);
216 PieChartItem* pie = new PieChartItem(pieSeries, this);
212 if(m_options.testFlag(QChart::SeriesAnimations)) {
217 if(m_options.testFlag(QChart::SeriesAnimations)) {
213 m_animator->addAnimation(pie);
218 m_animator->addAnimation(pie);
214 }
219 }
215 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
220 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
216 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
221 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
217 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
222 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
218 // Hide all from background when there is only piechart
223 // Hide all from background when there is only piechart
219 // TODO: refactor this ugly code... should be one setting for this
224 // TODO: refactor this ugly code... should be one setting for this
220 if (m_chartItems.count() == 0) {
225 if (m_chartItems.count() == 0) {
221 m_chart->axisX()->hide();
226 m_chart->axisX()->hide();
222 m_chart->axisY()->hide();
227 m_chart->axisY()->hide();
223 }
228 }
224 item=pie;
229 item=pie;
225 break;
230 break;
226 }
231 }
227
232
228 case QSeries::SeriesTypeSpline: {
233 case QSeries::SeriesTypeSpline: {
229 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
234 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
230 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
235 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
231 if(m_options.testFlag(QChart::SeriesAnimations)) {
236 if(m_options.testFlag(QChart::SeriesAnimations)) {
232 m_animator->addAnimation(spline);
237 m_animator->addAnimation(spline);
233 }
238 }
234 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
239 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
235 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
240 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
236 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
241 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
237 item=spline;
242 item=spline;
238 break;
243 break;
239 }
244 }
240 default: {
245 default: {
241 qDebug()<< "Series type" << series->type() << "not implemented.";
246 qDebug()<< "Series type" << series->type() << "not implemented.";
242 break;
247 break;
243 }
248 }
244 }
249 }
245
250
246 //initialize
251 //initialize
247 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
252 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
248 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
253 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
249 m_chartItems.insert(series,item);
254 m_chartItems.insert(series,item);
250 }
255 }
251
256
252 void ChartPresenter::handleSeriesRemoved(QSeries* series)
257 void ChartPresenter::handleSeriesRemoved(QSeries* series)
253 {
258 {
254 Chart* item = m_chartItems.take(series);
259 Chart* item = m_chartItems.take(series);
255 Q_ASSERT(item);
260 Q_ASSERT(item);
256 if(m_animator) {
261 if(m_animator) {
257 //small hack to handle area animations
262 //small hack to handle area animations
258 if(series->type()==QSeries::SeriesTypeArea){
263 if(series->type()==QSeries::SeriesTypeArea){
259 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
264 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
260 AreaChartItem* area = static_cast<AreaChartItem*>(item);
265 AreaChartItem* area = static_cast<AreaChartItem*>(item);
261 m_animator->removeAnimation(area->upperLineItem());
266 m_animator->removeAnimation(area->upperLineItem());
262 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
267 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
263 }else
268 }else
264 m_animator->removeAnimation(item);
269 m_animator->removeAnimation(item);
265 }
270 }
266 delete item;
271 delete item;
267 }
272 }
268
273
269 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
274 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
270 {
275 {
271 if(m_chartTheme && m_chartTheme->id() == theme) return;
276 if(m_chartTheme && m_chartTheme->id() == theme) return;
272 delete m_chartTheme;
277 delete m_chartTheme;
273 m_themeForce = force;
278 m_themeForce = force;
274 m_chartTheme = ChartTheme::createTheme(theme);
279 m_chartTheme = ChartTheme::createTheme(theme);
275 m_chartTheme->decorate(m_chart,m_themeForce);
280 m_chartTheme->decorate(m_chart,m_themeForce);
276 m_chartTheme->decorate(&m_chart->legend(),m_themeForce);
281 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
277 resetAllElements();
282 resetAllElements();
278 }
283 }
279
284
280 QChart::ChartTheme ChartPresenter::theme()
285 QChart::ChartTheme ChartPresenter::theme()
281 {
286 {
282 return m_chartTheme->id();
287 return m_chartTheme->id();
283 }
288 }
284
289
285 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
290 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
286 {
291 {
287 if(m_options!=options) {
292 if(m_options!=options) {
288
293
289 m_options=options;
294 m_options=options;
290
295
291 if(m_options!=QChart::NoAnimation && !m_animator) {
296 if(m_options!=QChart::NoAnimation && !m_animator) {
292 m_animator= new ChartAnimator(this);
297 m_animator= new ChartAnimator(this);
293
298
294 }
299 }
295 resetAllElements();
300 resetAllElements();
296 }
301 }
297
302
298 }
303 }
299
304
300 void ChartPresenter::resetAllElements()
305 void ChartPresenter::resetAllElements()
301 {
306 {
302 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
307 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
303 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
308 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
304
309
305 foreach(QChartAxis* axis, axisList) {
310 foreach(QChartAxis* axis, axisList) {
306 handleAxisRemoved(axis);
311 handleAxisRemoved(axis);
307 handleAxisAdded(axis,m_dataset->domain(axis));
312 handleAxisAdded(axis,m_dataset->domain(axis));
308 }
313 }
309 foreach(QSeries* series, seriesList) {
314 foreach(QSeries* series, seriesList) {
310 handleSeriesRemoved(series);
315 handleSeriesRemoved(series);
311 handleSeriesAdded(series,m_dataset->domain(series));
316 handleSeriesAdded(series,m_dataset->domain(series));
312 }
317 }
313 }
318 }
314
319
315 void ChartPresenter::zoomIn()
320 void ChartPresenter::zoomIn()
316 {
321 {
317 QRectF rect = geometry();
322 QRectF rect = geometry();
318 rect.setWidth(rect.width()/2);
323 rect.setWidth(rect.width()/2);
319 rect.setHeight(rect.height()/2);
324 rect.setHeight(rect.height()/2);
320 rect.moveCenter(geometry().center());
325 rect.moveCenter(geometry().center());
321 zoomIn(rect);
326 zoomIn(rect);
322 }
327 }
323
328
324 void ChartPresenter::zoomIn(const QRectF& rect)
329 void ChartPresenter::zoomIn(const QRectF& rect)
325 {
330 {
326 QRectF r = rect.normalized();
331 QRectF r = rect.normalized();
327 r.translate(-m_padding, -m_padding);
332 r.translate(-m_padding, -m_padding);
328 if(m_animator) {
333 if(m_animator) {
329
334
330 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
335 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
331 m_animator->setState(ChartAnimator::ZoomInState,point);
336 m_animator->setState(ChartAnimator::ZoomInState,point);
332 }
337 }
333 m_dataset->zoomInDomain(r,geometry().size());
338 m_dataset->zoomInDomain(r,geometry().size());
334 if(m_animator) {
339 if(m_animator) {
335 m_animator->setState(ChartAnimator::ShowState);
340 m_animator->setState(ChartAnimator::ShowState);
336 }
341 }
337 }
342 }
338
343
339 void ChartPresenter::zoomOut()
344 void ChartPresenter::zoomOut()
340 {
345 {
341 if(m_animator)
346 if(m_animator)
342 {
347 {
343 m_animator->setState(ChartAnimator::ZoomOutState);
348 m_animator->setState(ChartAnimator::ZoomOutState);
344 }
349 }
345
350
346 QSizeF size = geometry().size();
351 QSizeF size = geometry().size();
347 QRectF rect = geometry();
352 QRectF rect = geometry();
348 rect.translate(-m_padding, -m_padding);
353 rect.translate(-m_padding, -m_padding);
349 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
354 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
350 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
355 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
351
356
352 if(m_animator){
357 if(m_animator){
353 m_animator->setState(ChartAnimator::ShowState);
358 m_animator->setState(ChartAnimator::ShowState);
354 }
359 }
355 }
360 }
356
361
357 void ChartPresenter::scroll(int dx,int dy)
362 void ChartPresenter::scroll(int dx,int dy)
358 {
363 {
359 if(m_animator){
364 if(m_animator){
360 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
365 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
361 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
366 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
362 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
367 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
363 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
368 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
364 }
369 }
365
370
366 m_dataset->scrollDomain(dx,dy,geometry().size());
371 m_dataset->scrollDomain(dx,dy,geometry().size());
367
372
368 if(m_animator){
373 if(m_animator){
369 m_animator->setState(ChartAnimator::ShowState);
374 m_animator->setState(ChartAnimator::ShowState);
370 }
375 }
371 }
376 }
372
377
373 QChart::AnimationOptions ChartPresenter::animationOptions() const
378 QChart::AnimationOptions ChartPresenter::animationOptions() const
374 {
379 {
375 return m_options;
380 return m_options;
376 }
381 }
377
382
378
383
379 #include "moc_chartpresenter_p.cpp"
384 #include "moc_chartpresenter_p.cpp"
380
385
381 QTCOMMERCIALCHART_END_NAMESPACE
386 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,372 +1,372
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartview.h"
3 #include "qchartview.h"
4 #include "qlegend.h"
4 #include "qlegend.h"
5 #include "qchartaxis.h"
5 #include "qchartaxis.h"
6 #include <QTime>
6 #include <QTime>
7
7
8 //series
8 //series
9 #include "qbarset.h"
9 #include "qbarset.h"
10 #include "qbarseries.h"
10 #include "qbarseries.h"
11 #include "qstackedbarseries.h"
11 #include "qstackedbarseries.h"
12 #include "qpercentbarseries.h"
12 #include "qpercentbarseries.h"
13 #include "qlineseries.h"
13 #include "qlineseries.h"
14 #include "qareaseries.h"
14 #include "qareaseries.h"
15 #include "qscatterseries.h"
15 #include "qscatterseries.h"
16 #include "qpieseries.h"
16 #include "qpieseries.h"
17 #include "qpieslice.h"
17 #include "qpieslice.h"
18 #include "qsplineseries.h"
18 #include "qsplineseries.h"
19
19
20 //items
20 //items
21 #include "axisitem_p.h"
21 #include "axisitem_p.h"
22 #include "barchartitem_p.h"
22 #include "barchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
24 #include "percentbarchartitem_p.h"
24 #include "percentbarchartitem_p.h"
25 #include "linechartitem_p.h"
25 #include "linechartitem_p.h"
26 #include "areachartitem_p.h"
26 #include "areachartitem_p.h"
27 #include "scatterchartitem_p.h"
27 #include "scatterchartitem_p.h"
28 #include "piechartitem_p.h"
28 #include "piechartitem_p.h"
29 #include "splinechartitem_p.h"
29 #include "splinechartitem_p.h"
30
30
31 //themes
31 //themes
32 #include "chartthemedefault_p.h"
32 #include "chartthemedefault_p.h"
33 #include "chartthemelight_p.h"
33 #include "chartthemelight_p.h"
34 #include "chartthemebluecerulean_p.h"
34 #include "chartthemebluecerulean_p.h"
35 #include "chartthemedark_p.h"
35 #include "chartthemedark_p.h"
36 #include "chartthemebrownsand_p.h"
36 #include "chartthemebrownsand_p.h"
37 #include "chartthemebluencs_p.h"
37 #include "chartthemebluencs_p.h"
38 #include "chartthemehighcontrast_p.h"
38 #include "chartthemehighcontrast_p.h"
39 #include "chartthemeblueicy_p.h"
39 #include "chartthemeblueicy_p.h"
40
40
41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42
42
43 ChartTheme::ChartTheme(QChart::ChartTheme id) :
43 ChartTheme::ChartTheme(QChart::ChartTheme id) :
44 m_masterFont(QFont("arial", 12)),
44 m_masterFont(QFont("arial", 12)),
45 m_labelFont(QFont("arial", 10)),
45 m_labelFont(QFont("arial", 10)),
46 m_titleBrush(QColor(QRgb(0x000000))),
46 m_titleBrush(QColor(QRgb(0x000000))),
47 m_axisLinePen(QPen(QRgb(0x000000))),
47 m_axisLinePen(QPen(QRgb(0x000000))),
48 m_axisLabelBrush(QColor(QRgb(0x000000))),
48 m_axisLabelBrush(QColor(QRgb(0x000000))),
49 m_backgroundShadesPen(Qt::NoPen),
49 m_backgroundShadesPen(Qt::NoPen),
50 m_backgroundShadesBrush(Qt::NoBrush),
50 m_backgroundShadesBrush(Qt::NoBrush),
51 m_backgroundShades(BackgroundShadesNone),
51 m_backgroundShades(BackgroundShadesNone),
52 m_gridLinePen(QPen(QRgb(0x000000)))
52 m_gridLinePen(QPen(QRgb(0x000000)))
53 {
53 {
54 m_id = id;
54 m_id = id;
55 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
55 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
56 }
56 }
57
57
58
58
59 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
59 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
60 {
60 {
61 switch(theme) {
61 switch(theme) {
62 case QChart::ChartThemeLight:
62 case QChart::ChartThemeLight:
63 return new ChartThemeLight();
63 return new ChartThemeLight();
64 case QChart::ChartThemeBlueCerulean:
64 case QChart::ChartThemeBlueCerulean:
65 return new ChartThemeBlueCerulean();
65 return new ChartThemeBlueCerulean();
66 case QChart::ChartThemeDark:
66 case QChart::ChartThemeDark:
67 return new ChartThemeDark();
67 return new ChartThemeDark();
68 case QChart::ChartThemeBrownSand:
68 case QChart::ChartThemeBrownSand:
69 return new ChartThemeBrownSand();
69 return new ChartThemeBrownSand();
70 case QChart::ChartThemeBlueNcs:
70 case QChart::ChartThemeBlueNcs:
71 return new ChartThemeBlueNcs();
71 return new ChartThemeBlueNcs();
72 case QChart::ChartThemeHighContrast:
72 case QChart::ChartThemeHighContrast:
73 return new ChartThemeHighContrast();
73 return new ChartThemeHighContrast();
74 case QChart::ChartThemeBlueIcy:
74 case QChart::ChartThemeBlueIcy:
75 return new ChartThemeBlueIcy();
75 return new ChartThemeBlueIcy();
76 default:
76 default:
77 return new ChartThemeDefault();
77 return new ChartThemeDefault();
78 }
78 }
79 }
79 }
80
80
81 void ChartTheme::decorate(QChart* chart,bool force)
81 void ChartTheme::decorate(QChart* chart,bool force)
82 {
82 {
83 QBrush brush;
83 QBrush brush;
84
84
85 if(brush == chart->backgroundBrush() || force)
85 if(brush == chart->backgroundBrush() || force)
86 chart->setBackgroundBrush(m_chartBackgroundGradient);
86 chart->setBackgroundBrush(m_chartBackgroundGradient);
87 chart->setTitleFont(m_masterFont);
87 chart->setTitleFont(m_masterFont);
88 chart->setTitleBrush(m_titleBrush);
88 chart->setTitleBrush(m_titleBrush);
89 }
89 }
90
90
91 void ChartTheme::decorate(QLegend* legend,bool force)
91 void ChartTheme::decorate(QLegend* legend,bool force)
92 {
92 {
93 QPen pen;
93 QPen pen;
94 QBrush brush;
94 QBrush brush;
95
95
96 if (pen == legend->pen() || force){
96 if (pen == legend->pen() || force){
97 //TODO:: legend->setPen();
97 legend->setPen(Qt::NoPen);
98 }
98 }
99
99
100
100
101 if (brush == legend->brush() || force) {
101 if (brush == legend->brush() || force) {
102 legend->setBrush(m_chartBackgroundGradient);
102 legend->setBrush(m_chartBackgroundGradient);
103 }
103 }
104 }
104 }
105
105
106 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
106 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
107 {
107 {
108 QPen pen;
108 QPen pen;
109 QBrush brush;
109 QBrush brush;
110
110
111 if (pen == series->pen() || force){
111 if (pen == series->pen() || force){
112 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
112 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
113 pen.setWidthF(2);
113 pen.setWidthF(2);
114 series->setPen(pen);
114 series->setPen(pen);
115 }
115 }
116
116
117 if (brush == series->brush() || force) {
117 if (brush == series->brush() || force) {
118 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
118 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
119 series->setBrush(brush);
119 series->setBrush(brush);
120 }
120 }
121 }
121 }
122
122
123
123
124 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
124 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
125 {
125 {
126 QPen pen;
126 QPen pen;
127 if(pen == series->pen() || force ){
127 if(pen == series->pen() || force ){
128 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
128 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
129 pen.setWidthF(2);
129 pen.setWidthF(2);
130 series->setPen(pen);
130 series->setPen(pen);
131 }
131 }
132 }
132 }
133
133
134 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
134 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
135 {
135 {
136 QBrush brush;
136 QBrush brush;
137 QPen pen;
137 QPen pen;
138 QList<QBarSet*> sets = series->barSets();
138 QList<QBarSet*> sets = series->barSets();
139
139
140 qreal takeAtPos = 0.5;
140 qreal takeAtPos = 0.5;
141 qreal step = 0.2;
141 qreal step = 0.2;
142 if (sets.count() > 1 ) {
142 if (sets.count() > 1 ) {
143 step = 1.0 / (qreal) sets.count();
143 step = 1.0 / (qreal) sets.count();
144 if (sets.count() % m_seriesGradients.count())
144 if (sets.count() % m_seriesGradients.count())
145 step *= m_seriesGradients.count();
145 step *= m_seriesGradients.count();
146 else
146 else
147 step *= (m_seriesGradients.count() - 1);
147 step *= (m_seriesGradients.count() - 1);
148 }
148 }
149
149
150 for (int i(0); i < sets.count(); i++) {
150 for (int i(0); i < sets.count(); i++) {
151 int colorIndex = (index + i) % m_seriesGradients.count();
151 int colorIndex = (index + i) % m_seriesGradients.count();
152 if (i > 0 && i % m_seriesGradients.count() == 0) {
152 if (i > 0 && i % m_seriesGradients.count() == 0) {
153 // There is no dedicated base color for each sets, generate more colors
153 // There is no dedicated base color for each sets, generate more colors
154 takeAtPos += step;
154 takeAtPos += step;
155 if (takeAtPos == 1.0)
155 if (takeAtPos == 1.0)
156 takeAtPos += step;
156 takeAtPos += step;
157 takeAtPos -= (int) takeAtPos;
157 takeAtPos -= (int) takeAtPos;
158 }
158 }
159 qDebug() << "pos:" << takeAtPos;
159 qDebug() << "pos:" << takeAtPos;
160 if (brush == sets.at(i)->brush() || force )
160 if (brush == sets.at(i)->brush() || force )
161 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
161 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
162
162
163 // Pick label color from the opposite end of the gradient.
163 // Pick label color from the opposite end of the gradient.
164 // 0.3 as a boundary seems to work well.
164 // 0.3 as a boundary seems to work well.
165 if (takeAtPos < 0.3)
165 if (takeAtPos < 0.3)
166 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
166 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
167 else
167 else
168 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
168 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
169
169
170 if (pen == sets.at(i)->pen() || force) {
170 if (pen == sets.at(i)->pen() || force) {
171 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
171 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
172 sets.at(i)->setPen(c);
172 sets.at(i)->setPen(c);
173 }
173 }
174 }
174 }
175 }
175 }
176
176
177 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
177 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
178 {
178 {
179 QPen pen;
179 QPen pen;
180 QBrush brush;
180 QBrush brush;
181
181
182 if (pen == series->pen() || force) {
182 if (pen == series->pen() || force) {
183 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
183 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
184 pen.setWidthF(2);
184 pen.setWidthF(2);
185 series->setPen(pen);
185 series->setPen(pen);
186 }
186 }
187
187
188 if (brush == series->brush() || force) {
188 if (brush == series->brush() || force) {
189 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
189 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
190 series->setBrush(brush);
190 series->setBrush(brush);
191 }
191 }
192 }
192 }
193
193
194 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
194 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
195 {
195 {
196 for (int i(0); i < series->slices().count(); i++) {
196 for (int i(0); i < series->slices().count(); i++) {
197
197
198 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
198 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
199
199
200 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
200 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
201 qreal pos = (qreal) (i + 1) / (qreal) series->count();
201 qreal pos = (qreal) (i + 1) / (qreal) series->count();
202 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
202 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
203
203
204 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
204 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
205 PieSliceData data = s->m_data;
205 PieSliceData data = s->m_data;
206
206
207 if (data.m_slicePen.isThemed() || force) {
207 if (data.m_slicePen.isThemed() || force) {
208 data.m_slicePen = penColor;
208 data.m_slicePen = penColor;
209 data.m_slicePen.setThemed(true);
209 data.m_slicePen.setThemed(true);
210 }
210 }
211
211
212 if (data.m_sliceBrush.isThemed() || force) {
212 if (data.m_sliceBrush.isThemed() || force) {
213 data.m_sliceBrush = brushColor;
213 data.m_sliceBrush = brushColor;
214 data.m_sliceBrush.setThemed(true);
214 data.m_sliceBrush.setThemed(true);
215 }
215 }
216
216
217 if (data.m_labelPen.isThemed() || force) {
217 if (data.m_labelPen.isThemed() || force) {
218 data.m_labelPen = QPen(m_titleBrush.color());
218 data.m_labelPen = QPen(m_titleBrush.color());
219 data.m_labelPen.setThemed(true);
219 data.m_labelPen.setThemed(true);
220 }
220 }
221
221
222 if (data.m_labelFont.isThemed() || force) {
222 if (data.m_labelFont.isThemed() || force) {
223 data.m_labelFont = m_labelFont;
223 data.m_labelFont = m_labelFont;
224 data.m_labelFont.setThemed(true);
224 data.m_labelFont.setThemed(true);
225 }
225 }
226
226
227 if (s->m_data != data) {
227 if (s->m_data != data) {
228 s->m_data = data;
228 s->m_data = data;
229 emit s->changed();
229 emit s->changed();
230 }
230 }
231 }
231 }
232 }
232 }
233
233
234 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
234 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
235 {
235 {
236 QPen pen;
236 QPen pen;
237 if(pen == series->pen() || force){
237 if(pen == series->pen() || force){
238 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
238 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
239 pen.setWidthF(2);
239 pen.setWidthF(2);
240 series->setPen(pen);
240 series->setPen(pen);
241 }
241 }
242 }
242 }
243
243
244 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
244 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
245 {
245 {
246 QPen pen;
246 QPen pen;
247 QBrush brush;
247 QBrush brush;
248 QFont font;
248 QFont font;
249
249
250 if (axis->isAxisVisible()) {
250 if (axis->isAxisVisible()) {
251
251
252 if(brush == axis->labelsBrush() || force){
252 if(brush == axis->labelsBrush() || force){
253 axis->setLabelsBrush(m_axisLabelBrush);
253 axis->setLabelsBrush(m_axisLabelBrush);
254 }
254 }
255 if(pen == axis->labelsPen() || force){
255 if(pen == axis->labelsPen() || force){
256 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
256 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
257 }
257 }
258
258
259
259
260 if (axis->shadesVisible() || force) {
260 if (axis->shadesVisible() || force) {
261
261
262 if(brush == axis->shadesBrush() || force){
262 if(brush == axis->shadesBrush() || force){
263 axis->setShadesBrush(m_backgroundShadesBrush);
263 axis->setShadesBrush(m_backgroundShadesBrush);
264 }
264 }
265
265
266 if(pen == axis->shadesPen() || force){
266 if(pen == axis->shadesPen() || force){
267 axis->setShadesPen(m_backgroundShadesPen);
267 axis->setShadesPen(m_backgroundShadesPen);
268 }
268 }
269
269
270 if(force && (m_backgroundShades == BackgroundShadesBoth
270 if(force && (m_backgroundShades == BackgroundShadesBoth
271 || (m_backgroundShades == BackgroundShadesVertical && axisX)
271 || (m_backgroundShades == BackgroundShadesVertical && axisX)
272 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
272 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
273 axis->setShadesVisible(true);
273 axis->setShadesVisible(true);
274
274
275 }
275 }
276 }
276 }
277
277
278 if(pen == axis->axisPen() || force){
278 if(pen == axis->axisPen() || force){
279 axis->setAxisPen(m_axisLinePen);
279 axis->setAxisPen(m_axisLinePen);
280 }
280 }
281
281
282 if(pen == axis->gridLinePen() || force){
282 if(pen == axis->gridLinePen() || force){
283 axis->setGridLinePen(m_gridLinePen);
283 axis->setGridLinePen(m_gridLinePen);
284 }
284 }
285
285
286 if(font == axis->labelsFont() || force){
286 if(font == axis->labelsFont() || force){
287 axis->setLabelsFont(m_labelFont);
287 axis->setLabelsFont(m_labelFont);
288 }
288 }
289 }
289 }
290 }
290 }
291
291
292 void ChartTheme::generateSeriesGradients()
292 void ChartTheme::generateSeriesGradients()
293 {
293 {
294 // Generate gradients in HSV color space
294 // Generate gradients in HSV color space
295 foreach (QColor color, m_seriesColors) {
295 foreach (QColor color, m_seriesColors) {
296 QLinearGradient g;
296 QLinearGradient g;
297 qreal h = color.hsvHueF();
297 qreal h = color.hsvHueF();
298 qreal s = color.hsvSaturationF();
298 qreal s = color.hsvSaturationF();
299
299
300 // TODO: tune the algorithm to give nice results with most base colors defined in
300 // TODO: tune the algorithm to give nice results with most base colors defined in
301 // most themes. The rest of the gradients we can define manually in theme specific
301 // most themes. The rest of the gradients we can define manually in theme specific
302 // implementation.
302 // implementation.
303 QColor start = color;
303 QColor start = color;
304 start.setHsvF(h, 0.0, 1.0);
304 start.setHsvF(h, 0.0, 1.0);
305 g.setColorAt(0.0, start);
305 g.setColorAt(0.0, start);
306
306
307 g.setColorAt(0.5, color);
307 g.setColorAt(0.5, color);
308
308
309 QColor end = color;
309 QColor end = color;
310 end.setHsvF(h, s, 0.25);
310 end.setHsvF(h, s, 0.25);
311 g.setColorAt(1.0, end);
311 g.setColorAt(1.0, end);
312
312
313 m_seriesGradients << g;
313 m_seriesGradients << g;
314 }
314 }
315 }
315 }
316
316
317
317
318 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
318 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
319 {
319 {
320 Q_ASSERT(pos >=0.0 && pos <= 1.0);
320 Q_ASSERT(pos >=0.0 && pos <= 1.0);
321 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
321 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
322 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
322 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
323 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
323 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
324 QColor c;
324 QColor c;
325 c.setRgbF(r, g, b);
325 c.setRgbF(r, g, b);
326 return c;
326 return c;
327 }
327 }
328
328
329 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
329 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
330 {
330 {
331 Q_ASSERT(pos >=0 && pos <= 1.0);
331 Q_ASSERT(pos >=0 && pos <= 1.0);
332
332
333 // another possibility:
333 // another possibility:
334 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
334 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
335
335
336 QGradientStops stops = gradient.stops();
336 QGradientStops stops = gradient.stops();
337 int count = stops.count();
337 int count = stops.count();
338
338
339 // find previous stop relative to position
339 // find previous stop relative to position
340 QGradientStop prev = stops.first();
340 QGradientStop prev = stops.first();
341 for (int i=0; i<count; i++) {
341 for (int i=0; i<count; i++) {
342 QGradientStop stop = stops.at(i);
342 QGradientStop stop = stops.at(i);
343 if (pos > stop.first)
343 if (pos > stop.first)
344 prev = stop;
344 prev = stop;
345
345
346 // given position is actually a stop position?
346 // given position is actually a stop position?
347 if (pos == stop.first) {
347 if (pos == stop.first) {
348 //qDebug() << "stop color" << pos;
348 //qDebug() << "stop color" << pos;
349 return stop.second;
349 return stop.second;
350 }
350 }
351 }
351 }
352
352
353 // find next stop relative to position
353 // find next stop relative to position
354 QGradientStop next = stops.last();
354 QGradientStop next = stops.last();
355 for (int i=count-1; i>=0; i--) {
355 for (int i=count-1; i>=0; i--) {
356 QGradientStop stop = stops.at(i);
356 QGradientStop stop = stops.at(i);
357 if (pos < stop.first)
357 if (pos < stop.first)
358 next = stop;
358 next = stop;
359 }
359 }
360
360
361 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
361 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
362
362
363 qreal range = next.first - prev.first;
363 qreal range = next.first - prev.first;
364 qreal posDelta = pos - prev.first;
364 qreal posDelta = pos - prev.first;
365 qreal relativePos = posDelta / range;
365 qreal relativePos = posDelta / range;
366
366
367 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
367 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
368
368
369 return colorAt(prev.second, next.second, relativePos);
369 return colorAt(prev.second, next.second, relativePos);
370 }
370 }
371
371
372 QTCOMMERCIALCHART_END_NAMESPACE
372 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,458 +1,439
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 }
271
272 /*!
273 Gives ownership of legend to user.
274 */
275 QLegend* QChart::takeLegend()
276 {
277 QLegend* l = d_ptr->m_legend;
278 d_ptr->m_legend = 0;
279 return l;
280 }
281
282 /*!
283 Gives ownership of legend back to chart. QChart takes ownership of \a legend and deletes existing one
284 */
285 void QChart::giveLegend(QLegend *legend)
286 {
287 if (d_ptr->m_legend) {
288 // Should not happen.
289 qDebug() << "Warning! Giving more than one legend to chart.";
290 delete d_ptr->m_legend;
291 }
292
293 d_ptr->m_legend = legend;
294
295 // Reconnect legend, in case not already connected.
296 disconnect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
297 disconnect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*)));
298 connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
299 connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*)));
300 }
270 }
301
271
302 /*!
272 /*!
303 Resizes and updates the chart area using the \a event data
273 Resizes and updates the chart area using the \a event data
304 */
274 */
305 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
275 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
306 {
276 {
307 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
277 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
308 d_ptr->updateLayout();
278 d_ptr->updateLayout();
309 QGraphicsWidget::resizeEvent(event);
279 QGraphicsWidget::resizeEvent(event);
310 update();
280 update();
311 }
281 }
312
282
313 /*!
283 /*!
314 Sets animation \a options for the chart
284 Sets animation \a options for the chart
315 */
285 */
316 void QChart::setAnimationOptions(AnimationOptions options)
286 void QChart::setAnimationOptions(AnimationOptions options)
317 {
287 {
318 d_ptr->m_presenter->setAnimationOptions(options);
288 d_ptr->m_presenter->setAnimationOptions(options);
319 }
289 }
320
290
321 /*!
291 /*!
322 Returns animation options for the chart
292 Returns animation options for the chart
323 */
293 */
324 QChart::AnimationOptions QChart::animationOptions() const
294 QChart::AnimationOptions QChart::animationOptions() const
325 {
295 {
326 return d_ptr->m_presenter->animationOptions();
296 return d_ptr->m_presenter->animationOptions();
327 }
297 }
328
298
329 void QChart::scrollLeft()
299 void QChart::scrollLeft()
330 {
300 {
331 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);
332 }
302 }
333
303
334 void QChart::scrollRight()
304 void QChart::scrollRight()
335 {
305 {
336 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);
337 }
307 }
338
308
339 void QChart::scrollUp()
309 void QChart::scrollUp()
340 {
310 {
341 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));
342 }
312 }
343
313
344 void QChart::scrollDown()
314 void QChart::scrollDown()
345 {
315 {
346 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));
347 }
317 }
348
318
349 void QChart::setBackgroundVisible(bool visible)
319 void QChart::setBackgroundVisible(bool visible)
350 {
320 {
351 d_ptr->createChartBackgroundItem();
321 d_ptr->createChartBackgroundItem();
352 d_ptr->m_backgroundItem->setVisible(visible);
322 d_ptr->m_backgroundItem->setVisible(visible);
353 }
323 }
354
324
355 bool QChart::isBackgroundVisible() const
325 bool QChart::isBackgroundVisible() const
356 {
326 {
357 if (!d_ptr->m_backgroundItem) return false;
327 if (!d_ptr->m_backgroundItem) return false;
358 return d_ptr->m_backgroundItem->isVisible();
328 return d_ptr->m_backgroundItem->isVisible();
359 }
329 }
360
330
361 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
331 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
362
332
363 QChartPrivate::QChartPrivate(QChart *parent):
333 QChartPrivate::QChartPrivate(QChart *parent):
364 q_ptr(parent),
334 q_ptr(parent),
365 m_backgroundItem(0),
335 m_backgroundItem(0),
366 m_titleItem(0),
336 m_titleItem(0),
367 m_legend(0),
337 m_legend(0),
368 m_dataset(0),
338 m_dataset(0),
369 m_presenter(0)
339 m_presenter(0)
370 {
340 {
371
341
372 }
342 }
373
343
374 QChartPrivate::~QChartPrivate()
344 QChartPrivate::~QChartPrivate()
375 {
345 {
376
346
377 }
347 }
378
348
379 void QChartPrivate::createChartBackgroundItem()
349 void QChartPrivate::createChartBackgroundItem()
380 {
350 {
381 if (!m_backgroundItem) {
351 if (!m_backgroundItem) {
382 m_backgroundItem = new ChartBackground(q_ptr);
352 m_backgroundItem = new ChartBackground(q_ptr);
383 m_backgroundItem->setPen(Qt::NoPen);
353 m_backgroundItem->setPen(Qt::NoPen);
384 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
354 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
385 }
355 }
386 }
356 }
387
357
388 void QChartPrivate::createChartTitleItem()
358 void QChartPrivate::createChartTitleItem()
389 {
359 {
390 if (!m_titleItem) {
360 if (!m_titleItem) {
391 m_titleItem = new QGraphicsSimpleTextItem(q_ptr);
361 m_titleItem = new QGraphicsSimpleTextItem(q_ptr);
392 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
362 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
393 }
363 }
394 }
364 }
395
365
396 void QChartPrivate::updateLegendLayout()
366 void QChartPrivate::updateLegendLayout()
397 {
367 {
398 int padding = m_presenter->padding();
368 int padding = m_presenter->padding();
399 QRectF plotRect = m_rect.adjusted(padding,padding,-padding,-padding);
369 QRectF plotRect = m_rect.adjusted(padding,padding,-padding,-padding);
400 QRectF legendRect;
370 QRectF legendRect;
401
371
402 switch (m_legend->alignment())
372 switch (m_legend->alignment())
403 {
373 {
404 case QLegend::LayoutTop: {
374 case QLegend::LayoutTop: {
405 legendRect = plotRect.adjusted(0,0,0,-padding - plotRect.height());
375 legendRect = plotRect.adjusted(0,0,0,-padding - plotRect.height());
406 break;
376 break;
407 }
377 }
408 case QLegend::LayoutBottom: {
378 case QLegend::LayoutBottom: {
409 legendRect = plotRect.adjusted(padding,padding + plotRect.height(),-padding,0);
379 legendRect = plotRect.adjusted(padding,padding + plotRect.height(),-padding,0);
410 break;
380 break;
411 }
381 }
412 case QLegend::LayoutLeft: {
382 case QLegend::LayoutLeft: {
413 legendRect = plotRect.adjusted(0,padding,-padding - plotRect.width(),-padding);
383 legendRect = plotRect.adjusted(0,padding,-padding - plotRect.width(),-padding);
414 break;
384 break;
415 }
385 }
416 case QLegend::LayoutRight: {
386 case QLegend::LayoutRight: {
417 legendRect = plotRect.adjusted(padding + plotRect.width(),padding,0,-padding);
387 legendRect = plotRect.adjusted(padding + plotRect.width(),padding,0,-padding);
418 break;
388 break;
419 }
389 }
420 default: {
390 default: {
421 legendRect = plotRect;
391 legendRect = plotRect;
422 break;
392 break;
423 }
393 }
424 }
394 }
425
395
426 m_legend->setMaximumSize(legendRect.size());
396 m_legend->setMaximumSize(legendRect.size());
427 m_legend->setPos(legendRect.topLeft());
397
398 qreal width = legendRect.width() - m_legend->size().width();
399 qreal height = legendRect.height() - m_legend->size().height();
400
401 QPointF pos = legendRect.topLeft();
402 if (width > 0) {
403 pos.setX(pos.x() + width/2);
404 }
405 if (height > 0) {
406 pos.setY(pos.y() + height/2);
407 }
408 m_legend->setPos(pos);
428 }
409 }
429
410
430 void QChartPrivate::updateLayout()
411 void QChartPrivate::updateLayout()
431 {
412 {
432 if (!m_rect.isValid()) return;
413 if (!m_rect.isValid()) return;
433
414
434 int padding = m_presenter->padding();
415 int padding = m_presenter->padding();
435 int backgroundPadding = m_presenter->backgroundPadding();
416 int backgroundPadding = m_presenter->backgroundPadding();
436
417
437 // recalculate title position
418 // recalculate title position
438 if (m_titleItem) {
419 if (m_titleItem) {
439 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
420 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
440 m_titleItem->setPos(center.x(),m_rect.top()/2 + padding/2);
421 m_titleItem->setPos(center.x(),m_rect.top()/2 + padding/2);
441 }
422 }
442
423
443 //recalculate background gradient
424 //recalculate background gradient
444 if (m_backgroundItem) {
425 if (m_backgroundItem) {
445 m_backgroundItem->setRect(m_rect.adjusted(backgroundPadding,backgroundPadding, -backgroundPadding, -backgroundPadding));
426 m_backgroundItem->setRect(m_rect.adjusted(backgroundPadding,backgroundPadding, -backgroundPadding, -backgroundPadding));
446 }
427 }
447
428
448 // recalculate legend position
429 // recalculate legend position
449 if (m_legend) {
430 if (m_legend) {
450 if (m_legend->parentObject() == q_ptr) {
431 if (m_legend->parentObject() == q_ptr) {
451 updateLegendLayout();
432 updateLegendLayout();
452 }
433 }
453 }
434 }
454 }
435 }
455
436
456 #include "moc_qchart.cpp"
437 #include "moc_qchart.cpp"
457
438
458 QTCOMMERCIALCHART_END_NAMESPACE
439 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,117 +1,115
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 QCHART_H
21 #ifndef QCHART_H
22 #define QCHART_H
22 #define QCHART_H
23
23
24 #include <QSeries>
24 #include <QSeries>
25 #include <QGraphicsWidget>
25 #include <QGraphicsWidget>
26
26
27 class QGraphicsSceneResizeEvent;
27 class QGraphicsSceneResizeEvent;
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 class QSeries;
31 class QSeries;
32 class QChartAxis;
32 class QChartAxis;
33 class QLegend;
33 class QLegend;
34 struct QChartPrivate;
34 struct QChartPrivate;
35
35
36 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
36 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
37 {
37 {
38 Q_OBJECT
38 Q_OBJECT
39 public:
39 public:
40 enum ChartTheme {
40 enum ChartTheme {
41 ChartThemeDefault,
41 ChartThemeDefault,
42 ChartThemeLight,
42 ChartThemeLight,
43 ChartThemeBlueCerulean,
43 ChartThemeBlueCerulean,
44 ChartThemeDark,
44 ChartThemeDark,
45 ChartThemeBrownSand,
45 ChartThemeBrownSand,
46 ChartThemeBlueNcs,
46 ChartThemeBlueNcs,
47 ChartThemeHighContrast,
47 ChartThemeHighContrast,
48 ChartThemeBlueIcy,
48 ChartThemeBlueIcy,
49 ChartThemeCount
49 ChartThemeCount
50 };
50 };
51
51
52 enum AnimationOption {
52 enum AnimationOption {
53 NoAnimation = 0x0,
53 NoAnimation = 0x0,
54 GridAxisAnimations = 0x1,
54 GridAxisAnimations = 0x1,
55 SeriesAnimations =0x2,
55 SeriesAnimations =0x2,
56 AllAnimations = 0x3
56 AllAnimations = 0x3
57 };
57 };
58
58
59 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
59 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
60
60
61 public:
61 public:
62 explicit QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
62 explicit QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
63 ~QChart();
63 ~QChart();
64
64
65 void addSeries(QSeries *series, QChartAxis *axisY = 0);
65 void addSeries(QSeries *series, QChartAxis *axisY = 0);
66 void removeSeries(QSeries *series);
66 void removeSeries(QSeries *series);
67 void removeAllSeries();
67 void removeAllSeries();
68
68
69 void setTheme(QChart::ChartTheme theme);
69 void setTheme(QChart::ChartTheme theme);
70 QChart::ChartTheme theme() const;
70 QChart::ChartTheme theme() const;
71
71
72 void setTitle(const QString& title);
72 void setTitle(const QString& title);
73 QString title() const;
73 QString title() const;
74 void setTitleFont(const QFont& font);
74 void setTitleFont(const QFont& font);
75 QFont titleFont() const;
75 QFont titleFont() const;
76 void setTitleBrush(const QBrush &brush);
76 void setTitleBrush(const QBrush &brush);
77 QBrush titleBrush() const;
77 QBrush titleBrush() const;
78 void setBackgroundBrush(const QBrush& brush);
78 void setBackgroundBrush(const QBrush &brush);
79 QBrush backgroundBrush() const;
79 QBrush backgroundBrush() const;
80 void setBackgroundPen(const QPen& pen);
80 void setBackgroundPen(const QPen &pen);
81 QPen backgroundPen() const;
81 QPen backgroundPen() const;
82
82
83 void setBackgroundVisible(bool visible);
83 void setBackgroundVisible(bool visible);
84 bool isBackgroundVisible() const;
84 bool isBackgroundVisible() const;
85
85
86 void setAnimationOptions(AnimationOptions options);
86 void setAnimationOptions(AnimationOptions options);
87 AnimationOptions animationOptions() const;
87 AnimationOptions animationOptions() const;
88
88
89 void zoomIn();
89 void zoomIn();
90 void zoomIn(const QRectF& rect);
90 void zoomIn(const QRectF &rect);
91 void zoomOut();
91 void zoomOut();
92 void scrollLeft();
92 void scrollLeft();
93 void scrollRight();
93 void scrollRight();
94 void scrollUp();
94 void scrollUp();
95 void scrollDown();
95 void scrollDown();
96
96
97 QChartAxis* axisX() const;
97 QChartAxis* axisX() const;
98 QChartAxis* axisY() const;
98 QChartAxis* axisY() const;
99
99
100 QLegend& legend() const;
100 QLegend* legend() const;
101 QLegend* takeLegend();
102 void giveLegend(QLegend* legend);
103
101
104 protected:
102 protected:
105 void resizeEvent(QGraphicsSceneResizeEvent *event);
103 void resizeEvent(QGraphicsSceneResizeEvent *event);
106
104
107 protected:
105 protected:
108 QScopedPointer<QChartPrivate> d_ptr;
106 QScopedPointer<QChartPrivate> d_ptr;
109 friend class QChartView;
107 friend class QChartView;
110 Q_DISABLE_COPY(QChart)
108 Q_DISABLE_COPY(QChart)
111 };
109 };
112
110
113 QTCOMMERCIALCHART_END_NAMESPACE
111 QTCOMMERCIALCHART_END_NAMESPACE
114
112
115 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
113 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
116
114
117 #endif
115 #endif
@@ -1,706 +1,706
1 #include "qchartglobal.h"
1 #include "qchartglobal.h"
2 #include "qlegend.h"
2 #include "qlegend.h"
3 #include "qseries.h"
3 #include "qseries.h"
4 #include "legendmarker_p.h"
4 #include "legendmarker_p.h"
5 #include "legendscrollbutton_p.h"
5 #include "legendscrollbutton_p.h"
6 #include "qxyseries.h"
6 #include "qxyseries.h"
7 #include "qlineseries.h"
7 #include "qlineseries.h"
8 #include "qareaseries.h"
8 #include "qareaseries.h"
9 #include "qscatterseries.h"
9 #include "qscatterseries.h"
10 #include "qsplineseries.h"
10 #include "qsplineseries.h"
11 #include "qbarseries.h"
11 #include "qbarseries.h"
12 #include "qstackedbarseries.h"
12 #include "qstackedbarseries.h"
13 #include "qpercentbarseries.h"
13 #include "qpercentbarseries.h"
14 #include "qbarset.h"
14 #include "qbarset.h"
15 #include "qpieseries.h"
15 #include "qpieseries.h"
16 #include "qpieslice.h"
16 #include "qpieslice.h"
17 #include "chartpresenter_p.h"
17 #include "chartpresenter_p.h"
18 #include <QPainter>
18 #include <QPainter>
19 #include <QPen>
19 #include <QPen>
20
20
21 #include <QGraphicsSceneEvent>
21 #include <QGraphicsSceneEvent>
22
22
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24
24
25 /*!
25 /*!
26 \class QLegend
26 \class QLegend
27 \brief part of QtCommercial chart API.
27 \brief part of QtCommercial chart API.
28
28
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
31 handle the drawing manually.
31 handle the drawing manually.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
33
33
34 \mainclass
34 \mainclass
35
35
36 \sa QChart, QSeries
36 \sa QChart, QSeries
37 */
37 */
38
38
39 /*!
39 /*!
40 \enum QLegend::Layout
40 \enum QLegend::Layout
41
41
42 This enum describes the possible position for legend inside chart.
42 This enum describes the possible position for legend inside chart.
43
43
44 \value LayoutTop
44 \value LayoutTop
45 \value LayoutBottom
45 \value LayoutBottom
46 \value LayoutLeft
46 \value LayoutLeft
47 \value LayoutRight
47 \value LayoutRight
48 */
48 */
49
49
50
50
51 /*!
51 /*!
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
53 \brief Notifies when series has been clicked on legend \a series \a button
53 \brief Notifies when series has been clicked on legend \a series \a button
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
58 \brief Notifies when barset has been clicked on legend \a barset \a button
58 \brief Notifies when barset has been clicked on legend \a barset \a button
59 */
59 */
60
60
61 /*!
61 /*!
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs the legend object and sets the parent to \a parent
67 Constructs the legend object and sets the parent to \a parent
68 */
68 */
69 QLegend::QLegend(QGraphicsItem *parent) : QGraphicsObject(parent),
69 QLegend::QLegend(QGraphicsItem *parent) : QGraphicsObject(parent),
70 m_margin(5),
70 m_pos(0,0),
71 m_pos(0,0),
71 m_size(0,0),
72 m_minimumSize(50,20), // TODO: magic numbers
72 m_minimumSize(50,20), // TODO: magic numbers
73 m_maximumSize(150,100),
73 m_maximumSize(150,100),
74 m_brush(Qt::darkGray), // TODO: from theme?
74 m_size(m_minimumSize),
75 m_brush(Qt::darkGray),
75 m_alignment(QLegend::LayoutTop),
76 m_alignment(QLegend::LayoutTop),
76 mFirstMarker(0),
77 mFirstMarker(0)
77 m_margin(5)
78 {
78 {
79 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
79 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
80 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
80 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
81 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
81 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
82 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
82 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
83
83
84 connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
84 connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
85 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
85 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
86 connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
86 connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
87 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
87 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
88 connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
88 connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
89 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
89 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
90 connect(m_scrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
90 connect(m_scrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
91 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
91 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
92
92
93 setZValue(ChartPresenter::LegendZValue);
93 setZValue(ChartPresenter::LegendZValue);
94 }
94 }
95
95
96 /*!
96 /*!
97 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
97 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
98 */
98 */
99 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
99 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
100 {
100 {
101 Q_UNUSED(option)
101 Q_UNUSED(option)
102 Q_UNUSED(widget)
102 Q_UNUSED(widget)
103
103
104 painter->setOpacity(opacity());
104 painter->setOpacity(opacity());
105 painter->setPen(m_pen);
105 painter->setPen(m_pen);
106 painter->setBrush(m_brush);
106 painter->setBrush(m_brush);
107 painter->drawRect(boundingRect());
107 painter->drawRect(boundingRect());
108 }
108 }
109
109
110 /*!
110 /*!
111 Bounding rect of legend.
111 Bounding rect of legend.
112 */
112 */
113 QRectF QLegend::boundingRect() const
113 QRectF QLegend::boundingRect() const
114 {
114 {
115 return QRectF(m_pos,m_size);
115 return QRectF(m_pos,m_size);
116 }
116 }
117
117
118 /*!
118 /*!
119 Sets the \a brush of legend. Brush affects the background of legend.
119 Sets the \a brush of legend. Brush affects the background of legend.
120 */
120 */
121 void QLegend::setBrush(const QBrush &brush)
121 void QLegend::setBrush(const QBrush &brush)
122 {
122 {
123 if (m_brush != brush) {
123 if (m_brush != brush) {
124 m_brush = brush;
124 m_brush = brush;
125 update();
125 update();
126 }
126 }
127 }
127 }
128
128
129 /*!
129 /*!
130 Returns the brush used by legend.
130 Returns the brush used by legend.
131 */
131 */
132 QBrush QLegend::brush() const
132 QBrush QLegend::brush() const
133 {
133 {
134 return m_brush;
134 return m_brush;
135 }
135 }
136
136
137 /*!
137 /*!
138 Sets the \a pen of legend. Pen affects the legend borders.
138 Sets the \a pen of legend. Pen affects the legend borders.
139 */
139 */
140 void QLegend::setPen(const QPen &pen)
140 void QLegend::setPen(const QPen &pen)
141 {
141 {
142 if (m_pen != pen) {
142 if (m_pen != pen) {
143 m_pen = pen;
143 m_pen = pen;
144 update();
144 update();
145 }
145 }
146 }
146 }
147
147
148 /*!
148 /*!
149 Returns the pen used by legend
149 Returns the pen used by legend
150 */
150 */
151
151
152 QPen QLegend::pen() const
152 QPen QLegend::pen() const
153 {
153 {
154 return m_pen;
154 return m_pen;
155 }
155 }
156
156
157 /*!
157 /*!
158 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
158 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
159 \sa QLegend::Layout
159 \sa QLegend::Layout
160 */
160 */
161 void QLegend::setAlignmnent(QLegend::Layout alignment)
161 void QLegend::setAlignmnent(QLegend::Layout alignment)
162 {
162 {
163 m_alignment = alignment;
163 m_alignment = alignment;
164 updateLayout();
164 updateLayout();
165 }
165 }
166
166
167 /*!
167 /*!
168 Returns the preferred layout for legend
168 Returns the preferred layout for legend
169 */
169 */
170 QLegend::Layout QLegend::alignment() const
170 QLegend::Layout QLegend::alignment() const
171 {
171 {
172 return m_alignment;
172 return m_alignment;
173 }
173 }
174
174
175 /*!
175 /*!
176 Returns the maximum size of legend.
176 Returns the maximum size of legend.
177 */
177 */
178 QSizeF QLegend::maximumSize() const
178 QSizeF QLegend::maximumSize() const
179 {
179 {
180 return m_maximumSize;
180 return m_maximumSize;
181 }
181 }
182
182
183 /*!
183 /*!
184 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
184 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
185 more series than legend can fit to this size, scroll buttons are displayed.
185 more series than legend can fit to this size, scroll buttons are displayed.
186 */
186 */
187 void QLegend::setMaximumSize(const QSizeF size)
187 void QLegend::setMaximumSize(const QSizeF size)
188 {
188 {
189 m_maximumSize = size;
189 m_maximumSize = size;
190 updateLayout();
190 updateLayout();
191 }
191 }
192
192
193 /*!
193 /*!
194 Returns the current size of legend.
194 Returns the current size of legend.
195 */
195 */
196 QSizeF QLegend::size() const
196 QSizeF QLegend::size() const
197 {
197 {
198 return m_size;
198 return m_size;
199 }
199 }
200
200
201 /*!
201 /*!
202 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
202 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
203 \sa setMmaximumSize()
203 \sa setMmaximumSize()
204 */
204 */
205 void QLegend::setSize(const QSizeF size)
205 void QLegend::setSize(const QSizeF size)
206 {
206 {
207 m_size = size;
207 m_size = size;
208 if (m_size.width() > m_maximumSize.width()) {
208 if (m_size.width() > m_maximumSize.width()) {
209 m_size.setWidth(m_maximumSize.width());
209 m_size.setWidth(m_maximumSize.width());
210 }
210 }
211 if (m_size.height() > m_maximumSize.height()) {
211 if (m_size.height() > m_maximumSize.height()) {
212 m_size.setHeight(m_maximumSize.height());
212 m_size.setHeight(m_maximumSize.height());
213 }
213 }
214 }
214 }
215
215
216 /*!
216 /*!
217 Sets position of legend to \a pos
217 Sets position of legend to \a pos
218 */
218 */
219 void QLegend::setPos(const QPointF &pos)
219 void QLegend::setPos(const QPointF &pos)
220 {
220 {
221 m_pos = pos;
221 m_pos = pos;
222 updateLayout();
222 updateLayout();
223 }
223 }
224
224
225 /*!
225 /*!
226 \internal \a series \a domain Should be called when series is added to chart.
226 \internal \a series \a domain Should be called when series is added to chart.
227 */
227 */
228 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
228 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
229 {
229 {
230 Q_UNUSED(domain)
230 Q_UNUSED(domain)
231
231
232 createMarkers(series);
232 createMarkers(series);
233 connectSeries(series);
233 connectSeries(series);
234 updateLayout();
234 updateLayout();
235 }
235 }
236
236
237 /*!
237 /*!
238 \internal \a series Should be called when series is removed from chart.
238 \internal \a series Should be called when series is removed from chart.
239 */
239 */
240 void QLegend::handleSeriesRemoved(QSeries *series)
240 void QLegend::handleSeriesRemoved(QSeries *series)
241 {
241 {
242 disconnectSeries(series);
242 disconnectSeries(series);
243
243
244 if (series->type() == QSeries::SeriesTypeArea) {
244 if (series->type() == QSeries::SeriesTypeArea) {
245 // This is special case. Area series has upper and lower series, which each have markers
245 // This is special case. Area series has upper and lower series, which each have markers
246 QAreaSeries* s = static_cast<QAreaSeries *> (series);
246 QAreaSeries* s = static_cast<QAreaSeries *> (series);
247 deleteMarkers(s->upperSeries());
247 deleteMarkers(s->upperSeries());
248 deleteMarkers(s->lowerSeries());
248 deleteMarkers(s->lowerSeries());
249 } else {
249 } else {
250 deleteMarkers(series);
250 deleteMarkers(series);
251 }
251 }
252
252
253 updateLayout();
253 updateLayout();
254 }
254 }
255
255
256 /*!
256 /*!
257 \internal \a slices Should be called when slices are added to pie chart.
257 \internal \a slices Should be called when slices are added to pie chart.
258 */
258 */
259 void QLegend::handleAdded(QList<QPieSlice *> slices)
259 void QLegend::handleAdded(QList<QPieSlice *> slices)
260 {
260 {
261 QPieSeries* series = static_cast<QPieSeries *> (sender());
261 QPieSeries* series = static_cast<QPieSeries *> (sender());
262 foreach(QPieSlice* s, slices) {
262 foreach(QPieSlice* s, slices) {
263 LegendMarker* marker = new LegendMarker(series, s, this);
263 LegendMarker* marker = new LegendMarker(series, s, this);
264 marker->setName(s->label());
264 marker->setName(s->label());
265 marker->setBrush(s->brush());
265 marker->setBrush(s->brush());
266 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
266 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
267 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
267 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
268 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
268 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
269 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
269 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
270 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
270 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
271 m_markers.append(marker);
271 m_markers.append(marker);
272 childItems().append(marker);
272 childItems().append(marker);
273 }
273 }
274 updateLayout();
274 updateLayout();
275 }
275 }
276
276
277 /*!
277 /*!
278 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
278 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
279 because removed slices are also deleted and we listen destroyed signal
279 because removed slices are also deleted and we listen destroyed signal
280 */
280 */
281 void QLegend::handleRemoved(QList<QPieSlice *> slices)
281 void QLegend::handleRemoved(QList<QPieSlice *> slices)
282 {
282 {
283 Q_UNUSED(slices)
283 Q_UNUSED(slices)
284 }
284 }
285
285
286
286
287 /*!
287 /*!
288 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
288 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
289 */
289 */
290 void QLegend::handleMarkerDestroyed()
290 void QLegend::handleMarkerDestroyed()
291 {
291 {
292 LegendMarker* m = static_cast<LegendMarker *> (sender());
292 LegendMarker* m = static_cast<LegendMarker *> (sender());
293 m_markers.removeOne(m);
293 m_markers.removeOne(m);
294 updateLayout();
294 updateLayout();
295 }
295 }
296
296
297 /*!
297 /*!
298 \internal \a event Handles clicked signals from scroll buttons
298 \internal \a event Handles clicked signals from scroll buttons
299 */
299 */
300 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
300 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
301 {
301 {
302 Q_UNUSED(event); // Maybe later something happens with right click...
302 Q_UNUSED(event); // Maybe later something happens with right click...
303
303
304 LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender());
304 LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender());
305 Q_ASSERT(scrollButton);
305 Q_ASSERT(scrollButton);
306
306
307 switch (scrollButton->id()) {
307 switch (scrollButton->id()) {
308 case LegendScrollButton::ScrollButtonIdLeft:
308 case LegendScrollButton::ScrollButtonIdLeft:
309 case LegendScrollButton::ScrollButtonIdUp: {
309 case LegendScrollButton::ScrollButtonIdUp: {
310 // Lower limit is same in these cases
310 // Lower limit is same in these cases
311 mFirstMarker--;
311 mFirstMarker--;
312 checkFirstMarkerBounds();
312 checkFirstMarkerBounds();
313 break;
313 break;
314 }
314 }
315 case LegendScrollButton::ScrollButtonIdRight:
315 case LegendScrollButton::ScrollButtonIdRight:
316 case LegendScrollButton::ScrollButtonIdDown: {
316 case LegendScrollButton::ScrollButtonIdDown: {
317 mFirstMarker++;
317 mFirstMarker++;
318 checkFirstMarkerBounds();
318 checkFirstMarkerBounds();
319 break;
319 break;
320 }
320 }
321 default: {
321 default: {
322 break;
322 break;
323 }
323 }
324 }
324 }
325 updateLayout();
325 updateLayout();
326 }
326 }
327
327
328 /*!
328 /*!
329 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
329 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
330 Not all series notify about events
330 Not all series notify about events
331 */
331 */
332 void QLegend::connectSeries(QSeries *series)
332 void QLegend::connectSeries(QSeries *series)
333 {
333 {
334 // Connect relevant signals from series. Currently only pie series has interesting signals
334 // Connect relevant signals from series. Currently only pie series has interesting signals
335 // TODO: bar chart may have
335 // TODO: bar chart may have
336 if (series->type() == QSeries::SeriesTypePie) {
336 if (series->type() == QSeries::SeriesTypePie) {
337 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
337 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
338 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
338 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
339 }
339 }
340 }
340 }
341
341
342 /*!
342 /*!
343 \internal Disconnects \a series from legend. No more status updates from series to legend.
343 \internal Disconnects \a series from legend. No more status updates from series to legend.
344 */
344 */
345 void QLegend::disconnectSeries(QSeries *series)
345 void QLegend::disconnectSeries(QSeries *series)
346 {
346 {
347 if (series->type() == QSeries::SeriesTypePie) {
347 if (series->type() == QSeries::SeriesTypePie) {
348 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
348 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
349 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
349 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
350 }
350 }
351 }
351 }
352
352
353 /*!
353 /*!
354 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
354 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
355 With pie chart, created markers depend on pie slices.
355 With pie chart, created markers depend on pie slices.
356 With bar chart, created markers depend on bar sets.
356 With bar chart, created markers depend on bar sets.
357 */
357 */
358 void QLegend::createMarkers(QSeries *series)
358 void QLegend::createMarkers(QSeries *series)
359 {
359 {
360 switch (series->type())
360 switch (series->type())
361 {
361 {
362 case QSeries::SeriesTypeLine: {
362 case QSeries::SeriesTypeLine: {
363 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
363 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
364 appendMarkers(lineSeries);
364 appendMarkers(lineSeries);
365 break;
365 break;
366 }
366 }
367 case QSeries::SeriesTypeArea: {
367 case QSeries::SeriesTypeArea: {
368 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
368 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
369 appendMarkers(areaSeries->upperSeries());
369 appendMarkers(areaSeries->upperSeries());
370 if(areaSeries->lowerSeries())
370 if(areaSeries->lowerSeries())
371 appendMarkers(areaSeries->lowerSeries());
371 appendMarkers(areaSeries->lowerSeries());
372 break;
372 break;
373 }
373 }
374 case QSeries::SeriesTypeBar: {
374 case QSeries::SeriesTypeBar: {
375 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
375 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
376 appendMarkers(barSeries);
376 appendMarkers(barSeries);
377 break;
377 break;
378 }
378 }
379 case QSeries::SeriesTypeStackedBar: {
379 case QSeries::SeriesTypeStackedBar: {
380 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
380 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
381 appendMarkers(stackedBarSeries);
381 appendMarkers(stackedBarSeries);
382 break;
382 break;
383 }
383 }
384 case QSeries::SeriesTypePercentBar: {
384 case QSeries::SeriesTypePercentBar: {
385 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
385 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
386 appendMarkers(percentBarSeries);
386 appendMarkers(percentBarSeries);
387 break;
387 break;
388 }
388 }
389 case QSeries::SeriesTypeScatter: {
389 case QSeries::SeriesTypeScatter: {
390 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
390 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
391 appendMarkers(scatterSeries);
391 appendMarkers(scatterSeries);
392 break;
392 break;
393 }
393 }
394 case QSeries::SeriesTypePie: {
394 case QSeries::SeriesTypePie: {
395 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
395 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
396 appendMarkers(pieSeries);
396 appendMarkers(pieSeries);
397 break;
397 break;
398 }
398 }
399 case QSeries::SeriesTypeSpline: {
399 case QSeries::SeriesTypeSpline: {
400 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
400 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
401 appendMarkers(splineSeries);
401 appendMarkers(splineSeries);
402 break;
402 break;
403 }
403 }
404 default: {
404 default: {
405 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
405 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
406 break;
406 break;
407 }
407 }
408 }
408 }
409 }
409 }
410
410
411 /*!
411 /*!
412 \internal Helper function. Appends markers from \a series to legend.
412 \internal Helper function. Appends markers from \a series to legend.
413 */
413 */
414 void QLegend::appendMarkers(QXYSeries* series)
414 void QLegend::appendMarkers(QXYSeries* series)
415 {
415 {
416 LegendMarker* marker = new LegendMarker(series,this);
416 LegendMarker* marker = new LegendMarker(series,this);
417 marker->setName(series->name());
417 marker->setName(series->name());
418 marker->setPen(series->pen());
418 marker->setPen(series->pen());
419 marker->setBrush(series->brush());
419 marker->setBrush(series->brush());
420 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
420 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
421 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
421 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
422 m_markers.append(marker);
422 m_markers.append(marker);
423 childItems().append(marker);
423 childItems().append(marker);
424 }
424 }
425
425
426 /*!
426 /*!
427 \internal Helper function. Appends markers from \a series to legend.
427 \internal Helper function. Appends markers from \a series to legend.
428 */
428 */
429 void QLegend::appendMarkers(QBarSeries *series)
429 void QLegend::appendMarkers(QBarSeries *series)
430 {
430 {
431 foreach(QBarSet* s, series->barSets()) {
431 foreach(QBarSet* s, series->barSets()) {
432 LegendMarker* marker = new LegendMarker(series, s, this);
432 LegendMarker* marker = new LegendMarker(series, s, this);
433 marker->setName(s->name());
433 marker->setName(s->name());
434 marker->setPen(s->pen());
434 marker->setPen(s->pen());
435 marker->setBrush(s->brush());
435 marker->setBrush(s->brush());
436 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
436 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
437 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
437 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
438 connect(s, SIGNAL(valueChanged()), marker, SLOT(changed()));
438 connect(s, SIGNAL(valueChanged()), marker, SLOT(changed()));
439 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
439 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
440 m_markers.append(marker);
440 m_markers.append(marker);
441 childItems().append(marker);
441 childItems().append(marker);
442 }
442 }
443 }
443 }
444
444
445 /*!
445 /*!
446 \internal Helper function. Appends markers from \a series to legend.
446 \internal Helper function. Appends markers from \a series to legend.
447 */
447 */
448 void QLegend::appendMarkers(QPieSeries *series)
448 void QLegend::appendMarkers(QPieSeries *series)
449 {
449 {
450 foreach(QPieSlice* s, series->slices()) {
450 foreach(QPieSlice* s, series->slices()) {
451 LegendMarker* marker = new LegendMarker(series, s, this);
451 LegendMarker* marker = new LegendMarker(series, s, this);
452 marker->setName(s->label());
452 marker->setName(s->label());
453 marker->setPen(s->pen());
453 marker->setPen(s->pen());
454 marker->setBrush(s->brush());
454 marker->setBrush(s->brush());
455 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
455 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
456 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
456 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
457 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
457 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
458 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
458 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
459 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
459 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
460 m_markers.append(marker);
460 m_markers.append(marker);
461 childItems().append(marker);
461 childItems().append(marker);
462 }
462 }
463 }
463 }
464
464
465 /*!
465 /*!
466 \internal Deletes all markers that are created from \a series
466 \internal Deletes all markers that are created from \a series
467 */
467 */
468 void QLegend::deleteMarkers(QSeries *series)
468 void QLegend::deleteMarkers(QSeries *series)
469 {
469 {
470 // Search all markers that belong to given series and delete them.
470 // Search all markers that belong to given series and delete them.
471 foreach (LegendMarker *m, m_markers) {
471 foreach (LegendMarker *m, m_markers) {
472 if (m->series() == series) {
472 if (m->series() == series) {
473 m_markers.removeOne(m);
473 m_markers.removeOne(m);
474 delete m;
474 delete m;
475 }
475 }
476 }
476 }
477 }
477 }
478
478
479 /*!
479 /*!
480 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
480 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
481 If items don't fit, sets the visibility of scroll buttons accordingly.
481 If items don't fit, sets the visibility of scroll buttons accordingly.
482 Causes legend to be resized.
482 Causes legend to be resized.
483 */
483 */
484 void QLegend::updateLayout()
484 void QLegend::updateLayout()
485 {
485 {
486 // Calculate layout for markers and text
486 // Calculate layout for markers and text
487 if (m_markers.count() <= 0) {
487 if (m_markers.count() <= 0) {
488 // Nothing to do
488 // Nothing to do
489 return;
489 return;
490 }
490 }
491
491
492 // Find out widest item.
492 // Find out widest item.
493 QSizeF markerMaxSize = maximumMarkerSize();
493 QSizeF markerMaxSize = maximumMarkerSize();
494 checkFirstMarkerBounds();
494 checkFirstMarkerBounds();
495
495
496 // Use max height as scroll button size
496 // Use max height as scroll button size
497 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
497 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
498
498
499 qreal totalWidth = 0;
499 qreal totalWidth = 0;
500 qreal totalHeight = 0;
500 qreal totalHeight = 0;
501 switch (m_alignment)
501 switch (m_alignment)
502 {
502 {
503 // Both cases organise items horizontally
503 // Both cases organise items horizontally
504 case QLegend::LayoutBottom:
504 case QLegend::LayoutBottom:
505 case QLegend::LayoutTop: {
505 case QLegend::LayoutTop: {
506
506
507 qreal xStep = markerMaxSize.width();
507 qreal xStep = markerMaxSize.width();
508 qreal x = m_pos.x() + m_margin;
508 qreal x = m_pos.x() + m_margin;
509 qreal y = m_pos.y() + m_margin;
509 qreal y = m_pos.y() + m_margin;
510 int column = 0;
510 int column = 0;
511 int maxColumns = 1;
511 int maxColumns = 1;
512 qreal scrollButtonWidth = 0;
512 qreal scrollButtonWidth = 0;
513
513
514 // Set correct visibility for scroll scrollbuttons
514 // Set correct visibility for scroll scrollbuttons
515 if (scrollButtonsVisible()) {
515 if (scrollButtonsVisible()) {
516 m_scrollButtonLeft->setVisible(true);
516 m_scrollButtonLeft->setVisible(true);
517 m_scrollButtonRight->setVisible(true);
517 m_scrollButtonRight->setVisible(true);
518 // scrollbuttons visible, so add their width to total width
518 // scrollbuttons visible, so add their width to total width
519 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
519 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
520 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
520 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
521 // start position changes by scrollbutton width
521 // start position changes by scrollbutton width
522 x += scrollButtonWidth;
522 x += scrollButtonWidth;
523 } else {
523 } else {
524 m_scrollButtonLeft->setVisible(false);
524 m_scrollButtonLeft->setVisible(false);
525 m_scrollButtonRight->setVisible(false);
525 m_scrollButtonRight->setVisible(false);
526 }
526 }
527 m_scrollButtonUp->setVisible(false);
527 m_scrollButtonUp->setVisible(false);
528 m_scrollButtonDown->setVisible(false);
528 m_scrollButtonDown->setVisible(false);
529
529
530 for (int i=0; i < m_markers.count(); i++) {
530 for (int i=0; i < m_markers.count(); i++) {
531 LegendMarker *m = m_markers.at(i);
531 LegendMarker *m = m_markers.at(i);
532 if (i < mFirstMarker) {
532 if (i < mFirstMarker) {
533 // Markers before first are not visible.
533 // Markers before first are not visible.
534 m->setVisible(false);
534 m->setVisible(false);
535 } else {
535 } else {
536 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
536 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
537 // This marker would go outside legend rect.
537 // This marker would go outside legend rect.
538 m->setVisible(false);
538 m->setVisible(false);
539 } else {
539 } else {
540 // This marker is ok
540 // This marker is ok
541 m->setVisible(true);
541 m->setVisible(true);
542 m->setPos(x, y);
542 m->setPos(x, y);
543 x += xStep;
543 x += xStep;
544 column++;
544 column++;
545 }
545 }
546 }
546 }
547 maxColumns = column;
547 maxColumns = column;
548 }
548 }
549
549
550 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
550 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
551 m_scrollButtonRight->setPos(x + m_margin, y);
551 m_scrollButtonRight->setPos(x + m_margin, y);
552
552
553 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
553 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
554 totalHeight = markerMaxSize.height() + m_margin * 2;
554 totalHeight = markerMaxSize.height() + m_margin * 2;
555
555
556 break;
556 break;
557 }
557 }
558 // Both cases organize items vertically
558 // Both cases organize items vertically
559 case QLegend::LayoutLeft:
559 case QLegend::LayoutLeft:
560 case QLegend::LayoutRight: {
560 case QLegend::LayoutRight: {
561 qreal yStep = markerMaxSize.height();
561 qreal yStep = markerMaxSize.height();
562 qreal x = m_pos.x() + m_margin;
562 qreal x = m_pos.x() + m_margin;
563 qreal y = m_pos.y() + m_margin;
563 qreal y = m_pos.y() + m_margin;
564 int row = 1;
564 int row = 1;
565 int maxRows = 1;
565 int maxRows = 1;
566 qreal scrollButtonHeight = 0;
566 qreal scrollButtonHeight = 0;
567
567
568 // Set correct visibility for scroll scrollbuttons
568 // Set correct visibility for scroll scrollbuttons
569 if (scrollButtonsVisible()) {
569 if (scrollButtonsVisible()) {
570 m_scrollButtonUp->setVisible(true);
570 m_scrollButtonUp->setVisible(true);
571 m_scrollButtonDown->setVisible(true);
571 m_scrollButtonDown->setVisible(true);
572 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
572 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
573 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
573 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
574 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
574 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
575 } else {
575 } else {
576 m_scrollButtonUp->setVisible(false);
576 m_scrollButtonUp->setVisible(false);
577 m_scrollButtonDown->setVisible(false);
577 m_scrollButtonDown->setVisible(false);
578 }
578 }
579 m_scrollButtonLeft->setVisible(false);
579 m_scrollButtonLeft->setVisible(false);
580 m_scrollButtonRight->setVisible(false);
580 m_scrollButtonRight->setVisible(false);
581
581
582 for (int i=0; i < m_markers.count(); i++) {
582 for (int i=0; i < m_markers.count(); i++) {
583 LegendMarker* m = m_markers.at(i);
583 LegendMarker* m = m_markers.at(i);
584 if (i < mFirstMarker) {
584 if (i < mFirstMarker) {
585 // Markers before first are not visible.
585 // Markers before first are not visible.
586 m->setVisible(false);
586 m->setVisible(false);
587 } else {
587 } else {
588 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
588 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
589 // This marker would go outside legend rect.
589 // This marker would go outside legend rect.
590 m->setVisible(false);
590 m->setVisible(false);
591 } else {
591 } else {
592 // This marker is ok
592 // This marker is ok
593 m->setVisible(true);
593 m->setVisible(true);
594 m->setPos(x, y);
594 m->setPos(x, y);
595 y += yStep;
595 y += yStep;
596 row++;
596 row++;
597 }
597 }
598 }
598 }
599 maxRows = row;
599 maxRows = row;
600 }
600 }
601
601
602 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
602 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
603 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
603 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
604
604
605 totalWidth += markerMaxSize.width() + m_margin * 2;
605 totalWidth += markerMaxSize.width() + m_margin * 2;
606 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
606 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
607 break;
607 break;
608 }
608 }
609 default: {
609 default: {
610 break;
610 break;
611 }
611 }
612 }
612 }
613
613
614 m_size.setWidth(totalWidth);
614 m_size.setWidth(totalWidth);
615 m_size.setHeight(totalHeight);
615 m_size.setHeight(totalHeight);
616
616
617 update();
617 update();
618 }
618 }
619
619
620 /*!
620 /*!
621 \internal Sets the size of scroll buttons to \a size
621 \internal Sets the size of scroll buttons to \a size
622 */
622 */
623 void QLegend::rescaleScrollButtons(const QSize &size)
623 void QLegend::rescaleScrollButtons(const QSize &size)
624 {
624 {
625 QPolygonF left;
625 QPolygonF left;
626 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
626 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
627 QPolygonF right;
627 QPolygonF right;
628 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
628 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
629 QPolygonF up;
629 QPolygonF up;
630 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
630 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
631 QPolygonF down;
631 QPolygonF down;
632 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
632 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
633
633
634 m_scrollButtonLeft->setPolygon(left);
634 m_scrollButtonLeft->setPolygon(left);
635 m_scrollButtonRight->setPolygon(right);
635 m_scrollButtonRight->setPolygon(right);
636 m_scrollButtonUp->setPolygon(up);
636 m_scrollButtonUp->setPolygon(up);
637 m_scrollButtonDown->setPolygon(down);
637 m_scrollButtonDown->setPolygon(down);
638 }
638 }
639
639
640 /*!
640 /*!
641 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
641 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
642 */
642 */
643 QSizeF QLegend::maximumMarkerSize()
643 QSizeF QLegend::maximumMarkerSize()
644 {
644 {
645 QSizeF max(0,0);
645 QSizeF max(0,0);
646 foreach (LegendMarker* m, m_markers) {
646 foreach (LegendMarker* m, m_markers) {
647 if (m->boundingRect().width() > max.width())
647 if (m->boundingRect().width() > max.width())
648 max.setWidth(m->boundingRect().width());
648 max.setWidth(m->boundingRect().width());
649 if (m->boundingRect().height() > max.height())
649 if (m->boundingRect().height() > max.height())
650 max.setHeight(m->boundingRect().height());
650 max.setHeight(m->boundingRect().height());
651 }
651 }
652 return max;
652 return max;
653 }
653 }
654
654
655 /*!
655 /*!
656 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
656 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
657 If scrollbuttons are visible, they affect the number of visible markers.
657 If scrollbuttons are visible, they affect the number of visible markers.
658 */
658 */
659 void QLegend::checkFirstMarkerBounds()
659 void QLegend::checkFirstMarkerBounds()
660 {
660 {
661 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
661 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
662 // Bounds limited by height.
662 // Bounds limited by height.
663 int max;
663 int max;
664 if (scrollButtonsVisible()) {
664 if (scrollButtonsVisible()) {
665 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
665 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
666 } else {
666 } else {
667 max = m_maximumSize.height() / maximumMarkerSize().height();
667 max = m_maximumSize.height() / maximumMarkerSize().height();
668 }
668 }
669
669
670 if (mFirstMarker > m_markers.count() - max)
670 if (mFirstMarker > m_markers.count() - max)
671 mFirstMarker = m_markers.count() - max;
671 mFirstMarker = m_markers.count() - max;
672 } else {
672 } else {
673 // Bounds limited by width
673 // Bounds limited by width
674 int max;
674 int max;
675 if (scrollButtonsVisible()) {
675 if (scrollButtonsVisible()) {
676 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
676 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
677 } else {
677 } else {
678 max = m_maximumSize.width() / maximumMarkerSize().width();
678 max = m_maximumSize.width() / maximumMarkerSize().width();
679 }
679 }
680
680
681 if (mFirstMarker > m_markers.count() - max)
681 if (mFirstMarker > m_markers.count() - max)
682 mFirstMarker = m_markers.count() - max;
682 mFirstMarker = m_markers.count() - max;
683 }
683 }
684
684
685 if (mFirstMarker < 0)
685 if (mFirstMarker < 0)
686 mFirstMarker = 0;
686 mFirstMarker = 0;
687 }
687 }
688
688
689 /*!
689 /*!
690 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
690 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
691 */
691 */
692 bool QLegend::scrollButtonsVisible()
692 bool QLegend::scrollButtonsVisible()
693 {
693 {
694 // Just a helper to clarify, what the magic below means :)
694 // Just a helper to clarify, what the magic below means :)
695 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
695 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
696 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
696 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
697 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
697 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
698 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
698 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
699 }
699 }
700
700
701 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
701 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
702 }
702 }
703
703
704 #include "moc_qlegend.cpp"
704 #include "moc_qlegend.cpp"
705
705
706 QTCOMMERCIALCHART_END_NAMESPACE
706 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,111 +1,111
1 #ifndef QLEGEND_H
1 #ifndef QLEGEND_H
2 #define QLEGEND_H
2 #define QLEGEND_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QGraphicsObject>
5 #include <QGraphicsObject>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class Domain;
11 class Domain;
12 class LegendMarker;
12 class LegendMarker;
13 class QPieSlice;
13 class QPieSlice;
14 class QXYSeries;
14 class QXYSeries;
15 class QBarSet;
15 class QBarSet;
16 class QBarSeries;
16 class QBarSeries;
17 class QPieSeries;
17 class QPieSeries;
18 class LegendScrollButton;
18 class LegendScrollButton;
19 class QSeries;
19 class QSeries;
20
20
21 // TODO: This as widget
21 // TODO: This as widget
22 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
22 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
23 {
23 {
24 Q_OBJECT
24 Q_OBJECT
25 public:
25 public:
26
26
27 // We only support these alignments (for now)
27 // We only support these alignments (for now)
28 enum Layout {
28 enum Layout {
29 LayoutTop = Qt::AlignTop,
29 LayoutTop = Qt::AlignTop,
30 LayoutBottom = Qt::AlignBottom,
30 LayoutBottom = Qt::AlignBottom,
31 LayoutLeft = Qt::AlignLeft,
31 LayoutLeft = Qt::AlignLeft,
32 LayoutRight = Qt::AlignRight
32 LayoutRight = Qt::AlignRight
33 };
33 };
34
34
35 explicit QLegend(QGraphicsItem *parent = 0);
35 explicit QLegend(QGraphicsItem *parent = 0);
36
36
37 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
37 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
38 QRectF boundingRect() const;
38 QRectF boundingRect() const;
39
39
40 void setBrush(const QBrush &brush);
40 void setBrush(const QBrush &brush);
41 QBrush brush() const;
41 QBrush brush() const;
42
42
43 void setPen(const QPen &pen);
43 void setPen(const QPen &pen);
44 QPen pen() const;
44 QPen pen() const;
45
45
46 void setAlignmnent(QLegend::Layout alignment);
46 void setAlignmnent(QLegend::Layout alignment);
47 QLegend::Layout alignment() const;
47 QLegend::Layout alignment() const;
48
48
49 QSizeF maximumSize() const;
49 QSizeF maximumSize() const;
50 void setMaximumSize(const QSizeF size);
50 void setMaximumSize(const QSizeF size);
51
51
52 QSizeF size() const;
52 QSizeF size() const;
53 void setSize(const QSizeF size);
53 void setSize(const QSizeF size);
54 void setPos(const QPointF &pos);
54 void setPos(const QPointF &pos);
55
55
56 Q_SIGNALS:
56 Q_SIGNALS:
57 // for interactions.
57 // for interactions.
58 void clicked(QSeries *series, Qt::MouseButton button);
58 void clicked(QSeries *series, Qt::MouseButton button);
59 void clicked(QBarSet *barset, Qt::MouseButton button);
59 void clicked(QBarSet *barset, Qt::MouseButton button);
60 void clicked(QPieSlice *slice, Qt::MouseButton button);
60 void clicked(QPieSlice *slice, Qt::MouseButton button);
61
61
62 public Q_SLOTS:
62 public Q_SLOTS:
63 // PIMPL --->
63 // PIMPL --->
64 void handleSeriesAdded(QSeries *series, Domain *domain);
64 void handleSeriesAdded(QSeries *series, Domain *domain);
65 void handleSeriesRemoved(QSeries *series);
65 void handleSeriesRemoved(QSeries *series);
66 void handleAdded(QList<QPieSlice *> slices);
66 void handleAdded(QList<QPieSlice *> slices);
67 void handleRemoved(QList<QPieSlice *> slices);
67 void handleRemoved(QList<QPieSlice *> slices);
68 void handleMarkerDestroyed();
68 void handleMarkerDestroyed();
69 void handleScrollButtonClicked(QGraphicsSceneMouseEvent *event);
69 void handleScrollButtonClicked(QGraphicsSceneMouseEvent *event);
70 // PIMPL <---
70 // PIMPL <---
71
71
72 private:
72 private:
73 // PIMPL --->
73 // PIMPL --->
74 void connectSeries(QSeries *series);
74 void connectSeries(QSeries *series);
75 void disconnectSeries(QSeries *series);
75 void disconnectSeries(QSeries *series);
76 void createMarkers(QSeries *series);
76 void createMarkers(QSeries *series);
77 void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now
77 void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now
78 void appendMarkers(QBarSeries *series);
78 void appendMarkers(QBarSeries *series);
79 void appendMarkers(QPieSeries *series);
79 void appendMarkers(QPieSeries *series);
80 void deleteMarkers(QSeries *series);
80 void deleteMarkers(QSeries *series);
81 void updateLayout();
81 void updateLayout();
82 void rescaleScrollButtons(const QSize &size);
82 void rescaleScrollButtons(const QSize &size);
83 QSizeF maximumMarkerSize();
83 QSizeF maximumMarkerSize();
84 void checkFirstMarkerBounds();
84 void checkFirstMarkerBounds();
85 bool scrollButtonsVisible();
85 bool scrollButtonsVisible();
86
86
87 qreal m_margin;
87 QPointF m_pos;
88 QPointF m_pos;
88 QSizeF m_size;
89 QSizeF m_minimumSize;
89 QSizeF m_minimumSize;
90 QSizeF m_maximumSize;
90 QSizeF m_maximumSize;
91 QSizeF m_size;
91
92
92 QList<LegendMarker *> m_markers;
93 QList<LegendMarker *> m_markers;
93
94
94 QBrush m_brush;
95 QBrush m_brush;
95 QPen m_pen;
96 QPen m_pen;
96 QLegend::Layout m_alignment;
97 QLegend::Layout m_alignment;
97
98
98 int mFirstMarker;
99 int mFirstMarker;
99
100
100 LegendScrollButton *m_scrollButtonLeft;
101 LegendScrollButton *m_scrollButtonLeft;
101 LegendScrollButton *m_scrollButtonRight;
102 LegendScrollButton *m_scrollButtonRight;
102 LegendScrollButton *m_scrollButtonUp;
103 LegendScrollButton *m_scrollButtonUp;
103 LegendScrollButton *m_scrollButtonDown;
104 LegendScrollButton *m_scrollButtonDown;
104
105
105 qreal m_margin;
106 // <--- PIMPL
106 // <--- PIMPL
107 };
107 };
108
108
109 QTCOMMERCIALCHART_END_NAMESPACE
109 QTCOMMERCIALCHART_END_NAMESPACE
110
110
111 #endif // QLEGEND_H
111 #endif // QLEGEND_H
General Comments 0
You need to be logged in to leave comments. Login now