##// END OF EJS Templates
Marek Rosa -
r461:5973afc43f62 merge
parent child
Show More
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,373 +1,371
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartdataset_p.h"
4 #include "chartdataset_p.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 //series
6 //series
7 #include "qbarseries.h"
7 #include "qbarseries.h"
8 #include "qstackedbarseries.h"
8 #include "qstackedbarseries.h"
9 #include "qpercentbarseries.h"
9 #include "qpercentbarseries.h"
10 #include "qlineseries.h"
10 #include "qlineseries.h"
11 #include "qareaseries.h"
11 #include "qareaseries.h"
12 #include "qpieseries.h"
12 #include "qpieseries.h"
13 #include "qscatterseries.h"
13 #include "qscatterseries.h"
14 #include "qsplineseries.h"
14 #include "qsplineseries.h"
15 //items
15 //items
16 #include "axisitem_p.h"
16 #include "axisitem_p.h"
17 #include "axisanimationitem_p.h"
17 #include "axisanimationitem_p.h"
18 #include "areachartitem_p.h"
18 #include "areachartitem_p.h"
19 #include "barpresenter_p.h"
19 #include "barpresenter_p.h"
20 #include "stackedbarpresenter_p.h"
20 #include "stackedbarpresenter_p.h"
21 #include "percentbarpresenter_p.h"
21 #include "percentbarpresenter_p.h"
22 #include "linechartitem_p.h"
22 #include "linechartitem_p.h"
23 #include "linechartanimationitem_p.h"
23 #include "linechartanimationitem_p.h"
24 #include "piepresenter_p.h"
24 #include "piepresenter_p.h"
25 #include "scatterpresenter_p.h"
25 #include "scatterpresenter_p.h"
26 #include "splinechartitem_p.h"
26 #include "splinechartitem_p.h"
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
31 m_chart(chart),
31 m_chart(chart),
32 m_dataset(dataset),
32 m_dataset(dataset),
33 m_chartTheme(0),
33 m_chartTheme(0),
34 m_zoomIndex(0),
34 m_zoomIndex(0),
35 m_marginSize(0),
35 m_marginSize(0),
36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
37 m_options(QChart::NoAnimation)
37 m_options(QChart::NoAnimation)
38 {
38 {
39 createConnections();
39 createConnections();
40 setChartTheme(QChart::ChartThemeDefault);
40 setChartTheme(QChart::ChartThemeDefault);
41 }
41 }
42
42
43 ChartPresenter::~ChartPresenter()
43 ChartPresenter::~ChartPresenter()
44 {
44 {
45 }
45 }
46
46
47 void ChartPresenter::createConnections()
47 void ChartPresenter::createConnections()
48 {
48 {
49 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
49 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
50 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
50 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
51 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
51 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
52 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
52 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
53 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
53 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
54 }
54 }
55
55
56
56
57 QRectF ChartPresenter::geometry() const
57 QRectF ChartPresenter::geometry() const
58 {
58 {
59 return m_rect;
59 return m_rect;
60 }
60 }
61
61
62 void ChartPresenter::handleGeometryChanged()
62 void ChartPresenter::handleGeometryChanged()
63 {
63 {
64 QRectF rect(QPoint(0,0),m_chart->size());
64 QRectF rect(QPoint(0,0),m_chart->size());
65 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
65 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
66
66
67 //rewrite zoom stack
67 //rewrite zoom stack
68 for(int i=0;i<m_zoomStack.count();i++){
68 for(int i=0;i<m_zoomStack.count();i++){
69 QRectF r = m_zoomStack[i];
69 QRectF r = m_zoomStack[i];
70 qreal w = rect.width()/m_rect.width();
70 qreal w = rect.width()/m_rect.width();
71 qreal h = rect.height()/m_rect.height();
71 qreal h = rect.height()/m_rect.height();
72 QPointF tl = r.topLeft();
72 QPointF tl = r.topLeft();
73 tl.setX(tl.x()*w);
73 tl.setX(tl.x()*w);
74 tl.setY(tl.y()*h);
74 tl.setY(tl.y()*h);
75 QPointF br = r.bottomRight();
75 QPointF br = r.bottomRight();
76 br.setX(br.x()*w);
76 br.setX(br.x()*w);
77 br.setY(br.y()*h);
77 br.setY(br.y()*h);
78 r.setTopLeft(tl);
78 r.setTopLeft(tl);
79 r.setBottomRight(br);
79 r.setBottomRight(br);
80 m_zoomStack[i]=r;
80 m_zoomStack[i]=r;
81 }
81 }
82
82
83 m_rect = rect;
83 m_rect = rect;
84 Q_ASSERT(m_rect.isValid());
84 Q_ASSERT(m_rect.isValid());
85 emit geometryChanged(m_rect);
85 emit geometryChanged(m_rect);
86 }
86 }
87
87
88 int ChartPresenter::margin() const
88 int ChartPresenter::margin() const
89 {
89 {
90 return m_marginSize;
90 return m_marginSize;
91 }
91 }
92
92
93 void ChartPresenter::setMargin(int margin)
93 void ChartPresenter::setMargin(int margin)
94 {
94 {
95 m_marginSize = margin;
95 m_marginSize = margin;
96 }
96 }
97
97
98 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
98 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
99 {
99 {
100
100
101 AxisItem* item ;
101 AxisItem* item ;
102
102
103 if(!m_options.testFlag(QChart::GridAxisAnimations))
103 if(!m_options.testFlag(QChart::GridAxisAnimations))
104 {
104 {
105 item = new AxisItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
105 item = new AxisItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
106 }else{
106 }else{
107 item = new AxisAnimationItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
107 item = new AxisAnimationItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
108 }
108 }
109 if(axis==m_dataset->axisX()){
109 if(axis==m_dataset->axisX()){
110 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
110 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
111 //initialize
111 //initialize
112 item->handleRangeChanged(domain->minX(),domain->maxX());
112 item->handleRangeChanged(domain->minX(),domain->maxX());
113 item->handleTicksCountChanged(4);
113 item->handleTicksCountChanged(4);
114 }
114 }
115 else{
115 else{
116 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
116 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
117 //initialize
117 //initialize
118 item->handleRangeChanged(domain->minY(),domain->maxY());
118 item->handleRangeChanged(domain->minY(),domain->maxY());
119 item->handleTicksCountChanged(4);
119 item->handleTicksCountChanged(4);
120 }
120 }
121
121
122 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
122 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
123 //initialize
123 //initialize
124 item->handleGeometryChanged(m_rect);
124 item->handleGeometryChanged(m_rect);
125 m_chartTheme->decorate(axis,item);
125 m_chartTheme->decorate(axis,item);
126 m_axisItems.insert(axis,item);
126 m_axisItems.insert(axis,item);
127 }
127 }
128
128
129 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
129 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
130 {
130 {
131 AxisItem* item = m_axisItems.take(axis);
131 AxisItem* item = m_axisItems.take(axis);
132 Q_ASSERT(item);
132 Q_ASSERT(item);
133 delete item;
133 delete item;
134 }
134 }
135
135
136
136
137 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
137 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
138 {
138 {
139 switch(series->type())
139 switch(series->type())
140 {
140 {
141 case QSeries::SeriesTypeLine: {
141 case QSeries::SeriesTypeLine: {
142
142
143 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
143 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
144 LineChartItem* item;
144 LineChartItem* item;
145 if(m_options.testFlag(QChart::SeriesAnimations)){
145 if(m_options.testFlag(QChart::SeriesAnimations)){
146 item = new LineChartAnimationItem(lineSeries,m_chart);
146 item = new LineChartAnimationItem(lineSeries,m_chart);
147 }else{
147 }else{
148 item = new LineChartItem(lineSeries,m_chart);
148 item = new LineChartItem(lineSeries,m_chart);
149 }
149 }
150 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
150 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
151 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
151 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
152 //initialize
152 //initialize
153 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
153 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
154 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
154 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
155 //decorate
155 //decorate
156 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
156 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
157 m_chartItems.insert(series,item);
157 m_chartItems.insert(series,item);
158 break;
158 break;
159 }
159 }
160
160
161 case QSeries::SeriesTypeArea: {
161 case QSeries::SeriesTypeArea: {
162
162
163 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
163 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
164 AreaChartItem* item;
164 AreaChartItem* item;
165 if(m_options.testFlag(QChart::SeriesAnimations)) {
165 if(m_options.testFlag(QChart::SeriesAnimations)) {
166 item = new AreaChartItem(areaSeries,m_chart);
166 item = new AreaChartItem(areaSeries,m_chart);
167 }
167 }
168 else {
168 else {
169 item = new AreaChartItem(areaSeries,m_chart);
169 item = new AreaChartItem(areaSeries,m_chart);
170 }
170 }
171 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
171 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
172 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
172 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
173 //initialize
173 //initialize
174 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
174 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
175 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
175 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
176 //decorate
176 //decorate
177 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
177 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
178 m_chartItems.insert(series,item);
178 m_chartItems.insert(series,item);
179 break;
179 break;
180 }
180 }
181
181
182 case QSeries::SeriesTypeBar: {
182 case QSeries::SeriesTypeBar: {
183 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
183 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
184 BarPresenter* item = new BarPresenter(barSeries,m_chart);
184 BarPresenter* item = new BarPresenter(barSeries,m_chart);
185 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
185 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
186 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
186 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
187 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
187 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
188 m_chartItems.insert(series,item);
188 m_chartItems.insert(series,item);
189 // m_axisXItem->setVisible(false);
189 // m_axisXItem->setVisible(false);
190 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
190 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
191 break;
191 break;
192 }
192 }
193
193
194 case QSeries::SeriesTypeStackedBar: {
194 case QSeries::SeriesTypeStackedBar: {
195
195
196 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
196 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
197 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
197 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
198 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
198 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
199 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
199 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
200 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
200 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
201 m_chartItems.insert(series,item);
201 m_chartItems.insert(series,item);
202 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
202 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
203 break;
203 break;
204 }
204 }
205
205
206 case QSeries::SeriesTypePercentBar: {
206 case QSeries::SeriesTypePercentBar: {
207
207
208 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
208 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
209 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
209 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
210 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
210 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
211 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
211 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
212 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
212 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
213 m_chartItems.insert(series,item);
213 m_chartItems.insert(series,item);
214 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
214 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
215 break;
215 break;
216 }
216 }
217 case QSeries::SeriesTypeScatter: {
217 case QSeries::SeriesTypeScatter: {
218 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
218 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
219 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
219 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
220 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
221 scatterSeries, SIGNAL(clicked(QPointF)));
222 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
220 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
223 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
221 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
224 QObject::connect(domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),
222 QObject::connect(domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),
225 scatterPresenter, SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
223 scatterPresenter, SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
226 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
224 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
227 m_chartItems.insert(scatterSeries, scatterPresenter);
225 m_chartItems.insert(scatterSeries, scatterPresenter);
228 if (m_rect.isValid())
226 if (m_rect.isValid())
229 scatterPresenter->handleGeometryChanged(m_rect);
227 scatterPresenter->handleGeometryChanged(m_rect);
230 scatterPresenter->handleDomainChanged(domain->minX(), domain->maxX(), domain->minY(), domain->maxY());
228 scatterPresenter->handleDomainChanged(domain->minX(), domain->maxX(), domain->minY(), domain->maxY());
231 break;
229 break;
232 }
230 }
233 case QSeries::SeriesTypePie: {
231 case QSeries::SeriesTypePie: {
234 QPieSeries *s = qobject_cast<QPieSeries *>(series);
232 QPieSeries *s = qobject_cast<QPieSeries *>(series);
235 PiePresenter* pie = new PiePresenter(m_chart, s);
233 PiePresenter* pie = new PiePresenter(m_chart, s);
236 m_chartTheme->decorate(pie, s, m_chartItems.count());
234 m_chartTheme->decorate(pie, s, m_chartItems.count());
237 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
235 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
238
236
239 // Hide all from background when there is only piechart
237 // Hide all from background when there is only piechart
240 // TODO: refactor this ugly code... should be one setting for this
238 // TODO: refactor this ugly code... should be one setting for this
241 if (m_chartItems.count() == 0) {
239 if (m_chartItems.count() == 0) {
242 m_chart->axisX()->setAxisVisible(false);
240 m_chart->axisX()->setAxisVisible(false);
243 m_chart->axisY()->setAxisVisible(false);
241 m_chart->axisY()->setAxisVisible(false);
244 m_chart->axisX()->setGridVisible(false);
242 m_chart->axisX()->setGridVisible(false);
245 m_chart->axisY()->setGridVisible(false);
243 m_chart->axisY()->setGridVisible(false);
246 m_chart->axisX()->setLabelsVisible(false);
244 m_chart->axisX()->setLabelsVisible(false);
247 m_chart->axisY()->setLabelsVisible(false);
245 m_chart->axisY()->setLabelsVisible(false);
248 m_chart->axisX()->setShadesVisible(false);
246 m_chart->axisX()->setShadesVisible(false);
249 m_chart->axisY()->setShadesVisible(false);
247 m_chart->axisY()->setShadesVisible(false);
250 m_chart->setChartBackgroundBrush(Qt::transparent);
248 m_chart->setChartBackgroundBrush(Qt::transparent);
251 }
249 }
252
250
253 m_chartItems.insert(series, pie);
251 m_chartItems.insert(series, pie);
254 pie->handleGeometryChanged(m_rect);
252 pie->handleGeometryChanged(m_rect);
255 break;
253 break;
256 }
254 }
257
255
258 case QSeries::SeriesTypeSpline: {
256 case QSeries::SeriesTypeSpline: {
259 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
257 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
260 SplineChartItem* splinePresenter = new SplineChartItem(splineSeries, m_chart);
258 SplineChartItem* splinePresenter = new SplineChartItem(splineSeries, m_chart);
261 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&)));
259 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&)));
262 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),splinePresenter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
260 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),splinePresenter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
263 //initialize
261 //initialize
264 splinePresenter->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
262 splinePresenter->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
265 m_chartTheme->decorate(splinePresenter, splineSeries, m_chartItems.count());
263 m_chartTheme->decorate(splinePresenter, splineSeries, m_chartItems.count());
266 m_chartItems.insert(splineSeries, splinePresenter);
264 m_chartItems.insert(splineSeries, splinePresenter);
267 break;
265 break;
268 }
266 }
269 default: {
267 default: {
270 qDebug()<< "Series type" << series->type() << "not implemented.";
268 qDebug()<< "Series type" << series->type() << "not implemented.";
271 break;
269 break;
272 }
270 }
273 }
271 }
274
272
275 zoomReset();
273 zoomReset();
276 }
274 }
277
275
278 void ChartPresenter::handleSeriesRemoved(QSeries* series)
276 void ChartPresenter::handleSeriesRemoved(QSeries* series)
279 {
277 {
280 ChartItem* item = m_chartItems.take(series);
278 ChartItem* item = m_chartItems.take(series);
281 delete item;
279 delete item;
282 }
280 }
283
281
284 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
282 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
285 {
283 {
286 delete m_chartTheme;
284 delete m_chartTheme;
287
285
288 m_chartTheme = ChartTheme::createTheme(theme);
286 m_chartTheme = ChartTheme::createTheme(theme);
289
287
290 m_chartTheme->decorate(m_chart);
288 m_chartTheme->decorate(m_chart);
291 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
289 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
292
290
293 int index=0;
291 int index=0;
294 while (i.hasNext()) {
292 while (i.hasNext()) {
295 i.next();
293 i.next();
296 m_chartTheme->decorate(i.value(),i.key(),index);
294 m_chartTheme->decorate(i.value(),i.key(),index);
297 index++;
295 index++;
298 }
296 }
299
297
300 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
298 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
301 while (j.hasNext()) {
299 while (j.hasNext()) {
302 j.next();
300 j.next();
303 m_chartTheme->decorate(j.key(),j.value());
301 m_chartTheme->decorate(j.key(),j.value());
304 }
302 }
305 }
303 }
306
304
307 QChart::ChartTheme ChartPresenter::chartTheme()
305 QChart::ChartTheme ChartPresenter::chartTheme()
308 {
306 {
309 return m_chartTheme->id();
307 return m_chartTheme->id();
310 }
308 }
311
309
312 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
310 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
313 {
311 {
314 if(m_options!=options) {
312 if(m_options!=options) {
315
313
316 m_options=options;
314 m_options=options;
317
315
318 //recreate elements
316 //recreate elements
319 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
317 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
320 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
318 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
321
319
322 foreach(QChartAxis* axis, axisList) {
320 foreach(QChartAxis* axis, axisList) {
323 handleAxisRemoved(axis);
321 handleAxisRemoved(axis);
324 handleAxisAdded(axis,m_dataset->domain(axis));
322 handleAxisAdded(axis,m_dataset->domain(axis));
325 }
323 }
326 foreach(QSeries* series, seriesList) {
324 foreach(QSeries* series, seriesList) {
327 handleSeriesRemoved(series);
325 handleSeriesRemoved(series);
328 handleSeriesAdded(series,m_dataset->domain(series));
326 handleSeriesAdded(series,m_dataset->domain(series));
329 }
327 }
330 }
328 }
331 }
329 }
332
330
333 void ChartPresenter::zoomIn()
331 void ChartPresenter::zoomIn()
334 {
332 {
335 QRectF rect = geometry();
333 QRectF rect = geometry();
336 rect.setWidth(rect.width()/2);
334 rect.setWidth(rect.width()/2);
337 rect.setHeight(rect.height()/2);
335 rect.setHeight(rect.height()/2);
338 rect.moveCenter(geometry().center());
336 rect.moveCenter(geometry().center());
339 zoomIn(rect);
337 zoomIn(rect);
340 }
338 }
341
339
342 void ChartPresenter::zoomIn(const QRectF& rect)
340 void ChartPresenter::zoomIn(const QRectF& rect)
343 {
341 {
344 QRectF r = rect.normalized();
342 QRectF r = rect.normalized();
345 r.translate(-m_marginSize, -m_marginSize);
343 r.translate(-m_marginSize, -m_marginSize);
346 m_dataset->zoomInDomain(r,geometry().size());
344 m_dataset->zoomInDomain(r,geometry().size());
347 m_zoomStack<<r;
345 m_zoomStack<<r;
348 m_zoomIndex++;
346 m_zoomIndex++;
349 }
347 }
350
348
351 void ChartPresenter::zoomOut()
349 void ChartPresenter::zoomOut()
352 {
350 {
353 if(m_zoomIndex==0) return;
351 if(m_zoomIndex==0) return;
354 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
352 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
355 m_zoomIndex--;
353 m_zoomIndex--;
356 m_zoomStack.resize(m_zoomIndex);
354 m_zoomStack.resize(m_zoomIndex);
357 }
355 }
358
356
359 void ChartPresenter::zoomReset()
357 void ChartPresenter::zoomReset()
360 {
358 {
361 m_zoomIndex=0;
359 m_zoomIndex=0;
362 m_zoomStack.resize(m_zoomIndex);
360 m_zoomStack.resize(m_zoomIndex);
363 }
361 }
364
362
365 QChart::AnimationOptions ChartPresenter::animationOptions() const
363 QChart::AnimationOptions ChartPresenter::animationOptions() const
366 {
364 {
367 return m_options;
365 return m_options;
368 }
366 }
369
367
370
368
371 #include "moc_chartpresenter_p.cpp"
369 #include "moc_chartpresenter_p.cpp"
372
370
373 QTCOMMERCIALCHART_END_NAMESPACE
371 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,298 +1,305
1 #include "qscatterseries.h"
1 #include "qscatterseries.h"
2 #include "scatterseries_p.h"
2 #include "scatterseries_p.h"
3 #include "qchart.h"
3 #include "qchart.h"
4
4
5 /*!
5 /*!
6 \class QScatterSeries
6 \class QScatterSeries
7 \brief QtCommercial Chart series API for showing scatter series.
7 \brief QtCommercial Chart series API for showing scatter series.
8
8
9 \mainclass
9 \mainclass
10
10
11 Example on how to create a chart with scatter series:
11 Example on how to create a chart with scatter series:
12 \snippet ../example/scatter/main.cpp 1
12 \snippet ../example/scatter/main.cpp 1
13
13
14 The example code would result the following:
14 The example code would result the following:
15
15
16 \image scatter_example1.jpg
16 \image scatter_example1.jpg
17
17
18 To customize the graphical representation of the series, you can modify pen, brush, shape and
18 To customize the graphical representation of the series, you can modify pen, brush, shape and
19 size of the marker items. For example:
19 size of the marker items. For example:
20
20
21 \snippet ../example/scatter/main.cpp 3
21 \snippet ../example/scatter/main.cpp 3
22
22
23 Would present your scatter markers as big rectangles with opaque, uglyish green outlines and
23 Would present your scatter markers as big rectangles with opaque, uglyish green outlines and
24 opaque red filling instead of the beatiful markers defined by the chart's theme:
24 opaque red filling instead of the beatiful markers defined by the chart's theme:
25 \image scatter_example_custom.jpg
25 \image scatter_example_custom.jpg
26 */
26 */
27
27
28 /*!
28 /*!
29 \enum QScatterSeries::MarkerShape
29 \enum QScatterSeries::MarkerShape
30
30
31 This enum describes the shape used when rendering marker items.
31 This enum describes the shape used when rendering marker items.
32
32
33 \value MarkerShapeDefault
33 \value MarkerShapeDefault
34 \value MarkerShapeX
34 \value MarkerShapeX
35 \value MarkerShapeRectangle
35 \value MarkerShapeRectangle
36 \value MarkerShapeRoundedRectangle
36 \value MarkerShapeTiltedRectangle
37 \value MarkerShapeTiltedRectangle
37 \value MarkerShapeTriangle
38 \value MarkerShapeTriangle
38 \value MarkerShapeCircle
39 \value MarkerShapeCircle
39 */
40 */
40
41
41 /*!
42 /*!
42 \fn QChartSeriesType QScatterSeries::type() const
43 \fn QChartSeriesType QScatterSeries::type() const
43 \brief Returns QChartSeries::SeriesTypeScatter.
44 \brief Returns QChartSeries::SeriesTypeScatter.
44 */
45 */
45
46
46 /*!
47 /*!
47 \fn void QScatterSeries::clicked(QPointF coordinate)
48 \fn void QScatterSeries::clicked(QPointF coordinate)
48 User clicked the scatter series. Note that the \a coordinate is the chart coordinate that the
49 User clicked the scatter series. Note that the \a coordinate is the chart coordinate that the
49 click occurred on; not necessarily a data point coordinate. To find the corresponding (closest)
50 click occurred on; not necessarily a data point coordinate. To find the corresponding (closest)
50 data point you can use closestPoint().
51 data point you can use closestPoint().
51 */
52 */
52
53
53 /*!
54 \fn void QScatterSeries::changed()
55 \brief TODO
56 */
57
58 QTCOMMERCIALCHART_BEGIN_NAMESPACE
54 QTCOMMERCIALCHART_BEGIN_NAMESPACE
59
55
60 QScatterSeriesPrivate::QScatterSeriesPrivate() :
56 QScatterSeriesPrivate::QScatterSeriesPrivate(QObject *parent) :
57 QObject(parent),
61 m_data(QList<QPointF>()),
58 m_data(QList<QPointF>()),
62 m_markerPen(QPen(QColor::Invalid)),
59 m_markerPen(QPen(QColor::Invalid)),
63 m_markerBrush(QBrush(QColor::Invalid)),
60 m_markerBrush(QBrush(QColor::Invalid)),
64 m_markerShape(QScatterSeries::MarkerShapeDefault),
61 m_markerShape(QScatterSeries::MarkerShapeDefault),
65 m_markerSize(9.0)
62 m_markerSize(9.0)
66 {
63 {
67 }
64 }
68
65
66 void QScatterSeriesPrivate::emitChanged()
67 {
68 emit changed();
69 }
70
71 #include "moc_scatterseries_p.cpp"
72
69 /*!
73 /*!
70 Constructs a series object which is a child of \a parent.
74 Constructs a series object which is a child of \a parent.
71 */
75 */
72 QScatterSeries::QScatterSeries(QObject *parent) :
76 QScatterSeries::QScatterSeries(QObject *parent) :
73 QSeries(parent),
77 QSeries(parent),
74 d(new QScatterSeriesPrivate())
78 d(new QScatterSeriesPrivate(this))
75 {
79 {
76 }
80 }
77
81
78 /*!
82 /*!
79 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
83 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
80 */
84 */
81 QScatterSeries::~QScatterSeries()
85 QScatterSeries::~QScatterSeries()
82 {
86 {
83 delete d;
87 delete d;
84 }
88 }
85
89
86 /*!
90 /*!
87 Add single data point with \a x and \a y coordinates to the series.
91 Add single data point with \a x and \a y coordinates to the series.
88 */
92 */
89 void QScatterSeries::add(qreal x, qreal y)
93 void QScatterSeries::add(qreal x, qreal y)
90 {
94 {
91 d->m_data.append(QPointF(x, y));
95 d->m_data.append(QPointF(x, y));
92 emit changed();
96 d->emitChanged();
93 }
97 }
94
98
95 /*!
99 /*!
96 Add single data point with \a value to the series.
100 Add single data point with \a value to the series.
97 */
101 */
98 void QScatterSeries::add(QPointF value)
102 void QScatterSeries::add(QPointF value)
99 {
103 {
100 d->m_data.append(value);
104 d->m_data.append(value);
101 emit changed();
105 d->emitChanged();
102 }
106 }
103
107
104 /*!
108 /*!
105 Add list of \a points to the series.
109 Add list of \a points to the series.
106 */
110 */
107 void QScatterSeries::add(QList<QPointF> points)
111 void QScatterSeries::add(QList<QPointF> points)
108 {
112 {
109 d->m_data.append(points);
113 d->m_data.append(points);
110 emit changed();
114 d->emitChanged();
111 }
115 }
112
116
113 /*!
117 /*!
114 Stream operator for adding a data point with \a value to the series.
118 Stream operator for adding a data point with \a value to the series.
115 \sa add()
119 \sa add()
116
120
117 For example:
121 For example:
118 \snippet ../example/scatter/main.cpp 2
122 \snippet ../example/scatter/main.cpp 2
119 */
123 */
120 QScatterSeries& QScatterSeries::operator << (const QPointF &value)
124 QScatterSeries& QScatterSeries::operator << (const QPointF &value)
121 {
125 {
122 d->m_data.append(value);
126 d->m_data.append(value);
123 emit changed();
127 d->emitChanged();
124 return *this;
128 return *this;
125 }
129 }
126
130
127 /*!
131 /*!
128 Stream operator for adding a list of points to the series.
132 Stream operator for adding a list of points to the series.
129 \sa add()
133 \sa add()
130 */
134 */
131 QScatterSeries& QScatterSeries::operator << (QList<QPointF> value)
135 QScatterSeries& QScatterSeries::operator << (QList<QPointF> value)
132 {
136 {
133 d->m_data.append(value);
137 d->m_data.append(value);
134 emit changed();
138 d->emitChanged();
135 return *this;
139 return *this;
136 }
140 }
137
141
138 /*!
142 /*!
139 Replaces the data of the series with the given list of data \a points.
143 Replaces the data of the series with the given list of data \a points.
140 */
144 */
141 void QScatterSeries::setData(QList<QPointF> points)
145 void QScatterSeries::setData(QList<QPointF> points)
142 {
146 {
143 d->m_data = points;
147 d->m_data = points;
144 emit changed();
148 d->emitChanged();
145 }
149 }
146
150
147 /*!
151 /*!
148 Returns the current list of data points of the series.
152 Returns the current list of data points of the series.
149 */
153 */
150 QList<QPointF> QScatterSeries::data()
154 QList<QPointF> QScatterSeries::data()
151 {
155 {
152 return d->m_data;
156 return d->m_data;
153 }
157 }
154
158
155 /*!
159 /*!
156 Replaces the point at \a index with \a newPoint. Returns true if \a index is a valid position
160 Replaces the point at \a index with \a newPoint. Returns true if \a index is a valid position
157 in the series data, false otherwise.
161 in the series data, false otherwise.
158 */
162 */
159 bool QScatterSeries::replace(int index, QPointF newPoint)
163 bool QScatterSeries::replace(int index, QPointF newPoint)
160 {
164 {
161 if (index >= 0 && index < d->m_data.count()) {
165 if (index >= 0 && index < d->m_data.count()) {
162 d->m_data.replace(index, newPoint);
166 d->m_data.replace(index, newPoint);
163 emit changed();
167 d->emitChanged();
164 return true;
168 return true;
165 }
169 }
166 return false;
170 return false;
167 }
171 }
168
172
169 /*!
173 /*!
170 Remove the data point at \a index. Returns true if a point was removed, false if the point
174 Remove the data point at \a index. Returns true if a point was removed, false if the point
171 at \a index does not exist on the series.
175 at \a index does not exist on the series.
172 */
176 */
173 bool QScatterSeries::removeAt(int index)
177 bool QScatterSeries::removeAt(int index)
174 {
178 {
175 if (index >=0 && index < d->m_data.count()) {
179 if (index >=0 && index < d->m_data.count()) {
176 d->m_data.removeAt(index);
180 d->m_data.removeAt(index);
177 emit changed();
181 d->emitChanged();
178 return true;
182 return true;
179 }
183 }
180 return false;
184 return false;
181 }
185 }
182
186
183 /*!
187 /*!
184 Remove all occurrences of \a point from the series and returns the number of points removed.
188 Remove all occurrences of \a point from the series and returns the number of points removed.
185 */
189 */
186 int QScatterSeries::removeAll(QPointF point)
190 int QScatterSeries::removeAll(QPointF point)
187 {
191 {
188 int count = d->m_data.removeAll(point);
192 int count = d->m_data.removeAll(point);
189 emit changed();
193 d->emitChanged();
190 return count;
194 return count;
191 }
195 }
192
196
193 /*!
197 /*!
194 Remove all data points from the series.
198 Remove all data points from the series.
195 */
199 */
196 void QScatterSeries::clear()
200 void QScatterSeries::clear()
197 {
201 {
198 d->m_data.clear();
202 d->m_data.clear();
199 emit changed();
203 d->emitChanged();
200 }
204 }
201
205
202 /*!
206 /*!
203 Returns the index of the data point that is closest to \a coordinate. If several data points
207 Returns the index of the data point that is closest to \a coordinate. If several data points
204 are at the same distance from the \a coordinate, returns the last one. If no points exist,
208 are at the same distance from the \a coordinate, returns the last one. If no points exist,
205 returns -1.
209 returns -1.
206 */
210 */
207 int QScatterSeries::closestPoint(QPointF coordinate)
211 int QScatterSeries::closestPoint(QPointF coordinate)
208 {
212 {
209 qreal distance(-1);
213 qreal distance(-1);
210 int pointIndex(-1);
214 int pointIndex(-1);
211 for (int i(0); i < d->m_data.count(); i++) {
215 for (int i(0); i < d->m_data.count(); i++) {
212 QPointF dataPoint = d->m_data.at(i);
216 QPointF dataPoint = d->m_data.at(i);
213 QPointF difference = dataPoint - coordinate;
217 QPointF difference = dataPoint - coordinate;
214 if (i == 0 || difference.manhattanLength() <= distance) {
218 if (i == 0 || difference.manhattanLength() <= distance) {
215 distance = difference.manhattanLength();
219 distance = difference.manhattanLength();
216 pointIndex = i;
220 pointIndex = i;
217 }
221 }
218 }
222 }
219 return pointIndex;
223 return pointIndex;
220 }
224 }
221
225
222 /*!
226 /*!
227 Returns the pen used for drawing markers.
228 */
229 QPen QScatterSeries::pen() const
230 {
231 return d->m_markerPen;
232 }
233
234 /*!
223 Overrides the default pen used for drawing a marker item with a user defined \a pen. The
235 Overrides the default pen used for drawing a marker item with a user defined \a pen. The
224 default pen is defined by chart theme setting.
236 default pen is defined by chart theme setting.
225
237
226 \sa setBrush()
238 \sa setBrush()
227 \sa QChart::setChartTheme()
239 \sa QChart::setChartTheme()
228 */
240 */
229 void QScatterSeries::setPen(QPen pen)
241 void QScatterSeries::setPen(const QPen &pen)
230 {
242 {
231 d->m_markerPen = pen;
243 d->m_markerPen = pen;
244 d->emitChanged();
232 }
245 }
233
246
234 /*!
247 /*!
235 Returns the pen used for drawing markers.
248 Returns the brush used for drawing markers.
236 */
249 */
237 QPen QScatterSeries::pen()
250 QBrush QScatterSeries::brush() const
238 {
251 {
239 return d->m_markerPen;
252 return d->m_markerBrush;
240 }
253 }
241
254
242 /*!
255 /*!
243 Overrides the default brush of the marker items with a user defined \a brush. The default brush
256 Overrides the default brush of the marker items with a user defined \a brush. The default brush
244 is defined by chart theme setting.
257 is defined by chart theme setting.
245
258
246 \sa setPen()
259 \sa setPen()
247 \sa QChart::setChartTheme()
260 \sa QChart::setChartTheme()
248 */
261 */
249 void QScatterSeries::setBrush(QBrush brush)
262 void QScatterSeries::setBrush(const QBrush &brush)
250 {
263 {
251 d->m_markerBrush = brush;
264 d->m_markerBrush = brush;
265 d->emitChanged();
252 }
266 }
253
267
254 /*!
268 /*!
255 Returns the brush used for drawing markers.
269 Returns the shape used for drawing markers.
256 */
270 */
257 QBrush QScatterSeries::brush()
271 QScatterSeries::MarkerShape QScatterSeries::shape() const
258 {
272 {
259 return d->m_markerBrush;
273 return (QScatterSeries::MarkerShape) d->m_markerShape;
260 }
274 }
261
275
262 /*!
276 /*!
263 Overrides the default shape of the marker items with a user defined \a shape. The default shape
277 Overrides the default shape of the marker items with a user defined \a shape. The default shape
264 is defined by chart theme setting.
278 is defined by chart theme setting.
265 */
279 */
266 void QScatterSeries::setShape(MarkerShape shape)
280 void QScatterSeries::setShape(MarkerShape shape)
267 {
281 {
268 d->m_markerShape = shape;
282 d->m_markerShape = shape;
269 }
283 d->emitChanged();
270
271 /*!
272 Returns the shape used for drawing markers.
273 */
274 QScatterSeries::MarkerShape QScatterSeries::shape()
275 {
276 return (QScatterSeries::MarkerShape) d->m_markerShape;
277 }
284 }
278
285
279 /*!
286 /*!
280 Returns the size of the marker items.
287 Returns the size of the marker items.
281 */
288 */
282 qreal QScatterSeries::size()
289 qreal QScatterSeries::size() const
283 {
290 {
284 return d->m_markerSize;
291 return d->m_markerSize;
285 }
292 }
286
293
287 /*!
294 /*!
288 Set the \a size of the marker items. The default size is 9.0.
295 Set the \a size of the marker items. The default size is 9.0.
289 */
296 */
290 void QScatterSeries::setSize(qreal size)
297 void QScatterSeries::setSize(qreal size)
291 {
298 {
292 d->m_markerSize = size;
299 d->m_markerSize = size;
293 emit changed();
300 d->emitChanged();
294 }
301 }
295
302
296 #include "moc_qscatterseries.cpp"
303 #include "moc_qscatterseries.cpp"
297
304
298 QTCOMMERCIALCHART_END_NAMESPACE
305 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,73 +1,71
1 #ifndef QSCATTERSERIES_H
1 #ifndef QSCATTERSERIES_H
2 #define QSCATTERSERIES_H
2 #define QSCATTERSERIES_H
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include <QRectF>
5 #include <QRectF>
6 #include <QColor>
6 #include <QColor>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 class QScatterSeriesPrivate;
9 class QScatterSeriesPrivate;
10
10
11 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QSeries
11 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QSeries
12 {
12 {
13 Q_OBJECT
13 Q_OBJECT
14
14
15 public:
15 public:
16 enum MarkerShape {
16 enum MarkerShape {
17 // TODO: to be defined by the graphics design
17 // TODO: to be defined by the graphics design
18 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
18 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
19 MarkerShapeDefault = 0,
19 MarkerShapeDefault = 0,
20 MarkerShapeX,
20 MarkerShapeX,
21 MarkerShapeRectangle,
21 MarkerShapeRectangle,
22 MarkerShapeRoundedRectangle,
22 MarkerShapeTiltedRectangle,
23 MarkerShapeTiltedRectangle,
23 MarkerShapeTriangle,
24 MarkerShapeTriangle,
24 MarkerShapeCircle
25 MarkerShapeCircle
25 };
26 };
26
27
27 public:
28 public:
28 QScatterSeries(QObject *parent = 0);
29 QScatterSeries(QObject *parent = 0);
29 ~QScatterSeries();
30 ~QScatterSeries();
30
31
31 public: // from QChartSeries
32 public: // from QChartSeries
32 QSeriesType type() const { return QSeries::SeriesTypeScatter; }
33 QSeriesType type() const { return QSeries::SeriesTypeScatter; }
33
34
34 public:
35 public:
35 void add(qreal x, qreal y);
36 void add(qreal x, qreal y);
36 void add(QPointF value);
37 void add(QPointF value);
37 void add(QList<QPointF> points);
38 void add(QList<QPointF> points);
38 void setData(QList<QPointF> points);
39 void setData(QList<QPointF> points);
39 QScatterSeries& operator << (const QPointF &value);
40 QScatterSeries& operator << (const QPointF &value);
40 QScatterSeries& operator << (QList<QPointF> points);
41 QScatterSeries& operator << (QList<QPointF> points);
41 QList<QPointF> data();
42 QList<QPointF> data();
42 bool replace(int index, QPointF newPoint);
43 bool replace(int index, QPointF newPoint);
43 bool removeAt(int index);
44 bool removeAt(int index);
44 int removeAll(QPointF point);
45 int removeAll(QPointF point);
45 void clear();
46 void clear();
46 int closestPoint(QPointF coordinate);
47 int closestPoint(QPointF coordinate);
47 //TODO: insert, replace...?
48 //TODO: insert, replace...?
48
49
49 QPen pen();
50 QPen pen() const;
50 void setPen(QPen pen);
51 void setPen(const QPen &pen);
51 QBrush brush();
52 QBrush brush() const;
52 void setBrush(QBrush brush);
53 void setBrush(const QBrush &brush);
53 MarkerShape shape();
54 MarkerShape shape() const;
54 void setShape(MarkerShape shape);
55 void setShape(MarkerShape shape);
55 qreal size();
56 qreal size() const;
56 void setSize(qreal size);
57 void setSize(qreal size);
57
58
58 Q_SIGNALS:
59 Q_SIGNALS:
59 void clicked(QPointF coordinate);
60 void clicked(QPointF coordinate);
60 // TODO: move to PIMPL for simplicity or does the user ever need changed signals?
61 // TODO: more finegrained signaling for performance reasons
62 // (check QPieSeries implementation with change sets)
63 void changed();
64
61
65 private:
62 private:
66 Q_DECLARE_PRIVATE(QScatterSeries)
63 Q_DECLARE_PRIVATE(QScatterSeries)
67 Q_DISABLE_COPY(QScatterSeries)
64 Q_DISABLE_COPY(QScatterSeries)
68 QScatterSeriesPrivate *const d;
65 friend class ScatterPresenter;
66 QScatterSeriesPrivate *d;
69 };
67 };
70
68
71 QTCOMMERCIALCHART_END_NAMESPACE
69 QTCOMMERCIALCHART_END_NAMESPACE
72
70
73 #endif // QSCATTERSERIES_H
71 #endif // QSCATTERSERIES_H
@@ -1,156 +1,166
1 #include "scatterpresenter_p.h"
1 #include "scatterpresenter_p.h"
2 #include "qscatterseries.h"
2 #include "qscatterseries.h"
3 #include "scatterseries_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartpresenter_p.h"
4 #include <QPen>
5 #include <QPen>
5 #include <QPainter>
6 #include <QPainter>
6 #include <QGraphicsScene>
7 #include <QGraphicsScene>
7 #include <QGraphicsSceneMouseEvent>
8 #include <QGraphicsSceneMouseEvent>
8 #include <QGraphicsDropShadowEffect>
9 #include <QGraphicsDropShadowEffect>
9 #include <QDebug>
10 #include <QDebug>
10 #include <QTime>
11 #include <QTime>
11
12
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
14
14 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
15 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
15 ChartItem(parent),
16 ChartItem(parent),
16 m_minX(0),
17 m_minX(0),
17 m_maxX(0),
18 m_maxX(0),
18 m_minY(0),
19 m_minY(0),
19 m_maxY(0),
20 m_maxY(0),
20 m_series(series),
21 m_series(series),
21 m_clippingRect()
22 m_clippingRect()
22 {
23 {
23 if (parent)
24 Q_ASSERT(parent);
24 m_clippingRect = parent->boundingRect();
25 Q_ASSERT(series);
25
26 if (series) {
27 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
28 }
29
26
27 m_clippingRect = parent->boundingRect();
28 connect(series->d, SIGNAL(changed()), this, SLOT(handleModelChanged()));
29 connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
30 setZValue(ChartPresenter::ScatterSeriesZValue);
30 setZValue(ChartPresenter::ScatterSeriesZValue);
31
31
32 // TODO: how to draw a drop shadow?
32 // TODO: how to draw a drop shadow?
33 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
33 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
34 // dropShadow->setOffset(2.0);
34 // dropShadow->setOffset(2.0);
35 // dropShadow->setBlurRadius(2.0);
35 // dropShadow->setBlurRadius(2.0);
36 // setGraphicsEffect(dropShadow);
36 // setGraphicsEffect(dropShadow);
37 }
37 }
38
38
39 void ScatterPresenter::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
39 void ScatterPresenter::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 {
40 {
41 m_minX = minX;
41 m_minX = minX;
42 m_maxX = maxX;
42 m_maxX = maxX;
43 m_minY = minY;
43 m_minY = minY;
44 m_maxY = maxY;
44 m_maxY = maxY;
45 changeGeometry();
45 changeGeometry();
46 }
46 }
47
47
48 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
48 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
49 {
49 {
50 m_clippingRect = rect.translated(-rect.topLeft());
50 m_clippingRect = rect.translated(-rect.topLeft());
51 changeGeometry();
51 changeGeometry();
52 setPos(rect.topLeft());
52 setPos(rect.topLeft());
53 }
53 }
54
54
55 void ScatterPresenter::handleModelChanged()
55 void ScatterPresenter::handleModelChanged()
56 {
56 {
57 // TODO: more fine grained modelChanged signaling
57 // TODO: more fine grained modelChanged signaling
58 changeGeometry();
58 changeGeometry();
59 }
59 }
60
60
61 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
61 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
62 {
62 {
63 painter->save();
63 painter->save();
64 painter->setClipRect(m_clippingRect);
64 painter->setClipRect(m_clippingRect);
65
65
66 // TODO: how to draw a drop shadow?
66 // TODO: how to draw a drop shadow?
67 // Now using a custom implementation for drop shadow instead of QGraphicsDropShadowEffect.
67 // Now using a custom implementation for drop shadow instead of QGraphicsDropShadowEffect.
68 // It seems QGraphicsDropShadowEffect is quite heavy, at least on windows without open gl.
68 // It seems QGraphicsDropShadowEffect is quite heavy, at least on windows without open gl.
69 QPen dropShadowPen(QColor(0, 0, 0, 70));
69 QPen dropShadowPen(QColor(0, 0, 0, 70));
70 dropShadowPen.setWidth(3);
70 dropShadowPen.setWidth(3);
71 painter->setPen(dropShadowPen);
71 painter->setPen(dropShadowPen);
72 painter->setBrush(dropShadowPen.color());
72 painter->setBrush(dropShadowPen.color());
73 // painter->setRenderHint(QPainter::Antialiasing);
73 // painter->setRenderHint(QPainter::Antialiasing);
74 painter->drawPath(m_path.translated(2, 2));
74 painter->drawPath(m_path.translated(2, 2));
75
75
76 // Paint the shape
76 // Paint the shape
77 // The custom settings in series override those defined by the theme
77 // The custom settings in series override those defined by the theme
78 QPen pen = m_markerPen;
78 QPen pen = m_markerPen;
79 if (m_series->pen().color().isValid())
79 if (m_series->pen().color().isValid())
80 pen = m_series->pen();
80 pen = m_series->pen();
81 painter->setPen(pen);
81 painter->setPen(pen);
82 if (m_series->brush().color().isValid())
82 if (m_series->brush().color().isValid())
83 painter->setBrush(m_series->brush());
83 painter->setBrush(m_series->brush());
84 else
84 else
85 painter->setBrush(m_markerBrush);
85 painter->setBrush(m_markerBrush);
86
86
87 // If either pen or brush is opaque, we need to draw the polygons one-by-one
87 // If either pen or brush is opaque, we need to draw the polygons one-by-one
88 if (painter->pen().color().alpha() < 255 || painter->brush().color().alpha() < 255) {
88 if (painter->pen().color().alpha() < 255 || painter->brush().color().alpha() < 255) {
89 foreach (QPolygonF pol, m_path.toSubpathPolygons())
89 foreach (QPolygonF pol, m_path.toSubpathPolygons())
90 painter->drawPolygon(pol);
90 painter->drawPolygon(pol);
91 } else {
91 } else {
92 painter->drawPath(m_path);
92 painter->drawPath(m_path);
93 }
93 }
94
94
95 painter->restore();
95 painter->restore();
96 }
96 }
97
97
98 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
98 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
99 {
99 {
100 // Empty implementation to grab mouse release events for this item
100 // Empty implementation to grab mouse release events for this item
101 Q_UNUSED(event)
101 Q_UNUSED(event)
102 }
102 }
103
103
104 void ScatterPresenter::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
104 void ScatterPresenter::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
105 {
105 {
106 QPointF clickedPoint(
106 QPointF clickedPoint(
107 m_minX + (event->lastPos().x() / m_clippingRect.width()) * (m_maxX-m_minX),
107 m_minX + (event->lastPos().x() / m_clippingRect.width()) * (m_maxX-m_minX),
108 m_maxY - (event->lastPos().y() / m_clippingRect.height()) * (m_maxY-m_minY));
108 m_maxY - (event->lastPos().y() / m_clippingRect.height()) * (m_maxY-m_minY));
109 emit clicked(clickedPoint);
109 emit clicked(clickedPoint);
110 }
110 }
111
111
112 void ScatterPresenter::changeGeometry()
112 void ScatterPresenter::changeGeometry()
113 {
113 {
114 if (m_clippingRect.isValid()) {
114 if (m_clippingRect.isValid()) {
115 prepareGeometryChange();
115 prepareGeometryChange();
116 qreal scalex = m_clippingRect.width() / (m_maxX - m_minX);
116 qreal scalex = m_clippingRect.width() / (m_maxX - m_minX);
117 qreal scaley = m_clippingRect.height() / (m_maxY - m_minY);
117 qreal scaley = m_clippingRect.height() / (m_maxY - m_minY);
118
118
119 int shape = m_series->shape();
119 int shape = m_series->shape();
120 m_path = QPainterPath();
120 m_path = QPainterPath();
121 m_path.setFillRule(Qt::WindingFill);
121 m_path.setFillRule(Qt::WindingFill);
122 const qreal size = m_series->size();
122 const qreal size = m_series->size();
123
123
124 foreach (QPointF point, m_series->data()) {
124 foreach (QPointF point, m_series->data()) {
125 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
125 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
126 qreal x = point.x() * scalex - m_minX * scalex - size / 2;
126 qreal x = point.x() * scalex - m_minX * scalex - size / 2;
127 qreal y = m_clippingRect.height() - point.y() * scaley + m_minY * scaley - size / 2;
127 qreal y = m_clippingRect.height() - point.y() * scaley + m_minY * scaley - size / 2;
128
128
129 if (x < scene()->width() && y < scene()->height()) {
129 if (x < scene()->width() && y < scene()->height()) {
130 switch (shape) {
130 switch (shape) {
131 case QScatterSeries::MarkerShapeDefault:
131 case QScatterSeries::MarkerShapeDefault:
132 // Fallthrough, defaults to circle
132 // Fallthrough, defaults to circle
133 case QScatterSeries::MarkerShapeCircle:
133 case QScatterSeries::MarkerShapeCircle:
134 m_path.addEllipse(x, y, size, size);
134 m_path.addEllipse(x, y, size, size);
135 break;
135 break;
136 case QScatterSeries::MarkerShapeRectangle:
136 case QScatterSeries::MarkerShapeRectangle:
137 m_path.addRect(x, y, size, size);
137 m_path.addRect(x, y, size, size);
138 break;
138 break;
139 case QScatterSeries::MarkerShapeRoundedRectangle:
140 m_path.addRoundedRect(x, y, size, size, size / 4.0, size / 4.0);
141 break;
139 case QScatterSeries::MarkerShapeTiltedRectangle: {
142 case QScatterSeries::MarkerShapeTiltedRectangle: {
140 // TODO: tilt the rectangle
143 // TODO: tilt the rectangle
141 m_path.addRect(x, y, size, size);
144 m_path.addRect(x, y, size, size);
142 break;
145 break;
143 }
146 }
147 case QScatterSeries::MarkerShapeTriangle: {
148 QPolygonF polygon;
149 polygon << QPointF(0.0, -size) << QPointF(size / 2.0, 0.0) << QPointF(-size / 2, 0.0);
150 // TODO: the position is not exactly right...
151 m_path.addPolygon(polygon.translated(x + size / 2.0, y + size));
152 break;
153 }
144 default:
154 default:
145 // TODO: implement the rest of the shapes
155 // TODO: implement the rest of the shapes
146 Q_ASSERT(false);
156 Q_ASSERT(false);
147 break;
157 break;
148 }
158 }
149 }
159 }
150 }
160 }
151 }
161 }
152 }
162 }
153
163
154 #include "moc_scatterpresenter_p.cpp"
164 #include "moc_scatterpresenter_p.cpp"
155
165
156 QTCOMMERCIALCHART_END_NAMESPACE
166 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,28 +1,37
1 #ifndef QSCATTERSERIESPRIVATE_H
1 #ifndef QSCATTERSERIESPRIVATE_H
2 #define QSCATTERSERIESPRIVATE_H
2 #define QSCATTERSERIESPRIVATE_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qseries.h"
5 #include "qseries.h"
6 #include <QObject>
6 #include <QPen>
7 #include <QPen>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 /*!
11 /*!
11 * The PIMPL class of QScatterSeries.
12 * The PIMPL class of QScatterSeries.
12 */
13 */
13 class QScatterSeriesPrivate
14 class QScatterSeriesPrivate : public QObject
14 {
15 {
16 Q_OBJECT
17
15 public:
18 public:
16 QScatterSeriesPrivate();
19 QScatterSeriesPrivate(QObject *parent);
20 void emitChanged();
21
22 Q_SIGNALS:
23 // TODO: more finegrained signaling for performance reasons
24 // (see for example QPieSeries implementation with change sets)
25 void changed();
17
26
18 public:
27 public:
19 QList<QPointF> m_data;
28 QList<QPointF> m_data;
20 QPen m_markerPen;
29 QPen m_markerPen;
21 QBrush m_markerBrush;
30 QBrush m_markerBrush;
22 int m_markerShape;
31 int m_markerShape;
23 qreal m_markerSize;
32 qreal m_markerSize;
24 };
33 };
25
34
26 QTCOMMERCIALCHART_END_NAMESPACE
35 QTCOMMERCIALCHART_END_NAMESPACE
27
36
28 #endif // QSCATTERSERIESPRIVATE_H
37 #endif // QSCATTERSERIESPRIVATE_H
General Comments 0
You need to be logged in to leave comments. Login now