0

I have a data set in an QSqlQueryModel that looks like this

+-----------+-----------+------------+
| date      | sent      | recv       |
|===========+===========+============+
| 2013-4-21 | 3839088   | 140036219  |
| 2013-4-22 | 146037305 | 1439537452 |
| 2013-4-23 | 67140372  | 1787850213 |
| ...                                |
+-----------+-----------+------------+

Values in the date column are QDateTime objects, values in the sent and recv columns are integers.

I want to display this data in a QML ChartView using the StackedBarSeries and a VBarModelMapper:

ChartView {
    anchors.fill: parent
    antialiasing: true

    StackedBarSeries {
        VBarModelMapper {
            model: SqlTrafficModel {}
            firstBarSetColumn: 1
            lastBarSetColumn: 2
            firstRow: 0
        }
    }
}

This is the current state of my view ChartView using some test data

My problem is that the StackedBarSeries just uses an index for the x-axis label, however I'd like to display the date of each bar as it's x-axis label.

I tried to use DateTimeAxis for the axisX property but it looks like it just shifts the x-axis to the provided min and max values while interpreting the original labels as unix timestamps.

strnmn
  • 555
  • 1
  • 6
  • 30

1 Answers1

1

One possible solution is to implement a Q_INVOKABLE method that returns the requested column in a QStringList and set it to categories in a BarCategoryAxis assigned to the X axis, and call it when the Component.onCompleted and onModelReset signals are emited:

sqltrafficmodel.h

#ifndef SQLTRAFFICMODEL_H
#define SQLTRAFFICMODEL_H

#include <QSqlQuery>
#include <QSqlQueryModel>

class SqlTrafficModel : public QSqlQueryModel
{
    Q_OBJECT
    Q_PROPERTY(QString queryStr READ queryStr WRITE setQueryStr NOTIFY queryStrChanged)
public:
    SqlTrafficModel(QObject *parent = nullptr):QSqlQueryModel(parent){}

    Q_INVOKABLE QStringList getColumn(int col){
        QStringList mColumn;
        for(int row=0; row< rowCount(); ++row){
            mColumn<<index(row, col).data().toString();
        }
        return mColumn;
    }

    QString queryStr() const{
        return mQueryStr;
    }
    void setQueryStr(const QString &queryStr){
        if(queryStr == mQueryStr)
            return;
        mQueryStr = queryStr;
        setQuery(mQueryStr);
        emit queryStrChanged();
    }

signals:
    void queryStrChanged();
private:
    QString mQueryStr;
};

#endif // SQLTRAFFICMODEL_H

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtCharts 2.2

import com.eyllanesc.models 1.0

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

    ChartView {
        anchors.fill: parent
        antialiasing: true

        StackedBarSeries {
            VBarModelMapper {
                model: SqlTrafficModel {
                    id: trafficModel
                    queryStr: "select * from traffic"
                    onModelReset: bar_axis.categories = getColumn(0)
                    Component.onCompleted: bar_axis.categories = getColumn(0)
                }
                firstBarSetColumn: 1
                lastBarSetColumn: 2
                firstRow: 0
            }
            axisX: BarCategoryAxis {
                id: bar_axis
            }
        }
    }
}

enter image description here

The complete example can be found in the following link

strnmn
  • 555
  • 1
  • 6
  • 30
eyllanesc
  • 235,170
  • 19
  • 170
  • 241