##// END OF EJS Templates
Fixed issue with multiple QML charts...
Tero Ahola -
r213:d6e1b3166f68
parent child
Show More
@@ -1,208 +1,210
1 #include "linechartitem_p.h"
1 #include "linechartitem_p.h"
2 #include "qlinechartseries.h"
2 #include "qlinechartseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include <QPainter>
4 #include <QPainter>
5
5
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 //TODO: optimazie : remove points which are not visible
9 //TODO: optimazie : remove points which are not visible
10
10
11 LineChartItem::LineChartItem(ChartPresenter* presenter, QLineChartSeries* series,QGraphicsItem *parent):ChartItem(parent),
11 LineChartItem::LineChartItem(ChartPresenter* presenter, QLineChartSeries* series,QGraphicsItem *parent):ChartItem(parent),
12 m_presenter(presenter),
12 m_presenter(presenter),
13 m_series(series),
13 m_series(series),
14 m_dirtyData(false),
14 m_dirtyData(false),
15 m_dirtyGeometry(false),
15 m_dirtyGeometry(false),
16 m_dirtyDomain(false)
16 m_dirtyDomain(false)
17 {
17 {
18
18
19 }
19 }
20
20
21 QRectF LineChartItem::boundingRect() const
21 QRectF LineChartItem::boundingRect() const
22 {
22 {
23 return m_rect;
23 return m_rect;
24 }
24 }
25
25
26 QPainterPath LineChartItem::shape() const
26 QPainterPath LineChartItem::shape() const
27 {
27 {
28 return m_path;
28 return m_path;
29 }
29 }
30
30
31
31
32 void LineChartItem::addPoints(const QVector<QPointF>& points)
32 void LineChartItem::addPoints(const QVector<QPointF>& points)
33 {
33 {
34 m_data = points;
34 m_data = points;
35 for(int i=0; i<m_data.size();i++){
35 for(int i=0; i<m_data.size();i++){
36 const QPointF& point =m_data[i];
36 const QPointF& point =m_data[i];
37 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3,this);
37 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3,this);
38 item->setPos(point.x()-1,point.y()-1);;
38 item->setPos(point.x()-1,point.y()-1);;
39 if(!m_clipRect.contains(point) || !m_series->isPointsVisible()) item->setVisible(false);
39 if(!m_clipRect.contains(point) || !m_series->isPointsVisible()) item->setVisible(false);
40 m_points << item;
40 m_points << item;
41 }
41 }
42 }
42 }
43
43
44 void LineChartItem::addPoint(const QPointF& point)
44 void LineChartItem::addPoint(const QPointF& point)
45 {
45 {
46 m_data << point;
46 m_data << point;
47 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3,this);
47 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3,this);
48 m_clipRect.contains(point);
48 m_clipRect.contains(point);
49 item->setPos(point.x()-1,point.y()-1);
49 item->setPos(point.x()-1,point.y()-1);
50 if(!m_clipRect.contains(point) || !m_series->isPointsVisible()) item->setVisible(false);
50 if(!m_clipRect.contains(point) || !m_series->isPointsVisible()) item->setVisible(false);
51 m_points << item;
51 m_points << item;
52 }
52 }
53
53
54 void LineChartItem::removePoint(const QPointF& point)
54 void LineChartItem::removePoint(const QPointF& point)
55 {
55 {
56 Q_ASSERT(m_data.count() == m_points.count());
56 Q_ASSERT(m_data.count() == m_points.count());
57 int index = m_data.lastIndexOf(point,0);
57 int index = m_data.lastIndexOf(point,0);
58 m_data.remove(index);
58 m_data.remove(index);
59 delete(m_points.takeAt(index));
59 delete(m_points.takeAt(index));
60 }
60 }
61
61
62 void LineChartItem::setPoint(const QPointF& oldPoint,const QPointF& newPoint)
62 void LineChartItem::setPoint(const QPointF& oldPoint,const QPointF& newPoint)
63 {
63 {
64 Q_ASSERT(m_data.count() == m_points.count());
64 Q_ASSERT(m_data.count() == m_points.count());
65 int index = m_data.lastIndexOf(oldPoint,0);
65 int index = m_data.lastIndexOf(oldPoint,0);
66
66
67 if(index > -1){
67 if(index > -1){
68 m_data.replace(index,newPoint);
68 m_data.replace(index,newPoint);
69 QGraphicsItem* item = m_points.at(index);
69 QGraphicsItem* item = m_points.at(index);
70 item->setPos(newPoint.x()-1,newPoint.y()-1);
70 item->setPos(newPoint.x()-1,newPoint.y()-1);
71 }
71 }
72 }
72 }
73
73
74 void LineChartItem::setPoint(int index,const QPointF& point)
74 void LineChartItem::setPoint(int index,const QPointF& point)
75 {
75 {
76 Q_ASSERT(m_data.count() == m_points.count());
76 Q_ASSERT(m_data.count() == m_points.count());
77 Q_ASSERT(index>=0);
77 Q_ASSERT(index>=0);
78
78
79 m_data.replace(index,point);
79 m_data.replace(index,point);
80 QGraphicsItem* item = m_points.at(index);
80 QGraphicsItem* item = m_points.at(index);
81 item->setPos(point.x()-1,point.y()-1);
81 item->setPos(point.x()-1,point.y()-1);
82 }
82 }
83
83
84 void LineChartItem::clear()
84 void LineChartItem::clear()
85 {
85 {
86 qDeleteAll(m_points);
86 qDeleteAll(m_points);
87 m_points.clear();
87 m_points.clear();
88 m_hash.clear();
88 m_hash.clear();
89 m_path = QPainterPath();
89 m_path = QPainterPath();
90 m_rect = QRect();
90 m_rect = QRect();
91 m_data.clear();
91 m_data.clear();
92 }
92 }
93
93
94 void LineChartItem::clearView()
94 void LineChartItem::clearView()
95 {
95 {
96 qDeleteAll(m_points);
96 qDeleteAll(m_points);
97 m_points.clear();
97 m_points.clear();
98 m_path = QPainterPath();
98 m_path = QPainterPath();
99 m_rect = QRect();
99 m_rect = QRect();
100 m_data.clear();
100 m_data.clear();
101 }
101 }
102
102
103 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
103 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
104 {
104 {
105 Q_UNUSED(widget);
105 Q_UNUSED(widget);
106 Q_UNUSED(option);
106 Q_UNUSED(option);
107 painter->save();
107 painter->setPen(m_pen);
108 painter->setPen(m_pen);
108 painter->setClipRect(m_clipRect);
109 painter->setClipRect(m_clipRect);
109 painter->drawPath(m_path);
110 painter->drawPath(m_path);
111 painter->restore();
110 }
112 }
111
113
112 void LineChartItem::calculatePoint(QPointF& point, int index, const QLineChartSeries* series,const QSizeF& size, const Domain& domain) const
114 void LineChartItem::calculatePoint(QPointF& point, int index, const QLineChartSeries* series,const QSizeF& size, const Domain& domain) const
113 {
115 {
114 const qreal deltaX = size.width()/domain.spanX();
116 const qreal deltaX = size.width()/domain.spanX();
115 const qreal deltaY = size.height()/domain.spanY();
117 const qreal deltaY = size.height()/domain.spanY();
116 qreal x = (series->x(index) - domain.m_minX)* deltaX;
118 qreal x = (series->x(index) - domain.m_minX)* deltaX;
117 qreal y = (series->y(index) - domain.m_minY)*-deltaY + size.height();
119 qreal y = (series->y(index) - domain.m_minY)*-deltaY + size.height();
118 point.setX(x);
120 point.setX(x);
119 point.setY(y);
121 point.setY(y);
120 }
122 }
121
123
122
124
123 void LineChartItem::calculatePoints(QVector<QPointF>& points, QHash<int,int>& hash,const QLineChartSeries* series,const QSizeF& size, const Domain& domain) const
125 void LineChartItem::calculatePoints(QVector<QPointF>& points, QHash<int,int>& hash,const QLineChartSeries* series,const QSizeF& size, const Domain& domain) const
124 {
126 {
125 const qreal deltaX = size.width()/domain.spanX();
127 const qreal deltaX = size.width()/domain.spanX();
126 const qreal deltaY = size.height()/domain.spanY();
128 const qreal deltaY = size.height()/domain.spanY();
127
129
128 for (int i = 0; i < series->count(); ++i) {
130 for (int i = 0; i < series->count(); ++i) {
129 qreal x = (series->x(i) - domain.m_minX)* deltaX;
131 qreal x = (series->x(i) - domain.m_minX)* deltaX;
130 qreal y = (series->y(i) - domain.m_minY)*-deltaY + size.height();
132 qreal y = (series->y(i) - domain.m_minY)*-deltaY + size.height();
131 hash[i] = points.size();
133 hash[i] = points.size();
132 points << QPointF(x,y);
134 points << QPointF(x,y);
133 }
135 }
134 }
136 }
135
137
136 void LineChartItem::updateDomain()
138 void LineChartItem::updateDomain()
137 {
139 {
138 clear();
140 clear();
139 prepareGeometryChange();
141 prepareGeometryChange();
140 calculatePoints(m_data,m_hash,m_series,m_size, m_domain);
142 calculatePoints(m_data,m_hash,m_series,m_size, m_domain);
141 addPoints(m_data);
143 addPoints(m_data);
142 }
144 }
143
145
144 void LineChartItem::updateData()
146 void LineChartItem::updateData()
145 {
147 {
146 //for now the same
148 //for now the same
147 updateDomain();
149 updateDomain();
148 }
150 }
149
151
150 void LineChartItem::updateGeometry()
152 void LineChartItem::updateGeometry()
151 {
153 {
152
154
153 if(m_data.size()==0) return;
155 if(m_data.size()==0) return;
154
156
155 prepareGeometryChange();
157 prepareGeometryChange();
156 QPainterPath path;
158 QPainterPath path;
157 const QPointF& point = m_data.at(0);
159 const QPointF& point = m_data.at(0);
158 path.moveTo(point);
160 path.moveTo(point);
159
161
160 foreach( const QPointF& point , m_data) {
162 foreach( const QPointF& point , m_data) {
161 path.lineTo(point);
163 path.lineTo(point);
162 }
164 }
163
165
164 m_path = path;
166 m_path = path;
165 m_rect = path.boundingRect();
167 m_rect = path.boundingRect();
166 }
168 }
167
169
168 void LineChartItem::setPen(const QPen& pen)
170 void LineChartItem::setPen(const QPen& pen)
169 {
171 {
170 m_pen = pen;
172 m_pen = pen;
171 }
173 }
172
174
173 //handlers
175 //handlers
174
176
175 void LineChartItem::handleModelChanged(int index)
177 void LineChartItem::handleModelChanged(int index)
176 {
178 {
177 Q_ASSERT(index<m_series->count());
179 Q_ASSERT(index<m_series->count());
178 if(m_hash.contains(index)){
180 if(m_hash.contains(index)){
179 int i = m_hash.value(index);
181 int i = m_hash.value(index);
180 QPointF point;
182 QPointF point;
181 calculatePoint(point,index,m_series,m_size,m_domain);
183 calculatePoint(point,index,m_series,m_size,m_domain);
182 setPoint(i,point);
184 setPoint(i,point);
183 }
185 }
184 update();
186 update();
185 }
187 }
186
188
187 void LineChartItem::handleDomainChanged(const Domain& domain)
189 void LineChartItem::handleDomainChanged(const Domain& domain)
188 {
190 {
189 m_domain = domain;
191 m_domain = domain;
190 updateDomain();
192 updateDomain();
191 update();
193 update();
192 }
194 }
193
195
194 void LineChartItem::handleGeometryChanged(const QRectF& rect)
196 void LineChartItem::handleGeometryChanged(const QRectF& rect)
195 {
197 {
196 Q_ASSERT(rect.isValid());
198 Q_ASSERT(rect.isValid());
197 m_size=rect.size();
199 m_size=rect.size();
198 m_clipRect=rect.translated(-rect.topLeft());
200 m_clipRect=rect.translated(-rect.topLeft());
199 updateDomain();
201 updateDomain();
200 updateGeometry();
202 updateGeometry();
201 setPos(rect.topLeft());
203 setPos(rect.topLeft());
202 update();
204 update();
203 }
205 }
204
206
205
207
206 #include "moc_linechartitem_p.cpp"
208 #include "moc_linechartitem_p.cpp"
207
209
208 QTCOMMERCIALCHART_END_NAMESPACE
210 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,96 +1,93
1 import QtQuick 1.0
1 import QtQuick 1.0
2 import QtCommercial.Chart 1.0
2 import QtCommercial.Chart 1.0
3
3
4 Rectangle {
4 Rectangle {
5 width: 360
5 width: 360
6 height: 360
6 height: 360
7
7
8 // Another option for QML data api:
8 // Another option for QML data api:
9 // ListModel {
9 // ListModel {
10 // id: listModelForPie
10 // id: listModelForPie
11 // // PieDataElement
11 // // PieDataElement
12 // ListElement {
12 // ListElement {
13 // label: "Apple"
13 // label: "Apple"
14 // value: 4.3
14 // value: 4.3
15 // }
15 // }
16 // ListElement {
16 // ListElement {
17 // label: "Blackberry"
17 // label: "Blackberry"
18 // value: 15.1
18 // value: 15.1
19 // }
19 // }
20 // }
20 // }
21
21
22 Component.onCompleted: {
22 Component.onCompleted: {
23 // console.log("Component.onCompleted: " + scatterElement.x);
23 // console.log("Component.onCompleted: " + scatterElement.x);
24 // console.log("Component.onCompleted: " + scatterElement.y);
24 // console.log("Component.onCompleted: " + scatterElement.y);
25 // console.log("Component.onCompleted: " + scatterElement.dataX);
25 // console.log("Component.onCompleted: " + scatterElement.dataX);
26 // console.log("Component.onCompleted: " + scatterElement.dataY);
26 // console.log("Component.onCompleted: " + scatterElement.dataY);
27 //console.log("Component.onCompleted: " + chartModel.get(0).x);
27 //console.log("Component.onCompleted: " + chartModel.get(0).x);
28 //console.log("Component.onCompleted: " + chartModel.scatterElements);
28 //console.log("Component.onCompleted: " + chartModel.scatterElements);
29 // console.log("Component.onCompleted: " + elementt.dataX);
29 // console.log("Component.onCompleted: " + elementt.dataX);
30 // console.log("Component.onCompleted: " + chartModel.get(0).dataX);
30 // console.log("Component.onCompleted: " + chartModel.get(0).dataX);
31 }
31 }
32
32
33 Chart {
33 Chart {
34 id: chart1
34 id: chart1
35 anchors.top: parent.top
35 anchors.top: parent.top
36 anchors.left: parent.left
36 anchors.left: parent.left
37 anchors.right: parent.right
37 anchors.right: parent.right
38 height: parent.height / 2
38 height: parent.height / 2
39 theme: Chart.ThemeIcy
39 theme: Chart.ThemeIcy
40 // opacity: 0.3
40 // opacity: 0.3
41
41
42 Series {
42 Series {
43 seriesType: Series.SeriesTypePie
43 seriesType: Series.SeriesTypePie
44 }
44 }
45
45
46 // TODO: a bug: drawing order affects the drawing; if you draw chart1 first (by changing the
46 Series {
47 // z-order), then chart2 is not shown at all. By drawing chart2 first, both are visible.
47 seriesType: Series.SeriesTypeLine
48 // Also, if you don't draw line series on chart1 (only pie), both charts are visible.
48 }
49 // Series {
50 // seriesType: Series.SeriesTypeLine
51 // }
52 // TODO:
49 // TODO:
53 // Series {
50 // Series {
54 // seriesType: Series.SeriesTypeBar
51 // seriesType: Series.SeriesTypeBar
55 // }
52 // }
56 }
53 }
57
54
58
55
59 Chart {
56 Chart {
60 id: chart2
57 id: chart2
61 anchors.top: chart1.bottom
58 anchors.top: chart1.bottom
62 anchors.bottom: parent.bottom
59 anchors.bottom: parent.bottom
63 anchors.left: parent.left
60 anchors.left: parent.left
64 anchors.right: parent.right
61 anchors.right: parent.right
65 theme: Chart.ThemeScientific
62 theme: Chart.ThemeScientific
66
63
67 ScatterSeries {
64 ScatterSeries {
68 data: [
65 data: [
69 ScatterElement { x: 1.1; y: 2.1 },
66 ScatterElement { x: 1.1; y: 2.1 },
70 ScatterElement { x: 1.2; y: 2.0 },
67 ScatterElement { x: 1.2; y: 2.0 },
71 ScatterElement { x: 1.4; y: 2.3 }
68 ScatterElement { x: 1.4; y: 2.3 }
72 ]
69 ]
73 }
70 }
74 ScatterSeries {
71 ScatterSeries {
75 data: [
72 data: [
76 ScatterElement { x: 1.2; y: 2.2 },
73 ScatterElement { x: 1.2; y: 2.2 },
77 ScatterElement { x: 1.3; y: 2.2 },
74 ScatterElement { x: 1.3; y: 2.2 },
78 ScatterElement { x: 1.7; y: 2.6 }
75 ScatterElement { x: 1.7; y: 2.6 }
79 ]
76 ]
80 }
77 }
81 ScatterSeries {
78 ScatterSeries {
82 data: [
79 data: [
83 ScatterElement { x: 1.3; y: 2.3 },
80 ScatterElement { x: 1.3; y: 2.3 },
84 ScatterElement { x: 1.5; y: 2.4 },
81 ScatterElement { x: 1.5; y: 2.4 },
85 ScatterElement { x: 2.0; y: 2.9 }
82 ScatterElement { x: 2.0; y: 2.9 }
86 ]
83 ]
87 }
84 }
88 ScatterSeries {
85 ScatterSeries {
89 data: [
86 data: [
90 ScatterElement { x: 1.4; y: 2.4 },
87 ScatterElement { x: 1.4; y: 2.4 },
91 ScatterElement { x: 1.8; y: 2.7 },
88 ScatterElement { x: 1.8; y: 2.7 },
92 ScatterElement { x: 2.5; y: 3.2 }
89 ScatterElement { x: 2.5; y: 3.2 }
93 ]
90 ]
94 }
91 }
95 }
92 }
96 }
93 }
General Comments 0
You need to be logged in to leave comments. Login now