From 79d9101394e590064c337653912df6c7f6a1c94e 2012-07-19 12:56:57 From: Michal Klocek Date: 2012-07-19 12:56:57 Subject: [PATCH] Fixes rounding issue with labels numbering --- diff --git a/src/axis/categoriesaxis/chartcategoriesaxisx.cpp b/src/axis/categoriesaxis/chartcategoriesaxisx.cpp index fdac3de..6b5eba7 100644 --- a/src/axis/categoriesaxis/chartcategoriesaxisx.cpp +++ b/src/axis/categoriesaxis/chartcategoriesaxisx.cpp @@ -21,7 +21,8 @@ #include "chartcategoriesaxisx_p.h" #include "chartpresenter_p.h" #include "qbarcategoriesaxis_p.h" -#include +#include +#include static int label_padding = 5; @@ -42,29 +43,47 @@ QVector ChartCategoriesAxisX::calculateLayout() const Q_ASSERT(m_categoriesAxis->categories().count()>=1); QVector points; - points.resize(m_categoriesAxis->categories().count()+1); + points.resize(m_categoriesAxis->categories().count()+2); const qreal delta = m_rect.width()/(m_categoriesAxis->categories().count()); - const qreal min = m_categoriesAxis->d_ptr->min(); - const qreal max = m_categoriesAxis->d_ptr->max(); - qreal start =-min-0.5; - if(start<=0) { - start = fmod(start * m_rect.width()/(max - min),delta) + delta; + qreal offset =-m_min-0.5; + + if(offset<=0) { + offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta) + delta; } else { - start = fmod(start * m_rect.width()/(max - min),delta); + offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta); } - points[m_categoriesAxis->categories().count()] = m_rect.left() + m_rect.width(); + points[0] = m_rect.left(); + points[m_categoriesAxis->categories().count()+1] = m_rect.right(); for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) { - qreal x = start + i * delta + m_rect.left(); - points[i] = x; + qreal x = offset + i * delta + m_rect.left(); + points[i+1] = x; } - return points; } +QStringList ChartCategoriesAxisX::createCategoryLabels(const QVector& layout) const +{ + QStringList result; + qreal d = (m_max - m_min)/m_rect.width(); + for (int i = 0;i < layout.count()-1; ++i) { + qreal x = qFloor((((layout[i+1] + layout[i])/2-m_rect.left())*d + m_min+0.5)); + if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) { + result << m_categoriesAxis->categories().at(x); + } + else { + // No label for x coordinate + result << ""; + } + } + result << ""; + return result; +} + + void ChartCategoriesAxisX::updateGeometry() { const QVector& layout = ChartAxis::layout(); @@ -74,9 +93,7 @@ void ChartCategoriesAxisX::updateGeometry() if(layout.isEmpty()) return; - QStringList ticksList; - - createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories()); + QStringList ticksList = createCategoryLabels(layout); QList lines = m_grid->childItems(); QList labels = m_labels->childItems(); @@ -101,10 +118,10 @@ void ChartCategoriesAxisX::updateGeometry() QPointF center = rect.center(); labelItem->setTransformOriginPoint(center.x(), center.y()); - if(i==layout.size()-1){ - labelItem->setPos(layout[i-1] + (delta)/2 - center.x(), m_rect.bottom() + label_padding); + if(i==0){ + labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), m_rect.bottom() + label_padding); }else{ - labelItem->setPos(layout[i] - (delta)/2 - center.x(), m_rect.bottom() + label_padding); + labelItem->setPos(layout[i] + (delta)/2 - center.x(), m_rect.bottom() + label_padding); } if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()>m_rect.right()) { diff --git a/src/axis/categoriesaxis/chartcategoriesaxisx_p.h b/src/axis/categoriesaxis/chartcategoriesaxisx_p.h index 730e5b6..3bed620 100644 --- a/src/axis/categoriesaxis/chartcategoriesaxisx_p.h +++ b/src/axis/categoriesaxis/chartcategoriesaxisx_p.h @@ -49,6 +49,8 @@ public: protected: QVector calculateLayout() const; void updateGeometry(); +private: + QStringList createCategoryLabels(const QVector& layout) const; Q_SLOTS void handleAxisUpdated(); diff --git a/src/axis/categoriesaxis/chartcategoriesaxisy.cpp b/src/axis/categoriesaxis/chartcategoriesaxisy.cpp index 28e9f67..2c009fa 100644 --- a/src/axis/categoriesaxis/chartcategoriesaxisy.cpp +++ b/src/axis/categoriesaxis/chartcategoriesaxisy.cpp @@ -21,8 +21,7 @@ #include "chartcategoriesaxisy_p.h" #include "chartpresenter_p.h" #include "qbarcategoriesaxis_p.h" -#include -#include +#include static int label_padding = 5; @@ -42,32 +41,46 @@ QVector ChartCategoriesAxisY::calculateLayout() const Q_ASSERT(m_categoriesAxis->categories().count()>=1); QVector points; - points.resize(m_categoriesAxis->categories().count()+1); + points.resize(m_categoriesAxis->categories().count()+2); - qreal delta = m_rect.height()/(m_categoriesAxis->categories().count()); - - const qreal min = m_categoriesAxis->d_ptr->min(); - const qreal max = m_categoriesAxis->d_ptr->max(); - - qreal start =-min-0.5; + const qreal delta = m_rect.height()/(m_categoriesAxis->categories().count()); + qreal offset = - m_min - 0.5; - if(start<=0) { - start = fmod(start * m_rect.height()/(max - min),delta) + delta; + if(offset<=0) { + offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta) + delta; } else { - start = fmod(start * m_rect.height()/(max - min),delta); + offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta); } - points[m_categoriesAxis->categories().count()] = m_rect.top(); + points[0] = m_rect.bottom(); + points[m_categoriesAxis->categories().count()+1] = m_rect.top(); for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) { - int y = m_rect.bottom() - i * delta - start; - points[i] = y; + int y = m_rect.bottom() - i * delta - offset; + points[i+1] = y; } - return points; } +QStringList ChartCategoriesAxisY::createCategoryLabels(const QVector& layout) const +{ + QStringList result; + qreal d = (m_max - m_min)/m_rect.height(); + for (int i = 0;i < layout.count()-1; ++i) { + qreal x = qFloor(((m_rect.height()- (layout[i+1] + layout[i])/2 + m_rect.top())*d + m_min+0.5)); + if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) { + result << m_categoriesAxis->categories().at(x); + } + else { + // No label for x coordinate + result << ""; + } + } + result << ""; + return result; +} + void ChartCategoriesAxisY::updateGeometry() { const QVector& layout = ChartAxis::layout(); @@ -77,9 +90,7 @@ void ChartCategoriesAxisY::updateGeometry() if(layout.isEmpty()) return; - QStringList ticksList; - - createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories()); + QStringList ticksList = createCategoryLabels(layout); QList lines = m_grid->childItems(); QList labels = m_labels->childItems(); @@ -104,11 +115,11 @@ void ChartCategoriesAxisY::updateGeometry() QPointF center = rect.center(); labelItem->setTransformOriginPoint(center.x(), center.y()); - if(i==layout.size()-1) { - labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i-1] - (delta)/2 - center.y()); + if(i==0) { + labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y()); } else { - labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] + (delta)/2 - center.y()); + labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y()); } if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < m_rect.top()) { @@ -137,7 +148,10 @@ void ChartCategoriesAxisY::handleAxisUpdated() if(m_categoriesAxis->categories()!=m_categories) { m_categories=m_categoriesAxis->categories(); - if(ChartAxis::layout().count()==m_categories.size()+1) updateGeometry(); + if(ChartAxis::layout().count()==m_categories.size()+1) { + + updateGeometry(); + } } ChartAxis::handleAxisUpdated(); } diff --git a/src/axis/categoriesaxis/chartcategoriesaxisy_p.h b/src/axis/categoriesaxis/chartcategoriesaxisy_p.h index ffe1fa9..899006b 100644 --- a/src/axis/categoriesaxis/chartcategoriesaxisy_p.h +++ b/src/axis/categoriesaxis/chartcategoriesaxisy_p.h @@ -49,10 +49,13 @@ public: protected: QVector calculateLayout() const; void updateGeometry(); +private: + QStringList createCategoryLabels(const QVector& layout) const; Q_SLOTS void handleAxisUpdated(); private: QStringList m_categories; + QVector m_labelIndex; QBarCategoriesAxis *m_categoriesAxis; }; diff --git a/src/axis/chartaxis.cpp b/src/axis/chartaxis.cpp index 809c346..005b903 100644 --- a/src/axis/chartaxis.cpp +++ b/src/axis/chartaxis.cpp @@ -24,8 +24,6 @@ #include "chartpresenter_p.h" #include "chartanimator_p.h" #include "domain_p.h" -#include -#include #include #include @@ -362,7 +360,7 @@ void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int Q_ASSERT(max>min); Q_ASSERT(ticks>1); - int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0); + int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0); n++; for (int i=0; i< ticks; i++) { qreal value = min + (i * (max - min)/ (ticks-1)); @@ -370,27 +368,6 @@ void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int } } -void ChartAxis::createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const -{ - Q_ASSERT(max>min); - Q_UNUSED(max); - - int x = qFloor(min+0.5); - int count = 0; - - // Try to find category for x coordinate - while (count < categories.count()+1) { - if ((x < categories.count()) && (x >= 0)) { - labels << categories.at(x); - } else { - // No label for x coordinate - labels << ""; - } - x++; - count++; - } -} - #include "moc_chartaxis_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/axis/chartaxis_p.h b/src/axis/chartaxis_p.h index eb44c6c..ef92262 100644 --- a/src/axis/chartaxis_p.h +++ b/src/axis/chartaxis_p.h @@ -92,7 +92,6 @@ protected: virtual void updateGeometry() = 0; virtual QVector calculateLayout() const = 0; void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const; - void createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const; public Q_SLOTS: virtual void handleAxisUpdated();