I need to plot a chart, whose axis X has data type of date-time
.
I'm trying to use QtCharts
to do so, but I find that QtCharts::QDateTimeAxis
can only process consecutive data(the X axis is proportional and consecutive).
For example, given a LineSeries:
{
{ "20:15:00", 123.0 },
{ "20:15:01", 124.0 },
{ "21:00:00", 125.0 },
{ "21:00:01", 126.0 },
}
If I use a QDateTimeAxis
as the X-axis, I would get too more white-space range on X axis, not only 4 spots.
Even though there is no data between "20:15:02" to "20:59::59", QChart
still gives the space of a lot of slots in X axis that have no meaning.
Can we plot a chart that has non-consecutive X-axis with Qt
?
If Qt
cannot do it, is there a open-source C++ library that can do the same?
You don't have to use QDateTimeAxis since that axis is designed so that the points are spaced proportionally to the time difference. So one possible solution is to use QCategoryAxis:
#include <QtWidgets>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
std::vector<std::pair<QString, float>> data = {
{ "20:15:00", 123.0 },
{ "20:15:01", 124.0 },
{ "21:00:00", 125.0 },
{ "21:00:01", 126.0 },
};
QScatterSeries *series = new QScatterSeries(); // or QLineSeries *series = new QLineSeries;
QCategoryAxis *axisX = new QCategoryAxis;
axisX->setMin(.5);
axisX->setMax(data.size() + .5);
axisX->setTitleText("Time");
QValueAxis *axisY = new QValueAxis;
axisY->setLabelFormat("%.2f");
axisY->setTitleText("Example");
axisY->setMin(122);
axisY->setMax(127);
for(std::size_t i=0; i < data.size(); i++){
series->append(i + 1, data.at(i).second);
axisX->append(data.at(i).first, i + 1.5);
}
QChart *chart = new QChart();
chart->addSeries(series);
chart->legend()->hide();
chart->addAxis(axisX, Qt::AlignBottom);
series->attachAxis(axisX);
chart->addAxis(axisY, Qt::AlignLeft);
series->attachAxis(axisY);
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(820, 600);
window.show();
return a.exec();
}