Truncated labels in Y-axis of QChartView
-
G'day everyone.
I have a panel of tens of QChartViews and they are all displayed with the labels in the Y-axis truncated (replaced with ...). The values range from 0.0 to 2.0. In order for make them use as much space as possible to be displayed correctly in the restricted space of the window, I do this:
...... //create a chart object to contain all the data series in the same chart QChart *chart = new QChart(); { chart->legend()->hide(); ..... chart->layout()->setContentsMargins(2, 2, 2, 2); chart->setMargins(QMargins(2, 2, 2, 2)); } ....... //-------create the sum chart's axes once----------------- QValueAxis *axisY = dynamic_cast<QValueAxis *>( chart->axisY() ); if( ! axisY ) { axisY = new QValueAxis(); axisY->setRange( 0.0, 2.0 ); axisY->applyNiceNumbers(); axisY->setLabelFormat("%i"); } QValueAxis *axisX = dynamic_cast<QValueAxis *>( chart->axisX() ); if( ! axisX ) { axisX = new QValueAxis(); axisX->setRange( hInitial, hFinal ); axisX->applyNiceNumbers(); axisX->setLabelFormat("%i"); } //-------------------------------------------------
But only the labels in X-axis are correctly displayed.
Here is the result:
Notice the charts in the last column: the labels in X-axis are OK. But the labels in Y-axis, despite the same layout settings and low range (0.0 - 2.0) are truncated.
Any help will be much appreciated.
-
@PauloCarvalhoRJ Dear Paulo,
I am facing a very similar issue. I do not have that many charts to draw, yet too many labels on a Y axis. The QChart are so badly shaped, that it seems it is impossible to easily fix it. A first option, is to change the pixel size of the font used to draw the labels in the resize event.
void yourCharView::resizeEvent(QResizeEvent *event) { if(series.size() > 0) { QFont font = this->axis_y_stack->labelsFont(); int pixel_size = event->size().height() / series.size() / 3; font.setPixelSize(pixel_size); this->axis_y->setLabelsFont(font); } QChartView::resizeEvent(event); }
(this->y_axis beeing your y axis)
But it might prove insufficient, as in my case.
Labels are truncated in verticalaxis.cpp (for the vertical axes) :
QRectF boundingRect; // don't truncate empty labels if (text.isEmpty()) { labelItem->setHtml(text); } else { qreal labelHeight = (axisRect.height() / layout.count()) - (2 * labelPadding()); QString truncatedText = ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(), availableSpace, labelHeight, boundingRect); labelItem->setTextWidth(ChartPresenter::textBoundingRect(axis()->labelsFont(), truncatedText).width()); labelItem->setHtml(truncatedText); }
The truncation code lies here :
QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle, qreal maxWidth, qreal maxHeight, QRectF &boundingRect) { QString truncatedString(text); boundingRect = textBoundingRect(font, truncatedString, angle); if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) { // It can be assumed that almost any amount of string manipulation is faster // than calculating one bounding rectangle, so first prepare a list of truncated strings // to try. static QRegularExpression truncateMatcher(QStringLiteral("&#?[0-9a-zA-Z]*;$")); ........ static QLatin1String ellipsis("..."); ........ // Default to "..." if nothing fits if (bestIndex == count) { boundingRect = textBoundingRect(font, ellipsis, angle); truncatedString = ellipsis; } else { truncatedString = testStrings.at(bestIndex); } } return truncatedString; }
I can't think of any way to interfere with this and avoid turning my nice labels into three dots...
Any input from anyone else ? We can't even change the labelPadding() !!!!
inline qreal labelPadding() const { return qreal(4.0); }
=> I will hide the presenter labels and draw the labels myself, overriding the paintEvent.
Cheers
Côme
-
Hi
Eventhough this thread is quite old, I faced a similar issue with this truncated axis labels. I found a workaround which is working for me by removing and adding the axes again to the chart.
Here is the example code I use (precondition: axes must be added once to chart and series before):
auto axes = chart()->axes(); QHash<QAbstractSeries*, QList<QAbstractAxis*>> seriesAxes; for (auto serie : series) { auto attachedAxes = serie->attachedAxes(); for (auto axis : attachedAxes) { if (axes.contains(axis)) { auto &serieAxes = seriesAxes[serie]; serieAxes.append(axis); } } } for (auto axis : axes) { chart()->removeAxis(axis); auto alignment = axis->alignment(); chart()->addAxis(axis, alignment); } QHashIterator<QAbstractSeries*, QList<QAbstractAxis*>> iSeriesAxes(seriesAxes); while (iSeriesAxes.hasNext()) { auto serie = iSeriesAxes.next().key(); auto axes = iSeriesAxes.value(); for (auto axis : axes) { serie->attachAxis(axis); } }
Cheers,
Reto -
I'm not sure how this happened to the previous two question askers, but for me the solution was quite simple. Qt works just fine at displaying the plot axis data so long as you:
- Have enough space to do so
- Don't mess with the default settings
In my case, I had the axis tick count set pretty high which was causing the labels to squish together. If you leave the tick counts at their default, or let Qt decide, it should work just fine.