##// END OF EJS Templates
Adds clicked(Point) to lineSeries, changes visible points handling
Michal Klocek -
r544:e21e24989fda
parent child
Show More
@@ -1,316 +1,317
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qlegend.h"
3 #include "qlegend.h"
4 #include "qchartaxis.h"
4 #include "qchartaxis.h"
5 #include <QTime>
5 #include <QTime>
6
6
7 //series
7 //series
8 #include "qbarset.h"
8 #include "qbarset.h"
9 #include "qbarseries.h"
9 #include "qbarseries.h"
10 #include "qstackedbarseries.h"
10 #include "qstackedbarseries.h"
11 #include "qpercentbarseries.h"
11 #include "qpercentbarseries.h"
12 #include "qlineseries.h"
12 #include "qlineseries.h"
13 #include "qareaseries.h"
13 #include "qareaseries.h"
14 #include "qscatterseries.h"
14 #include "qscatterseries.h"
15 #include "qpieseries.h"
15 #include "qpieseries.h"
16 #include "qpieslice.h"
16 #include "qpieslice.h"
17 #include "qsplineseries.h"
17 #include "qsplineseries.h"
18
18
19 //items
19 //items
20 #include "axisitem_p.h"
20 #include "axisitem_p.h"
21 #include "barpresenter_p.h"
21 #include "barpresenter_p.h"
22 #include "stackedbarpresenter_p.h"
22 #include "stackedbarpresenter_p.h"
23 #include "percentbarpresenter_p.h"
23 #include "percentbarpresenter_p.h"
24 #include "linechartitem_p.h"
24 #include "linechartitem_p.h"
25 #include "areachartitem_p.h"
25 #include "areachartitem_p.h"
26 #include "scatterchartitem_p.h"
26 #include "scatterchartitem_p.h"
27 #include "piepresenter_p.h"
27 #include "piepresenter_p.h"
28 #include "splinechartitem_p.h"
28 #include "splinechartitem_p.h"
29
29
30 //themes
30 //themes
31 #include "chartthemedefault_p.h"
31 #include "chartthemedefault_p.h"
32 #include "chartthemevanilla_p.h"
32 #include "chartthemevanilla_p.h"
33 #include "chartthemeicy_p.h"
33 #include "chartthemeicy_p.h"
34 #include "chartthemegrayscale_p.h"
34 #include "chartthemegrayscale_p.h"
35 #include "chartthemescientific_p.h"
35 #include "chartthemescientific_p.h"
36
36
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 ChartTheme::ChartTheme(QChart::ChartTheme id)
40 ChartTheme::ChartTheme(QChart::ChartTheme id)
41 {
41 {
42 m_id = id;
42 m_id = id;
43 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
43 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
44 }
44 }
45
45
46
46
47 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
47 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
48 {
48 {
49 switch(theme) {
49 switch(theme) {
50 case QChart::ChartThemeVanilla:
50 case QChart::ChartThemeVanilla:
51 return new ChartThemeVanilla();
51 return new ChartThemeVanilla();
52 case QChart::ChartThemeIcy:
52 case QChart::ChartThemeIcy:
53 return new ChartThemeIcy();
53 return new ChartThemeIcy();
54 case QChart::ChartThemeGrayscale:
54 case QChart::ChartThemeGrayscale:
55 return new ChartThemeGrayscale();
55 return new ChartThemeGrayscale();
56 case QChart::ChartThemeScientific:
56 case QChart::ChartThemeScientific:
57 return new ChartThemeScientific();
57 return new ChartThemeScientific();
58 default:
58 default:
59 return new ChartThemeDefault();
59 return new ChartThemeDefault();
60 }
60 }
61 }
61 }
62
62
63 void ChartTheme::decorate(QChart* chart)
63 void ChartTheme::decorate(QChart* chart)
64 {
64 {
65 chart->setChartBackgroundBrush(m_backgroundGradient);
65 chart->setChartBackgroundBrush(m_backgroundGradient);
66 }
66 }
67
67
68 void ChartTheme::decorate(QLegend* legend)
68 void ChartTheme::decorate(QLegend* legend)
69 {
69 {
70 legend->setBackgroundBrush(m_backgroundGradient);
70 legend->setBackgroundBrush(m_backgroundGradient);
71 }
71 }
72
72
73 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series, int index)
73 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series, int index)
74 {
74 {
75 QPen pen;
75 QPen pen;
76 QBrush brush;
76 QBrush brush;
77
77
78 if (pen != series->pen()){
78 if (pen != series->pen()){
79 item->setPen(series->pen());
79 item->setPen(series->pen());
80 } else {
80 } else {
81 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
81 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
82 pen.setWidthF(2);
82 pen.setWidthF(2);
83 item->setPen(pen);
83 item->setPen(pen);
84 }
84 }
85
85
86 if (brush != series->brush()) {
86 if (brush != series->brush()) {
87 item->setBrush(series->brush());
87 item->setBrush(series->brush());
88 } else {
88 } else {
89 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
89 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
90 item->setBrush(brush);
90 item->setBrush(brush);
91 }
91 }
92 }
92 }
93
93
94
94
95 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int index)
95 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int index)
96 {
96 {
97 QPen pen;
97 QPen pen;
98 if(pen != series->pen()){
98 if(pen != series->pen()){
99 item->setLinePen(series->pen());
99 series->setPen(series->pen());
100 return;
100 return;
101 }else{
102 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
103 pen.setWidthF(2);
104 series->setPen(pen);
101 }
105 }
102 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
103 pen.setWidthF(2);
104 item->setLinePen(pen);
105 }
106 }
106
107
107 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int index)
108 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int index)
108 {
109 {
109 QList<QBarSet*> sets = series->barSets();
110 QList<QBarSet*> sets = series->barSets();
110 for (int i=0; i<sets.count(); i++) {
111 for (int i=0; i<sets.count(); i++) {
111 qreal pos = 0.5;
112 qreal pos = 0.5;
112 if (sets.count() > 1)
113 if (sets.count() > 1)
113 pos = (qreal) i / (qreal) (sets.count() - 1);
114 pos = (qreal) i / (qreal) (sets.count() - 1);
114 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
115 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
115 sets.at(i)->setBrush(QBrush(c));
116 sets.at(i)->setBrush(QBrush(c));
116
117
117 // Pick label color as far as possible from bar color (within gradient).
118 // Pick label color as far as possible from bar color (within gradient).
118 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
119 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
119 // TODO: better picking of label color?
120 // TODO: better picking of label color?
120 if (pos < 0.3) {
121 if (pos < 0.3) {
121 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
122 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
122 } else {
123 } else {
123 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
124 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
124 }
125 }
125 sets.at(i)->setFloatingValuePen(QPen(c));
126 sets.at(i)->setFloatingValuePen(QPen(c));
126 }
127 }
127 }
128 }
128
129
129 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int index)
130 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int index)
130 {
131 {
131 QList<QBarSet*> sets = series->barSets();
132 QList<QBarSet*> sets = series->barSets();
132 for (int i=0; i<sets.count(); i++) {
133 for (int i=0; i<sets.count(); i++) {
133 qreal pos = 0.5;
134 qreal pos = 0.5;
134 if (sets.count() > 1)
135 if (sets.count() > 1)
135 pos = (qreal) i / (qreal) (sets.count() - 1);
136 pos = (qreal) i / (qreal) (sets.count() - 1);
136 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
137 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
137 sets.at(i)->setBrush(QBrush(c));
138 sets.at(i)->setBrush(QBrush(c));
138
139
139 if (pos < 0.3) {
140 if (pos < 0.3) {
140 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
141 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
141 } else {
142 } else {
142 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
143 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
143 }
144 }
144 sets.at(i)->setFloatingValuePen(QPen(c));
145 sets.at(i)->setFloatingValuePen(QPen(c));
145 }
146 }
146 }
147 }
147
148
148 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int index)
149 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int index)
149 {
150 {
150 QList<QBarSet*> sets = series->barSets();
151 QList<QBarSet*> sets = series->barSets();
151 for (int i=0; i<sets.count(); i++) {
152 for (int i=0; i<sets.count(); i++) {
152 qreal pos = 0.5;
153 qreal pos = 0.5;
153 if (sets.count() > 1)
154 if (sets.count() > 1)
154 pos = (qreal) i / (qreal) (sets.count() - 1);
155 pos = (qreal) i / (qreal) (sets.count() - 1);
155 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
156 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
156 sets.at(i)->setBrush(QBrush(c));
157 sets.at(i)->setBrush(QBrush(c));
157
158
158 if (pos < 0.3) {
159 if (pos < 0.3) {
159 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
160 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
160 } else {
161 } else {
161 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
162 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
162 }
163 }
163 sets.at(i)->setFloatingValuePen(QPen(c));
164 sets.at(i)->setFloatingValuePen(QPen(c));
164 }
165 }
165 }
166 }
166
167
167 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int index)
168 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int index)
168 {
169 {
169 Q_ASSERT(item);
170 Q_ASSERT(item);
170 Q_ASSERT(series);
171 Q_ASSERT(series);
171
172
172 QPen pen;
173 QPen pen;
173 QBrush brush;
174 QBrush brush;
174
175
175 if (pen == series->pen()) {
176 if (pen == series->pen()) {
176 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
177 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
177 pen.setWidthF(2);
178 pen.setWidthF(2);
178 series->setPen(pen);
179 series->setPen(pen);
179 }
180 }
180
181
181 if (brush == series->brush()) {
182 if (brush == series->brush()) {
182 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
183 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
183 series->setBrush(brush);
184 series->setBrush(brush);
184 }
185 }
185 }
186 }
186
187
187 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int index)
188 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int index)
188 {
189 {
189 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
190 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
190 for (int i(0); i < series->slices().count(); i++) {
191 for (int i(0); i < series->slices().count(); i++) {
191 qreal pos = (qreal) i / (qreal) series->count();
192 qreal pos = (qreal) i / (qreal) series->count();
192 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
193 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
193 series->slices().at(i)->setSlicePen(penColor);
194 series->slices().at(i)->setSlicePen(penColor);
194 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
195 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
195 series->slices().at(i)->setSliceBrush(brushColor);
196 series->slices().at(i)->setSliceBrush(brushColor);
196 }
197 }
197 }
198 }
198
199
199
200
200 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
201 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
201 {
202 {
202 //TODO: dummy defults for now
203 //TODO: dummy defults for now
203 axis->setLabelsBrush(Qt::black);
204 axis->setLabelsBrush(Qt::black);
204 axis->setLabelsPen(Qt::NoPen);
205 axis->setLabelsPen(Qt::NoPen);
205 axis->setShadesPen(Qt::NoPen);
206 axis->setShadesPen(Qt::NoPen);
206 axis->setShadesOpacity(0.5);
207 axis->setShadesOpacity(0.5);
207 }
208 }
208
209
209 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int index)
210 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int index)
210 {
211 {
211 Q_ASSERT(item);
212 Q_ASSERT(item);
212 Q_ASSERT(series);
213 Q_ASSERT(series);
213
214
214 QPen pen;
215 QPen pen;
215
216
216 if(pen != series->pen()){
217 if(pen != series->pen()){
217 item->setLinePen(series->pen());
218 item->setLinePen(series->pen());
218 }else{
219 }else{
219 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
220 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
220 pen.setWidthF(series->pen().widthF());
221 pen.setWidthF(series->pen().widthF());
221 item->setLinePen(series->pen());
222 item->setLinePen(series->pen());
222 }
223 }
223
224
224 // QColor color = m_seriesColors.at(index % m_seriesColors.size());
225 // QColor color = m_seriesColors.at(index % m_seriesColors.size());
225 // TODO: define alpha in the theme? or in the series?
226 // TODO: define alpha in the theme? or in the series?
226 //color.setAlpha(120);
227 //color.setAlpha(120);
227
228
228 // QBrush brush(color, Qt::SolidPattern);
229 // QBrush brush(color, Qt::SolidPattern);
229 // presenter->m_markerBrush = brush;
230 // presenter->m_markerBrush = brush;
230
231
231 // QPen pen(brush, 3);
232 // QPen pen(brush, 3);
232 // pen.setColor(color);
233 // pen.setColor(color);
233 // presenter->m_markerPen = pen;
234 // presenter->m_markerPen = pen;
234 }
235 }
235
236
236 void ChartTheme::generateSeriesGradients()
237 void ChartTheme::generateSeriesGradients()
237 {
238 {
238 // Generate gradients in HSV color space
239 // Generate gradients in HSV color space
239 foreach (QColor color, m_seriesColors) {
240 foreach (QColor color, m_seriesColors) {
240 QLinearGradient g;
241 QLinearGradient g;
241 qreal h = color.hsvHueF();
242 qreal h = color.hsvHueF();
242 qreal s = color.hsvSaturationF();
243 qreal s = color.hsvSaturationF();
243
244
244 // TODO: tune the algorithm to give nice results with most base colors defined in
245 // TODO: tune the algorithm to give nice results with most base colors defined in
245 // most themes. The rest of the gradients we can define manually in theme specific
246 // most themes. The rest of the gradients we can define manually in theme specific
246 // implementation.
247 // implementation.
247 QColor start = color;
248 QColor start = color;
248 start.setHsvF(h, 0.05, 0.95);
249 start.setHsvF(h, 0.05, 0.95);
249 g.setColorAt(0.0, start);
250 g.setColorAt(0.0, start);
250
251
251 g.setColorAt(0.5, color);
252 g.setColorAt(0.5, color);
252
253
253 QColor end = color;
254 QColor end = color;
254 end.setHsvF(h, s, 0.25);
255 end.setHsvF(h, s, 0.25);
255 g.setColorAt(1.0, end);
256 g.setColorAt(1.0, end);
256
257
257 m_seriesGradients << g;
258 m_seriesGradients << g;
258 }
259 }
259 }
260 }
260
261
261
262
262 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
263 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
263 {
264 {
264 Q_ASSERT(pos >=0.0 && pos <= 1.0);
265 Q_ASSERT(pos >=0.0 && pos <= 1.0);
265 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
266 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
266 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
267 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
267 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
268 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
268 QColor c;
269 QColor c;
269 c.setRgbF(r, g, b);
270 c.setRgbF(r, g, b);
270 return c;
271 return c;
271 }
272 }
272
273
273 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
274 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
274 {
275 {
275 Q_ASSERT(pos >=0 && pos <= 1.0);
276 Q_ASSERT(pos >=0 && pos <= 1.0);
276
277
277 // another possibility:
278 // another possibility:
278 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
279 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
279
280
280 QGradientStops stops = gradient.stops();
281 QGradientStops stops = gradient.stops();
281 int count = stops.count();
282 int count = stops.count();
282
283
283 // find previous stop relative to position
284 // find previous stop relative to position
284 QGradientStop prev = stops.first();
285 QGradientStop prev = stops.first();
285 for (int i=0; i<count; i++) {
286 for (int i=0; i<count; i++) {
286 QGradientStop stop = stops.at(i);
287 QGradientStop stop = stops.at(i);
287 if (pos > stop.first)
288 if (pos > stop.first)
288 prev = stop;
289 prev = stop;
289
290
290 // given position is actually a stop position?
291 // given position is actually a stop position?
291 if (pos == stop.first) {
292 if (pos == stop.first) {
292 //qDebug() << "stop color" << pos;
293 //qDebug() << "stop color" << pos;
293 return stop.second;
294 return stop.second;
294 }
295 }
295 }
296 }
296
297
297 // find next stop relative to position
298 // find next stop relative to position
298 QGradientStop next = stops.last();
299 QGradientStop next = stops.last();
299 for (int i=count-1; i>=0; i--) {
300 for (int i=count-1; i>=0; i--) {
300 QGradientStop stop = stops.at(i);
301 QGradientStop stop = stops.at(i);
301 if (pos < stop.first)
302 if (pos < stop.first)
302 next = stop;
303 next = stop;
303 }
304 }
304
305
305 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
306 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
306
307
307 qreal range = next.first - prev.first;
308 qreal range = next.first - prev.first;
308 qreal posDelta = pos - prev.first;
309 qreal posDelta = pos - prev.first;
309 qreal relativePos = posDelta / range;
310 qreal relativePos = posDelta / range;
310
311
311 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
312 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
312
313
313 return colorAt(prev.second, next.second, relativePos);
314 return colorAt(prev.second, next.second, relativePos);
314 }
315 }
315
316
316 QTCOMMERCIALCHART_END_NAMESPACE
317 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,127 +1,84
1 #include "linechartitem_p.h"
1 #include "linechartitem_p.h"
2 #include "qlineseries.h"
2 #include "qlineseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include <QPainter>
4 #include <QPainter>
5 #include <QGraphicsSceneMouseEvent>
5
6
6
7
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9
9 //TODO: optimize : remove points which are not visible
10 //TODO: optimize : remove points which are not visible
10
11
11 LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent),
12 LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent),
12 m_series(series),
13 m_series(series),
13 m_items(this)
14 m_pointsVisible(false)
14 {
15 {
15 setZValue(ChartPresenter::LineChartZValue);
16 setZValue(ChartPresenter::LineChartZValue);
16 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
17 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
17 QObject::connect(this,SIGNAL(clicked()),series,SIGNAL(clicked()));
18 QObject::connect(this,SIGNAL(clicked(const QPointF&)),series,SIGNAL(clicked(const QPointF&)));
18 handleUpdated();
19 handleUpdated();
19 }
20 }
20
21
21 QRectF LineChartItem::boundingRect() const
22 QRectF LineChartItem::boundingRect() const
22 {
23 {
23 return m_rect;
24 return m_rect;
24 }
25 }
25
26
26 QPainterPath LineChartItem::shape() const
27 QPainterPath LineChartItem::shape() const
27 {
28 {
28 return m_path;
29 return m_path;
29 }
30 }
30
31
31 void LineChartItem::createPoints(int count)
32 {
33 for (int i = 0; i < count; ++i) {
34 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3);
35 m_items.addToGroup(item);
36 }
37 }
38
39 void LineChartItem::deletePoints(int count)
40 {
41 QList<QGraphicsItem *> items = m_items.childItems();
42
43 for (int i = 0; i < count; ++i) {
44 delete(items.takeLast());
45 }
46 }
47
48 void LineChartItem::setGeometry(QVector<QPointF>& points)
32 void LineChartItem::setGeometry(QVector<QPointF>& points)
49 {
33 {
50 if(points.size()==0) return;
34 if(points.size()==0) return;
51
35
52 int diff = XYChartItem::points().size() - points.size();
53
54 if(diff>0) {
55 deletePoints(diff);
56 }
57 else if(diff<0) {
58 createPoints(-diff);
59 }
60
61 QList<QGraphicsItem*> items = m_items.childItems();
36 QList<QGraphicsItem*> items = m_items.childItems();
62
37
63 QPainterPath path;
38 QPainterPath linePath(points.at(0));
64 const QPointF& point = points.at(0);
65 path.moveTo(point);
66 QGraphicsItem* item = items.at(0);
67 item->setPos(point.x()-1,point.y()-1);
68 if(!clipRect().contains(point)) {
69 item->setVisible(false);
70 }
71 else {
72 item->setVisible(true);
73 }
74
39
75 for(int i=1; i< points.size();i++) {
40 for(int i=1; i< points.size();i++) {
76 QGraphicsItem* item = items.at(i);
41 linePath.lineTo(points.at(i));
77 const QPointF& point = points.at(i);
78 item->setPos(point.x()-1,point.y()-1);
79 if(!clipRect().contains(point)) {
80 item->setVisible(false);
81 }
82 else {
83 item->setVisible(true);
84 }
85 path.lineTo(point);
86 }
42 }
87
43
88 prepareGeometryChange();
44 prepareGeometryChange();
89 m_path = path;
45 m_path = linePath;
90 m_rect = path.boundingRect();
46 m_rect = linePath.boundingRect();
91
47
92 XYChartItem::setGeometry(points);
48 XYChartItem::setGeometry(points);
93 }
49 }
94
50
95 void LineChartItem::setLinePen(const QPen& pen)
96 {
97 m_pen = pen;
98 }
99
100 void LineChartItem::handleUpdated()
51 void LineChartItem::handleUpdated()
101 {
52 {
102 m_items.setVisible(m_series->pointsVisible());
53 m_pointsVisible = m_series->pointsVisible();
103 setLinePen(m_series->pen());
54 m_linePen = m_series->pen();
55 m_pointPen = m_series->pen();
56 m_pointPen.setWidthF(2*m_pointPen.width());
104 update();
57 update();
105 }
58 }
106
59
107 //painter
60 //painter
108
61
109 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
62 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 {
63 {
111 Q_UNUSED(widget);
64 Q_UNUSED(widget);
112 Q_UNUSED(option);
65 Q_UNUSED(option);
113 painter->save();
66 painter->save();
114 painter->setPen(m_pen);
67 painter->setPen(m_linePen);
115 painter->setClipRect(clipRect());
68 painter->setClipRect(clipRect());
116 painter->drawPath(m_path);
69 painter->drawPath(m_path);
70 if(m_pointsVisible){
71 painter->setPen(m_pointPen);
72 painter->drawPoints(points());
73 }
117 painter->restore();
74 painter->restore();
118 }
75 }
119
76
120 void LineChartItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
77 void LineChartItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
121 {
78 {
122 emit clicked();
79 emit clicked(calculateDomainPoint(event->pos()));
123 }
80 }
124
81
125 #include "moc_linechartitem_p.cpp"
82 #include "moc_linechartitem_p.cpp"
126
83
127 QTCOMMERCIALCHART_END_NAMESPACE
84 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,52 +1,47
1 #ifndef LINECHARTITEM_H
1 #ifndef LINECHARTITEM_H
2 #define LINECHARTITEM_H
2 #define LINECHARTITEM_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "xychartitem_p.h"
5 #include "xychartitem_p.h"
6 #include <QPen>
6 #include <QPen>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QLineSeries;
10 class QLineSeries;
11
11
12 class LineChartItem : public XYChartItem
12 class LineChartItem : public XYChartItem
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 public:
15 public:
16 explicit LineChartItem(QLineSeries* series,QGraphicsItem *parent = 0);
16 explicit LineChartItem(QLineSeries* series,QGraphicsItem *parent = 0);
17 ~ LineChartItem(){};
17 ~ LineChartItem(){};
18
18
19 //from QGraphicsItem
19 //from QGraphicsItem
20 QRectF boundingRect() const;
20 QRectF boundingRect() const;
21 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
21 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
22 QPainterPath shape() const;
22 QPainterPath shape() const;
23
23
24 void setLinePen(const QPen& pen);
25 void setPointsVisible(bool visible);
26
27 public slots:
24 public slots:
28 void handleUpdated();
25 void handleUpdated();
29
26
30 signals:
27 signals:
31 void clicked();
28 void clicked(const QPointF& point);
32
29
33 protected:
30 protected:
34 virtual void setGeometry(QVector<QPointF>& points);
31 virtual void setGeometry(QVector<QPointF>& points);
35 void mousePressEvent( QGraphicsSceneMouseEvent * event );
32 void mousePressEvent( QGraphicsSceneMouseEvent * event );
36
33
37 private:
34 private:
38 void createPoints(int count);
39 void deletePoints(int count);
40
41 private:
42 QLineSeries* m_series;
35 QLineSeries* m_series;
43 QGraphicsItemGroup m_items;
36 QGraphicsItemGroup m_items;
44 QPainterPath m_path;
37 QPainterPath m_path;
45 QRectF m_rect;
38 QRectF m_rect;
46 QPen m_pen;
39 QPen m_linePen;
40 QPen m_pointPen;
41 bool m_pointsVisible;
47
42
48 };
43 };
49
44
50 QTCOMMERCIALCHART_END_NAMESPACE
45 QTCOMMERCIALCHART_END_NAMESPACE
51
46
52 #endif
47 #endif
@@ -1,39 +1,39
1 #ifndef QLINESERIES_H_
1 #ifndef QLINESERIES_H_
2 #define QLINESERIES_H_
2 #define QLINESERIES_H_
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qxyseries.h"
5 #include "qxyseries.h"
6 #include <QDebug>
6 #include <QDebug>
7 #include <QPen>
7 #include <QPen>
8 #include <QBrush>
8 #include <QBrush>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class QTCOMMERCIALCHART_EXPORT QLineSeries : public QXYSeries
12 class QTCOMMERCIALCHART_EXPORT QLineSeries : public QXYSeries
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 public:
15 public:
16 QLineSeries(QObject* parent=0);
16 QLineSeries(QObject* parent=0);
17 virtual ~QLineSeries();
17 virtual ~QLineSeries();
18
18
19 void setLinePen(const QPen& pen);
19 void setLinePen(const QPen& pen);
20 QPen linePen() const {return m_pen;}
20 QPen linePen() const {return m_pen;}
21
21
22 void setPointsVisible(bool visible);
22 void setPointsVisible(bool visible);
23 bool pointsVisible() const {return m_pointsVisible;}
23 bool pointsVisible() const {return m_pointsVisible;}
24
24
25 signals:
25 signals:
26 void clicked();
26 void clicked(const QPointF& point);
27
27
28 public: // from QChartSeries
28 public: // from QChartSeries
29 virtual QSeriesType type() const {return QSeries::SeriesTypeLine;}
29 virtual QSeriesType type() const {return QSeries::SeriesTypeLine;}
30 friend QDebug operator<< (QDebug d, const QLineSeries series);
30 friend QDebug operator<< (QDebug d, const QLineSeries series);
31 private:
31 private:
32 QPen m_pen;
32 QPen m_pen;
33 bool m_pointsVisible;
33 bool m_pointsVisible;
34
34
35 };
35 };
36
36
37 QTCOMMERCIALCHART_END_NAMESPACE
37 QTCOMMERCIALCHART_END_NAMESPACE
38
38
39 #endif
39 #endif
@@ -1,147 +1,156
1 #include "xychartitem_p.h"
1 #include "xychartitem_p.h"
2 #include "qxyseries.h"
2 #include "qxyseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartanimator_p.h"
4 #include "chartanimator_p.h"
5 #include <QPainter>
5 #include <QPainter>
6
6
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 //TODO: optimize : remove points which are not visible
10 //TODO: optimize : remove points which are not visible
11
11
12 XYChartItem::XYChartItem(QXYSeries* series, QGraphicsItem *parent):ChartItem(parent),
12 XYChartItem::XYChartItem(QXYSeries* series, QGraphicsItem *parent):ChartItem(parent),
13 m_minX(0),
13 m_minX(0),
14 m_maxX(0),
14 m_maxX(0),
15 m_minY(0),
15 m_minY(0),
16 m_maxY(0),
16 m_maxY(0),
17 m_series(series)
17 m_series(series)
18 {
18 {
19 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
19 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
20 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
20 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
21 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
21 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
22
22
23 }
23 }
24
24
25 QPointF XYChartItem::calculateGeometryPoint(const QPointF& point) const
25 QPointF XYChartItem::calculateGeometryPoint(const QPointF& point) const
26 {
26 {
27 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
27 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
28 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
28 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
29 qreal x = (point.x() - m_minX)* deltaX;
29 qreal x = (point.x() - m_minX)* deltaX;
30 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
30 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
31 return QPointF(x,y);
31 return QPointF(x,y);
32 }
32 }
33
33
34
34
35 QPointF XYChartItem::calculateGeometryPoint(int index) const
35 QPointF XYChartItem::calculateGeometryPoint(int index) const
36 {
36 {
37 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
37 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
38 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
38 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
39 qreal x = (m_series->x(index) - m_minX)* deltaX;
39 qreal x = (m_series->x(index) - m_minX)* deltaX;
40 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
40 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
41 return QPointF(x,y);
41 return QPointF(x,y);
42 }
42 }
43
43
44 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
44 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
45 {
45 {
46 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
46 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
47 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
47 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
48
48
49 QVector<QPointF> points;
49 QVector<QPointF> points;
50 points.reserve(m_series->count());
50 points.reserve(m_series->count());
51 for (int i = 0; i < m_series->count(); ++i) {
51 for (int i = 0; i < m_series->count(); ++i) {
52 qreal x = (m_series->x(i) - m_minX)* deltaX;
52 qreal x = (m_series->x(i) - m_minX)* deltaX;
53 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
53 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
54 points << QPointF(x,y);
54 points << QPointF(x,y);
55 }
55 }
56 return points;
56 return points;
57 }
57 }
58
58
59 QPointF XYChartItem::calculateDomainPoint(const QPointF& point) const
60 {
61 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
62 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
63 qreal x = point.x()/deltaX +m_minX;
64 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
65 return QPointF(x,y);
66 }
67
59 void XYChartItem::updatePoints(QVector<QPointF>& points)
68 void XYChartItem::updatePoints(QVector<QPointF>& points)
60 {
69 {
61 if(m_animator){
70 if(m_animator){
62 m_animator->applyLayout(this,points);
71 m_animator->applyLayout(this,points);
63 }
72 }
64 else setGeometry(points);
73 else setGeometry(points);
65
74
66 }
75 }
67
76
68 void XYChartItem::updatePoint(QVector<QPointF>& points)
77 void XYChartItem::updatePoint(QVector<QPointF>& points)
69 {
78 {
70 setGeometry(points);
79 setGeometry(points);
71 }
80 }
72
81
73 void XYChartItem::setGeometry(QVector<QPointF>& points)
82 void XYChartItem::setGeometry(QVector<QPointF>& points)
74 {
83 {
75 m_points = points;
84 m_points = points;
76 }
85 }
77
86
78 //handlers
87 //handlers
79
88
80 void XYChartItem::handlePointAdded(int index)
89 void XYChartItem::handlePointAdded(int index)
81 {
90 {
82 Q_ASSERT(index<m_series->count());
91 Q_ASSERT(index<m_series->count());
83 Q_ASSERT(index>=0);
92 Q_ASSERT(index>=0);
84
93
85 QPointF point = calculateGeometryPoint(index);
94 QPointF point = calculateGeometryPoint(index);
86 QVector<QPointF> points = m_points;
95 QVector<QPointF> points = m_points;
87 points.insert(index,point);
96 points.insert(index,point);
88 updatePoints(points);
97 updatePoints(points);
89 update();
98 update();
90 }
99 }
91 void XYChartItem::handlePointRemoved(int index)
100 void XYChartItem::handlePointRemoved(int index)
92 {
101 {
93 Q_ASSERT(index<m_series->count());
102 Q_ASSERT(index<m_series->count());
94 Q_ASSERT(index>=0);
103 Q_ASSERT(index>=0);
95 QPointF point = calculateGeometryPoint(index);
104 QPointF point = calculateGeometryPoint(index);
96 QVector<QPointF> points = m_points;
105 QVector<QPointF> points = m_points;
97 points.remove(index);
106 points.remove(index);
98 updatePoints(points);
107 updatePoints(points);
99 update();
108 update();
100 }
109 }
101
110
102 void XYChartItem::handlePointReplaced(int index)
111 void XYChartItem::handlePointReplaced(int index)
103 {
112 {
104 Q_ASSERT(index<m_series->count());
113 Q_ASSERT(index<m_series->count());
105 Q_ASSERT(index>=0);
114 Q_ASSERT(index>=0);
106 QPointF point = calculateGeometryPoint(index);
115 QPointF point = calculateGeometryPoint(index);
107 QVector<QPointF> points = m_points;
116 QVector<QPointF> points = m_points;
108 points.replace(index,point);
117 points.replace(index,point);
109 updatePoint(points);
118 updatePoint(points);
110 update();
119 update();
111 }
120 }
112
121
113 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
122 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
114 {
123 {
115 m_minX=minX;
124 m_minX=minX;
116 m_maxX=maxX;
125 m_maxX=maxX;
117 m_minY=minY;
126 m_minY=minY;
118 m_maxY=maxY;
127 m_maxY=maxY;
119
128
120 if(isEmpty()) return;
129 if(isEmpty()) return;
121 QVector<QPointF> points = calculateGeometryPoints();
130 QVector<QPointF> points = calculateGeometryPoints();
122 updatePoints(points);
131 updatePoints(points);
123 update();
132 update();
124 }
133 }
125
134
126 void XYChartItem::handleGeometryChanged(const QRectF& rect)
135 void XYChartItem::handleGeometryChanged(const QRectF& rect)
127 {
136 {
128 Q_ASSERT(rect.isValid());
137 Q_ASSERT(rect.isValid());
129 m_size=rect.size();
138 m_size=rect.size();
130 m_clipRect=rect.translated(-rect.topLeft());
139 m_clipRect=rect.translated(-rect.topLeft());
131 setPos(rect.topLeft());
140 setPos(rect.topLeft());
132
141
133 if(isEmpty()) return;
142 if(isEmpty()) return;
134 QVector<QPointF> points = calculateGeometryPoints();
143 QVector<QPointF> points = calculateGeometryPoints();
135 updatePoints(points);
144 updatePoints(points);
136 update();
145 update();
137 }
146 }
138
147
139
148
140 bool XYChartItem::isEmpty()
149 bool XYChartItem::isEmpty()
141 {
150 {
142 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
151 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
143 }
152 }
144
153
145 #include "moc_xychartitem_p.cpp"
154 #include "moc_xychartitem_p.cpp"
146
155
147 QTCOMMERCIALCHART_END_NAMESPACE
156 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,57 +1,58
1 #ifndef XYCHARTITEM_H
1 #ifndef XYCHARTITEM_H
2 #define XYCHARTITEM_H
2 #define XYCHARTITEM_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include <QPen>
6 #include <QPen>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class ChartPresenter;
10 class ChartPresenter;
11 class QXYSeries;
11 class QXYSeries;
12
12
13 class XYChartItem : public QObject , public ChartItem
13 class XYChartItem : public QObject , public ChartItem
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 public:
16 public:
17 explicit XYChartItem(QXYSeries* series, QGraphicsItem *parent = 0);
17 explicit XYChartItem(QXYSeries* series, QGraphicsItem *parent = 0);
18 ~ XYChartItem(){};
18 ~ XYChartItem(){};
19
19
20 QVector<QPointF> points() const {return m_points;}
20 QVector<QPointF> points() const {return m_points;}
21 QRectF clipRect() const { return m_clipRect;}
21 QRectF clipRect() const { return m_clipRect;}
22
22
23 public slots:
23 public slots:
24 void handlePointAdded(int index);
24 void handlePointAdded(int index);
25 void handlePointRemoved(int index);
25 void handlePointRemoved(int index);
26 void handlePointReplaced(int index);
26 void handlePointReplaced(int index);
27 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
27 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
28 void handleGeometryChanged(const QRectF& size);
28 void handleGeometryChanged(const QRectF& size);
29
29
30 protected:
30 protected:
31 virtual void setGeometry(QVector<QPointF>& points);
31 virtual void setGeometry(QVector<QPointF>& points);
32 QPointF calculateGeometryPoint(const QPointF& point) const;
32 QPointF calculateGeometryPoint(const QPointF& point) const;
33 QPointF calculateGeometryPoint(int index) const;
33 QPointF calculateGeometryPoint(int index) const;
34 QPointF calculateDomainPoint(const QPointF& point) const;
34 QVector<QPointF> calculateGeometryPoints() const;
35 QVector<QPointF> calculateGeometryPoints() const;
35
36
36 private:
37 private:
37 void updatePoints(QVector<QPointF>& points);
38 void updatePoints(QVector<QPointF>& points);
38 void updatePoint(QVector<QPointF>& points);
39 void updatePoint(QVector<QPointF>& points);
39 inline bool isEmpty();
40 inline bool isEmpty();
40
41
41 private:
42 private:
42 qreal m_minX;
43 qreal m_minX;
43 qreal m_maxX;
44 qreal m_maxX;
44 qreal m_minY;
45 qreal m_minY;
45 qreal m_maxY;
46 qreal m_maxY;
46 QXYSeries* m_series;
47 QXYSeries* m_series;
47 QSizeF m_size;
48 QSizeF m_size;
48 QRectF m_clipRect;
49 QRectF m_clipRect;
49 QVector<QPointF> m_points;
50 QVector<QPointF> m_points;
50
51
51 friend class XYAnimation;
52 friend class XYAnimation;
52
53
53 };
54 };
54
55
55 QTCOMMERCIALCHART_END_NAMESPACE
56 QTCOMMERCIALCHART_END_NAMESPACE
56
57
57 #endif
58 #endif
General Comments 0
You need to be logged in to leave comments. Login now