##// END OF EJS Templates
Added clicked signal to scatter...
Tero Ahola -
r316:101197172c50
parent child
Show More
@@ -1,282 +1,283
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 "qbarchartseries.h"
7 #include "qbarchartseries.h"
8 #include "qstackedbarchartseries.h"
8 #include "qstackedbarchartseries.h"
9 #include "qpercentbarchartseries.h"
9 #include "qpercentbarchartseries.h"
10 #include "qlinechartseries.h"
10 #include "qlinechartseries.h"
11 #include "qpieseries.h"
11 #include "qpieseries.h"
12 #include "qscatterseries.h"
12 #include "qscatterseries.h"
13 //items
13 //items
14 #include "axisitem_p.h"
14 #include "axisitem_p.h"
15 #include "axisanimationitem_p.h"
15 #include "axisanimationitem_p.h"
16 #include "barpresenter.h"
16 #include "barpresenter.h"
17 #include "stackedbarpresenter.h"
17 #include "stackedbarpresenter.h"
18 #include "linechartitem_p.h"
18 #include "linechartitem_p.h"
19 #include "percentbarpresenter.h"
19 #include "percentbarpresenter.h"
20 #include "linechartanimationitem_p.h"
20 #include "linechartanimationitem_p.h"
21 #include "piepresenter.h"
21 #include "piepresenter.h"
22 #include "scatterpresenter_p.h"
22 #include "scatterpresenter_p.h"
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
26 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
27 m_chart(chart),
27 m_chart(chart),
28 m_dataset(dataset),
28 m_dataset(dataset),
29 m_chartTheme(0),
29 m_chartTheme(0),
30 m_marginSize(0),
30 m_marginSize(0),
31 m_rect(QRectF(QPoint(0,0),m_chart->size())),
31 m_rect(QRectF(QPoint(0,0),m_chart->size())),
32 m_options(0)
32 m_options(0)
33 {
33 {
34 createConnections();
34 createConnections();
35 setChartTheme(QChart::ChartThemeDefault);
35 setChartTheme(QChart::ChartThemeDefault);
36
36
37 }
37 }
38
38
39 ChartPresenter::~ChartPresenter()
39 ChartPresenter::~ChartPresenter()
40 {
40 {
41 }
41 }
42
42
43 void ChartPresenter::createConnections()
43 void ChartPresenter::createConnections()
44 {
44 {
45 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
45 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
46 QObject::connect(m_dataset,SIGNAL(seriesAdded(QChartSeries*)),this,SLOT(handleSeriesAdded(QChartSeries*)));
46 QObject::connect(m_dataset,SIGNAL(seriesAdded(QChartSeries*)),this,SLOT(handleSeriesAdded(QChartSeries*)));
47 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QChartSeries*)),this,SLOT(handleSeriesRemoved(QChartSeries*)));
47 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QChartSeries*)),this,SLOT(handleSeriesRemoved(QChartSeries*)));
48 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
48 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
49 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
49 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
50 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QChartSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QChartSeries*,const Domain&)));
50 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QChartSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QChartSeries*,const Domain&)));
51 QObject::connect(m_dataset,SIGNAL(axisLabelsChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisLabelsChanged(QChartAxis*,const QStringList&)));
51 QObject::connect(m_dataset,SIGNAL(axisLabelsChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisLabelsChanged(QChartAxis*,const QStringList&)));
52 }
52 }
53
53
54
54
55 QRectF ChartPresenter::geometry() const
55 QRectF ChartPresenter::geometry() const
56 {
56 {
57 return m_rect;
57 return m_rect;
58 }
58 }
59
59
60 void ChartPresenter::handleGeometryChanged()
60 void ChartPresenter::handleGeometryChanged()
61 {
61 {
62 m_rect = QRectF(QPoint(0,0),m_chart->size());
62 m_rect = QRectF(QPoint(0,0),m_chart->size());
63 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
63 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
64 Q_ASSERT(m_rect.isValid());
64 Q_ASSERT(m_rect.isValid());
65 emit geometryChanged(m_rect);
65 emit geometryChanged(m_rect);
66 }
66 }
67
67
68 int ChartPresenter::margin() const
68 int ChartPresenter::margin() const
69 {
69 {
70 return m_marginSize;
70 return m_marginSize;
71 }
71 }
72
72
73 void ChartPresenter::setMargin(int margin)
73 void ChartPresenter::setMargin(int margin)
74 {
74 {
75 m_marginSize = margin;
75 m_marginSize = margin;
76 }
76 }
77
77
78 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
78 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
79 {
79 {
80
80
81 AxisItem* item ;
81 AxisItem* item ;
82
82
83 if(!m_options.testFlag(QChart::GridAxisAnimations))
83 if(!m_options.testFlag(QChart::GridAxisAnimations))
84 {
84 {
85 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
85 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
86 }else{
86 }else{
87 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
87 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
88 }
88 }
89
89
90 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
90 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
91 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
91 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
92
92
93 item->handleAxisUpdate(axis);
93 item->handleAxisUpdate(axis);
94 item->handleGeometryChanged(m_rect);
94 item->handleGeometryChanged(m_rect);
95 m_chartTheme->decorate(axis,item);
95 m_chartTheme->decorate(axis,item);
96 m_axisItems.insert(axis,item);
96 m_axisItems.insert(axis,item);
97 }
97 }
98
98
99 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
99 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
100 {
100 {
101 AxisItem* item = m_axisItems.take(axis);
101 AxisItem* item = m_axisItems.take(axis);
102 Q_ASSERT(item);
102 Q_ASSERT(item);
103 delete item;
103 delete item;
104 }
104 }
105
105
106
106
107 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
107 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
108 {
108 {
109 switch(series->type())
109 switch(series->type())
110 {
110 {
111 case QChartSeries::SeriesTypeLine: {
111 case QChartSeries::SeriesTypeLine: {
112 QLineChartSeries* lineSeries = static_cast<QLineChartSeries*>(series);
112 QLineChartSeries* lineSeries = static_cast<QLineChartSeries*>(series);
113 LineChartItem* item;
113 LineChartItem* item;
114 if(m_options.testFlag(QChart::SeriesAnimations)){
114 if(m_options.testFlag(QChart::SeriesAnimations)){
115 item = new LineChartAnimationItem(this,lineSeries,m_chart);
115 item = new LineChartAnimationItem(this,lineSeries,m_chart);
116 }else{
116 }else{
117 item = new LineChartItem(this,lineSeries,m_chart);
117 item = new LineChartItem(this,lineSeries,m_chart);
118 }
118 }
119 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
119 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
121 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
122 m_chartItems.insert(series,item);
122 m_chartItems.insert(series,item);
123 break;
123 break;
124 }
124 }
125
125
126 case QChartSeries::SeriesTypeBar: {
126 case QChartSeries::SeriesTypeBar: {
127 QBarChartSeries* barSeries = static_cast<QBarChartSeries*>(series);
127 QBarChartSeries* barSeries = static_cast<QBarChartSeries*>(series);
128 BarPresenter* item = new BarPresenter(barSeries,m_chart);
128 BarPresenter* item = new BarPresenter(barSeries,m_chart);
129 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
129 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
130 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
130 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
131 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
131 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
132 m_chartItems.insert(series,item);
132 m_chartItems.insert(series,item);
133 // m_axisXItem->setVisible(false);
133 // m_axisXItem->setVisible(false);
134 break;
134 break;
135 }
135 }
136
136
137 case QChartSeries::SeriesTypeStackedBar: {
137 case QChartSeries::SeriesTypeStackedBar: {
138
138
139 QStackedBarChartSeries* stackedBarSeries = static_cast<QStackedBarChartSeries*>(series);
139 QStackedBarChartSeries* stackedBarSeries = static_cast<QStackedBarChartSeries*>(series);
140 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
140 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
141 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
141 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
142 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
142 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
143 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
143 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
144 m_chartItems.insert(series,item);
144 m_chartItems.insert(series,item);
145 break;
145 break;
146 }
146 }
147
147
148 case QChartSeries::SeriesTypePercentBar: {
148 case QChartSeries::SeriesTypePercentBar: {
149
149
150 QPercentBarChartSeries* percentBarSeries = static_cast<QPercentBarChartSeries*>(series);
150 QPercentBarChartSeries* percentBarSeries = static_cast<QPercentBarChartSeries*>(series);
151 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
151 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
152 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
152 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
153 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
153 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
154 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
154 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
155 m_chartItems.insert(series,item);
155 m_chartItems.insert(series,item);
156 break;
156 break;
157 }
157 }
158 case QChartSeries::SeriesTypeScatter: {
158 case QChartSeries::SeriesTypeScatter: {
159 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
159 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
160 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
160 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
161 QObject::connect(scatterPresenter, SIGNAL(clicked()), scatterSeries, SIGNAL(clicked()));
161 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
162 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
162 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
163 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
163 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
164 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
164 m_chartItems.insert(scatterSeries, scatterPresenter);
165 m_chartItems.insert(scatterSeries, scatterPresenter);
165 break;
166 break;
166 }
167 }
167 case QChartSeries::SeriesTypePie: {
168 case QChartSeries::SeriesTypePie: {
168 QPieSeries *s = qobject_cast<QPieSeries *>(series);
169 QPieSeries *s = qobject_cast<QPieSeries *>(series);
169 PiePresenter* pie = new PiePresenter(m_chart, s);
170 PiePresenter* pie = new PiePresenter(m_chart, s);
170 m_chartTheme->decorate(pie, s, m_chartItems.count());
171 m_chartTheme->decorate(pie, s, m_chartItems.count());
171 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
172 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
172
173
173 // Hide all from background when there is only piechart
174 // Hide all from background when there is only piechart
174 // TODO: refactor this ugly code... should be one setting for this
175 // TODO: refactor this ugly code... should be one setting for this
175 if (m_chartItems.count() == 0) {
176 if (m_chartItems.count() == 0) {
176 m_chart->axisX()->setAxisVisible(false);
177 m_chart->axisX()->setAxisVisible(false);
177 m_chart->axisY()->setAxisVisible(false);
178 m_chart->axisY()->setAxisVisible(false);
178 m_chart->axisX()->setGridVisible(false);
179 m_chart->axisX()->setGridVisible(false);
179 m_chart->axisY()->setGridVisible(false);
180 m_chart->axisY()->setGridVisible(false);
180 m_chart->axisX()->setLabelsVisible(false);
181 m_chart->axisX()->setLabelsVisible(false);
181 m_chart->axisY()->setLabelsVisible(false);
182 m_chart->axisY()->setLabelsVisible(false);
182 m_chart->axisX()->setShadesVisible(false);
183 m_chart->axisX()->setShadesVisible(false);
183 m_chart->axisY()->setShadesVisible(false);
184 m_chart->axisY()->setShadesVisible(false);
184 m_chart->setChartBackgroundBrush(Qt::transparent);
185 m_chart->setChartBackgroundBrush(Qt::transparent);
185 }
186 }
186
187
187 m_chartItems.insert(series, pie);
188 m_chartItems.insert(series, pie);
188 break;
189 break;
189 }
190 }
190 default: {
191 default: {
191 qDebug()<< "Series type" << series->type() << "not implemented.";
192 qDebug()<< "Series type" << series->type() << "not implemented.";
192 break;
193 break;
193 }
194 }
194 }
195 }
195
196
196 if(m_rect.isValid()) emit geometryChanged(m_rect);
197 if(m_rect.isValid()) emit geometryChanged(m_rect);
197 }
198 }
198
199
199 void ChartPresenter::handleSeriesRemoved(QChartSeries* series)
200 void ChartPresenter::handleSeriesRemoved(QChartSeries* series)
200 {
201 {
201 ChartItem* item = m_chartItems.take(series);
202 ChartItem* item = m_chartItems.take(series);
202 delete item;
203 delete item;
203 }
204 }
204
205
205 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
206 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
206 {
207 {
207 //TODO:
208 //TODO:
208 }
209 }
209
210
210 void ChartPresenter::handleSeriesDomainChanged(QChartSeries* series, const Domain& domain)
211 void ChartPresenter::handleSeriesDomainChanged(QChartSeries* series, const Domain& domain)
211 {
212 {
212 m_chartItems.value(series)->handleDomainChanged(domain);
213 m_chartItems.value(series)->handleDomainChanged(domain);
213 }
214 }
214
215
215 void ChartPresenter::handleAxisLabelsChanged(QChartAxis* axis,const QStringList& labels)
216 void ChartPresenter::handleAxisLabelsChanged(QChartAxis* axis,const QStringList& labels)
216 {
217 {
217 m_axisItems.value(axis)->handleLabelsChanged(axis,labels);
218 m_axisItems.value(axis)->handleLabelsChanged(axis,labels);
218 }
219 }
219
220
220 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
221 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
221 {
222 {
222 delete m_chartTheme;
223 delete m_chartTheme;
223
224
224 m_chartTheme = ChartTheme::createTheme(theme);
225 m_chartTheme = ChartTheme::createTheme(theme);
225
226
226 m_chartTheme->decorate(m_chart);
227 m_chartTheme->decorate(m_chart);
227 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
228 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
228
229
229 int index=0;
230 int index=0;
230 while (i.hasNext()) {
231 while (i.hasNext()) {
231 i.next();
232 i.next();
232 m_chartTheme->decorate(i.value(),i.key(),index);
233 m_chartTheme->decorate(i.value(),i.key(),index);
233 index++;
234 index++;
234 }
235 }
235
236
236 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
237 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
237 while (j.hasNext()) {
238 while (j.hasNext()) {
238 j.next();
239 j.next();
239 m_chartTheme->decorate(j.key(),j.value());
240 m_chartTheme->decorate(j.key(),j.value());
240 }
241 }
241 }
242 }
242
243
243 QChart::ChartTheme ChartPresenter::chartTheme()
244 QChart::ChartTheme ChartPresenter::chartTheme()
244 {
245 {
245 return m_chartTheme->id();
246 return m_chartTheme->id();
246 }
247 }
247
248
248 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
249 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
249 {
250 {
250 if(m_options!=options) {
251 if(m_options!=options) {
251
252
252 m_options=options;
253 m_options=options;
253
254
254 //recreate elements
255 //recreate elements
255
256
256 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
257 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
257 QList<QChartSeries*> seriesList = m_chartItems.uniqueKeys();
258 QList<QChartSeries*> seriesList = m_chartItems.uniqueKeys();
258
259
259 foreach(QChartAxis* axis, axisList) {
260 foreach(QChartAxis* axis, axisList) {
260 handleAxisRemoved(axis);
261 handleAxisRemoved(axis);
261 handleAxisAdded(axis);
262 handleAxisAdded(axis);
262 }
263 }
263 foreach(QChartSeries* series, seriesList) {
264 foreach(QChartSeries* series, seriesList) {
264 handleSeriesRemoved(series);
265 handleSeriesRemoved(series);
265 handleSeriesAdded(series);
266 handleSeriesAdded(series);
266 }
267 }
267
268
268 //now reintialize view data
269 //now reintialize view data
269 //TODO: make it more nice
270 //TODO: make it more nice
270 m_dataset->setDomain(m_dataset->domainIndex());
271 m_dataset->setDomain(m_dataset->domainIndex());
271 }
272 }
272 }
273 }
273
274
274 QChart::AnimationOptions ChartPresenter::animationOptions() const
275 QChart::AnimationOptions ChartPresenter::animationOptions() const
275 {
276 {
276 return m_options;
277 return m_options;
277 }
278 }
278
279
279
280
280 #include "moc_chartpresenter_p.cpp"
281 #include "moc_chartpresenter_p.cpp"
281
282
282 QTCOMMERCIALCHART_END_NAMESPACE
283 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,162 +1,134
1 #include "scatterpresenter_p.h"
1 #include "scatterpresenter_p.h"
2 #include "qscatterseries.h"
2 #include "qscatterseries.h"
3 #include <QPen>
3 #include <QPen>
4 #include <QPainter>
4 #include <QPainter>
5 #include <QGraphicsScene>
5 #include <QGraphicsScene>
6 #include <QGraphicsSceneMouseEvent>
6 #include <QDebug>
7 #include <QDebug>
7 #include <QTime>
8 #include <QTime>
8
9
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
11
11 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
12 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
12 ChartItem(parent),
13 ChartItem(parent),
13 m_series(series),
14 m_series(series),
14 m_boundingRect(),
15 m_boundingRect(),
15 //m_markerColor(QColor()),
16 //m_markerColor(QColor()),
16 // m_markerColor(QColor(255, 0, 0)),
17 // m_markerColor(QColor(255, 0, 0)),
17 m_visibleChartArea()
18 m_visibleChartArea()
18 {
19 {
19 if (parent)
20 if (parent)
20 m_boundingRect = parent->boundingRect();
21 m_boundingRect = parent->boundingRect();
21
22
22 if (series) {
23 if (series) {
23 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
24 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
24 }
25 }
25 }
26 }
26
27
27 void ScatterPresenter::handleDomainChanged(const Domain& domain)
28 void ScatterPresenter::handleDomainChanged(const Domain& domain)
28 {
29 {
29 m_visibleChartArea = domain;
30 m_visibleChartArea = domain;
30 changeGeometry();
31 changeGeometry();
31 }
32 }
32
33
33 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
34 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
34 {
35 {
35 m_boundingRect = rect;
36 m_boundingRect = rect;
36 changeGeometry();
37 changeGeometry();
37 }
38 }
38
39
39 void ScatterPresenter::handleModelChanged()
40 void ScatterPresenter::handleModelChanged()
40 {
41 {
41 // TODO: more fine grained modelChanged signaling
42 // TODO: more fine grained modelChanged signaling
42 changeGeometry();
43 changeGeometry();
43 }
44 }
44
45
45 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
46 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
46 {
47 {
47 // TODO: Optimization: avoid setting on every paint method call?
48 // The custom settings in series override those defined by the theme
49 int shape = m_series->markerShape();
50
51 painter->save();
48 painter->save();
52 painter->setClipRect(m_boundingRect);
49 painter->setClipRect(m_boundingRect);
53
50
54 // Paint dropshadow
55 QPen dropShadowPen(QColor(0, 0, 0, 70));
56 dropShadowPen.setWidth(3);
57 painter->setPen(dropShadowPen);
58 painter->setBrush(Qt::NoBrush);
59 painter->setRenderHint(QPainter::Antialiasing);
60 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
61 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
62 switch (shape) {
63 case QScatterSeries::MarkerShapeDefault:
64 // Fallthrough, defaults to circle
65 case QScatterSeries::MarkerShapeCircle:
66 painter->drawChord(m_scenex.at(i) + 2, m_sceney.at(i) + 2, 9, 9, 0, 5760);
67 break;
68 case QScatterSeries::MarkerShapePoint:
69 //painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
70 break;
71 case QScatterSeries::MarkerShapeRectangle:
72 painter->drawRect(m_scenex.at(i) + 2, m_sceney.at(i) + 2, 8, 8);
73 break;
74 case QScatterSeries::MarkerShapeTiltedRectangle: {
75 // TODO:
76 static const QPointF points[4] = {
77 QPointF(-1.0 + m_scenex.at(i), 0.0 + m_sceney.at(i)),
78 QPointF(0.0 + m_scenex.at(i), 1.0 + m_sceney.at(i)),
79 QPointF(1.0 + m_scenex.at(i), 0.0 + m_sceney.at(i)),
80 QPointF(0.0 + m_scenex.at(i), -1.0 + m_sceney.at(i))
81 };
82 painter->drawPolygon(points, 4);
83 break;
84 }
85 default:
86 // TODO: implement the rest of the shapes
87 Q_ASSERT(false);
88 break;
89 }
90 }
91
92 // Paint the shape
51 // Paint the shape
52 // The custom settings in series override those defined by the theme
93 QPen pen = m_markerPen;
53 QPen pen = m_markerPen;
94 if (m_series->markerPen().color().isValid())
54 if (m_series->markerPen().color().isValid())
95 pen = m_series->markerPen();
55 pen = m_series->markerPen();
96 if (m_series->markerBrush().color().isValid())
56 if (m_series->markerBrush().color().isValid())
97 painter->setBrush(m_series->markerBrush());
57 painter->setBrush(m_series->markerBrush());
98 else
58 else
99 painter->setBrush(m_markerBrush);
59 painter->setBrush(m_markerBrush);
100 painter->setPen(pen);
60 painter->setPen(pen);
101 painter->setRenderHint(QPainter::Antialiasing, false);
61 painter->drawPath(m_path);
102 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
62
103 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
63 // TODO: how to draw a drop shadow?
104 switch (shape) {
64 QPen dropShadowPen(QColor(0, 0, 0, 70));
105 case QScatterSeries::MarkerShapeDefault:
65 dropShadowPen.setWidth(3);
106 // Fallthrough, defaults to circle
66 painter->setPen(dropShadowPen);
107 case QScatterSeries::MarkerShapeCircle:
67 painter->setBrush(Qt::NoBrush);
108 painter->drawChord(m_scenex.at(i), m_sceney.at(i), 9, 9, 0, 5760);
68 painter->setRenderHint(QPainter::Antialiasing);
109 break;
69 painter->drawPath(m_path.translated(2, 2));
110 case QScatterSeries::MarkerShapePoint:
111 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
112 break;
113 case QScatterSeries::MarkerShapeRectangle:
114 painter->drawRect(m_scenex.at(i), m_sceney.at(i), 9, 9);
115 break;
116 case QScatterSeries::MarkerShapeTiltedRectangle: {
117 // TODO:
118 static const QPointF points[4] = {
119 QPointF(-1.0 + m_scenex.at(i), 0.0 + m_sceney.at(i)),
120 QPointF(0.0 + m_scenex.at(i), 1.0 + m_sceney.at(i)),
121 QPointF(1.0 + m_scenex.at(i), 0.0 + m_sceney.at(i)),
122 QPointF(0.0 + m_scenex.at(i), -1.0 + m_sceney.at(i))
123 };
124 painter->drawPolygon(points, 4);
125 break;
126 }
127 default:
128 // TODO: implement the rest of the shapes
129 Q_ASSERT(false);
130 break;
131 }
132 }
133
70
134 painter->restore();
71 painter->restore();
135 }
72 }
136
73
137 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
74 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
138 {
75 {
139 qDebug() << "ScatterPresenter::mousePressEvent" << event;
76 qDebug() << "ScatterPresenter::mousePressEvent" << event << " cont: "
77 << m_path.contains(event->lastPos());
78
79 if (m_path.contains(event->lastPos()))
80 emit clicked();
140 }
81 }
141
82
142 void ScatterPresenter::changeGeometry()
83 void ScatterPresenter::changeGeometry()
143 {
84 {
144 if (m_boundingRect.isValid()) {
85 if (m_boundingRect.isValid()) {
145
146 prepareGeometryChange();
86 prepareGeometryChange();
147 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
87 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
148 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
88 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
149 m_scenex.clear();
150 m_sceney.clear();
151
89
152 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
90 int shape = m_series->markerShape();
91 m_path = QPainterPath();
92
153 foreach (QPointF point, m_series->data()) {
93 foreach (QPointF point, m_series->data()) {
154 m_scenex.append(m_boundingRect.left() + point.x() * scalex - m_visibleChartArea.m_minX * scalex);
94 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
155 m_sceney.append(m_boundingRect.bottom() - point.y() * scaley + m_visibleChartArea.m_minY * scaley);
95 qreal x = m_boundingRect.left() + point.x() * scalex - m_visibleChartArea.m_minX * scalex;
96 qreal y = m_boundingRect.bottom() - point.y() * scaley + m_visibleChartArea.m_minY * scaley;
97
98 if (scene()->width() > x && scene()->height() > y) {
99 switch (shape) {
100 case QScatterSeries::MarkerShapeDefault:
101 // Fallthrough, defaults to circle
102 case QScatterSeries::MarkerShapeCircle:
103 m_path.addEllipse(x, y, 9, 9);
104 break;
105 case QScatterSeries::MarkerShapePoint:
106 m_path.addEllipse(x, y, 2, 2);
107 break;
108 case QScatterSeries::MarkerShapeRectangle:
109 m_path.addRect(x, y, 9, 9);
110 break;
111 case QScatterSeries::MarkerShapeTiltedRectangle: {
112 // TODO:
113 // static const QPointF points[4] = {
114 // QPointF(-1.0 + x, 0.0 + y),
115 // QPointF(0.0 + x, 1.0 + y),
116 // QPointF(1.0 + x, 0.0 + y),
117 // QPointF(0.0 + x, -1.0 + y)
118 // };
119 //m_path.addPolygon(QPolygon(4, &points));
120 break;
121 }
122 default:
123 // TODO: implement the rest of the shapes
124 Q_ASSERT(false);
125 break;
126 }
127 }
156 }
128 }
157 }
129 }
158 }
130 }
159
131
160 #include "moc_scatterpresenter_p.cpp"
132 #include "moc_scatterpresenter_p.cpp"
161
133
162 QTCOMMERCIALCHART_END_NAMESPACE
134 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,49 +1,50
1 #ifndef SCATTERPRESENTER_H
1 #ifndef SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include <QObject>
6 #include <QObject>
7 #include <QPen>
7 #include <QPen>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class QScatterSeries;
11 class QScatterSeries;
12
12
13 /*!
13 /*!
14 * The "business logic" of scatter series. This is a QObject that does not have a parent QObject.
14 * The "business logic" of scatter series. This is a QObject that does not have a parent QObject.
15 * The QGraphicsItem parent owns the object instead.
15 * The QGraphicsItem parent owns the object instead.
16 */
16 */
17 class ScatterPresenter : public QObject, public ChartItem
17 class ScatterPresenter : public QObject, public ChartItem
18 {
18 {
19 Q_OBJECT
19 Q_OBJECT
20 public:
20 public:
21 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
21 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
22
22
23 public: // from ChartItem
23 public: // from ChartItem
24 QRectF boundingRect() const { return m_boundingRect; }
24 QRectF boundingRect() const { return m_path.boundingRect(); }
25 QPainterPath shape() const { return m_path; }
25 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
26 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
26 void mousePressEvent (QGraphicsSceneMouseEvent * event);
27 void mousePressEvent (QGraphicsSceneMouseEvent * event);
27
28
28 signals:
29 Q_SIGNALS:
30 void clicked();
29
31
30 public Q_SLOTS:
32 public Q_SLOTS:
31 void handleDomainChanged(const Domain& domain);
33 void handleDomainChanged(const Domain& domain);
32 void handleGeometryChanged(const QRectF& rect);
34 void handleGeometryChanged(const QRectF& rect);
33 void handleModelChanged();
35 void handleModelChanged();
34
36
35 public:
37 public:
36 void changeGeometry();
38 void changeGeometry();
37
39
38 QScatterSeries *m_series;
40 QScatterSeries *m_series;
39 QRectF m_boundingRect;
41 QRectF m_boundingRect;
40 QList<qreal> m_scenex;
41 QList<qreal> m_sceney;
42 Domain m_visibleChartArea;
42 Domain m_visibleChartArea;
43 QPen m_markerPen;
43 QPen m_markerPen;
44 QBrush m_markerBrush;
44 QBrush m_markerBrush;
45 QPainterPath m_path;
45 };
46 };
46
47
47 QTCOMMERCIALCHART_END_NAMESPACE
48 QTCOMMERCIALCHART_END_NAMESPACE
48
49
49 #endif // SCATTERPRESENTER_H
50 #endif // SCATTERPRESENTER_H
General Comments 0
You need to be logged in to leave comments. Login now