From 5b27b7b1d72ab53651ea3bec3a875cebcb8abd1f 2013-03-19 09:39:50 From: Miikka Heikkinen Date: 2013-03-19 09:39:50 Subject: [PATCH] Fix vanishing labels for first and last ticks. Extra space must be reserved by layout for the axes that have wide labels for first or last tick. Changed the logic how axis sizeHint is interpreted to make the previously irrelevant height or width (depending on orientation) of the sizeHint to indicate how far the widest label extends past the first/last tick, and adjust the grid size accordingly in layout. Reviewed-by: Mika Salmela --- diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp b/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp index e06561f..b4b296e 100644 --- a/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp +++ b/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp @@ -109,13 +109,12 @@ QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constra QSizeF base = HorizontalAxis::sizeHint(which, constraint); QStringList ticksList = m_categoriesAxis->categories(); - qreal width=0; - qreal height=0; + qreal width = 0; // Width is irrelevant for X axes with interval labels + qreal height = 0; 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); @@ -126,11 +125,9 @@ QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constra 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; } diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp b/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp index f6f3cf4..e35aea6 100644 --- a/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp +++ b/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp @@ -107,8 +107,8 @@ QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constra QSizeF sh; QSizeF base = VerticalAxis::sizeHint(which, constraint); QStringList ticksList = m_categoriesAxis->categories(); - qreal width=0; - qreal height=0; + qreal width = 0; + qreal height = 0; // Height is irrelevant for Y axes with interval labels switch (which) { case Qt::MinimumSize: { @@ -117,7 +117,6 @@ QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constra width += base.width(); if (base.width() > 0) width += labelPadding(); - height = qMax(boundingRect.height(), base.height()); sh = QSizeF(width, height); break; } @@ -126,13 +125,11 @@ QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constra foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelWidth = qMax(rect.width(), labelWidth); - height += rect.height(); } width = labelWidth + labelPadding() + 1; width += base.width(); if (base.width() > 0) width += labelPadding(); - height = qMax(height, base.height()); sh = QSizeF(width, height); break; } diff --git a/src/axis/categoryaxis/chartcategoryaxisx.cpp b/src/axis/categoryaxis/chartcategoryaxisx.cpp index c0685ac..b0d6651 100644 --- a/src/axis/categoryaxis/chartcategoryaxisx.cpp +++ b/src/axis/categoryaxis/chartcategoryaxisx.cpp @@ -84,13 +84,12 @@ QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint QSizeF sh; QSizeF base = HorizontalAxis::sizeHint(which, constraint); QStringList ticksList = m_axis->categoriesLabels(); - qreal width = 0; + qreal width = 0; // Width is irrelevant for X axes with interval labels qreal height = 0; 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); @@ -101,11 +100,9 @@ QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint 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; } diff --git a/src/axis/categoryaxis/chartcategoryaxisy.cpp b/src/axis/categoryaxis/chartcategoryaxisy.cpp index b957856..ea86b56 100644 --- a/src/axis/categoryaxis/chartcategoryaxisy.cpp +++ b/src/axis/categoryaxis/chartcategoryaxisy.cpp @@ -86,14 +86,13 @@ QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint QSizeF base = VerticalAxis::sizeHint(which, constraint); QStringList ticksList = m_axis->categoriesLabels(); qreal width = 0; - qreal height = 0; + qreal height = 0; // Height is irrelevant for Y axes with interval labels switch (which) { case Qt::MinimumSize: { QRectF boundingRect = labelBoundingRect(fn, "..."); width = boundingRect.width() + labelPadding(); width += base.width(); - height = qMax(boundingRect.height(), base.height()); sh = QSizeF(width, height); break; } @@ -102,11 +101,9 @@ QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelWidth = qMax(rect.width(), labelWidth); - height += rect.height(); } width = labelWidth + labelPadding() + 1; width += base.width(); - height = qMax(height, base.height()); sh = QSizeF(width, height); break; } diff --git a/src/axis/datetimeaxis/chartdatetimeaxisx.cpp b/src/axis/datetimeaxis/chartdatetimeaxisx.cpp index c793285..591daf9 100644 --- a/src/axis/datetimeaxis/chartdatetimeaxisx.cpp +++ b/src/axis/datetimeaxis/chartdatetimeaxisx.cpp @@ -90,17 +90,18 @@ QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint QSizeF base = HorizontalAxis::sizeHint(which, constraint); QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format()); + // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base width is irrelevant. qreal width = 0; qreal height = 0; - if(ticksList.empty()){ + if (ticksList.empty()) return sh; - } switch (which) { case Qt::MinimumSize:{ QRectF boundingRect = labelBoundingRect(fn, "..."); - width = qMax(boundingRect.width(), base.width()); + width = boundingRect.width() / 2.0; height = boundingRect.height() + labelPadding(); height += base.height(); sh = QSizeF(width, height); @@ -108,14 +109,17 @@ QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint } case Qt::PreferredSize: { int labelHeight = 0; + int firstWidth = -1; foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelHeight = qMax(rect.height(), labelHeight); - width += rect.width(); + width = rect.width(); + if (firstWidth < 0) + firstWidth = width; } height = labelHeight + labelPadding(); height += base.height(); - width = qMax(width, base.width()); + width = qMax(width, qreal(firstWidth)) / 2.0; sh = QSizeF(width, height); break; } diff --git a/src/axis/datetimeaxis/chartdatetimeaxisy.cpp b/src/axis/datetimeaxis/chartdatetimeaxisy.cpp index b9a1407..8b27d1c 100644 --- a/src/axis/datetimeaxis/chartdatetimeaxisy.cpp +++ b/src/axis/datetimeaxis/chartdatetimeaxisy.cpp @@ -92,32 +92,35 @@ QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint QSizeF base = VerticalAxis::sizeHint(which, constraint); QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format()); qreal width = 0; + // Height of vertical axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base height is irrelevant. qreal height = 0; - - if(ticksList.empty()){ + if (ticksList.empty()) return sh; - } switch (which) { case Qt::MinimumSize: { QRectF boundingRect = labelBoundingRect(fn, "..."); width = boundingRect.width() + labelPadding(); width += base.width(); - height = qMax(boundingRect.height(), base.height()); + height = boundingRect.height() / 2.0; sh = QSizeF(width, height); break; } case Qt::PreferredSize: { int labelWidth = 0; + int firstHeight = -1; foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelWidth = qMax(rect.width(), labelWidth); - height += rect.height(); + height = rect.height(); + if (firstHeight < 0) + firstHeight = height; } width = labelWidth + labelPadding() + 2; //two pixels of tolerance width += base.width(); - height = qMax(height, base.height()); + height = qMax(height, qreal(firstHeight)) / 2.0; sh = QSizeF(width, height); break; } diff --git a/src/axis/logvalueaxis/chartlogvalueaxisx.cpp b/src/axis/logvalueaxis/chartlogvalueaxisx.cpp index 39e9db6..426b761 100644 --- a/src/axis/logvalueaxis/chartlogvalueaxisx.cpp +++ b/src/axis/logvalueaxis/chartlogvalueaxisx.cpp @@ -99,14 +99,15 @@ QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat()); else ticksList.append(QString(" ")); + // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base width is irrelevant. qreal width = 0; qreal height = 0; - switch (which) { case Qt::MinimumSize:{ QRectF boundingRect = labelBoundingRect(fn, "..."); - width = qMax(boundingRect.width(), base.width()); + width = boundingRect.width() / 2.0; height = boundingRect.height() + labelPadding(); height += base.height(); sh = QSizeF(width, height); @@ -114,14 +115,17 @@ QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint } case Qt::PreferredSize: { int labelHeight = 0; + int firstWidth = -1; foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelHeight = qMax(rect.height(), labelHeight); - width += rect.width(); + width = rect.width(); + if (firstWidth < 0) + firstWidth = width; } height = labelHeight + labelPadding(); height += base.height(); - width = qMax(width, base.width()); + width = qMax(width, qreal(firstWidth)) / 2.0; sh = QSizeF(width, height); break; } diff --git a/src/axis/logvalueaxis/chartlogvalueaxisy.cpp b/src/axis/logvalueaxis/chartlogvalueaxisy.cpp index d945e79..8a63a88 100644 --- a/src/axis/logvalueaxis/chartlogvalueaxisy.cpp +++ b/src/axis/logvalueaxis/chartlogvalueaxisy.cpp @@ -100,6 +100,8 @@ QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint else ticksList.append(QString(" ")); qreal width = 0; + // Height of vertical axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base height is irrelevant. qreal height = 0; switch (which) { @@ -107,20 +109,23 @@ QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint QRectF boundingRect = labelBoundingRect(fn, "..."); width = boundingRect.width() + labelPadding(); width += base.width(); - height = qMax(boundingRect.height(), base.height()); + height = boundingRect.height() / 2.0; sh = QSizeF(width, height); break; } case Qt::PreferredSize: { int labelWidth = 0; + int firstHeight = -1; foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelWidth = qMax(rect.width(), labelWidth); - height += rect.height(); + height = rect.height(); + if (firstHeight < 0) + firstHeight = height; } width = labelWidth + labelPadding() + 2; //two pixels of tolerance width += base.width(); - height = qMax(height, base.height()); + height = qMax(height, qreal(firstHeight)) / 2.0; sh = QSizeF(width, height); break; } diff --git a/src/axis/valueaxis/chartvalueaxisx.cpp b/src/axis/valueaxis/chartvalueaxisx.cpp index ead4abf..ccf4925 100644 --- a/src/axis/valueaxis/chartvalueaxisx.cpp +++ b/src/axis/valueaxis/chartvalueaxisx.cpp @@ -92,14 +92,15 @@ QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c QSizeF base = HorizontalAxis::sizeHint(which, constraint); QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat()); + // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base width is irrelevant. qreal width = 0; qreal height = 0; - switch (which) { case Qt::MinimumSize: { QRectF boundingRect = labelBoundingRect(fn, "..."); - width = qMax(boundingRect.width(), base.width()); + width = boundingRect.width() / 2.0; height = boundingRect.height() + labelPadding(); height += base.height(); sh = QSizeF(width, height); @@ -107,14 +108,17 @@ QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c } case Qt::PreferredSize: { int labelHeight = 0; + int firstWidth = -1; foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelHeight = qMax(rect.height(), labelHeight); - width += rect.width(); + width = rect.width(); + if (firstWidth < 0) + firstWidth = width; } height = labelHeight + labelPadding(); height += base.height(); - width = qMax(width, base.width()); + width = qMax(width, qreal(firstWidth)) / 2.0; sh = QSizeF(width, height); break; } diff --git a/src/axis/valueaxis/chartvalueaxisy.cpp b/src/axis/valueaxis/chartvalueaxisy.cpp index 4ed2456..848d4ae 100644 --- a/src/axis/valueaxis/chartvalueaxisy.cpp +++ b/src/axis/valueaxis/chartvalueaxisy.cpp @@ -93,6 +93,8 @@ QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c QSizeF base = VerticalAxis::sizeHint(which, constraint); QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat()); qreal width = 0; + // Height of vertical axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base height is irrelevant. qreal height = 0; switch (which) { @@ -100,20 +102,23 @@ QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c QRectF boundingRect = labelBoundingRect(fn, "..."); width = boundingRect.width() + labelPadding(); width += base.width(); - height = qMax(boundingRect.height(), base.height()); + height = boundingRect.height() / 2.0; sh = QSizeF(width, height); break; } case Qt::PreferredSize: { int labelWidth = 0; + int firstHeight = -1; foreach (const QString& s, ticksList) { QRect rect = labelBoundingRect(fn, s); labelWidth = qMax(rect.width(), labelWidth); - height += rect.height(); + height = rect.height(); + if (firstHeight < 0) + firstHeight = height; } width = labelWidth + labelPadding() + 2; //two pixels of tolerance width += base.width(); - height = qMax(height, base.height()); + height = qMax(height, qreal(firstHeight)) / 2.0; sh = QSizeF(width, height); break; } diff --git a/src/axis/verticalaxis.cpp b/src/axis/verticalaxis.cpp index 29d62ae..0c6ecac 100644 --- a/src/axis/verticalaxis.cpp +++ b/src/axis/verticalaxis.cpp @@ -154,8 +154,8 @@ void VerticalAxis::updateGeometry() //label overlap detection if(labelItem->pos().y() + boundingRect.height() > height || - labelItem->pos().y() + boundingRect.height()/2 > gridRect.bottom() || - labelItem->pos().y() + boundingRect.height()/2 < gridRect.top()) { + labelItem->pos().y() + boundingRect.height()/2 > axisRect.bottom() || + labelItem->pos().y() + boundingRect.height()/2 < axisRect.top()) { labelItem->setVisible(false); } else { diff --git a/src/chartlayout.cpp b/src/chartlayout.cpp index b3f34b7..bd885ba 100644 --- a/src/chartlayout.cpp +++ b/src/chartlayout.cpp @@ -109,6 +109,7 @@ QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QListisVisible()) continue; - QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize); //this is used to get single thick font size QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize); @@ -130,6 +130,7 @@ QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList