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