Максимум оси Y в QML BarSeries не обновляется

Я использую QML BarSeries для отображения некоторых данных и возникла проблема: ось Y BarSeries не обновляется автоматически.

Ниже приведен mcve, скопированный и измененный из документации BarSeries. Он обновляет серию полос, когда пользователь нажимает на фон.

//  main.qml

import QtQuick 2.6
import QtQuick.Window 2.2
import QtCharts 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    ChartView {
        id: chartView
        title: "Bar series"
        anchors.fill: parent
        legend.alignment: Qt.AlignBottom
        antialiasing: true

        BarSeries {
            id: mySeries
            axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }

            BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
            BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
            BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
        }

    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            mySeries.clear();  //  clear previous sets

            //  update with new sets
            mySeries.append("Bob", [3, 5, 8, 13, 5, 8]);
            mySeries.append("Susan", [2, 2, 3, 4, 5, 200]);
            mySeries.append("James", [5, 1, 2, 4, 1, 7]);

        }
    }
}

Из кода мы могли видеть, что щелчок по области мыши должен обновить серию, чтобы она имела ось Y до 200 (из-за нового набора значений Сьюзан).

На скриншотах ниже показано обновление столбцов, но не ось Y. (Обратите внимание, что я ожидаю, что максимум по оси Y обновится до 200.)

Перед щелчком мыши:

После щелчка мыши:

Какие изменения нужно внести, чтобы обновить максимум оси Y диаграммы?

После нескольких операторов mySeries.append в MouseArea::onClicked я попытался выполнить chartView.update(), но это сработало безрезультатно.

Я искал и исследовал, но ничего не нашел. Большинство ответов из Интернета касаются только QtCharts, запускаемых с C ++, или описывают другую проблему (если я не искал с неправильными ключевыми словами?).


Вот файл main.cpp для полноты:

#include <QApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication app(argc, argv);  // needs QT += widgets in qmake

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

person TrebledJ    schedule 26.02.2019    source источник


Ответы (1)


Мне удалось решить эту проблему, прикрепив пользовательский ValueAxis в BarSeries и вручную, программно обновляя новый максимум с помощью ValueAxis::max собственности.

import QtQuick 2.6
import QtQuick.Window 2.2
import QtCharts 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    
    ChartView {
        id: chartView
        title: "Bar series"
        anchors.fill: parent
        legend.alignment: Qt.AlignBottom
        antialiasing: true
    
        BarSeries {
            id: mySeries
            axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }

            axisY: ValueAxis {    //  <- custom ValueAxis attached to the y-axis
                id: valueAxis
            }

            BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
            BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
            BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
        }
        
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: {
            mySeries.clear();
            mySeries.append("Bob", [3, 5, 8, 13, 5, 8]);
            mySeries.append("Susan", [2, 2, 3, 4, 5, 200]);
            mySeries.append("James", [5, 1, 2, 4, 1, 7]);
            
            valueAxis.max = 200;  //  hard-code a new maximum
        }
    }
}

Это прекрасно работает. Вот как теперь выглядит диаграмма после щелчка по фону:

Вот решение, которое динамически вычисляет новый максимум (для краткости показан только слот onClicked):

onClicked: {
    mySeries.clear();
    mySeries.append("Bob", [3, 5, 8, 13, 5, 8]);
    mySeries.append("Susan", [2, 2, 3, 4, 5, 200]);
    mySeries.append("James", [5, 1, 2, 4, 1, 7]);
    
    //  deduce the new min and max
    var min = 1e8, max = -1e8;
    for (var i = 0; i < mySeries.count; i++) {
        //  min = Math.min(min, ...mySeries.at(i).values);  //  modern js not yet supported?
        //  max = Math.min(max, ...mySeries.at(i).values);

        min = Math.min(min, mySeries.at(i).values.reduce(function(a,b) {
            return Math.min(a, b);
        }));
        max = Math.max(max, mySeries.at(i).values.reduce(function(a,b) {
            return Math.max(a, b);
        }));
    }

    //  set the new min and max
    valueAxis.min = min;
    valueAxis.max = max;

    // valueAxis.max = max * 1.05; // or give a little margin?
    
}

Конечно, минимум можно не учитывать, но это полностью зависит от ваших данных и ситуации.

person TrebledJ    schedule 26.02.2019