qml draw a Linechart from Qlist using a repeater

575 Views Asked by At

I want to draw a plot of sensor data that is saved in a QList. I know that getting the data up to the qml level works fine, because it correctly prints to console (see code).

My question now is, how can I draw a LineChart out of this data? I tried a repeater and some sketchy for- loops but none seem to work and only an empty chart is displayed.

As stated above, the data works and is logged correctly. The axis are correct as well, there just is no line.

My most promising try:

import QtQuick 2.0
import QtCharts 2.3
Item {
    width:400
    height:600
    
    ChartView
    {
    
    width:parent.width
    height:parent.height
    Component.onCompleted:  {
    //Data displayed correctly
        console.log(device.AIN3data.length);
        console.log(device.AIN3data)
    }
    
    ValueAxis {
        id: axisX
        min: 0
        max: device.AIN3data.length
    }
    
    ValueAxis {
        id: axisY
        min: 0
        max: 1000
    }
    LineSeries
    {
        axisX: axisX
        axisY:axisY
    
    
        name: "AIN3"
        Repeater
        {
    
            model: device.AIN3data.length
            XYPoint{x:index;y:device.AIN3data[index]}
            Component.onCompleted: console.log("Repeater")
    
        }
    }
    }
}

1

There are 1 best solutions below

4
On

Repeater is used to generate several Items, not for XYPoint. In this case it is better to create a C++ model, export it to QML and then map to a LineSeries using VXYModelMapper.

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardItemModel>
#include <QTimer>

#include <random>

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QApplication app(argc, argv);

    QStandardItemModel model(0, 2);

    QTimer timer;
    timer.setInterval(1000);
    QObject::connect(&timer, &QTimer::timeout, &model, [&model](){
        static std::default_random_engine e;
        static std::uniform_real_distribution<> dis(0, 1000);
        QStandardItem *xItem = new QStandardItem;
        QStandardItem *yItem = new QStandardItem;
        xItem->setData(model.rowCount(), Qt::DisplayRole);
        yItem->setData(dis(e), Qt::DisplayRole);
        model.appendRow({xItem, yItem});
    });
    timer.start();

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("dataModel", &model);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
import QtCharts 2.3
import QtQuick 2.15
import QtQuick.Window 2.15

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

    ChartView {
        anchors.fill: parent

        ValueAxis {
            id: axisX

            min: 0
            max: lineSeries.count - 1
        }

        ValueAxis {
            id: axisY

            min: 0
            max: 1000
        }

        LineSeries {
            id: lineSeries

            axisX: axisX
            axisY: axisY
        }

    }

    VXYModelMapper {
        id: modelMapper

        model: dataModel
        series: lineSeries
        xColumn: 0
        yColumn: 1
    }

}