Permalink
Browse files

Plot: detect dates with time, pure dates and times data types

Three different date/time data types are detected and appropriately
displayed in the axis:
- DateTime: "yyyy-MM-dd\nhh:mm:ss"
- Date: "yyyy-MM-dd"
- Time: "hh:mm:ss"
  • Loading branch information...
mgrojo committed Jan 11, 2018
1 parent ce2b33a commit b2fbf450121a395fc83c8a331c5742f446adfa6e
Showing with 44 additions and 9 deletions.
  1. +44 −9 src/PlotDock.cpp
@@ -209,17 +209,33 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett
int xtype = xitemdata & (uint)0xFF;

// check if we have a x axis with datetime data
if(xtype == QVariant::DateTime)
{
switch (xtype) {
case QVariant::Date: {
QSharedPointer<QCPAxisTickerDateTime> ticker(new QCPAxisTickerDateTime);
ticker->setDateTimeFormat("yyyy-MM-dd");
ui->plotWidget->xAxis->setTicker(ticker);
} else {
break;
}
case QVariant::DateTime: {
QSharedPointer<QCPAxisTickerDateTime> ticker(new QCPAxisTickerDateTime);
ticker->setDateTimeFormat("yyyy-MM-dd\nhh:mm:ss");
ui->plotWidget->xAxis->setTicker(ticker);
break;
}
case QVariant::Time: {
QSharedPointer<QCPAxisTickerDateTime> ticker(new QCPAxisTickerDateTime);
ticker->setDateTimeFormat("hh:mm:ss");
ticker->setDateTimeSpec(Qt::UTC);
ui->plotWidget->xAxis->setTicker(ticker);
break;
}
default: {
QSharedPointer<QCPAxisTickerFixed> ticker(new QCPAxisTickerFixed);
ticker->setTickStepStrategy(QCPAxisTicker::tssReadability);
ticker->setScaleStrategy(QCPAxisTickerFixed::ssMultiples);
ui->plotWidget->xAxis->setTicker(ticker);
}
}

// add graph for each selected y axis
for(int i = 0; i < ui->treePlotColumns->topLevelItemCount(); ++i)
@@ -242,12 +258,21 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett
{
tdata[i] = i;
// convert x type axis if it's datetime
if(xtype == QVariant::DateTime)
{
switch (xtype) {
case QVariant::DateTime:
case QVariant::Date: {
QString s = model->data(model->index(i, x)).toString();
QDateTime d = QDateTime::fromString(s, Qt::ISODate);
xdata[i] = d.toMSecsSinceEpoch() / 1000.0;
} else {
break;
}
case QVariant::Time: {
QString s = model->data(model->index(i, x)).toString();
QTime t = QTime::fromString(s);
xdata[i] = t.msecsSinceStartOfDay() / 1000.0;
break;
}
default: {
// Get the x value for this point. If the selected column is -1, i.e. the row number, just use the current row number from the loop
// instead of retrieving some value from the model.
if(x == RowNumId)
@@ -256,6 +281,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett
else
xdata[i] = model->data(model->index(i, x)).toDouble();
}
}

if (i != 0)
isSorted &= (xdata[i-1] <= xdata[i]);
@@ -605,9 +631,18 @@ QVariant::Type PlotDock::guessDataType(SqliteTableModel* model, int column)
type = QVariant::Double;
} else {
QString s = model->data(model->index(i, column)).toString();
QDate d = QDate::fromString(s, Qt::ISODate);
if(d.isValid())
type = QVariant::DateTime;
QDateTime dt = QDateTime::fromString(s, Qt::ISODate);
QTime t = QTime::fromString(s);
if (dt.isValid())
// Since the way to discriminate dates with times and pure dates is that the time part is 0, we must take into account
// that some DateTimes could have "00:00:00" as time part and still the entire column has time information, so a single
// final Date should not set the type to Date if it has already been guessed as DateTime.
if (type != QVariant::DateTime && dt.time().msecsSinceStartOfDay() == 0)
type = QVariant::Date;
else
type = QVariant::DateTime;
else if (t.isValid())
type = QVariant::Time;
else
type = QVariant::String;
}

1 comment on commit b2fbf45

@justinclift

This comment has been minimized.

Copy link
Member

justinclift commented on b2fbf45 Jan 12, 2018

Oh, good idea. 😄

Please sign in to comment.