Can someone provide a working example of VXYModelMapper with lineseries chart ?



  • I want to implement something like this .With a model from cpp and combined with line charts but I am not able to understand yColumn and xColumn as in what data shall I provide it and I would like to Append the data to the lineseries every time it is updated.

    qml:
    
    
    Rectangle {
        implicitWidth: implicitWidth + 2*anchors.margins
        implicitHeight: implicitHeight + 2*anchors.margins
        clip: true
        color: "#ddd"
        Item {
        id: valueDisp
        implicitWidth: 640
        implicitHeight: 640
    
        ChartView
        {
            id: chartView
            title: " Scope "
            anchors.fill: parent
            legend.visible: false
            antialiasing: true
            backgroundColor: "white"
            plotAreaColor: "white"
            titleColor: "white"
    
            ValueAxis {
                id: axisX
                titleText:componentData.readXAxisName
                min: componentData.changeXMin
                max: componentData.changeXMax
                tickCount: 1
            }
    
            ValueAxis {
                id: axisY
                titleText:componentData.readYAxisName
                min: componentData.changeYMin
                max: componentData.changeYMax
                tickCount: 1
            }
    
            LineSeries {
    
                id: lineSeries
                name: "Data Output"
                axisX: axisX
                axisY: axisY
                useOpenGL: true
                VXYModelMapper{
                model:componentData.dataRead
                }
            }
        }
    

    cpp:

    
    //this is a snippet of the code I am using :
    // in class ScopeData I a updating setXdata and setYdata and whenever I update them I assert valueAdded signal as well 
    Q_PROPERTY(QQmlListProperty<ChartData> dataRead READ dataRead NOTIFY valueAdded)
    
    QQmlListProperty<ChartData> ScopeData::dataRead()
    {
    	return QQmlListProperty<xpcv::ChartData> (this,m_chartData);
    }
    
    // these are the functions that I am using to update the data in the chart
    ChartData::ChartData(QObject *parent)
    	: QObject(parent),
    		m_xValue(0), 
    		m_yValue(0)
    	{}
    	void ChartData::setXdata(int data)
    	{
    		m_xValue=data;
    	}
    
    	void ChartData::setYdata(double data)
    	{
    		m_yValue=data;
    	}
    

    but I get the following error:
    unable to assign qmlListProperty<ChartData> to QAbstractItemModel
    PS- I cannot share the entire code because of privacy of project details
    Thank You,
    Saransh Vora



  • This subject is rather old but I also have not found any example and I took time to make it work.
    Below my proposal
    Click on the chart to randomly append data

    main.cpp

    #include <QQmlEngine>
    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include "chartmodel.h"
    
    int main(int argc, char *argv[])
    {
    #if defined(Q_OS_WIN)
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    #endif
    
        QApplication app(argc, argv); //Use QApplication for QChart, QGuiApplication causes a bug
    
        qmlRegisterType<ChartModel> ("MainLib", 1, 0, "ChartModel");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    chartmodel.h

    #ifndef CHARTMODEL_H
    #define CHARTMODEL_H
    
    #include <QVector>
    #include <QAbstractTableModel>
    //#include <QDebug>
    
    class ChartModel : public QAbstractTableModel
    {
        Q_OBJECT
    
        QVector<QPair<double,double>> vec_;
    
        double m_xMin;
        double m_xMax;
        double m_yMin;
        double m_yMax;
    
        Q_PROPERTY (double xMin READ get_xMin WRITE set_xMin NOTIFY xMinChanged)
        Q_PROPERTY (double xMax READ get_xMax WRITE set_xMax NOTIFY xMaxChanged)
        Q_PROPERTY (double yMin READ get_yMin WRITE set_yMin NOTIFY yMinChanged)
        Q_PROPERTY (double yMax READ get_yMax WRITE set_yMax NOTIFY yMaxChanged)
    
    public:
        explicit ChartModel(QObject *parent = nullptr);
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        //    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    
        double get_xMin() const;
        double get_xMax() const;
        double get_yMin() const;
        double get_yMax() const;
    
    public slots:
        bool set_xMin(double val);
        bool set_xMax(double val);
        bool set_yMin(double val);
        bool set_yMax(double val);
    
        void appendData();
    
    signals:
        void xMinChanged(double);
        void xMaxChanged(double);
        void yMinChanged(double);
        void yMaxChanged(double);
    };
    
    #endif // CHARTMODEL_H
    
    

    chartmodel.cpp

    #include "chartmodel.h"
    
    ChartModel::ChartModel(QObject *parent) : QAbstractTableModel(parent)
    {
        m_xMin = 0.;
        m_xMax = 1.;
        m_yMin = 0.;
        m_yMax = 1.;
    }
    
    int ChartModel::rowCount(const QModelIndex & /* parent */) const
    {
        return vec_.size();
    }
    
    int ChartModel::columnCount(const QModelIndex & /* parent */) const
    {
        return 2;
    }
    
    QVariant ChartModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid() || role != Qt::DisplayRole)
            return QVariant();
    
        if (index.column() == 0){
            return vec_.at(index.row()).first;
        }
        if (index.column() == 1){
            return vec_.at(index.row()).second;
        }
        return QVariant();
    }
    
    double ChartModel::get_xMin() const
    {
        return m_xMin;
    }
    
    double ChartModel::get_xMax() const
    {
        return m_xMax;
    }
    double ChartModel::get_yMin() const
    {
        return m_yMin;
    }
    
    double ChartModel::get_yMax() const
    {
        return m_yMax;
    }
    
    bool ChartModel::set_xMin(double val)
    {
        bool ret = false;
        if ((ret = (m_xMin != val))) {
            m_xMin = val;
            emit xMinChanged (m_xMin);
        }
        return ret;
    }
    
    bool ChartModel::set_xMax(double val)
    {
        bool ret = false;
        if ((ret = (m_xMax != val))) {
            m_xMax = val;
            emit xMaxChanged (m_xMax);
        }
        return ret;
    }
    
    bool ChartModel::set_yMin(double val)
    {
        bool ret = false;
        if ((ret = (m_yMin != val))) {
            m_yMin = val;
            emit yMinChanged (m_yMin);
        }
        return ret;
    }
    
    bool ChartModel::set_yMax(double val)
    {
        bool ret = false;
        if ((ret = (m_yMax != val))) {
            m_yMax = val;
            emit yMaxChanged (m_yMax);
        }
        return ret;
    }
    
    void ChartModel::appendData()
    {
    
        int const nbData = 1+qRound(10.*double(qrand())/double(RAND_MAX));
        int const vecSize = vec_.size();
    
        if (!vecSize){
            m_xMin = qInf();
            m_xMax = -qInf();
            m_yMin = qInf();
            m_yMax = -qInf();
        }
    
        beginInsertRows(QModelIndex (), vecSize, vecSize+nbData);
    
        for(int seed = 0 ; seed <  nbData; ++seed){
            double const xVal = vec_.size();
            double const yVal = double(qrand())/double(RAND_MAX);
            set_xMin(qMin(m_xMin, xVal));
            set_xMax(qMax(m_xMax, xVal));
            set_yMin(qMin(m_yMin, yVal));
            set_yMax(qMax(m_yMax, yVal));
            vec_.append(qMakePair<double, double>(xVal, yVal));
        }
        endInsertRows();
    }
    
    

    main.qml

    import QtQuick 2.10
    import QtQuick.Window 2.10
    import QtCharts 2.0
    import MainLib 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        property ChartModel chartModel : ChartModel{}
    
        ChartView {
            id : chart
            anchors.fill: parent
            antialiasing: true
            animationOptions: ChartView.AllAnimations
    
            SplineSeries {
                id : serie1
    
                axisX : ValueAxis {
                    id: xAxis
                    min: chartModel.xMin
                    max: chartModel.xMax
                }
    
                axisY : ValueAxis {
                    id: yAxis
                    min: chartModel.yMin
                    max: chartModel.yMax
                }
    
                VXYModelMapper {
                    id: mapper
                    xColumn: 0
                    yColumn: 1
                    model: chartModel
                }
            }
            MouseArea{
                anchors.fill : parent
                onClicked: {
                    chartModel.appendData()
                }
            }
        }
    }
    
    


Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.