2019-06-21 04:24:47 +08:00
|
|
|
/** \example dateaxes.cpp
|
2019-01-20 23:15:10 +08:00
|
|
|
* Shows how to use date/time axes with JKQTPlotter
|
2019-01-13 01:53:16 +08:00
|
|
|
*
|
2019-01-20 23:15:10 +08:00
|
|
|
* \ref JKQTPlotterDateTimeAxes
|
2019-01-13 01:53:16 +08:00
|
|
|
*/
|
|
|
|
|
2018-12-29 00:46:47 +08:00
|
|
|
#include <QApplication>
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QTime>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QTextStream>
|
|
|
|
#include "jkqtplotter/jkqtplotter.h"
|
2019-06-20 22:06:31 +08:00
|
|
|
#include "jkqtplotter/graphs/jkqtpscatter.h"
|
|
|
|
#include "jkqtplotter/graphs/jkqtpgeometric.h"
|
2019-05-30 04:40:02 +08:00
|
|
|
#include "jkqtplotter/jkqtptools.h"
|
2019-06-20 22:06:31 +08:00
|
|
|
#include "jkqtplotter/graphs/jkqtpfilledcurve.h"
|
2018-12-29 00:46:47 +08:00
|
|
|
|
2019-01-20 23:15:10 +08:00
|
|
|
void drawWithDateAxis(JKQTPlotter& plot) {
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
2019-01-20 17:49:29 +08:00
|
|
|
JKQTPDatastore* ds=plot.getDatastore();
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 2. now we create data vectors with data parsed from a CSV-file
|
|
|
|
QVector<double> date;
|
|
|
|
QVector<double> temperature, temperature_min, temperature_max;
|
|
|
|
// parse a textfile with comments on the first line and the
|
|
|
|
// semicolon separated data. The first column is a date and time
|
|
|
|
// the second to fourth columns contain a floating-point number
|
|
|
|
// with temperature average, min and max
|
|
|
|
QFile file(":/weatherdata_gelsenkirchen.csv");
|
|
|
|
file.open(QFile::ReadOnly|QFile::Text);
|
|
|
|
file.readLine(); // eat comment
|
|
|
|
while (!file.atEnd()) {
|
|
|
|
QString line=file.readLine();
|
|
|
|
QTextStream in(&line);
|
|
|
|
QStringList items=line.split(";");
|
|
|
|
// date/time values are stored as doubles representing the corresponding number of milliseconds sind epoch
|
|
|
|
date<<QDateTime::fromString(items[0], Qt::ISODate).toUTC().toMSecsSinceEpoch();
|
|
|
|
// store Heidelbergs daily temperature
|
|
|
|
temperature<<items[1].toDouble();
|
|
|
|
temperature_min<<items[2].toDouble();
|
|
|
|
temperature_max<<items[3].toDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. add a plot for the data mean line (graphTemperature) and range (graphTemperatureRange)
|
2019-01-20 17:49:29 +08:00
|
|
|
JKQTPFilledVerticalRangeGraph* graphTemperatureRange=new JKQTPFilledVerticalRangeGraph(&plot);
|
|
|
|
JKQTPXYLineErrorGraph* graphTemperature=new JKQTPXYLineErrorGraph(&plot);
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 4. copy data into datastore and immediately set the yColumn
|
|
|
|
size_t colDate=ds->addCopiedColumn(date, "date");
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperature->setXColumn(colDate);
|
|
|
|
graphTemperature->setYColumn(ds->addCopiedColumn(temperature, "temperature"));
|
|
|
|
graphTemperatureRange->setXColumn(colDate);
|
|
|
|
graphTemperatureRange->setYColumn(ds->addCopiedColumn(temperature_min, "temperature_min"));
|
|
|
|
graphTemperatureRange->setYColumn2(ds->addCopiedColumn(temperature_max, "temperature_max"));
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
|
|
|
|
// 5. min/max range data
|
|
|
|
// graph fill color is a lighter shade of the average graph
|
2019-04-22 19:27:50 +08:00
|
|
|
graphTemperatureRange->setFillColor(graphTemperature->getLineColor().lighter());
|
2018-12-29 00:46:47 +08:00
|
|
|
// don't draw lines of the data
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperatureRange->setDrawLine(false);
|
2018-12-29 00:46:47 +08:00
|
|
|
// plot label in key
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperatureRange->setTitle("Min/Max Temperature");
|
2018-12-29 00:46:47 +08:00
|
|
|
// add the graph to the plot, so it is actually displayed
|
|
|
|
plot.addGraph(graphTemperatureRange);
|
|
|
|
|
|
|
|
// 6. average data
|
|
|
|
// don't use symbols
|
2019-04-22 19:27:50 +08:00
|
|
|
graphTemperature->setSymbolType(JKQTPNoSymbol);
|
2018-12-29 00:46:47 +08:00
|
|
|
// set the line width
|
2019-01-26 03:16:04 +08:00
|
|
|
graphTemperature->setLineWidth(1);
|
2018-12-29 00:46:47 +08:00
|
|
|
// draw small symbols
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperature->setSymbolSize(6);
|
2018-12-29 00:46:47 +08:00
|
|
|
// graph title
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperature->setTitle("Average Temperature");
|
2018-12-29 00:46:47 +08:00
|
|
|
// add the graph to the plot, so it is actually displayed
|
|
|
|
plot.addGraph(graphTemperature);
|
|
|
|
|
|
|
|
|
|
|
|
// 7. format the plot
|
|
|
|
// set the title above the plot, use LaTeX instructions to make text bold
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getPlotter()->setPlotLabel("\\textbf{Weather in Gelsenkirchen, 2017-2018}");
|
2018-12-29 00:46:47 +08:00
|
|
|
// set x-axis date-time-axis
|
2019-01-26 20:00:40 +08:00
|
|
|
plot.getXAxis()->setLabelType(JKQTPCALTdatetime);
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getXAxis()->setAxisLabel("Date");
|
2018-12-29 00:46:47 +08:00
|
|
|
// set format string for date axis (e.g. Jan '18), see Documentation of QDateTime::toString()
|
2019-01-26 20:00:40 +08:00
|
|
|
plot.getXAxis()->setTickDateTimeFormat("MMM ''yy");
|
2018-12-29 00:46:47 +08:00
|
|
|
// set y-axis temperature axis
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getYAxis()->setAxisLabel("Average Daily Temperature [{\\degree}C]");
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 8. autoscale the plot so the graph is contained
|
|
|
|
plot.zoomToFit();
|
|
|
|
|
|
|
|
// 9. show plotter and make it a decent size
|
|
|
|
plot.show();
|
|
|
|
plot.resize(600,400);
|
|
|
|
plot.setWindowTitle("Date Axis");
|
|
|
|
}
|
|
|
|
|
2019-01-20 23:15:10 +08:00
|
|
|
void drawWithTimeAxis(JKQTPlotter& plot) {
|
2018-12-29 00:46:47 +08:00
|
|
|
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
2019-01-20 17:49:29 +08:00
|
|
|
JKQTPDatastore* ds=plot.getDatastore();
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 2. now we create data vectors with data parsed from a CSV-file
|
|
|
|
QVector<double> time;
|
|
|
|
QVector<double> temperature;
|
|
|
|
// parse a textfile with comments on the first line and the
|
|
|
|
// semicolon separated data. The first column is a time
|
|
|
|
// the second contain a floating-point number with temperatures
|
|
|
|
QFile file(":/weatherdata_heidelberg_2018-10-14.csv");
|
|
|
|
file.open(QFile::ReadOnly|QFile::Text);
|
|
|
|
file.readLine(); // eat comment
|
|
|
|
while (!file.atEnd()) {
|
|
|
|
QString line=file.readLine();
|
|
|
|
QTextStream in(&line);
|
|
|
|
QStringList items=line.split(";");
|
|
|
|
// date/time values are stored as doubles representing the corresponding
|
|
|
|
// number of milliseconds sind epoch. Since the data is time only, we have to use an arbitrary
|
|
|
|
// date as basis
|
|
|
|
time<<QDateTime::fromString("1970-01-01T"+items[0], Qt::ISODate).toMSecsSinceEpoch();
|
|
|
|
// store Heidelbergs daily temperature
|
|
|
|
temperature<<items[1].toDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. add a plot for the data mean line (graphTemperature) and range (graphTemperatureRange)
|
2019-01-20 17:49:29 +08:00
|
|
|
JKQTPXYLineErrorGraph* graphTemperature=new JKQTPXYLineErrorGraph(&plot);
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 4. copy data into datastore and immediately set the yColumn
|
|
|
|
size_t colDate=ds->addCopiedColumn(time, "time");
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperature->setXColumn(colDate);
|
|
|
|
graphTemperature->setYColumn(ds->addCopiedColumn(temperature, "temperature"));
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
|
|
|
|
// 6. average data
|
|
|
|
// don't use symbols
|
2019-04-22 19:27:50 +08:00
|
|
|
graphTemperature->setSymbolType(JKQTPCross);
|
2018-12-29 00:46:47 +08:00
|
|
|
// set the line width
|
2019-01-26 03:16:04 +08:00
|
|
|
graphTemperature->setLineWidth(1);
|
2018-12-29 00:46:47 +08:00
|
|
|
// draw small symbols
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperature->setSymbolSize(6);
|
2018-12-29 00:46:47 +08:00
|
|
|
// graph title
|
2019-01-26 20:00:40 +08:00
|
|
|
graphTemperature->setTitle("Average Temperature");
|
2018-12-29 00:46:47 +08:00
|
|
|
// add the graph to the plot, so it is actually displayed
|
|
|
|
plot.addGraph(graphTemperature);
|
|
|
|
|
|
|
|
|
|
|
|
// 7. format the plot
|
|
|
|
// set the title above the plot, use LaTeX instructions to make text bold
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getPlotter()->setPlotLabel("\\textbf{Weather in Heidelberg, 14^{th} Oct 2018}");
|
2018-12-29 00:46:47 +08:00
|
|
|
// set x-axis date-time-axis
|
2019-01-26 20:00:40 +08:00
|
|
|
plot.getXAxis()->setLabelType(JKQTPCALTtime);
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getXAxis()->setAxisLabel("Time of Day");
|
2018-12-29 00:46:47 +08:00
|
|
|
// set format string for time axis with 24-hour and minute only,
|
|
|
|
// see QDateTime::toString() documentation for details on format strings
|
2019-01-26 20:00:40 +08:00
|
|
|
plot.getXAxis()->setTickTimeFormat("HH:mm");
|
2018-12-29 00:46:47 +08:00
|
|
|
// set y-axis temperature axis
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getYAxis()->setAxisLabel("Temperature [{\\degree}C]");
|
2018-12-29 00:46:47 +08:00
|
|
|
|
|
|
|
// 8. autoscale the plot so the graph is contained
|
|
|
|
plot.zoomToFit();
|
|
|
|
|
|
|
|
// 9. show plotter and make it a decent size
|
|
|
|
plot.show();
|
|
|
|
plot.resize(600,400);
|
|
|
|
plot.setWindowTitle("Time Axis");
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2022-04-16 05:01:09 +08:00
|
|
|
|
|
|
|
#if QT_VERSION >= 0x050600
|
|
|
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support
|
|
|
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); //HiDPI pixmaps
|
|
|
|
#endif
|
2018-12-29 00:46:47 +08:00
|
|
|
QApplication app(argc, argv);
|
2022-04-16 05:01:09 +08:00
|
|
|
|
2019-01-20 23:15:10 +08:00
|
|
|
JKQTPlotter plotDate;
|
2018-12-29 00:46:47 +08:00
|
|
|
drawWithDateAxis(plotDate);
|
|
|
|
plotDate.move(100,100);
|
2019-01-20 23:15:10 +08:00
|
|
|
JKQTPlotter plotTime;
|
2018-12-29 00:46:47 +08:00
|
|
|
drawWithTimeAxis(plotTime);
|
|
|
|
plotTime.move(100,550);
|
|
|
|
|
|
|
|
return app.exec();
|
|
|
|
}
|