##// END OF EJS Templates
Axis refactoring to support better barcharts
Michal Klocek -
r502:c37a1568cc38
parent child
Show More
@@ -50,7 +50,7 int main(int argc, char *argv[])
50 50 axisX->setLabelsAngle(45);
51 51 axisX->setGridPen(Qt::DashLine);
52 52
53 QChartAxisCategories *categoriesX = axisX->categories();
53 QChartAxisCategories* categoriesX = axisX->categories();
54 54 categoriesX->insert(0,"low");
55 55 categoriesX->insert(50,"medium");
56 56 categoriesX->insert(100,"High");
@@ -62,7 +62,7 int main(int argc, char *argv[])
62 62 axisY->setLabelsAngle(45);
63 63 axisY->setShadesBrush(Qt::yellow);
64 64
65 QChartAxisCategories *categoriesY = axisY->categories();
65 QChartAxisCategories* categoriesY = axisY->categories();
66 66 categoriesY->insert(0,"low");
67 67 categoriesY->insert(50,"medium");
68 68 categoriesY->insert(100,"High");
@@ -17,11 +17,9 AxisAnimationItem::~AxisAnimationItem()
17 17 {
18 18 }
19 19
20 void AxisAnimationItem::updateItem()
20 void AxisAnimationItem::updateLayout(QVector<qreal>& newLayout)
21 21 {
22 22 QVector<qreal> oldLayout = layout();
23 AxisItem::updateItem();
24 QVector<qreal> newLayout = layout();
25 23
26 24 if(newLayout.count()==0) return;
27 25 oldLayout.resize(newLayout.size());
@@ -21,7 +21,8 public:
21 21 void setLabelsAngle(int angle);
22 22
23 23 protected:
24 virtual void updateItem();
24 virtual void updateLayout(QVector<qreal>& layout);
25
25 26 private:
26 27 AxisAnimator *m_animation;
27 28 };
@@ -16,7 +16,10 m_labelsAngle(0),
16 16 m_grid(parent),
17 17 m_shades(parent),
18 18 m_labels(parent),
19 m_axis(parent)
19 m_axis(parent),
20 m_min(0),
21 m_max(0),
22 m_ticksCount(0)
20 23 {
21 24 //initial initialization
22 25 m_axis.setZValue(ChartPresenter::AxisZValue);
@@ -26,6 +29,8 m_axis(parent)
26 29
27 30 QObject::connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
28 31 QObject::connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
32
33 handleAxisUpdated();
29 34 }
30 35
31 36 AxisItem::~AxisItem()
@@ -49,7 +54,7 void AxisItem::createItems(int count)
49 54 }
50 55 }
51 56
52 void AxisItem::clear(int count)
57 void AxisItem::deleteItems(int count)
53 58 {
54 59 QList<QGraphicsItem *> lines = m_grid.childItems();
55 60 QList<QGraphicsItem *> labels = m_labels.childItems();
@@ -64,46 +69,22 void AxisItem::clear(int count)
64 69 }
65 70 }
66 71
67 void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
72 void AxisItem::updateLayout(QVector<qreal>& layout)
68 73 {
69 Q_UNUSED(painter);
70 Q_UNUSED(option);
71 Q_UNUSED(widget);
72 }
73
74 void AxisItem::updateItem()
75 {
76 QStringList labels = createLabels(m_ticks,m_min,m_max);
77
78 int diff = m_thicksList.size() - labels.size();
79
80 if(diff>0) {
81 clear(diff);
82 }
83 else if(diff<0) {
84 createItems(-diff);
85 }
86
87 if(diff!=0) handleAxisUpdated();
88
89 m_thicksList=labels;
90
91 QVector<qreal> layout = calculateLayout();
92 if(layout.count()==0) return;
93 74 setLayout(layout);
94
95 75 }
96 76
97 QStringList AxisItem::createLabels(int ticks, qreal min, qreal max)
77 QStringList AxisItem::createLabels(int ticks, qreal min, qreal max) const
98 78 {
99 79 Q_ASSERT(max>=min);
80 Q_ASSERT(ticks>0);
100 81
101 82 QStringList labels;
102 83
103 84 QChartAxisCategories* categories = m_chartAxis->categories();
104 85
105 for(int i=0; i<= ticks; i++) {
106 qreal value = min + (i * (max - min)/ ticks);
86 for(int i=0; i< ticks; i++) {
87 qreal value = min + (i * (max - min)/ (ticks-1));
107 88 if(categories->count()==0) {
108 89 labels << QString::number(value);
109 90 }
@@ -112,6 +93,8 QStringList AxisItem::createLabels(int ticks, qreal min, qreal max)
112 93 labels << label;
113 94 }
114 95 }
96
97
115 98 return labels;
116 99 }
117 100
@@ -216,15 +199,17 void AxisItem::setGridPen(const QPen& pen)
216 199
217 200 QVector<qreal> AxisItem::calculateLayout() const
218 201 {
202 Q_ASSERT(m_ticksCount>=2);
203
219 204 QVector<qreal> points;
220 points.resize(m_thicksList.size());
205 points.resize(m_ticksCount);
221 206
222 207 switch (m_type)
223 208 {
224 209 case X_AXIS:
225 210 {
226 const qreal deltaX = m_rect.width()/(m_thicksList.size()-1);
227 for (int i = 0; i < m_thicksList.size(); ++i) {
211 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
212 for (int i = 0; i < m_ticksCount; ++i) {
228 213 int x = i * deltaX + m_rect.left();
229 214 points[i] = x;
230 215 }
@@ -232,8 +217,8 QVector<qreal> AxisItem::calculateLayout() const
232 217 break;
233 218 case Y_AXIS:
234 219 {
235 const qreal deltaY = m_rect.height()/(m_thicksList.size()-1);
236 for (int i = 0; i < m_thicksList.size(); ++i) {
220 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
221 for (int i = 0; i < m_ticksCount; ++i) {
237 222 int y = i * -deltaY + m_rect.bottom();
238 223 points[i] = y;
239 224 }
@@ -243,77 +228,93 QVector<qreal> AxisItem::calculateLayout() const
243 228 return points;
244 229 }
245 230
246 void AxisItem::setLayout(const QVector<qreal>& layout)
231 void AxisItem::setLayout(QVector<qreal>& layout)
247 232 {
233 int diff = m_layoutVector.size() - layout.size();
234
235 if(diff>0) {
236 deleteItems(diff);
237 }
238 else if(diff<0) {
239 createItems(-diff);
240 }
241
242 QList<QGraphicsItem *> lines = m_grid.childItems();
243 QList<QGraphicsItem *> labels = m_labels.childItems();
244 QList<QGraphicsItem *> shades = m_shades.childItems();
245 QList<QGraphicsItem *> axis = m_axis.childItems();
246
247 Q_ASSERT(labels.size() == m_ticksList.size());
248 Q_ASSERT(layout.size() == m_ticksList.size());
249
250 switch (m_type)
251 {
252 case X_AXIS:
253 {
254 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
255 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
256
257 for (int i = 0; i < layout.size(); ++i) {
258 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
259 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
260 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
261 labelItem->setText(m_ticksList.at(i));
262 QPointF center = labelItem->boundingRect().center();
263 labelItem->setTransformOriginPoint(center.x(), center.y());
264 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
265 if(i%2 && i+1 < layout.size()) {
266 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2));
267 rectItem->setRect(layout[i],m_rect.top(),layout[i+1]-layout[i],m_rect.height());
268 }
269 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
270 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
271 }
272 }
273 break;
274
275 case Y_AXIS:
276 {
277 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
278 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
279
280 for (int i = 0; i < layout.size(); ++i) {
281 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
282 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
283 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
284 labelItem->setText(m_ticksList.at(i));
285 QPointF center = labelItem->boundingRect().center();
286 labelItem->setTransformOriginPoint(center.x(), center.y());
287 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
288 if(i%2 && i+1 < layout.size()) {
289 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2));
290 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i]-layout[i+1]);
291 }
292 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
293 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
294 }
295 }
296 break;
297 default:
298 qDebug()<<"Unknown axis type";
299 break;
300 }
301
302 if(diff!=0) handleAxisUpdated();
303 m_layoutVector=layout;
304 }
248 305
249 QList<QGraphicsItem *> lines = m_grid.childItems();
250 QList<QGraphicsItem *> labels = m_labels.childItems();
251 QList<QGraphicsItem *> shades = m_shades.childItems();
252 QList<QGraphicsItem *> axis = m_axis.childItems();
253
254 Q_ASSERT(labels.size() == m_thicksList.size());
255 Q_ASSERT(layout.size() == m_thicksList.size());
256
257 switch (m_type)
258 {
259 case X_AXIS:
260 {
261 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
262 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
263
264 for (int i = 0; i < layout.size(); ++i) {
265 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
266 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
267 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
268 labelItem->setText(m_thicksList.at(i));
269 QPointF center = labelItem->boundingRect().center();
270 labelItem->setTransformOriginPoint(center.x(), center.y());
271 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
272 if(i%2 && i+1 < layout.size()){
273 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2));
274 rectItem->setRect(layout[i],m_rect.top(),layout[i+1]-layout[i],m_rect.height());
275 }
276 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
277 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
278 }
279 }
280 break;
281
282 case Y_AXIS:
283 {
284 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
285 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
286
287 for (int i = 0; i < layout.size(); ++i) {
288 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
289 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
290 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
291 labelItem->setText(m_thicksList.at(i));
292 QPointF center = labelItem->boundingRect().center();
293 labelItem->setTransformOriginPoint(center.x(), center.y());
294 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
295 if(i%2 && i+1 < layout.size()){
296 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2));
297 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i]-layout[i+1]);
298 }
299 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
300 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
301 }
302 }
303 break;
304 default:
305 qDebug()<<"Unknown axis type";
306 break;
307 }
308
309 m_layoutVector=layout;
306 bool AxisItem::isEmpty()
307 {
308 return m_rect.isEmpty() || m_min==m_max || m_ticksCount==0;
310 309 }
311 310
312 311 //handlers
313 312
314 313 void AxisItem::handleAxisCategoriesUpdated()
315 314 {
316 updateItem();
315 if(isEmpty()) return;
316 m_ticksList = createLabels(m_ticksCount,m_min,m_max);
317 updateLayout(m_layoutVector);
317 318 }
318 319
319 320 void AxisItem::handleAxisUpdated()
@@ -321,9 +322,8 void AxisItem::handleAxisUpdated()
321 322
322 323 int count = m_chartAxis->ticksCount();
323 324
324 if(m_ticks!=count){
325 m_ticks=count;
326 updateItem();
325 if(m_ticksCount!=count){
326 handleTicksCountChanged(count);
327 327 }
328 328
329 329 if(isEmpty()) return;
@@ -368,6 +368,16 void AxisItem::handleAxisUpdated()
368 368
369 369 }
370 370
371 void AxisItem::handleTicksCountChanged(int count)
372 {
373 m_ticksCount=count;
374
375 if(isEmpty()) return;
376 m_ticksList = createLabels(m_ticksCount,m_min,m_max);
377 QVector<qreal> layout = calculateLayout();
378 updateLayout(layout);
379 }
380
371 381 void AxisItem::handleRangeChanged(qreal min, qreal max)
372 382 {
373 383
@@ -375,20 +385,29 void AxisItem::handleRangeChanged(qreal min, qreal max)
375 385 m_max = max;
376 386
377 387 if(isEmpty()) return;
378 updateItem();
388 m_ticksList = createLabels(m_ticksCount,m_min,m_max);
389 QVector<qreal> layout = calculateLayout();
390 updateLayout(layout);
379 391
380 392 }
381 393
382 394 void AxisItem::handleGeometryChanged(const QRectF& rect)
383 395 {
396
384 397 m_rect = rect;
385 398 if(isEmpty()) return;
386 updateItem();
399 m_ticksList = createLabels(m_ticksCount,m_min,m_max);
400 QVector<qreal> layout = calculateLayout();
401 updateLayout(layout);
387 402 }
388 403
389 bool AxisItem::isEmpty()
404 //painter
405
406 void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
390 407 {
391 return m_rect.isEmpty() || m_min==m_max || m_ticks==0;
408 Q_UNUSED(painter);
409 Q_UNUSED(option);
410 Q_UNUSED(widget);
392 411 }
393 412
394 413 //TODO "nice numbers algorithm"
@@ -50,22 +50,23 public:
50 50 void setLabelsFont(const QFont& font);
51 51
52 52 public slots:
53 void handleAxisUpdated();//qchartaxis update calls
54 void handleAxisCategoriesUpdated();//qchartaxis update calls
55 void handleRangeChanged(qreal min , qreal max); //domain update calls
56 void handleGeometryChanged(const QRectF& size); //geometry update calls
53 void handleAxisUpdated();
54 void handleAxisCategoriesUpdated();
55 void handleRangeChanged(qreal min , qreal max);
56 void handleTicksCountChanged(int count);
57 void handleGeometryChanged(const QRectF& size);
57 58
58 59 public:
59 virtual void updateItem();
60 QVector<qreal> calculateLayout() const;
61 void setLayout(const QVector<qreal>& points);
60 virtual void updateLayout(QVector<qreal>& layout);
61 void setLayout(QVector<qreal>& layout);
62 62 QVector<qreal> layout() { return m_layoutVector;};
63 63
64 64 private:
65 65 inline bool isEmpty();
66 void clear(int count);
67 66 void createItems(int count);
68 QStringList createLabels(int ticks, qreal min, qreal max);
67 void deleteItems(int count);
68 QVector<qreal> calculateLayout() const;
69 QStringList createLabels(int ticks, qreal min, qreal max) const;
69 70
70 71 private:
71 72 QChartAxis* m_chartAxis;
@@ -76,11 +77,11 private:
76 77 QGraphicsItemGroup m_shades;
77 78 QGraphicsItemGroup m_labels;
78 79 QGraphicsItemGroup m_axis;
79 QStringList m_thicksList;
80 QStringList m_ticksList;
80 81 QVector<qreal> m_layoutVector;
81 82 qreal m_min;
82 83 qreal m_max;
83 int m_ticks;
84 int m_ticksCount;
84 85
85 86 };
86 87
@@ -100,22 +100,23 void BarPresenterBase::initAxisLabels()
100 100 if (0 == count) {
101 101 return;
102 102 }
103 count++;
104 103
105 mChart->axisX()->setTicksCount(count);
104 mChart->axisX()->setTicksCount(count+2);
106 105
107 106 qreal min = 0;
108 qreal max = count;
107 qreal max = count+1;
109 108
110 109 mChart->axisX()->setMin(min);
111 110 mChart->axisX()->setMax(max);
112 min++;
111
113 112 QChartAxisCategories* categories = mChart->axisX()->categories();
114 113 categories->clear();
115 for (int i=0; i<count-1; i++) {
116 categories->insert(min,mSeries->categoryName(i));
117 min++;
114 for (int i=0; i<count; i++) {
115 categories->insert(i+1,mSeries->categoryName(i));
118 116 }
117
118
119
119 120 mChart->axisX()->setLabelsVisible(true);
120 121 }
121 122
General Comments 0
You need to be logged in to leave comments. Login now