##// END OF EJS Templates
Adds back reimplemnted categories handling
Michal Klocek -
r701:0d46cd22e84d
parent child
Show More
@@ -1,400 +1,413
1 #include "axisitem_p.h"
1 #include "axisitem_p.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.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 #include <QDebug>
6 #include <QDebug>
7 #include <cmath>
7 #include <cmath>
8
8
9 static int label_padding = 5;
9 static int label_padding = 5;
10
10
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
12
13 Axis::Axis(QChartAxis* axis,ChartPresenter* presenter,AxisType type) :
13 Axis::Axis(QChartAxis* axis,ChartPresenter* presenter,AxisType type) :
14 Chart(presenter),
14 Chart(presenter),
15 m_chartAxis(axis),
15 m_chartAxis(axis),
16 m_type(type),
16 m_type(type),
17 m_labelsAngle(0),
17 m_labelsAngle(0),
18 m_grid(presenter->rootItem()),
18 m_grid(presenter->rootItem()),
19 m_shades(presenter->rootItem()),
19 m_shades(presenter->rootItem()),
20 m_labels(presenter->rootItem()),
20 m_labels(presenter->rootItem()),
21 m_axis(presenter->rootItem()),
21 m_axis(presenter->rootItem()),
22 m_min(0),
22 m_min(0),
23 m_max(0),
23 m_max(0),
24 m_ticksCount(0)
24 m_ticksCount(0)
25 {
25 {
26 //initial initialization
26 //initial initialization
27 m_axis.setZValue(ChartPresenter::AxisZValue);
27 m_axis.setZValue(ChartPresenter::AxisZValue);
28 m_axis.setHandlesChildEvents(false);
28 m_axis.setHandlesChildEvents(false);
29
29
30 m_shades.setZValue(ChartPresenter::ShadesZValue);
30 m_shades.setZValue(ChartPresenter::ShadesZValue);
31 m_grid.setZValue(ChartPresenter::GridZValue);
31 m_grid.setZValue(ChartPresenter::GridZValue);
32
32
33 QObject::connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
33 QObject::connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
34 QObject::connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
34 QObject::connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
35
35
36 handleAxisUpdated();
36 handleAxisUpdated();
37 }
37 }
38
38
39 Axis::~Axis()
39 Axis::~Axis()
40 {
40 {
41 }
41 }
42
42
43 void Axis::createItems(int count)
43 void Axis::createItems(int count)
44 {
44 {
45
45
46 if(m_axis.children().size()==0)
46 if(m_axis.children().size()==0)
47 m_axis.addToGroup(new AxisItem(this));
47 m_axis.addToGroup(new AxisItem(this));
48 for (int i = 0; i < count; ++i) {
48 for (int i = 0; i < count; ++i) {
49 m_grid.addToGroup(new QGraphicsLineItem());
49 m_grid.addToGroup(new QGraphicsLineItem());
50 m_labels.addToGroup(new QGraphicsSimpleTextItem());
50 m_labels.addToGroup(new QGraphicsSimpleTextItem());
51 m_axis.addToGroup(new QGraphicsLineItem());
51 m_axis.addToGroup(new QGraphicsLineItem());
52 if((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
52 if((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
53 }
53 }
54 }
54 }
55
55
56 void Axis::deleteItems(int count)
56 void Axis::deleteItems(int count)
57 {
57 {
58 QList<QGraphicsItem *> lines = m_grid.childItems();
58 QList<QGraphicsItem *> lines = m_grid.childItems();
59 QList<QGraphicsItem *> labels = m_labels.childItems();
59 QList<QGraphicsItem *> labels = m_labels.childItems();
60 QList<QGraphicsItem *> shades = m_shades.childItems();
60 QList<QGraphicsItem *> shades = m_shades.childItems();
61 QList<QGraphicsItem *> axis = m_axis.childItems();
61 QList<QGraphicsItem *> axis = m_axis.childItems();
62
62
63 for (int i = 0; i < count; ++i) {
63 for (int i = 0; i < count; ++i) {
64 if(lines.size()%2 && lines.size()>1) delete(shades.takeLast());
64 if(lines.size()%2 && lines.size()>1) delete(shades.takeLast());
65 delete(lines.takeLast());
65 delete(lines.takeLast());
66 delete(labels.takeLast());
66 delete(labels.takeLast());
67 delete(axis.takeLast());
67 delete(axis.takeLast());
68 }
68 }
69 }
69 }
70
70
71 void Axis::updateLayout(QVector<qreal>& layout)
71 void Axis::updateLayout(QVector<qreal>& layout)
72 {
72 {
73 if(animator()){
73 if(animator()){
74 animator()->updateLayout(this,layout);
74 animator()->updateLayout(this,layout);
75 }
75 }
76 else setLayout(layout);
76 else setLayout(layout);
77 }
77 }
78
78
79 QStringList Axis::createLabels(int ticks, qreal min, qreal max) const
79 bool Axis::createLabels(QStringList& labels,qreal min, qreal max,int ticks) const
80 {
80 {
81 Q_ASSERT(max>=min);
81 Q_ASSERT(max>=min);
82 Q_ASSERT(ticks>1);
82 Q_ASSERT(ticks>1);
83
83
84 QStringList labels;
85
86 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
87
88 QChartAxisCategories* categories = m_chartAxis->categories();
84 QChartAxisCategories* categories = m_chartAxis->categories();
89
85
90 for(int i=0; i< ticks; i++) {
86 bool category = categories->count()>0;
91 qreal value = min + (i * (max - min)/ (ticks-1));
87
92 if(categories->count()==0) {
88 if(!category) {
89 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
90 for(int i=0; i< ticks; i++) {
91 qreal value = min + (i * (max - min)/ (ticks-1));
93 labels << QString::number(value,'f',n);
92 labels << QString::number(value,'f',n);
94 }
93 }
95 else {
94 }
96
95 else {
96 for(int i=0; i< ticks; i++) {
97 int value = ceil(min + (i * (max - min)/ (ticks-1)));
97 QString label = categories->label(value);
98 QString label = categories->label(value);
98 labels << label;
99 labels << label;
99 }
100 }
100 }
101 }
101 return labels;
102
103 return category;
102 }
104 }
103
105
104 void Axis::setAxisOpacity(qreal opacity)
106 void Axis::setAxisOpacity(qreal opacity)
105 {
107 {
106 m_axis.setOpacity(opacity);
108 m_axis.setOpacity(opacity);
107 }
109 }
108
110
109 qreal Axis::axisOpacity() const
111 qreal Axis::axisOpacity() const
110 {
112 {
111 return m_axis.opacity();
113 return m_axis.opacity();
112 }
114 }
113
115
114 void Axis::setGridOpacity(qreal opacity)
116 void Axis::setGridOpacity(qreal opacity)
115 {
117 {
116 m_grid.setOpacity(opacity);
118 m_grid.setOpacity(opacity);
117 }
119 }
118
120
119 qreal Axis::gridOpacity() const
121 qreal Axis::gridOpacity() const
120 {
122 {
121 return m_grid.opacity();
123 return m_grid.opacity();
122 }
124 }
123
125
124 void Axis::setLabelsOpacity(qreal opacity)
126 void Axis::setLabelsOpacity(qreal opacity)
125 {
127 {
126 m_labels.setOpacity(opacity);
128 m_labels.setOpacity(opacity);
127 }
129 }
128
130
129 qreal Axis::labelsOpacity() const
131 qreal Axis::labelsOpacity() const
130 {
132 {
131 return m_labels.opacity();
133 return m_labels.opacity();
132 }
134 }
133
135
134 void Axis::setShadesOpacity(qreal opacity)
136 void Axis::setShadesOpacity(qreal opacity)
135 {
137 {
136 m_shades.setOpacity(opacity);
138 m_shades.setOpacity(opacity);
137 }
139 }
138
140
139 qreal Axis::shadesOpacity() const
141 qreal Axis::shadesOpacity() const
140 {
142 {
141 return m_shades.opacity();
143 return m_shades.opacity();
142 }
144 }
143
145
144 void Axis::setLabelsAngle(int angle)
146 void Axis::setLabelsAngle(int angle)
145 {
147 {
146 foreach(QGraphicsItem* item , m_labels.childItems()) {
148 foreach(QGraphicsItem* item , m_labels.childItems()) {
147 QPointF center = item->boundingRect().center();
149 QPointF center = item->boundingRect().center();
148 item->setRotation(angle);
150 item->setRotation(angle);
149 }
151 }
150
152
151 m_labelsAngle=angle;
153 m_labelsAngle=angle;
152 }
154 }
153
155
154 void Axis::setLabelsPen(const QPen& pen)
156 void Axis::setLabelsPen(const QPen& pen)
155 {
157 {
156 foreach(QGraphicsItem* item , m_labels.childItems()) {
158 foreach(QGraphicsItem* item , m_labels.childItems()) {
157 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
159 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
158 }
160 }
159 }
161 }
160
162
161 void Axis::setLabelsBrush(const QBrush& brush)
163 void Axis::setLabelsBrush(const QBrush& brush)
162 {
164 {
163 foreach(QGraphicsItem* item , m_labels.childItems()) {
165 foreach(QGraphicsItem* item , m_labels.childItems()) {
164 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
166 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
165 }
167 }
166 }
168 }
167
169
168 void Axis::setLabelsFont(const QFont& font)
170 void Axis::setLabelsFont(const QFont& font)
169 {
171 {
170 foreach(QGraphicsItem* item , m_labels.childItems()) {
172 foreach(QGraphicsItem* item , m_labels.childItems()) {
171 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
173 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
172 }
174 }
173 }
175 }
174
176
175 void Axis::setShadesBrush(const QBrush& brush)
177 void Axis::setShadesBrush(const QBrush& brush)
176 {
178 {
177 foreach(QGraphicsItem* item , m_shades.childItems()) {
179 foreach(QGraphicsItem* item , m_shades.childItems()) {
178 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
180 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
179 }
181 }
180 }
182 }
181
183
182 void Axis::setShadesPen(const QPen& pen)
184 void Axis::setShadesPen(const QPen& pen)
183 {
185 {
184 foreach(QGraphicsItem* item , m_shades.childItems()) {
186 foreach(QGraphicsItem* item , m_shades.childItems()) {
185 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
187 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
186 }
188 }
187 }
189 }
188
190
189 void Axis::setAxisPen(const QPen& pen)
191 void Axis::setAxisPen(const QPen& pen)
190 {
192 {
191 foreach(QGraphicsItem* item , m_axis.childItems()) {
193 foreach(QGraphicsItem* item , m_axis.childItems()) {
192 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
194 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
193 }
195 }
194 }
196 }
195
197
196 void Axis::setGridPen(const QPen& pen)
198 void Axis::setGridPen(const QPen& pen)
197 {
199 {
198 foreach(QGraphicsItem* item , m_grid.childItems()) {
200 foreach(QGraphicsItem* item , m_grid.childItems()) {
199 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
201 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
200 }
202 }
201 }
203 }
202
204
203 QVector<qreal> Axis::calculateLayout() const
205 QVector<qreal> Axis::calculateLayout() const
204 {
206 {
205 Q_ASSERT(m_ticksCount>=2);
207 Q_ASSERT(m_ticksCount>=2);
206
208
207 QVector<qreal> points;
209 QVector<qreal> points;
208 points.resize(m_ticksCount);
210 points.resize(m_ticksCount);
209
211
210 switch (m_type)
212 switch (m_type)
211 {
213 {
212 case X_AXIS:
214 case X_AXIS:
213 {
215 {
214 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
216 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
215 for (int i = 0; i < m_ticksCount; ++i) {
217 for (int i = 0; i < m_ticksCount; ++i) {
216 int x = i * deltaX + m_rect.left();
218 int x = i * deltaX + m_rect.left();
217 points[i] = x;
219 points[i] = x;
218 }
220 }
219 }
221 }
220 break;
222 break;
221 case Y_AXIS:
223 case Y_AXIS:
222 {
224 {
223 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
225 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
224 for (int i = 0; i < m_ticksCount; ++i) {
226 for (int i = 0; i < m_ticksCount; ++i) {
225 int y = i * -deltaY + m_rect.bottom();
227 int y = i * -deltaY + m_rect.bottom();
226 points[i] = y;
228 points[i] = y;
227 }
229 }
228 }
230 }
229 break;
231 break;
230 }
232 }
231 return points;
233 return points;
232 }
234 }
233
235
234 void Axis::setLayout(QVector<qreal>& layout)
236 void Axis::setLayout(QVector<qreal>& layout)
235 {
237 {
236 int diff = m_layoutVector.size() - layout.size();
238 int diff = m_layoutVector.size() - layout.size();
237
239
238 if(diff>0) {
240 if(diff>0) {
239 deleteItems(diff);
241 deleteItems(diff);
240 }
242 }
241 else if(diff<0) {
243 else if(diff<0) {
242 createItems(-diff);
244 createItems(-diff);
243 }
245 }
244
246
245 if(diff!=0) handleAxisUpdated();
247 if(diff!=0) handleAxisUpdated();
246
248
247 QStringList ticksList = createLabels(layout.size(),m_min,m_max);
249 QStringList ticksList;
250
251 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
248
252
249 QList<QGraphicsItem *> lines = m_grid.childItems();
253 QList<QGraphicsItem *> lines = m_grid.childItems();
250 QList<QGraphicsItem *> labels = m_labels.childItems();
254 QList<QGraphicsItem *> labels = m_labels.childItems();
251 QList<QGraphicsItem *> shades = m_shades.childItems();
255 QList<QGraphicsItem *> shades = m_shades.childItems();
252 QList<QGraphicsItem *> axis = m_axis.childItems();
256 QList<QGraphicsItem *> axis = m_axis.childItems();
253
257
254 Q_ASSERT(labels.size() == ticksList.size());
258 Q_ASSERT(labels.size() == ticksList.size());
255 Q_ASSERT(layout.size() == ticksList.size());
259 Q_ASSERT(layout.size() == ticksList.size());
256
260
257 switch (m_type)
261 switch (m_type)
258 {
262 {
259 case X_AXIS:
263 case X_AXIS:
260 {
264 {
261 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
265 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
262 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
266 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
263
267
264 for (int i = 0; i < layout.size(); ++i) {
268 for (int i = 0; i < layout.size(); ++i) {
265 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
269 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
266 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
270 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
267 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
271 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
268 labelItem->setText(ticksList.at(i));
272
269 QPointF center = labelItem->boundingRect().center();
273 if(!categories){
270 labelItem->setTransformOriginPoint(center.x(), center.y());
274 labelItem->setText(ticksList.at(i));
271 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
275 QPointF center = labelItem->boundingRect().center();
276 labelItem->setTransformOriginPoint(center.x(), center.y());
277 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
278 }else if(i>0){
279 labelItem->setText(ticksList.at(i));
280 QPointF center = labelItem->boundingRect().center();
281 labelItem->setTransformOriginPoint(center.x(), center.y());
282 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
283 }
284
272 if((i+1)%2 && i>1) {
285 if((i+1)%2 && i>1) {
273 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
286 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
274 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
287 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
275 }
288 }
276 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
289 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
277 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
290 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
278 }
291 }
279 }
292 }
280 break;
293 break;
281
294
282 case Y_AXIS:
295 case Y_AXIS:
283 {
296 {
284 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
297 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
285 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
298 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
286
299
287 for (int i = 0; i < layout.size(); ++i) {
300 for (int i = 0; i < layout.size(); ++i) {
288 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
301 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
289 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
302 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
290 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
303 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
291 labelItem->setText(ticksList.at(i));
304 labelItem->setText(ticksList.at(i));
292 QPointF center = labelItem->boundingRect().center();
305 QPointF center = labelItem->boundingRect().center();
293 labelItem->setTransformOriginPoint(center.x(), center.y());
306 labelItem->setTransformOriginPoint(center.x(), center.y());
294 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
307 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
295 if((i+1)%2 && i>1) {
308 if((i+1)%2 && i>1) {
296 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
309 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
297 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
310 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
298 }
311 }
299 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
312 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
300 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
313 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
301 }
314 }
302 }
315 }
303 break;
316 break;
304 default:
317 default:
305 qDebug()<<"Unknown axis type";
318 qDebug()<<"Unknown axis type";
306 break;
319 break;
307 }
320 }
308
321
309 m_layoutVector=layout;
322 m_layoutVector=layout;
310 }
323 }
311
324
312 bool Axis::isEmpty()
325 bool Axis::isEmpty()
313 {
326 {
314 return m_rect.isEmpty() || m_min==m_max || m_ticksCount==0;
327 return m_rect.isEmpty() || m_min==m_max || m_ticksCount==0;
315 }
328 }
316
329
317 //handlers
330 //handlers
318
331
319 void Axis::handleAxisCategoriesUpdated()
332 void Axis::handleAxisCategoriesUpdated()
320 {
333 {
321 if(isEmpty()) return;
334 if(isEmpty()) return;
322 updateLayout(m_layoutVector);
335 updateLayout(m_layoutVector);
323 }
336 }
324
337
325 void Axis::handleAxisUpdated()
338 void Axis::handleAxisUpdated()
326 {
339 {
327
340
328 if(isEmpty()) return;
341 if(isEmpty()) return;
329
342
330 if(m_chartAxis->isAxisVisible()) {
343 if(m_chartAxis->isAxisVisible()) {
331 setAxisOpacity(100);
344 setAxisOpacity(100);
332 }
345 }
333 else {
346 else {
334 setAxisOpacity(0);
347 setAxisOpacity(0);
335 }
348 }
336
349
337 if(m_chartAxis->isGridLineVisible()) {
350 if(m_chartAxis->isGridLineVisible()) {
338 setGridOpacity(100);
351 setGridOpacity(100);
339 }
352 }
340 else {
353 else {
341 setGridOpacity(0);
354 setGridOpacity(0);
342 }
355 }
343
356
344 if(m_chartAxis->labelsVisible())
357 if(m_chartAxis->labelsVisible())
345 {
358 {
346 setLabelsOpacity(100);
359 setLabelsOpacity(100);
347 }
360 }
348 else {
361 else {
349 setLabelsOpacity(0);
362 setLabelsOpacity(0);
350 }
363 }
351
364
352 if(m_chartAxis->shadesVisible()) {
365 if(m_chartAxis->shadesVisible()) {
353 setShadesOpacity(m_chartAxis->shadesOpacity());
366 setShadesOpacity(m_chartAxis->shadesOpacity());
354 }
367 }
355 else {
368 else {
356 setShadesOpacity(0);
369 setShadesOpacity(0);
357 }
370 }
358
371
359 setLabelsAngle(m_chartAxis->labelsAngle());
372 setLabelsAngle(m_chartAxis->labelsAngle());
360 setAxisPen(m_chartAxis->axisPen());
373 setAxisPen(m_chartAxis->axisPen());
361 setLabelsPen(m_chartAxis->labelsPen());
374 setLabelsPen(m_chartAxis->labelsPen());
362 setLabelsBrush(m_chartAxis->labelsBrush());
375 setLabelsBrush(m_chartAxis->labelsBrush());
363 setLabelsFont(m_chartAxis->labelsFont());
376 setLabelsFont(m_chartAxis->labelsFont());
364 setGridPen(m_chartAxis->gridLinePen());
377 setGridPen(m_chartAxis->gridLinePen());
365 setShadesPen(m_chartAxis->shadesPen());
378 setShadesPen(m_chartAxis->shadesPen());
366 setShadesBrush(m_chartAxis->shadesBrush());
379 setShadesBrush(m_chartAxis->shadesBrush());
367
380
368 }
381 }
369
382
370 void Axis::handleRangeChanged(qreal min, qreal max,int tickCount)
383 void Axis::handleRangeChanged(qreal min, qreal max,int tickCount)
371 {
384 {
372 if(min==max || tickCount<2) return;
385 if(min==max || tickCount<2) return;
373
386
374 m_min = min;
387 m_min = min;
375 m_max = max;
388 m_max = max;
376 m_ticksCount= tickCount;
389 m_ticksCount= tickCount;
377
390
378 if(isEmpty()) return;
391 if(isEmpty()) return;
379 QVector<qreal> layout = calculateLayout();
392 QVector<qreal> layout = calculateLayout();
380 updateLayout(layout);
393 updateLayout(layout);
381
394
382 }
395 }
383
396
384 void Axis::handleGeometryChanged(const QRectF& rect)
397 void Axis::handleGeometryChanged(const QRectF& rect)
385 {
398 {
386 m_rect = rect;
399 m_rect = rect;
387 if(isEmpty()) return;
400 if(isEmpty()) return;
388 QVector<qreal> layout = calculateLayout();
401 QVector<qreal> layout = calculateLayout();
389 updateLayout(layout);
402 updateLayout(layout);
390 }
403 }
391
404
392 void Axis::axisSelected()
405 void Axis::axisSelected()
393 {
406 {
394 qDebug()<<"TODO axis clicked";
407 qDebug()<<"TODO axis clicked";
395 }
408 }
396
409
397 //TODO "nice numbers algorithm"
410 //TODO "nice numbers algorithm"
398 #include "moc_axisitem_p.cpp"
411 #include "moc_axisitem_p.cpp"
399
412
400 QTCOMMERCIALCHART_END_NAMESPACE
413 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,124 +1,124
1 #ifndef AXISITEM_H_
1 #ifndef AXISITEM_H_
2 #define AXISITEM_H_
2 #define AXISITEM_H_
3
3
4 #include "domain_p.h"
4 #include "domain_p.h"
5 #include "chart_p.h"
5 #include "chart_p.h"
6 #include <QGraphicsItem>
6 #include <QGraphicsItem>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QChartAxis;
10 class QChartAxis;
11 class ChartPresenter;
11 class ChartPresenter;
12
12
13 class Axis : public Chart
13 class Axis : public Chart
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 public:
16 public:
17 enum AxisType{X_AXIS,Y_AXIS};
17 enum AxisType{X_AXIS,Y_AXIS};
18
18
19 Axis(QChartAxis* axis,ChartPresenter* presenter,AxisType type = X_AXIS);
19 Axis(QChartAxis* axis,ChartPresenter* presenter,AxisType type = X_AXIS);
20 ~Axis();
20 ~Axis();
21
21
22 AxisType axisType() const {return m_type;};
22 AxisType axisType() const {return m_type;};
23
23
24 void setAxisOpacity(qreal opacity);
24 void setAxisOpacity(qreal opacity);
25 qreal axisOpacity() const;
25 qreal axisOpacity() const;
26
26
27 void setGridOpacity(qreal opacity);
27 void setGridOpacity(qreal opacity);
28 qreal gridOpacity() const;
28 qreal gridOpacity() const;
29
29
30 void setLabelsOpacity(qreal opacity);
30 void setLabelsOpacity(qreal opacity);
31 qreal labelsOpacity() const;
31 qreal labelsOpacity() const;
32
32
33 void setShadesOpacity(qreal opacity);
33 void setShadesOpacity(qreal opacity);
34 qreal shadesOpacity() const;
34 qreal shadesOpacity() const;
35
35
36 void setLabelsAngle(int angle);
36 void setLabelsAngle(int angle);
37 int labelsAngle()const { return m_labelsAngle; }
37 int labelsAngle()const { return m_labelsAngle; }
38
38
39 void setShadesBrush(const QBrush& brush);
39 void setShadesBrush(const QBrush& brush);
40 void setShadesPen(const QPen& pen);
40 void setShadesPen(const QPen& pen);
41
41
42 void setAxisPen(const QPen& pen);
42 void setAxisPen(const QPen& pen);
43 void setGridPen(const QPen& pen);
43 void setGridPen(const QPen& pen);
44
44
45 void setLabelsPen(const QPen& pen);
45 void setLabelsPen(const QPen& pen);
46 void setLabelsBrush(const QBrush& brush);
46 void setLabelsBrush(const QBrush& brush);
47 void setLabelsFont(const QFont& font);
47 void setLabelsFont(const QFont& font);
48
48
49 inline QRectF geometry() const { return m_rect; }
49 inline QRectF geometry() const { return m_rect; }
50 inline QVector<qreal> layout() { return m_layoutVector;};
50 inline QVector<qreal> layout() { return m_layoutVector;};
51
51
52 public slots:
52 public slots:
53 void handleAxisUpdated();
53 void handleAxisUpdated();
54 void handleAxisCategoriesUpdated();
54 void handleAxisCategoriesUpdated();
55 void handleRangeChanged(qreal min , qreal max,int tickCount);
55 void handleRangeChanged(qreal min , qreal max,int tickCount);
56 void handleGeometryChanged(const QRectF& size);
56 void handleGeometryChanged(const QRectF& size);
57
57
58
58
59 private:
59 private:
60 inline bool isEmpty();
60 inline bool isEmpty();
61 void createItems(int count);
61 void createItems(int count);
62 void deleteItems(int count);
62 void deleteItems(int count);
63
63
64 QVector<qreal> calculateLayout() const;
64 QVector<qreal> calculateLayout() const;
65 void updateLayout(QVector<qreal>& layout);
65 void updateLayout(QVector<qreal>& layout);
66 void setLayout(QVector<qreal>& layout);
66 void setLayout(QVector<qreal>& layout);
67
67
68 QStringList createLabels(int ticks, qreal min, qreal max) const;
68 bool createLabels(QStringList& labels,qreal min, qreal max,int ticks) const;
69 void axisSelected();
69 void axisSelected();
70
70
71 private:
71 private:
72 QChartAxis* m_chartAxis;
72 QChartAxis* m_chartAxis;
73 AxisType m_type;
73 AxisType m_type;
74 QRectF m_rect;
74 QRectF m_rect;
75 int m_labelsAngle;
75 int m_labelsAngle;
76 QGraphicsItemGroup m_grid;
76 QGraphicsItemGroup m_grid;
77 QGraphicsItemGroup m_shades;
77 QGraphicsItemGroup m_shades;
78 QGraphicsItemGroup m_labels;
78 QGraphicsItemGroup m_labels;
79 QGraphicsItemGroup m_axis;
79 QGraphicsItemGroup m_axis;
80 QVector<qreal> m_layoutVector;
80 QVector<qreal> m_layoutVector;
81 qreal m_min;
81 qreal m_min;
82 qreal m_max;
82 qreal m_max;
83 int m_ticksCount;
83 int m_ticksCount;
84 qreal m_zoomFactor;
84 qreal m_zoomFactor;
85
85
86 friend class AxisAnimation;
86 friend class AxisAnimation;
87 friend class AxisItem;
87 friend class AxisItem;
88
88
89 };
89 };
90
90
91 class AxisItem: public QGraphicsLineItem
91 class AxisItem: public QGraphicsLineItem
92 {
92 {
93 public:
93 public:
94
94
95 AxisItem(Axis* axis,QGraphicsItem* parent=0):QGraphicsLineItem(parent),m_axis(axis){};
95 AxisItem(Axis* axis,QGraphicsItem* parent=0):QGraphicsLineItem(parent),m_axis(axis){};
96
96
97 protected:
97 protected:
98 void mousePressEvent(QGraphicsSceneMouseEvent *event)
98 void mousePressEvent(QGraphicsSceneMouseEvent *event)
99 {
99 {
100 Q_UNUSED(event)
100 Q_UNUSED(event)
101 m_axis->axisSelected();
101 m_axis->axisSelected();
102 }
102 }
103
103
104 QRectF boundingRect() const
104 QRectF boundingRect() const
105 {
105 {
106 return shape().boundingRect();
106 return shape().boundingRect();
107 }
107 }
108
108
109 QPainterPath shape() const
109 QPainterPath shape() const
110 {
110 {
111 QPainterPath path = QGraphicsLineItem::shape();
111 QPainterPath path = QGraphicsLineItem::shape();
112 QRectF rect = path.boundingRect();
112 QRectF rect = path.boundingRect();
113 path.addRect(rect.adjusted(0,0,m_axis->axisType()!=Axis::X_AXIS?8:0,m_axis->axisType()!=Axis::Y_AXIS?8:0));
113 path.addRect(rect.adjusted(0,0,m_axis->axisType()!=Axis::X_AXIS?8:0,m_axis->axisType()!=Axis::Y_AXIS?8:0));
114 return path;
114 return path;
115 }
115 }
116
116
117 private:
117 private:
118 Axis* m_axis;
118 Axis* m_axis;
119
119
120 };
120 };
121
121
122 QTCOMMERCIALCHART_END_NAMESPACE
122 QTCOMMERCIALCHART_END_NAMESPACE
123
123
124 #endif /* AXISITEM_H_ */
124 #endif /* AXISITEM_H_ */
@@ -1,44 +1,54
1 #include "qchartaxiscategories.h"
1 #include "qchartaxiscategories.h"
2
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
4
5 QChartAxisCategories::QChartAxisCategories()
5 QChartAxisCategories::QChartAxisCategories()
6 {
6 {
7 // TODO Auto-generated constructor stub
7 // TODO Auto-generated constructor stub
8
8
9 }
9 }
10
10
11 QChartAxisCategories::~QChartAxisCategories()
11 QChartAxisCategories::~QChartAxisCategories()
12 {
12 {
13 // TODO Auto-generated destructor stub
13 // TODO Auto-generated destructor stub
14 }
14 }
15
15
16 void QChartAxisCategories::insert(QBarCategory& category)
17 {
18 int i=1;
19 foreach(QString string , category){
20 m_map.insert(i,string);
21 i++;
22 }
23 emit updated();
24 }
25
16 void QChartAxisCategories::insert(qreal value,QString label)
26 void QChartAxisCategories::insert(qreal value,QString label)
17 {
27 {
18 m_map.insert(value,label);
28 m_map.insert(value,label);
19 emit updated();
29 emit updated();
20 }
30 }
21 void QChartAxisCategories::remove(qreal value)
31 void QChartAxisCategories::remove(qreal value)
22 {
32 {
23 m_map.remove(value);
33 m_map.remove(value);
24 emit updated();
34 emit updated();
25 }
35 }
26 void QChartAxisCategories::clear()
36 void QChartAxisCategories::clear()
27 {
37 {
28 m_map.clear();
38 m_map.clear();
29 emit updated();
39 emit updated();
30 }
40 }
31 int QChartAxisCategories::count()
41 int QChartAxisCategories::count()
32 {
42 {
33 return m_map.count();
43 return m_map.count();
34 emit updated();
44 emit updated();
35 }
45 }
36
46
37 QString QChartAxisCategories::label(qreal value) const
47 QString QChartAxisCategories::label(qreal value) const
38 {
48 {
39 return m_map.value(value);
49 return m_map.value(value);
40 }
50 }
41
51
42 #include "moc_qchartaxiscategories.cpp"
52 #include "moc_qchartaxiscategories.cpp"
43
53
44 QTCOMMERCIALCHART_END_NAMESPACE
54 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,34 +1,37
1 #ifndef QCHARTAXISCATEGORIES_H_
1 #ifndef QCHARTAXISCATEGORIES_H_
2 #define QCHARTAXISCATEGORIES_H_
2 #define QCHARTAXISCATEGORIES_H_
3
3 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qbarseries.h>
4
6
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
8
7 class QTCOMMERCIALCHART_EXPORT QChartAxisCategories : public QObject
9 class QTCOMMERCIALCHART_EXPORT QChartAxisCategories : public QObject
8 {
10 {
9 Q_OBJECT
11 Q_OBJECT
10 private:
12 private:
11 QChartAxisCategories();
13 QChartAxisCategories();
12 public:
14 public:
13 ~QChartAxisCategories();
15 ~QChartAxisCategories();
14
16
17 void insert(QBarCategory& category);
15 void insert(qreal value,QString label);
18 void insert(qreal value,QString label);
16 void remove(qreal value);
19 void remove(qreal value);
17 QString label(qreal value) const;
20 QString label(qreal value) const;
18 void clear();
21 void clear();
19 int count();
22 int count();
20
23
21 //internal signal
24 //internal signal
22 signals:
25 signals:
23 void updated();
26 void updated();
24
27
25 private:
28 private:
26 QMap<qreal,QString> m_map;
29 QMap<qreal,QString> m_map;
27
30
28 friend class QChartAxis;
31 friend class QChartAxis;
29 };
32 };
30
33
31
34
32 QTCOMMERCIALCHART_END_NAMESPACE
35 QTCOMMERCIALCHART_END_NAMESPACE
33
36
34 #endif /* QCHARTAXISCATEGORIES_H_ */
37 #endif /* QCHARTAXISCATEGORIES_H_ */
@@ -1,251 +1,217
1 #include "barchartitem_p.h"
1 #include "barchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include "qchart.h"
6 #include "qchart.h"
7 #include "qchartaxis.h"
7 #include "qchartaxis.h"
8 #include "qchartaxiscategories.h"
8 #include "qchartaxiscategories.h"
9 #include "chartpresenter_p.h"
9 #include "chartpresenter_p.h"
10 #include "chartanimator_p.h"
10 #include "chartanimator_p.h"
11 #include "chartdataset_p.h"
11 #include "chartdataset_p.h"
12 #include <QDebug>
12 #include <QDebug>
13 #include <QToolTip>
13 #include <QToolTip>
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16
16
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
18 ChartItem(presenter),
18 ChartItem(presenter),
19 mLayoutSet(false),
19 mLayoutSet(false),
20 mSeries(series)
20 mSeries(series)
21 {
21 {
22 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
22 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
26 setZValue(ChartPresenter::BarSeriesZValue);
26 setZValue(ChartPresenter::BarSeriesZValue);
27 initAxisLabels();
28 dataChanged();
27 dataChanged();
29 }
28 }
30
29
31 BarChartItem::~BarChartItem()
30 BarChartItem::~BarChartItem()
32 {
31 {
33 disconnect(this,SLOT(showToolTip(QPoint,QString)));
32 disconnect(this,SLOT(showToolTip(QPoint,QString)));
34 }
33 }
35
34
36 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
35 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
37 {
36 {
38 if (!mLayoutSet) {
37 if (!mLayoutSet) {
39 qDebug() << "BarChartItem::paint called without layout set. Aborting.";
38 qDebug() << "BarChartItem::paint called without layout set. Aborting.";
40 return;
39 return;
41 }
40 }
42 foreach(QGraphicsItem* i, childItems()) {
41 foreach(QGraphicsItem* i, childItems()) {
43 i->paint(painter,option,widget);
42 i->paint(painter,option,widget);
44 }
43 }
45 }
44 }
46
45
47 QRectF BarChartItem::boundingRect() const
46 QRectF BarChartItem::boundingRect() const
48 {
47 {
49 return m_rect;
48 return m_rect;
50 }
49 }
51
50
52 void BarChartItem::dataChanged()
51 void BarChartItem::dataChanged()
53 {
52 {
54 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
53 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
55 // Delete old bars
54 // Delete old bars
56 foreach (QGraphicsItem* item, childItems()) {
55 foreach (QGraphicsItem* item, childItems()) {
57 delete item;
56 delete item;
58 }
57 }
59
58
60 mBars.clear();
59 mBars.clear();
61 mFloatingValues.clear();
60 mFloatingValues.clear();
62 mLayout.clear();
61 mLayout.clear();
63
62
64 // Create new graphic items for bars
63 // Create new graphic items for bars
65 for (int c=0; c<mSeries->categoryCount(); c++) {
64 for (int c=0; c<mSeries->categoryCount(); c++) {
66 QString category = mSeries->categoryName(c);
65 QString category = mSeries->categoryName(c);
67 for (int s=0; s<mSeries->barsetCount(); s++) {
66 for (int s=0; s<mSeries->barsetCount(); s++) {
68 QBarSet *set = mSeries->barsetAt(s);
67 QBarSet *set = mSeries->barsetAt(s);
69 Bar *bar = new Bar(category,this);
68 Bar *bar = new Bar(category,this);
70 childItems().append(bar);
69 childItems().append(bar);
71 mBars.append(bar);
70 mBars.append(bar);
72 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
71 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
73 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
72 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
74 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
73 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
75 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
74 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
76 mLayout.append(QRectF(0,0,0,0));
75 mLayout.append(QRectF(0,0,0,0));
77 }
76 }
78 }
77 }
79
78
80 // Create floating values
79 // Create floating values
81 for (int category=0; category<mSeries->categoryCount(); category++) {
80 for (int category=0; category<mSeries->categoryCount(); category++) {
82 for (int s=0; s<mSeries->barsetCount(); s++) {
81 for (int s=0; s<mSeries->barsetCount(); s++) {
83 QBarSet *set = mSeries->barsetAt(s);
82 QBarSet *set = mSeries->barsetAt(s);
84 BarValue *value = new BarValue(*set, this);
83 BarValue *value = new BarValue(*set, this);
85 childItems().append(value);
84 childItems().append(value);
86 mFloatingValues.append(value);
85 mFloatingValues.append(value);
87 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
86 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
88 }
87 }
89 }
88 }
90 }
89 }
91 QVector<QRectF> BarChartItem::calculateLayout()
90 QVector<QRectF> BarChartItem::calculateLayout()
92 {
91 {
93 QVector<QRectF> layout;
92 QVector<QRectF> layout;
94
93
95 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
94 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
96 qreal categoryCount = mSeries->categoryCount();
95 qreal categoryCount = mSeries->categoryCount();
97 qreal setCount = mSeries->barsetCount();
96 qreal setCount = mSeries->barsetCount();
98
97
99 qreal width = geometry().width();
98 qreal width = geometry().width();
100 qreal height = geometry().height();
99 qreal height = geometry().height();
101
100
102 qreal max = mSeries->max();
101 qreal max = mSeries->max();
103
102
104 // Domain:
103 // Domain:
105 if (mDomainMaxY > max) {
104 if (mDomainMaxY > max) {
106 max = mDomainMaxY;
105 max = mDomainMaxY;
107 }
106 }
108
107
109 qreal scale = (height/max);
108 qreal scale = (height/max);
110 qreal categoryWidth = width/categoryCount;
109 qreal categoryWidth = width/categoryCount;
111 qreal barWidth = categoryWidth / (setCount+1);
110 qreal barWidth = categoryWidth / (setCount+1);
112
111
113 int itemIndex(0);
112 int itemIndex(0);
114 for (int category=0; category < categoryCount; category++) {
113 for (int category=0; category < categoryCount; category++) {
115 qreal xPos = categoryWidth * category + barWidth/2;
114 qreal xPos = categoryWidth * category + barWidth/2;
116 qreal yPos = height;
115 qreal yPos = height;
117 for (int set = 0; set < setCount; set++) {
116 for (int set = 0; set < setCount; set++) {
118 qreal barHeight = mSeries->valueAt(set,category) * scale;
117 qreal barHeight = mSeries->valueAt(set,category) * scale;
119 Bar* bar = mBars.at(itemIndex);
118 Bar* bar = mBars.at(itemIndex);
120
119
121 QRectF rect(xPos,yPos-barHeight,barWidth,barHeight);
120 QRectF rect(xPos,yPos-barHeight,barWidth,barHeight);
122 layout.append(rect);
121 layout.append(rect);
123 bar->setPen(mSeries->barsetAt(set)->pen());
122 bar->setPen(mSeries->barsetAt(set)->pen());
124 bar->setBrush(mSeries->barsetAt(set)->brush());
123 bar->setBrush(mSeries->barsetAt(set)->brush());
125 itemIndex++;
124 itemIndex++;
126 xPos += barWidth;
125 xPos += barWidth;
127 }
126 }
128 }
127 }
129
128
130 // Position floating values
129 // Position floating values
131 itemIndex = 0;
130 itemIndex = 0;
132 for (int category=0; category < mSeries->categoryCount(); category++) {
131 for (int category=0; category < mSeries->categoryCount(); category++) {
133 qreal xPos = categoryWidth * category + barWidth;
132 qreal xPos = categoryWidth * category + barWidth;
134 qreal yPos = height;
133 qreal yPos = height;
135 for (int set=0; set < mSeries->barsetCount(); set++) {
134 for (int set=0; set < mSeries->barsetCount(); set++) {
136 qreal barHeight = mSeries->valueAt(set,category) * scale;
135 qreal barHeight = mSeries->valueAt(set,category) * scale;
137 BarValue* value = mFloatingValues.at(itemIndex);
136 BarValue* value = mFloatingValues.at(itemIndex);
138
137
139 QBarSet* barSet = mSeries->barsetAt(set);
138 QBarSet* barSet = mSeries->barsetAt(set);
140 value->resize(100,50); // TODO: proper layout for this.
139 value->resize(100,50); // TODO: proper layout for this.
141 value->setPos(xPos, yPos-barHeight/2);
140 value->setPos(xPos, yPos-barHeight/2);
142 value->setPen(barSet->floatingValuePen());
141 value->setPen(barSet->floatingValuePen());
143
142
144 if (mSeries->valueAt(set,category) != 0) {
143 if (mSeries->valueAt(set,category) != 0) {
145 value->setValueString(QString::number(mSeries->valueAt(set,category)));
144 value->setValueString(QString::number(mSeries->valueAt(set,category)));
146 } else {
145 } else {
147 value->setValueString(QString(""));
146 value->setValueString(QString(""));
148 }
147 }
149
148
150 itemIndex++;
149 itemIndex++;
151 xPos += barWidth;
150 xPos += barWidth;
152 }
151 }
153 }
152 }
154
153
155 return layout;
154 return layout;
156 }
155 }
157
156
158 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
157 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
159 {
158 {
160 if (animator())
159 if (animator())
161 animator()->updateLayout(this, mLayout, layout);
160 animator()->updateLayout(this, mLayout, layout);
162 else
161 else
163 setLayout(layout);
162 setLayout(layout);
164 }
163 }
165
164
166 void BarChartItem::setLayout(const QVector<QRectF> &layout)
165 void BarChartItem::setLayout(const QVector<QRectF> &layout)
167 {
166 {
168 mLayout = layout;
167 mLayout = layout;
169
168
170 for (int i=0; i<mBars.count(); i++) {
169 for (int i=0; i<mBars.count(); i++) {
171 mBars.at(i)->setRect(layout.at(i));
170 mBars.at(i)->setRect(layout.at(i));
172 }
171 }
173
172
174 update();
173 update();
175 }
174 }
176
175
177 void BarChartItem::initAxisLabels()
178 {
179 int count = mSeries->categoryCount();
180 if (0 == count) {
181 return;
182 }
183
184 Domain* domain = presenter()->dataSet()->domain(mSeries);
185
186 qreal min = 0;
187 qreal max = count+1;
188
189 domain->setRangeX(min,max,count+1);
190 }
191
192 //handlers
176 //handlers
193
177
194 void BarChartItem::handleModelChanged(int index)
178 void BarChartItem::handleModelChanged(int index)
195 {
179 {
196 Q_UNUSED(index)
180 Q_UNUSED(index)
197 dataChanged();
181 dataChanged();
198 }
182 }
199
183
200 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
184 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
201 {
185 {
202 mDomainMinX = minX;
186 mDomainMinX = minX;
203 mDomainMaxX = maxX;
187 mDomainMaxX = maxX;
204 mDomainMinY = minY;
188 mDomainMinY = minY;
205 mDomainMaxY = maxY;
189 mDomainMaxY = maxY;
206 handleLayoutChanged();
190 handleLayoutChanged();
207
208 /*
209 int count = mSeries->categoryCount();
210 if (0 == count) {
211 return;
212 }
213
214 // Position labels to domain
215 qreal min = domain.minX();
216 qreal max = domain.maxX();
217 qreal step = (max-min)/count;
218 QChartAxisCategories& categories = mChart->axisX()->categories();
219 categories.clear();
220 for (int i=0; i<count; i++) {
221 categories.insert(min,mSeries->categoryName(i));
222 min += step;
223 }
224 */
225 }
191 }
226
192
227 void BarChartItem::handleGeometryChanged(const QRectF& rect)
193 void BarChartItem::handleGeometryChanged(const QRectF& rect)
228 {
194 {
229 m_rect=rect;
195 m_rect=rect;
230 handleLayoutChanged();
196 handleLayoutChanged();
231 mLayoutSet = true;
197 mLayoutSet = true;
232 setPos(rect.topLeft());
198 setPos(rect.topLeft());
233 }
199 }
234
200
235 void BarChartItem::handleLayoutChanged()
201 void BarChartItem::handleLayoutChanged()
236 {
202 {
237 QVector<QRectF> layout = calculateLayout();
203 QVector<QRectF> layout = calculateLayout();
238 applyLayout(layout);
204 applyLayout(layout);
239 update();
205 update();
240 }
206 }
241
207
242
208
243 void BarChartItem::showToolTip(QPoint pos, QString tip)
209 void BarChartItem::showToolTip(QPoint pos, QString tip)
244 {
210 {
245 // TODO: cool tooltip instead of default
211 // TODO: cool tooltip instead of default
246 QToolTip::showText(pos,tip);
212 QToolTip::showText(pos,tip);
247 }
213 }
248
214
249 #include "moc_barchartitem_p.cpp"
215 #include "moc_barchartitem_p.cpp"
250
216
251 QTCOMMERCIALCHART_END_NAMESPACE
217 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,78 +1,75
1 #ifndef BARCHARTITEM_H
1 #ifndef BARCHARTITEM_H
2 #define BARCHARTITEM_H
2 #define BARCHARTITEM_H
3
3
4 #include "chartitem_p.h"
4 #include "chartitem_p.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8 #include <QGraphicsItem>
8 #include <QGraphicsItem>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class Bar;
12 class Bar;
13 class BarValue;
13 class BarValue;
14 class QChartAxisCategories;
14 class QChartAxisCategories;
15 class QChart;
15 class QChart;
16
16
17 //typedef QVector<QRectF> BarLayout;
17 //typedef QVector<QRectF> BarLayout;
18
18
19 class BarChartItem : public ChartItem
19 class BarChartItem : public ChartItem
20 {
20 {
21 Q_OBJECT
21 Q_OBJECT
22 public:
22 public:
23 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
23 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
24 virtual ~BarChartItem();
24 virtual ~BarChartItem();
25
25
26 // Common implemantation of different presenters. Not to be instantiated.
26 // Common implemantation of different presenters. Not to be instantiated.
27 // TODO: combine this with BarPresenter and derive other presenters from it?
27 // TODO: combine this with BarPresenter and derive other presenters from it?
28
28
29 public:
29 public:
30 // From QGraphicsItem
30 // From QGraphicsItem
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
32 QRectF boundingRect() const;
32 QRectF boundingRect() const;
33
33
34 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
34 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
35 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
35 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
36 private slots:
36 private slots:
37
37
38 public:
38 public:
39 virtual QVector<QRectF> calculateLayout();
39 virtual QVector<QRectF> calculateLayout();
40 void applyLayout(const QVector<QRectF> &layout);
40 void applyLayout(const QVector<QRectF> &layout);
41 void setLayout(const QVector<QRectF> &layout);
41 void setLayout(const QVector<QRectF> &layout);
42 void updateLayout(const QVector<QRectF> &layout);
42 void updateLayout(const QVector<QRectF> &layout);
43
43
44 QRectF geometry() const { return m_rect;}
44 QRectF geometry() const { return m_rect;}
45
45
46 protected:
47 void initAxisLabels();
48
49 public slots:
46 public slots:
50 void handleModelChanged(int index);
47 void handleModelChanged(int index);
51 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
48 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
52 void handleGeometryChanged(const QRectF& size);
49 void handleGeometryChanged(const QRectF& size);
53 void handleLayoutChanged();
50 void handleLayoutChanged();
54
51
55 // Internal slots
52 // Internal slots
56 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
53 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
57
54
58 protected:
55 protected:
59
56
60 // TODO: consider these.
57 // TODO: consider these.
61 qreal mDomainMinX;
58 qreal mDomainMinX;
62 qreal mDomainMaxX;
59 qreal mDomainMaxX;
63 qreal mDomainMinY;
60 qreal mDomainMinY;
64 qreal mDomainMaxY;
61 qreal mDomainMaxY;
65
62
66 QRectF m_rect;
63 QRectF m_rect;
67 bool mLayoutSet; // True, if component has been laid out.
64 bool mLayoutSet; // True, if component has been laid out.
68 QVector<QRectF> mLayout;
65 QVector<QRectF> mLayout;
69
66
70 // Not owned.
67 // Not owned.
71 QBarSeries* mSeries;
68 QBarSeries* mSeries;
72 QList<Bar*> mBars;
69 QList<Bar*> mBars;
73 QList<BarValue*> mFloatingValues;
70 QList<BarValue*> mFloatingValues;
74 };
71 };
75
72
76 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
77
74
78 #endif // BARCHARTITEM_H
75 #endif // BARCHARTITEM_H
@@ -1,91 +1,93
1 #ifndef BARSERIES_H
1 #ifndef BARSERIES_H
2 #define BARSERIES_H
2 #define BARSERIES_H
3
3
4 #include <qseries.h>
4 #include <qseries.h>
5 #include <QStringList>
5 #include <QStringList>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 typedef QStringList QBarCategory;
10
9 class QBarSet;
11 class QBarSet;
10 class BarChartModel;
12 class BarChartModel;
11 class BarCategory;
13 class BarCategory;
12
14
13 // Container for series
15 // Container for series
14 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
16 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
15 {
17 {
16 Q_OBJECT
18 Q_OBJECT
17 public:
19 public:
18 QBarSeries(QStringList categories, QObject* parent=0);
20 QBarSeries(QStringList categories, QObject* parent=0);
19
21
20 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
22 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
21
23
22 void addBarSet(QBarSet *set); // Takes ownership of set
24 void addBarSet(QBarSet *set); // Takes ownership of set
23 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
25 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
24 void insertBarSet(int i, QBarSet *set);
26 void insertBarSet(int i, QBarSet *set);
25 void insertCategory(int i, QString category);
27 void insertCategory(int i, QString category);
26 void removeCategory(int i);
28 void removeCategory(int i);
27 int barsetCount();
29 int barsetCount();
28 int categoryCount();
30 int categoryCount();
29 QList<QBarSet*> barSets();
31 QList<QBarSet*> barSets();
30
32
31 bool setModel(QAbstractItemModel* model);
33 bool setModel(QAbstractItemModel* model);
32 QAbstractItemModel* modelExt() {return m_model;}
34 QAbstractItemModel* modelExt() {return m_model;}
33 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
35 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
34
36
35 public:
37 public:
36 // TODO: Functions below this are not part of api and will be moved
38 // TODO: Functions below this are not part of api and will be moved
37 // to private implementation, when we start using it
39 // to private implementation, when we start using it
38 // TODO: TO PIMPL --->
40 // TODO: TO PIMPL --->
39 QBarSet* barsetAt(int index);
41 QBarSet* barsetAt(int index);
40 QString categoryName(int category);
42 QString categoryName(int category);
41 qreal min();
43 qreal min();
42 qreal max();
44 qreal max();
43 qreal valueAt(int set, int category);
45 qreal valueAt(int set, int category);
44 qreal percentageAt(int set, int category);
46 qreal percentageAt(int set, int category);
45 qreal categorySum(int category);
47 qreal categorySum(int category);
46 qreal maxCategorySum();
48 qreal maxCategorySum();
47 BarChartModel& model();
49 BarChartModel& model();
48 // <--- TO PIMPL
50 // <--- TO PIMPL
49
51
50 signals:
52 signals:
51 //void changed(int index);
53 //void changed(int index);
52 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
54 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
53 void rightClicked(QBarSet* barset, QString category);
55 void rightClicked(QBarSet* barset, QString category);
54
56
55 //
57 //
56 void updatedBars();
58 void updatedBars();
57 void restructuredBar(int);
59 void restructuredBar(int);
58
60
59 // TODO: internal signals, these to private implementation.
61 // TODO: internal signals, these to private implementation.
60 // TODO: TO PIMPL --->
62 // TODO: TO PIMPL --->
61 void showToolTip(QPoint pos, QString tip);
63 void showToolTip(QPoint pos, QString tip);
62 // <--- TO PIMPL
64 // <--- TO PIMPL
63
65
64 public Q_SLOTS:
66 public Q_SLOTS:
65 void setToolTipEnabled(bool enabled=true); // enables tooltips
67 void setToolTipEnabled(bool enabled=true); // enables tooltips
66
68
67 // TODO: TO PIMPL --->
69 // TODO: TO PIMPL --->
68 void barsetClicked(QString category);
70 void barsetClicked(QString category);
69 void barsetRightClicked(QString category);
71 void barsetRightClicked(QString category);
70 // <--- TO PIMPL
72 // <--- TO PIMPL
71
73
72 private Q_SLOTS:
74 private Q_SLOTS:
73 // slots for updating bars when data in model changes
75 // slots for updating bars when data in model changes
74 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
76 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
75 void modelDataAdded(QModelIndex parent, int start, int end);
77 void modelDataAdded(QModelIndex parent, int start, int end);
76 void modelDataRemoved(QModelIndex parent, int start, int end);
78 void modelDataRemoved(QModelIndex parent, int start, int end);
77 void barsetChanged();
79 void barsetChanged();
78
80
79 protected:
81 protected:
80 BarChartModel* mModel;
82 BarChartModel* mModel;
81
83
82 // QAbstractItemModel* m_model;
84 // QAbstractItemModel* m_model;
83 int m_mapCategories;
85 int m_mapCategories;
84 int m_mapBarBottom;
86 int m_mapBarBottom;
85 int m_mapBarTop;
87 int m_mapBarTop;
86 Qt::Orientation m_mapOrientation;
88 Qt::Orientation m_mapOrientation;
87 };
89 };
88
90
89 QTCOMMERCIALCHART_END_NAMESPACE
91 QTCOMMERCIALCHART_END_NAMESPACE
90
92
91 #endif // BARSERIES_H
93 #endif // BARSERIES_H
@@ -1,312 +1,334
1 #include "chartdataset_p.h"
1 #include "chartdataset_p.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 //series
3 //series
4 #include "qlineseries.h"
4 #include "qlineseries.h"
5 #include "qareaseries.h"
5 #include "qareaseries.h"
6 #include "qbarseries.h"
6 #include "qbarseries.h"
7 #include "qstackedbarseries.h"
7 #include "qstackedbarseries.h"
8 #include "qpercentbarseries.h"
8 #include "qpercentbarseries.h"
9 #include "qpieseries.h"
9 #include "qpieseries.h"
10 #include "qscatterseries.h"
10 #include "qscatterseries.h"
11 #include "qsplineseries.h"
11 #include "qsplineseries.h"
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
16 m_axisX(new QChartAxis(this)),
16 m_axisX(new QChartAxis(this)),
17 m_axisY(new QChartAxis(this)),
17 m_axisY(new QChartAxis(this)),
18 m_domainIndex(0),
18 m_domainIndex(0),
19 m_axisXInitialized(false)
19 m_axisXInitialized(false)
20 {
20 {
21 }
21 }
22
22
23 ChartDataSet::~ChartDataSet()
23 ChartDataSet::~ChartDataSet()
24 {
24 {
25 }
25 }
26
26
27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
28 {
28 {
29 if(axisY==0) axisY = m_axisY;
29 if(axisY==0) axisY = m_axisY;
30
30
31 QChartAxis* axis = m_seriesAxisMap.value(series);
31 QChartAxis* axis = m_seriesAxisMap.value(series);
32
32
33 if(axis) {
33 if(axis) {
34 qWarning() << "Can not add series. Series already on the chart";
34 qWarning() << "Can not add series. Series already on the chart";
35 return;
35 return;
36 }
36 }
37
37
38 if(!series->parent()){
38 if(!series->parent()){
39 series->setParent(this); // take ownership
39 series->setParent(this); // take ownership
40 };
40 };
41
41
42 if(!axisY->parent()){
42 if(!axisY->parent()){
43 axisY->setParent(this); // take ownership
43 axisY->setParent(this); // take ownership
44 }
44 }
45
45
46 Domain* domain = m_axisDomainMap.value(axisY);
46 Domain* domain = m_axisDomainMap.value(axisY);
47
47
48 if(!domain) {
48 if(!domain) {
49 domain = new Domain();
49 domain = new Domain();
50 QObject::connect(axisY,SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
50 QObject::connect(axisY,SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
51 QObject::connect(axisX(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
51 QObject::connect(axisX(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
52 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axisY,SLOT(handleAxisRangeChanged(qreal,qreal,int)));
52 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axisY,SLOT(handleAxisRangeChanged(qreal,qreal,int)));
53 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),axisX(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
53 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),axisX(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
54 //initialize
54 //initialize
55 m_axisDomainMap.insert(axisY,domain);
55 m_axisDomainMap.insert(axisY,domain);
56 emit axisAdded(axisY,domain);
56 emit axisAdded(axisY,domain);
57 }
57 }
58
58
59 if(!m_axisXInitialized){
59 if(!m_axisXInitialized){
60 emit axisAdded(axisX(),domain);
60 emit axisAdded(axisX(),domain);
61 m_axisXInitialized=true;
61 m_axisXInitialized=true;
62 }
62 }
63
63
64 calculateDomain(series,domain);
64 calculateDomain(series,domain);
65
65
66 m_seriesAxisMap.insert(series,axisY);
66 m_seriesAxisMap.insert(series,axisY);
67 emit seriesAdded(series,domain);
67 emit seriesAdded(series,domain);
68
68
69 }
69 }
70
70
71 void ChartDataSet::removeSeries(QSeries* series)
71 void ChartDataSet::removeSeries(QSeries* series)
72 {
72 {
73
73
74 QChartAxis* axis = m_seriesAxisMap.value(series);
74 QChartAxis* axis = m_seriesAxisMap.value(series);
75
75
76 if(!axis){
76 if(!axis){
77 qWarning()<<"Can not remove series. Series not found on the chart.";
77 qWarning()<<"Can not remove series. Series not found on the chart.";
78 return;
78 return;
79 }
79 }
80 emit seriesRemoved(series);
80 emit seriesRemoved(series);
81 m_seriesAxisMap.remove(series);
81 m_seriesAxisMap.remove(series);
82
82
83 if(series->parent()==this){
83 if(series->parent()==this){
84 delete series;
84 delete series;
85 series=0;
85 series=0;
86 }
86 }
87
87
88 QList<QChartAxis*> axes = m_seriesAxisMap.values();
88 QList<QChartAxis*> axes = m_seriesAxisMap.values();
89
89
90 int i = axes.indexOf(axis);
90 int i = axes.indexOf(axis);
91
91
92 if(i==-1){
92 if(i==-1){
93 Domain* domain = m_axisDomainMap.take(axis);
93 Domain* domain = m_axisDomainMap.take(axis);
94 emit axisRemoved(axis);
94 emit axisRemoved(axis);
95 if(axis!=axisY()){
95 if(axis!=axisY()){
96 if(axis->parent()==this){
96 if(axis->parent()==this){
97 delete axis;
97 delete axis;
98 axis=0;
98 axis=0;
99 }
99 }
100 }
100 }
101 delete domain;
101 delete domain;
102 }
102 }
103
103
104 if(m_seriesAxisMap.values().size()==0)
104 if(m_seriesAxisMap.values().size()==0)
105 {
105 {
106 m_axisXInitialized=false;
106 m_axisXInitialized=false;
107 emit axisRemoved(axisX());
107 emit axisRemoved(axisX());
108 }
108 }
109 }
109 }
110
110
111 void ChartDataSet::removeAllSeries()
111 void ChartDataSet::removeAllSeries()
112 {
112 {
113
113
114 QList<QSeries*> series = m_seriesAxisMap.keys();
114 QList<QSeries*> series = m_seriesAxisMap.keys();
115
115
116 foreach(QSeries* s , series) {
116 foreach(QSeries* s , series) {
117 removeSeries(s);
117 removeSeries(s);
118 }
118 }
119
119
120 Q_ASSERT(m_seriesAxisMap.count()==0);
120 Q_ASSERT(m_seriesAxisMap.count()==0);
121 Q_ASSERT(m_axisDomainMap.count()==0);
121 Q_ASSERT(m_axisDomainMap.count()==0);
122
122
123 }
123 }
124
124
125 //to be removed with PIMPL
125 //to be removed with PIMPL
126 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain) const
126 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain)
127 {
127 {
128 qreal minX(domain->minX());
129 qreal minY(domain->minY());
130 qreal maxX(domain->maxX());
131 qreal maxY(domain->maxY());
132 int tickXCount(domain->tickXCount());
133 int tickYCount(domain->tickYCount());
134
135
128 switch(series->type())
136 switch(series->type())
129 {
137 {
130 case QSeries::SeriesTypeLine:
138 case QSeries::SeriesTypeLine:
131 case QSeries::SeriesTypeSpline:
139 case QSeries::SeriesTypeSpline:
132 case QSeries::SeriesTypeScatter:
140 case QSeries::SeriesTypeScatter:
133 {
141 {
134
142
135 QXYSeries* xySeries = static_cast<QXYSeries*>(series);
143 QXYSeries* xySeries = static_cast<QXYSeries*>(series);
136
144
137 qreal minX(domain->minX());
138 qreal minY(domain->minY());
139 qreal maxX(domain->maxX());
140 qreal maxY(domain->maxY());
141
142 for (int i = 0; i < xySeries->count(); i++)
145 for (int i = 0; i < xySeries->count(); i++)
143 {
146 {
144 qreal x = xySeries->x(i);
147 qreal x = xySeries->x(i);
145 qreal y = xySeries->y(i);
148 qreal y = xySeries->y(i);
146 minX = qMin(minX, x);
149 minX = qMin(minX, x);
147 minY = qMin(minY, y);
150 minY = qMin(minY, y);
148 maxX = qMax(maxX, x);
151 maxX = qMax(maxX, x);
149 maxY = qMax(maxY, y);
152 maxY = qMax(maxY, y);
150 }
153 }
151
152 domain->setRange(minX, maxX, minY, maxY);
153 break;
154 break;
154 }
155 }
155 case QSeries::SeriesTypeArea: {
156 case QSeries::SeriesTypeArea: {
156
157
157 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
158 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
158
159 QLineSeries* upperSeries = areaSeries->upperSeries();
159 QLineSeries* upperSeries = areaSeries->upperSeries();
160 QLineSeries* lowerSeries = areaSeries->lowerSeries();
160 QLineSeries* lowerSeries = areaSeries->lowerSeries();
161
161
162 for (int i = 0; i < upperSeries->count(); i++)
162 for (int i = 0; i < upperSeries->count(); i++)
163 {
163 {
164 qreal x = upperSeries->x(i);
164 qreal x = upperSeries->x(i);
165 qreal y = upperSeries->y(i);
165 qreal y = upperSeries->y(i);
166 domain->setMinX(qMin(domain->minX(),x));
166 minX = qMin(minX, x);
167 domain->setMinY(qMin(domain->minY(),y));
167 minY = qMin(minY, y);
168 domain->setMaxX(qMax(domain->maxX(),x));
168 maxX = qMax(maxX, x);
169 domain->setMaxY(qMax(domain->maxY(),y));
169 maxY = qMax(maxY, y);
170 }
170 }
171 if(lowerSeries) {
171 if(lowerSeries) {
172 for (int i = 0; i < lowerSeries->count(); i++)
172 for (int i = 0; i < lowerSeries->count(); i++)
173 {
173 {
174 qreal x = lowerSeries->x(i);
174 qreal x = lowerSeries->x(i);
175 qreal y = lowerSeries->y(i);
175 qreal y = lowerSeries->y(i);
176 domain->setMinX(qMin(domain->minX(),x));
176 minX = qMin(minX, x);
177 domain->setMinY(qMin(domain->minY(),y));
177 minY = qMin(minY, y);
178 domain->setMaxX(qMax(domain->maxX(),x));
178 maxX = qMax(maxX, x);
179 domain->setMaxY(qMax(domain->maxY(),y));
179 maxY = qMax(maxY, y);
180 }}
180 }}
181 break;
181 break;
182 }
182 }
183 case QSeries::SeriesTypeBar: {
183 case QSeries::SeriesTypeBar: {
184
184 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
185 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
185 qreal x = barSeries->categoryCount();
186 qreal x = barSeries->categoryCount();
186 qreal y = barSeries->max();
187 qreal y = barSeries->max();
187 domain->setMinX(qMin(domain->minX(),x));
188 minX = qMin(minX, x);
188 domain->setMinY(qMin(domain->minY(),y));
189 minY = qMin(minY, y);
189 domain->setMaxX(qMax(domain->maxX(),x));
190 maxX = qMax(maxX, x);
190 domain->setMaxY(qMax(domain->maxY(),y));
191 maxY = qMax(maxY, y);
192 tickXCount = x+1;
193 setupCategories(barSeries);
191 break;
194 break;
192 }
195 }
193 case QSeries::SeriesTypeStackedBar: {
196 case QSeries::SeriesTypeStackedBar: {
197
194 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
198 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
195 qreal x = stackedBarSeries->categoryCount();
199 qreal x = stackedBarSeries->categoryCount();
196 qreal y = stackedBarSeries->maxCategorySum();
200 qreal y = stackedBarSeries->maxCategorySum();
197 domain->setMinX(qMin(domain->minX(),x));
201 minX = qMin(minX, x);
198 domain->setMinY(qMin(domain->minY(),y));
202 minY = qMin(minY, y);
199 domain->setMaxX(qMax(domain->maxX(),x));
203 maxX = qMax(maxX, x);
200 domain->setMaxY(qMax(domain->maxY(),y));
204 maxY = qMax(maxY, y);
205 tickXCount = x+1;
206 setupCategories(stackedBarSeries);
201 break;
207 break;
202 }
208 }
203 case QSeries::SeriesTypePercentBar: {
209 case QSeries::SeriesTypePercentBar: {
210
204 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
211 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
205 qreal x = percentBarSeries->categoryCount();
212 qreal x = percentBarSeries->categoryCount();
206 domain->setMinX(qMin(domain->minX(),x));
213 minX = qMin(minX, x);
207 domain->setMinY(0);
214 maxX = qMax(maxX, x);
208 domain->setMaxX(qMax(domain->maxX(),x));
215 minY = 0;
209 domain->setMaxY(100);
216 maxY = 100;
217 setupCategories(percentBarSeries);
210 break;
218 break;
211 }
219 }
212
220
213 case QSeries::SeriesTypePie: {
221 case QSeries::SeriesTypePie: {
214 //QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
222 //QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
215 // TODO: domain stuff
223 // TODO: domain stuff
216 break;
224 break;
217 }
225 }
218
226
219
227
220 default: {
228 default: {
221 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
229 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
222 return;
230 return;
223 break;
231 break;
224 }
232 }
225
233
226 }
234 }
235
236 domain->setRangeX(minX,maxX,tickXCount);
237 domain->setRangeY(minY,maxY,tickYCount);
238 }
239
240
241 void ChartDataSet::setupCategories(QBarSeries* series)
242 {
243 int count = series->categoryCount();
244 QChartAxisCategories* categories = axisX()->categories();
245 categories->clear();
246 for (int i=1; i<=count; i++) {
247 categories->insert(i,series->categoryName(i-1));
248 }
227 }
249 }
228
250
229 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
251 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
230 {
252 {
231 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
253 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
232 while (i.hasNext()) {
254 while (i.hasNext()) {
233 i.next();
255 i.next();
234 i.value()->zoomIn(rect,size);
256 i.value()->zoomIn(rect,size);
235 }
257 }
236 }
258 }
237
259
238 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
260 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
239 {
261 {
240 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
262 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
241 while (i.hasNext()) {
263 while (i.hasNext()) {
242 i.next();
264 i.next();
243 i.value()->zoomOut(rect,size);
265 i.value()->zoomOut(rect,size);
244 }
266 }
245 }
267 }
246
268
247 int ChartDataSet::seriesCount(QSeries::QSeriesType type)
269 int ChartDataSet::seriesCount(QSeries::QSeriesType type)
248 {
270 {
249 int count=0;
271 int count=0;
250 QMapIterator<QSeries*, QChartAxis*> i( m_seriesAxisMap);
272 QMapIterator<QSeries*, QChartAxis*> i( m_seriesAxisMap);
251 while (i.hasNext()) {
273 while (i.hasNext()) {
252 i.next();
274 i.next();
253 if(i.key()->type()==type) count++;
275 if(i.key()->type()==type) count++;
254 }
276 }
255 return count;
277 return count;
256 }
278 }
257
279
258 int ChartDataSet::seriesIndex(QSeries *series)
280 int ChartDataSet::seriesIndex(QSeries *series)
259 {
281 {
260 int count(-1);
282 int count(-1);
261 QMapIterator<QSeries*, QChartAxis*> i(m_seriesAxisMap);
283 QMapIterator<QSeries*, QChartAxis*> i(m_seriesAxisMap);
262 while (i.hasNext()) {
284 while (i.hasNext()) {
263 i.next();
285 i.next();
264 count++;
286 count++;
265 if (i.key() == series)
287 if (i.key() == series)
266 return count;
288 return count;
267 }
289 }
268 return count;
290 return count;
269 }
291 }
270
292
271 QChartAxis* ChartDataSet::axisY(QSeries* series) const
293 QChartAxis* ChartDataSet::axisY(QSeries* series) const
272 {
294 {
273 if(series == 0) return m_axisY;
295 if(series == 0) return m_axisY;
274 return m_seriesAxisMap.value(series);
296 return m_seriesAxisMap.value(series);
275 }
297 }
276
298
277 Domain* ChartDataSet::domain(QSeries* series) const
299 Domain* ChartDataSet::domain(QSeries* series) const
278 {
300 {
279 QChartAxis* axis = m_seriesAxisMap.value(series);
301 QChartAxis* axis = m_seriesAxisMap.value(series);
280 if(axis){
302 if(axis){
281 return m_axisDomainMap.value(axis);
303 return m_axisDomainMap.value(axis);
282 }else
304 }else
283 return 0;
305 return 0;
284 }
306 }
285
307
286 Domain* ChartDataSet::domain(QChartAxis* axis) const
308 Domain* ChartDataSet::domain(QChartAxis* axis) const
287 {
309 {
288 if(axis==axisX()) {
310 if(axis==axisX()) {
289 return m_axisDomainMap.value(axisY());
311 return m_axisDomainMap.value(axisY());
290 }
312 }
291 else {
313 else {
292 return m_axisDomainMap.value(axis);
314 return m_axisDomainMap.value(axis);
293 }
315 }
294 }
316 }
295
317
296 QChartAxis* ChartDataSet::axis(QSeries* series) const
318 QChartAxis* ChartDataSet::axis(QSeries* series) const
297 {
319 {
298 return m_seriesAxisMap.value(series);
320 return m_seriesAxisMap.value(series);
299 }
321 }
300
322
301 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
323 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
302 {
324 {
303 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
325 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
304 while (i.hasNext()) {
326 while (i.hasNext()) {
305 i.next();
327 i.next();
306 i.value()->move(dx,dy,size);
328 i.value()->move(dx,dy,size);
307 }
329 }
308 }
330 }
309
331
310 #include "moc_chartdataset_p.cpp"
332 #include "moc_chartdataset_p.cpp"
311
333
312 QTCOMMERCIALCHART_END_NAMESPACE
334 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,61
1 #ifndef CHARTDATASET_P_H_
1 #ifndef CHARTDATASET_P_H_
2 #define CHARTDATASET_P_H_
2 #define CHARTDATASET_P_H_
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include "domain_p.h"
5 #include "domain_p.h"
6 #include <QVector>
6 #include <QVector>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QChartAxis;
10 class QChartAxis;
11 class QBarSeries;
11
12
12 class ChartDataSet : public QObject
13 class ChartDataSet : public QObject
13 {
14 {
14 Q_OBJECT
15 Q_OBJECT
15 public:
16 public:
16 ChartDataSet(QObject* parent=0);
17 ChartDataSet(QObject* parent=0);
17 virtual ~ChartDataSet();
18 virtual ~ChartDataSet();
18
19
19 void addSeries(QSeries* series,QChartAxis *axisY = 0);
20 void addSeries(QSeries* series,QChartAxis *axisY = 0);
20 void removeSeries(QSeries* series);
21 void removeSeries(QSeries* series);
21 void removeAllSeries();
22 void removeAllSeries();
22
23
23 void zoomInDomain(const QRectF& rect, const QSizeF& size);
24 void zoomInDomain(const QRectF& rect, const QSizeF& size);
24 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
25 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
25 void scrollDomain(int dx,int dy,const QSizeF& size);
26 void scrollDomain(int dx,int dy,const QSizeF& size);
26
27
27 int seriesCount(QSeries::QSeriesType type);
28 int seriesCount(QSeries::QSeriesType type);
28 int seriesIndex(QSeries *series);
29 int seriesIndex(QSeries *series);
29
30
30 Domain* domain(QSeries* series) const;
31 Domain* domain(QSeries* series) const;
31 Domain* domain(QChartAxis* axis) const;
32 Domain* domain(QChartAxis* axis) const;
32 QChartAxis* axis(QSeries* series) const;
33 QChartAxis* axis(QSeries* series) const;
33
34
34 QChartAxis* axisX() const { return m_axisX;};
35 QChartAxis* axisX() const { return m_axisX;};
35 QChartAxis* axisY(QSeries* series = 0) const;
36 QChartAxis* axisY(QSeries* series = 0) const;
36
37
37 signals:
38 signals:
38 void seriesAdded(QSeries* series,Domain* domain);
39 void seriesAdded(QSeries* series,Domain* domain);
39 void seriesRemoved(QSeries* series);
40 void seriesRemoved(QSeries* series);
40 void axisAdded(QChartAxis* axis,Domain* domain);
41 void axisAdded(QChartAxis* axis,Domain* domain);
41 void axisRemoved(QChartAxis* axis);
42 void axisRemoved(QChartAxis* axis);
42
43
43 private:
44 private:
44 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
45 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
45 void calculateDomain(QSeries* series,Domain* domain) const;
46 void calculateDomain(QSeries* series,Domain* domain);
47 void setupCategories(QBarSeries* series);
46
48
47 private:
49 private:
48 QMap<QSeries*, QChartAxis*> m_seriesAxisMap;
50 QMap<QSeries*, QChartAxis*> m_seriesAxisMap;
49 QMap<QChartAxis*, Domain*> m_axisDomainMap;
51 QMap<QChartAxis*, Domain*> m_axisDomainMap;
50 QChartAxis* m_axisX;
52 QChartAxis* m_axisX;
51 QChartAxis* m_axisY;
53 QChartAxis* m_axisY;
52
54
53 int m_domainIndex;
55 int m_domainIndex;
54 bool m_axisXInitialized;
56 bool m_axisXInitialized;
55 };
57 };
56
58
57 QTCOMMERCIALCHART_END_NAMESPACE
59 QTCOMMERCIALCHART_END_NAMESPACE
58
60
59 #endif /* CHARTENGINE_P_H_ */
61 #endif /* CHARTENGINE_P_H_ */
@@ -1,89 +1,89
1 #ifndef CHARTPRESENTER_H_
1 #ifndef CHARTPRESENTER_H_
2 #define CHARTPRESENTER_H_
2 #define CHARTPRESENTER_H_
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
5 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
6 #include "qchartaxis.h"
6 #include "qchartaxis.h"
7 #include <QRectF>
7 #include <QRectF>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class Chart;
11 class Chart;
12 class QSeries;
12 class QSeries;
13 class ChartDataSet;
13 class ChartDataSet;
14 class Domain;
14 class Domain;
15 class Axis;
15 class Axis;
16 class ChartTheme;
16 class ChartTheme;
17 class ChartAnimator;
17 class ChartAnimator;
18
18
19 class ChartPresenter: public QObject
19 class ChartPresenter: public QObject
20 {
20 {
21 Q_OBJECT
21 Q_OBJECT
22 public:
22 public:
23 enum ZValues {
23 enum ZValues {
24 BackgroundZValue = -1,
24 BackgroundZValue = -1,
25 ShadesZValue,
25 ShadesZValue,
26 GridZValue,
26 GridZValue,
27 AxisZValue,
28 LineChartZValue,
27 LineChartZValue,
29 BarSeriesZValue,
28 BarSeriesZValue,
30 ScatterSeriesZValue,
29 ScatterSeriesZValue,
31 PieSeriesZValue,
30 PieSeriesZValue,
31 AxisZValue,
32 LegendZValue
32 LegendZValue
33 };
33 };
34
34
35 ChartPresenter(QChart* chart,ChartDataSet *dataset);
35 ChartPresenter(QChart* chart,ChartDataSet *dataset);
36 virtual ~ChartPresenter();
36 virtual ~ChartPresenter();
37
37
38 void setMargin(int margin);
38 void setMargin(int margin);
39 int margin() const;
39 int margin() const;
40
40
41 QRectF geometry() const;
41 QRectF geometry() const;
42
42
43 ChartAnimator* animator() const {return m_animator;}
43 ChartAnimator* animator() const {return m_animator;}
44 ChartTheme *theme() { return m_chartTheme; }
44 ChartTheme *theme() { return m_chartTheme; }
45 ChartDataSet *dataSet() { return m_dataset; }
45 ChartDataSet *dataSet() { return m_dataset; }
46
46
47 void setChartTheme(QChart::ChartTheme theme,bool force = true);
47 void setChartTheme(QChart::ChartTheme theme,bool force = true);
48 QChart::ChartTheme chartTheme();
48 QChart::ChartTheme chartTheme();
49
49
50 void setAnimationOptions(QChart::AnimationOptions options);
50 void setAnimationOptions(QChart::AnimationOptions options);
51 QChart::AnimationOptions animationOptions() const;
51 QChart::AnimationOptions animationOptions() const;
52
52
53 QGraphicsItem* rootItem() const {return m_chart;};
53 QGraphicsItem* rootItem() const {return m_chart;};
54
54
55 void zoomIn();
55 void zoomIn();
56 void zoomIn(const QRectF& rect);
56 void zoomIn(const QRectF& rect);
57 void zoomOut();
57 void zoomOut();
58 void scroll(int dx,int dy);
58 void scroll(int dx,int dy);
59
59
60 private:
60 private:
61 void createConnections();
61 void createConnections();
62 void resetAllElements();
62 void resetAllElements();
63
63
64 public slots:
64 public slots:
65 void handleSeriesAdded(QSeries* series,Domain* domain);
65 void handleSeriesAdded(QSeries* series,Domain* domain);
66 void handleSeriesRemoved(QSeries* series);
66 void handleSeriesRemoved(QSeries* series);
67 void handleAxisAdded(QChartAxis* axis,Domain* domain);
67 void handleAxisAdded(QChartAxis* axis,Domain* domain);
68 void handleAxisRemoved(QChartAxis* axis);
68 void handleAxisRemoved(QChartAxis* axis);
69 void handleGeometryChanged();
69 void handleGeometryChanged();
70
70
71 signals:
71 signals:
72 void geometryChanged(const QRectF& rect);
72 void geometryChanged(const QRectF& rect);
73
73
74 private:
74 private:
75 QChart* m_chart;
75 QChart* m_chart;
76 ChartAnimator* m_animator;
76 ChartAnimator* m_animator;
77 ChartDataSet* m_dataset;
77 ChartDataSet* m_dataset;
78 ChartTheme *m_chartTheme;
78 ChartTheme *m_chartTheme;
79 QMap<QSeries*,Chart*> m_chartItems;
79 QMap<QSeries*,Chart*> m_chartItems;
80 QMap<QChartAxis*,Axis*> m_axisItems;
80 QMap<QChartAxis*,Axis*> m_axisItems;
81 QRectF m_rect;
81 QRectF m_rect;
82 QChart::AnimationOptions m_options;
82 QChart::AnimationOptions m_options;
83 bool m_themeForce;
83 bool m_themeForce;
84
84
85 };
85 };
86
86
87 QTCOMMERCIALCHART_END_NAMESPACE
87 QTCOMMERCIALCHART_END_NAMESPACE
88
88
89 #endif /* CHARTPRESENTER_H_ */
89 #endif /* CHARTPRESENTER_H_ */
General Comments 0
You need to be logged in to leave comments. Login now