问题
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