diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp b/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp index c246031..fab7488 100644 --- a/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp +++ b/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp @@ -111,31 +111,32 @@ QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constra qreal width=0; qreal height=0; - switch (which) { - case Qt::MinimumSize: - width = fn.boundingRect("...").width(); - height = fn.height()+labelPadding(); - width=qMax(width,base.width()); + switch (which) { + case Qt::MinimumSize: { + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = qMax(boundingRect.width(), base.width()); + height = boundingRect.height() + labelPadding(); height += base.height(); - sh = QSizeF(width,height); + sh = QSizeF(width, height); break; + } case Qt::PreferredSize:{ - - for (int i = 0; i < ticksList.size(); ++i) - { - QRectF rect = fn.boundingRect(ticksList.at(i)); + int labelHeight = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelHeight = qMax(rect.height(), labelHeight); width += rect.width(); } - height = fn.height()+labelPadding(); - width = qMax(width,base.width()); + height = labelHeight + labelPadding(); height += base.height(); - sh = QSizeF(width,height); + width = qMax(width, base.width()); + sh = QSizeF(width, height); break; } default: break; - } - return sh; + } + return sh; } #include "moc_chartbarcategoryaxisx_p.cpp" diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp b/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp index 6465b1f..b6668de 100644 --- a/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp +++ b/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp @@ -109,27 +109,30 @@ QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constra qreal width=0; qreal height=0; - switch (which) { - case Qt::MinimumSize: - width = fn.boundingRect("...").width() + labelPadding(); - height = fn.height(); - width+=base.width(); - if(base.width()>0) width+=labelPadding(); - height=qMax(height,base.height()); - sh = QSizeF(width,height); + switch (which) { + case Qt::MinimumSize: { + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = boundingRect.width() + labelPadding(); + width += base.width(); + if (base.width() > 0) + width += labelPadding(); + height = qMax(boundingRect.height(), base.height()); + sh = QSizeF(width, height); break; + } case Qt::PreferredSize:{ - - for (int i = 0; i < ticksList.size(); ++i) - { - QRectF rect = fn.boundingRect(ticksList.at(i)); - height+=rect.height(); - width=qMax(rect.width()+labelPadding(),width); //one pixel torelance + int labelWidth = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelWidth = qMax(rect.width(), labelWidth); + height += rect.height(); } - height=qMax(height,base.height()); - width+=base.width(); - if(base.width()>0) width+=labelPadding(); - sh = QSizeF(width,height); + width = labelWidth + labelPadding() + 1; + width += base.width(); + if (base.width() > 0) + width += labelPadding(); + height = qMax(height, base.height()); + sh = QSizeF(width, height); break; } default: diff --git a/src/axis/categoryaxis/chartcategoryaxisx.cpp b/src/axis/categoryaxis/chartcategoryaxisx.cpp index ca9e176..6a3988b 100644 --- a/src/axis/categoryaxis/chartcategoryaxisx.cpp +++ b/src/axis/categoryaxis/chartcategoryaxisx.cpp @@ -90,22 +90,24 @@ QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint qreal height = 0; switch (which) { - case Qt::MinimumSize: - width = fn.boundingRect("...").width(); - height = fn.height() + labelPadding(); - width = qMax(width, base.width()); + case Qt::MinimumSize: { + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = qMax(boundingRect.width(), base.width()); + height = boundingRect.height() + labelPadding(); height += base.height(); sh = QSizeF(width, height); break; + } case Qt::PreferredSize: { - - for (int i = 0; i < ticksList.size(); ++i) { - QRectF rect = fn.boundingRect(ticksList.at(i)); + int labelHeight = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelHeight = qMax(rect.height(), labelHeight); width += rect.width(); - height = qMax(rect.height() + labelPadding(), height); } - width = qMax(width, base.width()); + height = labelHeight + labelPadding(); height += base.height(); + width = qMax(width, base.width()); sh = QSizeF(width, height); break; } diff --git a/src/axis/categoryaxis/chartcategoryaxisy.cpp b/src/axis/categoryaxis/chartcategoryaxisy.cpp index ec0b4da..d4d95ca 100644 --- a/src/axis/categoryaxis/chartcategoryaxisy.cpp +++ b/src/axis/categoryaxis/chartcategoryaxisy.cpp @@ -90,22 +90,24 @@ QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint qreal height = 0; switch (which) { - case Qt::MinimumSize: - width = fn.boundingRect("...").width() + labelPadding(); - height = fn.height(); + case Qt::MinimumSize: { + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = boundingRect.width() + labelPadding(); width += base.width(); - height = qMax(height, base.height());; + height = qMax(boundingRect.height(), base.height()); sh = QSizeF(width, height); break; + } case Qt::PreferredSize: { - - for (int i = 0; i < ticksList.size(); ++i) { - QRectF rect = fn.boundingRect(ticksList.at(i)); - width = qMax(rect.width() + labelPadding() + 1, width); + int labelWidth = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelWidth = qMax(rect.width(), labelWidth); height += rect.height(); } - height = qMax(height, base.height()); + width = labelWidth + labelPadding() + 1; width += base.width(); + height = qMax(height, base.height()); sh = QSizeF(width, height); break; } diff --git a/src/axis/chartaxis.cpp b/src/axis/chartaxis.cpp index 0585d1c..1cdb0fc 100644 --- a/src/axis/chartaxis.cpp +++ b/src/axis/chartaxis.cpp @@ -527,6 +527,20 @@ QStringList ChartAxis::createDateTimeLabels(qreal min, qreal max,int ticks,const return labels; } +QRect ChartAxis::labelBoundingRect(const QFontMetrics &fn, const QString &label) const +{ + QRect boundingRect = fn.boundingRect(label); + + // Take label rotation into account + if (m_labelsAngle) { + QTransform transform; + transform.rotate(m_labelsAngle); + boundingRect = transform.mapRect(boundingRect); + } + + return boundingRect; +} + #include "moc_chartaxis_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/axis/chartaxis_p.h b/src/axis/chartaxis_p.h index 37e94be..351bee4 100644 --- a/src/axis/chartaxis_p.h +++ b/src/axis/chartaxis_p.h @@ -109,6 +109,7 @@ protected: QFont font() const; qreal min() const; qreal max() const; + QRect labelBoundingRect(const QFontMetrics &fn, const QString &label) const; //handlers public Q_SLOTS: diff --git a/src/axis/datetimeaxis/chartdatetimeaxisx.cpp b/src/axis/datetimeaxis/chartdatetimeaxisx.cpp index dbb7180..192fd22 100644 --- a/src/axis/datetimeaxis/chartdatetimeaxisx.cpp +++ b/src/axis/datetimeaxis/chartdatetimeaxisx.cpp @@ -99,21 +99,24 @@ QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint switch (which) { case Qt::MinimumSize:{ - int count = qMax(ticksList.last().count(),ticksList.first().count()); - width = fn.averageCharWidth() * count; - height = fn.height() + labelPadding(); - width = qMax(width,base.width()); + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = qMax(boundingRect.width(), base.width()); + height = boundingRect.height() + labelPadding(); height += base.height(); - sh = QSizeF(width,height); + sh = QSizeF(width, height); break; } case Qt::PreferredSize: { - int count = qMax(ticksList.last().count(),ticksList.first().count()); - width=fn.averageCharWidth() * count; - height=fn.height()+labelPadding(); - width=qMax(width,base.width()); - height+=base.height(); - sh = QSizeF(width,height); + int labelHeight = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelHeight = qMax(rect.height(), labelHeight); + width += rect.width(); + } + height = labelHeight + labelPadding(); + height += base.height(); + width = qMax(width, base.width()); + sh = QSizeF(width, height); break; } default: diff --git a/src/axis/datetimeaxis/chartdatetimeaxisy.cpp b/src/axis/datetimeaxis/chartdatetimeaxisy.cpp index 2cd10c8..db8b59a 100644 --- a/src/axis/datetimeaxis/chartdatetimeaxisy.cpp +++ b/src/axis/datetimeaxis/chartdatetimeaxisy.cpp @@ -99,28 +99,26 @@ QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint return sh; } - int labelWidth = 0; - - foreach(const QString& s, ticksList) - { - labelWidth=qMax(fn.width(s),labelWidth); - } - switch (which) { case Qt::MinimumSize: { - width = fn.boundingRect("...").width() + labelPadding(); + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = boundingRect.width() + labelPadding(); width += base.width(); - height = fn.height(); - height = qMax(height,base.height()); - sh = QSizeF(width,height); + height = qMax(boundingRect.height(), base.height()); + sh = QSizeF(width, height); break; } case Qt::PreferredSize: { + int labelWidth = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelWidth = qMax(rect.width(), labelWidth); + height += rect.height(); + } width = labelWidth + labelPadding() + 2; //two pixels of tolerance width += base.width(); - height = fn.height() * ticksList.count(); - height = qMax(height,base.height()); - sh = QSizeF(width,height); + height = qMax(height, base.height()); + sh = QSizeF(width, height); break; } default: diff --git a/src/axis/horizontalaxis.cpp b/src/axis/horizontalaxis.cpp index 73cc55f..341975a 100644 --- a/src/axis/horizontalaxis.cpp +++ b/src/axis/horizontalaxis.cpp @@ -105,35 +105,32 @@ void HorizontalAxis::updateGeometry() gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom()); //label text wrapping - if(intervalAxis()&& i+1!=layout.size()) { - //wrapping in case of interval axis - const qreal delta = layout[i+1] - layout[i]; - QString text = labelList.at(i); - if (fn.boundingRect(text).width() + 1 > delta ) - { - QString label = text + "..."; - while (fn.boundingRect(label).width() >= delta && label.length() > 3) + QString text = labelList.at(i); + QRectF boundingRect = labelBoundingRect(fn, text); + qreal size = axisRect.bottom() - axisRect.top() - labelPadding() - title->boundingRect().height(); + if (boundingRect.height() > size) { + QString label = text + "..."; + while (boundingRect.height() >= size && label.length() > 3) { label.remove(label.length() - 4, 1); - labelItem->setText(label); - } - else { - labelItem->setText(text); + boundingRect = labelBoundingRect(fn, label); } - }else{ - labelItem->setText(labelList.at(i)); + labelItem->setText(label); + } else { + labelItem->setText(text); } //label transformation origin point const QRectF& rect = labelItem->boundingRect(); QPointF center = rect.center(); labelItem->setTransformOriginPoint(center.x(), center.y()); + int heightDiff = rect.height() - boundingRect.height(); //ticks and label position if (alignment() == Qt::AlignTop) { - labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() - labelPadding()); + labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2) - labelPadding()); tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding()); } else if (alignment() == Qt::AlignBottom) { - labelItem->setPos(layout[i] - center.x(), axisRect.top() + labelPadding()); + labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2) + labelPadding()); tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding()); } @@ -146,11 +143,11 @@ void HorizontalAxis::updateGeometry() //label overlap detection if(labelItem->pos().x() < width || labelItem->pos().x() < axisRect.left() || - labelItem->pos().x() + rect.width() -1 > axisRect.right()){ + labelItem->pos().x() + boundingRect.width() -1 > axisRect.right()){ labelItem->setVisible(false); } else { labelItem->setVisible(true); - width=rect.width()+labelItem->pos().x(); + width = boundingRect.width() + labelItem->pos().x(); } //shades diff --git a/src/axis/logvalueaxis/chartlogvalueaxisx.cpp b/src/axis/logvalueaxis/chartlogvalueaxisx.cpp index a06509f..766ea94 100644 --- a/src/axis/logvalueaxis/chartlogvalueaxisx.cpp +++ b/src/axis/logvalueaxis/chartlogvalueaxisx.cpp @@ -105,21 +105,24 @@ QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint switch (which) { case Qt::MinimumSize:{ - int count = qMax(ticksList.last().count(),ticksList.first().count()); - width = fn.averageCharWidth() * count; - height = fn.height() + labelPadding(); - width = qMax(width,base.width()); + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = qMax(boundingRect.width(), base.width()); + height = boundingRect.height() + labelPadding(); height += base.height(); - sh = QSizeF(width,height); + sh = QSizeF(width, height); break; } case Qt::PreferredSize: { - int count = qMax(ticksList.last().count(),ticksList.first().count()); - width=fn.averageCharWidth() * count; - height=fn.height()+labelPadding(); - width=qMax(width,base.width()); - height+=base.height(); - sh = QSizeF(width,height); + int labelHeight = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelHeight = qMax(rect.height(), labelHeight); + width += rect.width(); + } + height = labelHeight + labelPadding(); + height += base.height(); + width = qMax(width, base.width()); + sh = QSizeF(width, height); break; } default: diff --git a/src/axis/logvalueaxis/chartlogvalueaxisy.cpp b/src/axis/logvalueaxis/chartlogvalueaxisy.cpp index 4204307..256ef3b 100644 --- a/src/axis/logvalueaxis/chartlogvalueaxisy.cpp +++ b/src/axis/logvalueaxis/chartlogvalueaxisy.cpp @@ -102,29 +102,26 @@ QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint qreal width = 0; qreal height = 0; - - int labelWidth = 0; - - foreach(const QString& s, ticksList) - { - labelWidth=qMax(fn.width(s),labelWidth); - } - switch (which) { case Qt::MinimumSize: { - width = fn.boundingRect("...").width() + labelPadding(); + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = boundingRect.width() + labelPadding(); width += base.width(); - height = fn.height(); - height = qMax(height,base.height()); - sh = QSizeF(width,height); + height = qMax(boundingRect.height(), base.height()); + sh = QSizeF(width, height); break; } case Qt::PreferredSize: { + int labelWidth = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelWidth = qMax(rect.width(), labelWidth); + height += rect.height(); + } width = labelWidth + labelPadding() + 2; //two pixels of tolerance width += base.width(); - height = fn.height() * ticksList.count(); - height = qMax(height,base.height()); - sh = QSizeF(width,height); + height = qMax(height, base.height()); + sh = QSizeF(width, height); break; } default: diff --git a/src/axis/valueaxis/chartvalueaxisx.cpp b/src/axis/valueaxis/chartvalueaxisx.cpp index 26f41b6..dd14931 100644 --- a/src/axis/valueaxis/chartvalueaxisx.cpp +++ b/src/axis/valueaxis/chartvalueaxisx.cpp @@ -98,33 +98,29 @@ QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c switch (which) { case Qt::MinimumSize: { - if(!ticksList.empty()) { - foreach(QString label,ticksList) { - width = qMax(qreal(fn.boundingRect(label).width()),width); - } - } - height = fn.height() + labelPadding(); - width = qMax(width,base.width()); + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = qMax(boundingRect.width(), base.width()); + height = boundingRect.height() + labelPadding(); height += base.height(); - sh = QSizeF(width,height); + sh = QSizeF(width, height); break; } case Qt::PreferredSize: { - if(!ticksList.empty()) { - foreach(QString label,ticksList) { - width+=fn.boundingRect(label).width(); - } + int labelHeight = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelHeight = qMax(rect.height(), labelHeight); + width += rect.width(); } - height=fn.height()+labelPadding(); - width=qMax(width,base.width()); - height+=base.height(); - sh = QSizeF(width,height); + height = labelHeight + labelPadding(); + height += base.height(); + width = qMax(width, base.width()); + sh = QSizeF(width, height); break; } default: - break; + break; } - return sh; } diff --git a/src/axis/valueaxis/chartvalueaxisy.cpp b/src/axis/valueaxis/chartvalueaxisy.cpp index 13d1094..698dc43 100644 --- a/src/axis/valueaxis/chartvalueaxisy.cpp +++ b/src/axis/valueaxis/chartvalueaxisy.cpp @@ -95,29 +95,26 @@ QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c qreal width = 0; qreal height = 0; - int labelWidth = 0; - - foreach(const QString& s, ticksList) - { - labelWidth=qMax(fn.width(s),labelWidth); - } - switch (which) { case Qt::MinimumSize: { - width = fn.boundingRect("...").width() + labelPadding(); + QRectF boundingRect = labelBoundingRect(fn, "..."); + width = boundingRect.width() + labelPadding(); width += base.width(); - height = fn.height(); - height = qMax(height,base.height()); - sh = QSizeF(width,height); + height = qMax(boundingRect.height(), base.height()); + sh = QSizeF(width, height); break; } - case Qt::PreferredSize: - { + case Qt::PreferredSize: { + int labelWidth = 0; + foreach (const QString& s, ticksList) { + QRect rect = labelBoundingRect(fn, s); + labelWidth = qMax(rect.width(), labelWidth); + height += rect.height(); + } width = labelWidth + labelPadding() + 2; //two pixels of tolerance width += base.width(); - height = fn.height() * ticksList.count(); - height = qMax(height,base.height()); - sh = QSizeF(width,height); + height = qMax(height, base.height()); + sh = QSizeF(width, height); break; } default: diff --git a/src/axis/verticalaxis.cpp b/src/axis/verticalaxis.cpp index 19b6768..d9334c2 100644 --- a/src/axis/verticalaxis.cpp +++ b/src/axis/verticalaxis.cpp @@ -113,27 +113,33 @@ void VerticalAxis::updateGeometry() //label text wrapping QString text = labelList.at(i); + QRectF boundingRect = labelBoundingRect(fn, text); + qreal size = axisRect.right() - axisRect.left() - labelPadding() - title->boundingRect().height(); - if (fn.boundingRect(text).width() > size) { + if (boundingRect.width() > size) { QString label = text + "..."; - while (fn.boundingRect(label).width() > size && label.length() > 3) + while (boundingRect.width() > size && label.length() > 3) { label.remove(label.length() - 4, 1); + boundingRect = labelBoundingRect(fn, label); + } labelItem->setText(label); } else { labelItem->setText(text); } + //label transformation origin point const QRectF &rect = labelItem->boundingRect(); QPointF center = rect.center(); labelItem->setTransformOriginPoint(center.x(), center.y()); + int widthDiff = rect.width() - boundingRect.width(); //ticks and label position if (alignment() == Qt::AlignLeft) { - labelItem->setPos(axisRect.right() - rect.width() - labelPadding() , layout[i] - center.y()); + labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2) - labelPadding(), layout[i] - center.y()); tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]); } else if (alignment() == Qt::AlignRight) { - labelItem->setPos(axisRect.left() + labelPadding() , layout[i] - center.y()); + labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2), layout[i] - center.y()); tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]); } @@ -144,9 +150,9 @@ void VerticalAxis::updateGeometry() } //label overlap detection - if(labelItem->pos().y() + rect.height() > height || - labelItem->pos().y() + rect.height()/2 > gridRect.bottom() || - labelItem->pos().y() + rect.height()/2 < gridRect.top()) { + if(labelItem->pos().y() + boundingRect.height() > height || + labelItem->pos().y() + boundingRect.height()/2 > gridRect.bottom() || + labelItem->pos().y() + boundingRect.height()/2 < gridRect.top()) { labelItem->setVisible(false); } else {