##// END OF EJS Templates
Fixes rounding issue with labels numbering
Michal Klocek -
r1720:79d9101394e5
parent child
Show More
@@ -21,7 +21,8
21 #include "chartcategoriesaxisx_p.h"
21 #include "chartcategoriesaxisx_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qbarcategoriesaxis_p.h"
23 #include "qbarcategoriesaxis_p.h"
24 #include <cmath>
24 #include <QDebug>
25 #include <qmath.h>
25
26
26 static int label_padding = 5;
27 static int label_padding = 5;
27
28
@@ -42,29 +43,47 QVector<qreal> ChartCategoriesAxisX::calculateLayout() const
42 Q_ASSERT(m_categoriesAxis->categories().count()>=1);
43 Q_ASSERT(m_categoriesAxis->categories().count()>=1);
43
44
44 QVector<qreal> points;
45 QVector<qreal> points;
45 points.resize(m_categoriesAxis->categories().count()+1);
46 points.resize(m_categoriesAxis->categories().count()+2);
46
47
47 const qreal delta = m_rect.width()/(m_categoriesAxis->categories().count());
48 const qreal delta = m_rect.width()/(m_categoriesAxis->categories().count());
48 const qreal min = m_categoriesAxis->d_ptr->min();
49 qreal offset =-m_min-0.5;
49 const qreal max = m_categoriesAxis->d_ptr->max();
50
50 qreal start =-min-0.5;
51 if(offset<=0) {
51 if(start<=0) {
52 offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta) + delta;
52 start = fmod(start * m_rect.width()/(max - min),delta) + delta;
53 }
53 }
54 else {
54 else {
55 start = fmod(start * m_rect.width()/(max - min),delta);
55 offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta);
56 }
56 }
57
57
58 points[m_categoriesAxis->categories().count()] = m_rect.left() + m_rect.width();
58 points[0] = m_rect.left();
59 points[m_categoriesAxis->categories().count()+1] = m_rect.right();
59
60
60 for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) {
61 for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) {
61 qreal x = start + i * delta + m_rect.left();
62 qreal x = offset + i * delta + m_rect.left();
62 points[i] = x;
63 points[i+1] = x;
63 }
64 }
64
65 return points;
65 return points;
66 }
66 }
67
67
68 QStringList ChartCategoriesAxisX::createCategoryLabels(const QVector<qreal>& layout) const
69 {
70 QStringList result;
71 qreal d = (m_max - m_min)/m_rect.width();
72 for (int i = 0;i < layout.count()-1; ++i) {
73 qreal x = qFloor((((layout[i+1] + layout[i])/2-m_rect.left())*d + m_min+0.5));
74 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
75 result << m_categoriesAxis->categories().at(x);
76 }
77 else {
78 // No label for x coordinate
79 result << "";
80 }
81 }
82 result << "";
83 return result;
84 }
85
86
68 void ChartCategoriesAxisX::updateGeometry()
87 void ChartCategoriesAxisX::updateGeometry()
69 {
88 {
70 const QVector<qreal>& layout = ChartAxis::layout();
89 const QVector<qreal>& layout = ChartAxis::layout();
@@ -74,9 +93,7 void ChartCategoriesAxisX::updateGeometry()
74
93
75 if(layout.isEmpty()) return;
94 if(layout.isEmpty()) return;
76
95
77 QStringList ticksList;
96 QStringList ticksList = createCategoryLabels(layout);
78
79 createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories());
80
97
81 QList<QGraphicsItem *> lines = m_grid->childItems();
98 QList<QGraphicsItem *> lines = m_grid->childItems();
82 QList<QGraphicsItem *> labels = m_labels->childItems();
99 QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -101,10 +118,10 void ChartCategoriesAxisX::updateGeometry()
101 QPointF center = rect.center();
118 QPointF center = rect.center();
102 labelItem->setTransformOriginPoint(center.x(), center.y());
119 labelItem->setTransformOriginPoint(center.x(), center.y());
103
120
104 if(i==layout.size()-1){
121 if(i==0){
105 labelItem->setPos(layout[i-1] + (delta)/2 - center.x(), m_rect.bottom() + label_padding);
122 labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), m_rect.bottom() + label_padding);
106 }else{
123 }else{
107 labelItem->setPos(layout[i] - (delta)/2 - center.x(), m_rect.bottom() + label_padding);
124 labelItem->setPos(layout[i] + (delta)/2 - center.x(), m_rect.bottom() + label_padding);
108 }
125 }
109
126
110 if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()>m_rect.right()) {
127 if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()>m_rect.right()) {
@@ -49,6 +49,8 public:
49 protected:
49 protected:
50 QVector<qreal> calculateLayout() const;
50 QVector<qreal> calculateLayout() const;
51 void updateGeometry();
51 void updateGeometry();
52 private:
53 QStringList createCategoryLabels(const QVector<qreal>& layout) const;
52 Q_SLOTS
54 Q_SLOTS
53 void handleAxisUpdated();
55 void handleAxisUpdated();
54
56
@@ -21,8 +21,7
21 #include "chartcategoriesaxisy_p.h"
21 #include "chartcategoriesaxisy_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qbarcategoriesaxis_p.h"
23 #include "qbarcategoriesaxis_p.h"
24 #include <QDebug>
24 #include <qmath.h>
25 #include <cmath>
26
25
27 static int label_padding = 5;
26 static int label_padding = 5;
28
27
@@ -42,32 +41,46 QVector<qreal> ChartCategoriesAxisY::calculateLayout() const
42 Q_ASSERT(m_categoriesAxis->categories().count()>=1);
41 Q_ASSERT(m_categoriesAxis->categories().count()>=1);
43
42
44 QVector<qreal> points;
43 QVector<qreal> points;
45 points.resize(m_categoriesAxis->categories().count()+1);
44 points.resize(m_categoriesAxis->categories().count()+2);
46
45
47 qreal delta = m_rect.height()/(m_categoriesAxis->categories().count());
46 const qreal delta = m_rect.height()/(m_categoriesAxis->categories().count());
48
47 qreal offset = - m_min - 0.5;
49 const qreal min = m_categoriesAxis->d_ptr->min();
50 const qreal max = m_categoriesAxis->d_ptr->max();
51
52 qreal start =-min-0.5;
53
48
54 if(start<=0) {
49 if(offset<=0) {
55 start = fmod(start * m_rect.height()/(max - min),delta) + delta;
50 offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta) + delta;
56 }
51 }
57 else {
52 else {
58 start = fmod(start * m_rect.height()/(max - min),delta);
53 offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta);
59 }
54 }
60
55
61 points[m_categoriesAxis->categories().count()] = m_rect.top();
56 points[0] = m_rect.bottom();
57 points[m_categoriesAxis->categories().count()+1] = m_rect.top();
62
58
63 for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) {
59 for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) {
64 int y = m_rect.bottom() - i * delta - start;
60 int y = m_rect.bottom() - i * delta - offset;
65 points[i] = y;
61 points[i+1] = y;
66 }
62 }
67
68 return points;
63 return points;
69 }
64 }
70
65
66 QStringList ChartCategoriesAxisY::createCategoryLabels(const QVector<qreal>& layout) const
67 {
68 QStringList result;
69 qreal d = (m_max - m_min)/m_rect.height();
70 for (int i = 0;i < layout.count()-1; ++i) {
71 qreal x = qFloor(((m_rect.height()- (layout[i+1] + layout[i])/2 + m_rect.top())*d + m_min+0.5));
72 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
73 result << m_categoriesAxis->categories().at(x);
74 }
75 else {
76 // No label for x coordinate
77 result << "";
78 }
79 }
80 result << "";
81 return result;
82 }
83
71 void ChartCategoriesAxisY::updateGeometry()
84 void ChartCategoriesAxisY::updateGeometry()
72 {
85 {
73 const QVector<qreal>& layout = ChartAxis::layout();
86 const QVector<qreal>& layout = ChartAxis::layout();
@@ -77,9 +90,7 void ChartCategoriesAxisY::updateGeometry()
77
90
78 if(layout.isEmpty()) return;
91 if(layout.isEmpty()) return;
79
92
80 QStringList ticksList;
93 QStringList ticksList = createCategoryLabels(layout);
81
82 createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories());
83
94
84 QList<QGraphicsItem *> lines = m_grid->childItems();
95 QList<QGraphicsItem *> lines = m_grid->childItems();
85 QList<QGraphicsItem *> labels = m_labels->childItems();
96 QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -104,11 +115,11 void ChartCategoriesAxisY::updateGeometry()
104 QPointF center = rect.center();
115 QPointF center = rect.center();
105 labelItem->setTransformOriginPoint(center.x(), center.y());
116 labelItem->setTransformOriginPoint(center.x(), center.y());
106
117
107 if(i==layout.size()-1) {
118 if(i==0) {
108 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i-1] - (delta)/2 - center.y());
119 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y());
109 }
120 }
110 else {
121 else {
111 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] + (delta)/2 - center.y());
122 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y());
112 }
123 }
113
124
114 if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < m_rect.top()) {
125 if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < m_rect.top()) {
@@ -137,7 +148,10 void ChartCategoriesAxisY::handleAxisUpdated()
137 if(m_categoriesAxis->categories()!=m_categories)
148 if(m_categoriesAxis->categories()!=m_categories)
138 {
149 {
139 m_categories=m_categoriesAxis->categories();
150 m_categories=m_categoriesAxis->categories();
140 if(ChartAxis::layout().count()==m_categories.size()+1) updateGeometry();
151 if(ChartAxis::layout().count()==m_categories.size()+1) {
152
153 updateGeometry();
154 }
141 }
155 }
142 ChartAxis::handleAxisUpdated();
156 ChartAxis::handleAxisUpdated();
143 }
157 }
@@ -49,10 +49,13 public:
49 protected:
49 protected:
50 QVector<qreal> calculateLayout() const;
50 QVector<qreal> calculateLayout() const;
51 void updateGeometry();
51 void updateGeometry();
52 private:
53 QStringList createCategoryLabels(const QVector<qreal>& layout) const;
52 Q_SLOTS
54 Q_SLOTS
53 void handleAxisUpdated();
55 void handleAxisUpdated();
54 private:
56 private:
55 QStringList m_categories;
57 QStringList m_categories;
58 QVector<int> m_labelIndex;
56 QBarCategoriesAxis *m_categoriesAxis;
59 QBarCategoriesAxis *m_categoriesAxis;
57 };
60 };
58
61
@@ -24,8 +24,6
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "chartanimator_p.h"
25 #include "chartanimator_p.h"
26 #include "domain_p.h"
26 #include "domain_p.h"
27 #include <QPainter>
28 #include <QDebug>
29 #include <qmath.h>
27 #include <qmath.h>
30 #include <QDateTime>
28 #include <QDateTime>
31
29
@@ -362,7 +360,7 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int
362 Q_ASSERT(max>min);
360 Q_ASSERT(max>min);
363 Q_ASSERT(ticks>1);
361 Q_ASSERT(ticks>1);
364
362
365 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
363 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
366 n++;
364 n++;
367 for (int i=0; i< ticks; i++) {
365 for (int i=0; i< ticks; i++) {
368 qreal value = min + (i * (max - min)/ (ticks-1));
366 qreal value = min + (i * (max - min)/ (ticks-1));
@@ -370,27 +368,6 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int
370 }
368 }
371 }
369 }
372
370
373 void ChartAxis::createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const
374 {
375 Q_ASSERT(max>min);
376 Q_UNUSED(max);
377
378 int x = qFloor(min+0.5);
379 int count = 0;
380
381 // Try to find category for x coordinate
382 while (count < categories.count()+1) {
383 if ((x < categories.count()) && (x >= 0)) {
384 labels << categories.at(x);
385 } else {
386 // No label for x coordinate
387 labels << "";
388 }
389 x++;
390 count++;
391 }
392 }
393
394 #include "moc_chartaxis_p.cpp"
371 #include "moc_chartaxis_p.cpp"
395
372
396 QTCOMMERCIALCHART_END_NAMESPACE
373 QTCOMMERCIALCHART_END_NAMESPACE
@@ -92,7 +92,6 protected:
92 virtual void updateGeometry() = 0;
92 virtual void updateGeometry() = 0;
93 virtual QVector<qreal> calculateLayout() const = 0;
93 virtual QVector<qreal> calculateLayout() const = 0;
94 void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
94 void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
95 void createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const;
96
95
97 public Q_SLOTS:
96 public Q_SLOTS:
98 virtual void handleAxisUpdated();
97 virtual void handleAxisUpdated();
General Comments 0
You need to be logged in to leave comments. Login now