Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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:
    0_1553171182270_transiography_dialog.png

    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