How to set the range of a BarCategoryAxis in a QML bar chart?

回眸只為那壹抹淺笑 提交于 2020-06-01 06:50:33

问题


I am generating data in C++ (chartdata class) and then using it as input to QML charts (main.qml). However, for some reason, the BarCategoryAxis which corresponds to the AxisX is not showing the right range, therefore I only see a fraction of the categories. I have tried using min and max properties in the BarCategoryAxis object, but the categories are strings, so there is no min/max. I attach a screenshot of the window for clarity.

The lower chart of the window shows the bar chart, it can be seen that only 4 categories are visible. But 8 categories are generated by the C++ class, with values from 1 to 15

Please find below the relevant files :

.pro file

QT += quick core gui charts
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
    chartdata.cpp \
    main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
chartdata.h

main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include<QQmlContext>
#include"chartdata.h"

QT_CHARTS_USE_NAMESPACE

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication app(argc, argv);

    ChartData* chartdata = new ChartData();
    QQmlApplicationEngine engine;
    QQmlContext * context = engine.rootContext();
    context->setContextProperty("chartdata",chartdata);

    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();
 }

chartdata.h

#ifndef CHARTDATA_H
#define CHARTDATA_H

#include <QObject>
#include <QtCharts/QLineSeries>
#include<QtCharts/QBarSeries>
#include<QDate>

QT_CHARTS_USE_NAMESPACE

class ChartData : public QObject
{
    Q_OBJECT
public:
    ChartData();
public slots:
    void setLineSeries(QLineSeries* lineSeries);
    void setBarSeries(QBarSeries* barSeries);
    void generateData();

signals:
    void dataGenerated();

private:
    QVector<QDateTime> m_dates;
    QVector<double> m_data1;
    QStringList m_categories;
    QVector<int> m_data2;
};

#endif // CHARTDATA_H

chartdata.cpp

#include "chartdata.h"
#include<QtMath>
#include <QtCharts/QBarSet>

ChartData::ChartData()
{

}

void ChartData::setLineSeries(QLineSeries *lineSeries)
{
    for (int i = 0; i < m_data1.size(); i++) {
        lineSeries->append(m_dates[i].toMSecsSinceEpoch(),m_data1[i]);
    }
}

void ChartData::setBarSeries(QBarSeries *barSeries)
{
    for (int i = 0; i < m_data2.size(); i++) {
        QBarSet *set = new QBarSet(m_categories[i]);
        *set << m_data2[i];
        barSeries->append(set);
    }
}

void ChartData::generateData()
{
    //generate data for line series
    for (int i = 0; i < 15; i++) {
        m_dates.append(QDateTime::fromString("2020/1/"+QString::number(i), "yyyy/M/d"));
        m_data1.append(qCos(0.5*i));
    }

    //generate data for bar series
    for (int i = 0; i < 8; i++) {
        m_categories.append("Category_" + QString::number(i));
        m_data2.append(2*i+1);
    }

    if (m_dates.size() > 0){
        emit dataGenerated();
    }
}

main.qml. The C++ data is generated in the onCompleted block at the beginning, and then called in the charts using the functions addLineSeries() and addBarSeries().

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.3
import QtCharts 2.0

Window {
    visible: true
    width: 640
    height: 480

    Component.onCompleted: {
     chartdata.generateData()
    }

    Connections{
        target: chartdata
        onDataGenerated: {
            addLineSeries()
            addBarSeries()
        }
    }

    ColumnLayout{
        id:buttonLayout
        anchors.fill: parent
        spacing: 20

        ChartView {
            id:lineSeriesChart
            Layout.fillWidth: true
            Layout.fillHeight: true
            antialiasing: true

            DateTimeAxis {
                id:xTime
                format: "dd MM yyyy"
                tickCount: 5
                min: new Date(2019,12,1)
                max: new Date(2020,1,1)
            }

            ValueAxis {
                id:yValues
                min:-1
                max:1
            }
        }

        ChartView {
            id: barSeriesChart
            Layout.fillWidth: true
            Layout.fillHeight: true
            antialiasing: true
            legend.alignment: Qt.AlignBottom

            BarCategoryAxis {
                id: myCategories
            }

            ValueAxis{
                id: myBarValues
                min: -10
                max: 10
            }
        }
    }

    function addLineSeries()
    {
        var mySeries = lineSeriesChart.createSeries(ChartView.SeriesTypeLine, "my line series", xTime, yValues);
        chartdata.setLineSeries(mySeries)
    }

    function addBarSeries()
    {
        var mySeries = barSeriesChart.createSeries(ChartView.SeriesTypeBar,"my bar series", myCategories, myBarValues)
        chartdata.setBarSeries(mySeries)
        mySeries.barWidth = 0.1
    }
}

来源:https://stackoverflow.com/questions/61942795/how-to-set-the-range-of-a-barcategoryaxis-in-a-qml-bar-chart

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!