From 336d2255eb501f5c228a80a0fa469844bbc1ee2f Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Mon, 23 Jul 2018 18:15:31 +0100 Subject: [PATCH] Add graphs showing journeys/durations over last year --- harbour-pedalo.pro | 8 +++-- qml/pages/Stats.qml | 2 +- src/graph.cpp | 2 +- src/harbour-pedalo.cpp | 8 +++++ src/statshourcongestion.cpp | 5 --- src/statshourjourneys.cpp | 7 +--- src/statsweekdayave.cpp | 7 ---- src/statsweekdaycongestion.cpp | 5 --- src/statsyearduration.cpp | 61 ++++++++++++++++++++++++++++++++++ src/statsyearduration.h | 18 ++++++++++ src/statsyearjourneys.cpp | 61 ++++++++++++++++++++++++++++++++++ src/statsyearjourneys.h | 18 ++++++++++ 12 files changed, 175 insertions(+), 27 deletions(-) create mode 100644 src/statsyearduration.cpp create mode 100644 src/statsyearduration.h create mode 100644 src/statsyearjourneys.cpp create mode 100644 src/statsyearjourneys.h diff --git a/harbour-pedalo.pro b/harbour-pedalo.pro index bc118dd..ea9c88a 100644 --- a/harbour-pedalo.pro +++ b/harbour-pedalo.pro @@ -39,7 +39,9 @@ SOURCES += src/harbour-pedalo.cpp \ src/statsweekdayave.cpp \ src/statsweekdaycongestion.cpp \ src/statshourcongestion.cpp \ - src/statshourjourneys.cpp + src/statshourjourneys.cpp \ + src/statsyearjourneys.cpp \ + src/statsyearduration.cpp DISTFILES += qml/harbour-pedalo.qml \ qml/cover/CoverPage.qml \ @@ -87,4 +89,6 @@ HEADERS += \ src/statsweekdayave.h \ src/statsweekdaycongestion.h \ src/statshourcongestion.h \ - src/statshourjourneys.h + src/statshourjourneys.h \ + src/statsyearjourneys.h \ + src/statsyearduration.h diff --git a/qml/pages/Stats.qml b/qml/pages/Stats.qml index 235ca1c..45779c1 100644 --- a/qml/pages/Stats.qml +++ b/qml/pages/Stats.qml @@ -107,7 +107,7 @@ Page { height: (isPortrait ? (statsPage.height / 2.0) - Theme.paddingLarge : statsPage.height - Theme.paddingLarge - headerItem.height) - sectionHeaderItem.height anchors.left: parent.left bardata: barvalues - //linedata: barvalues + linedata: linevalues labelsx: labels //labelsy: ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"] unitsy: units diff --git a/src/graph.cpp b/src/graph.cpp index d4a60d2..6cc38d5 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -122,7 +122,7 @@ void Graph::paint(QPainter *painter) { painter->setBrush(Qt::NoBrush); if (labelsxcount > 0) { - for (count = 0; count < bars; count++) { + for (count = 0; count < labelsxcount; count++) { QRectF rect(labelxgap + axiswidth + (labelfullwidth * count), size.height() - labelygap + 8.0, labelfullwidth, labelygap - 8.0); painter->drawText(rect, Qt::AlignHCenter | Qt::NoClip | Qt::TextSingleLine, labelsx[count]); //painter->drawRect(rect); diff --git a/src/harbour-pedalo.cpp b/src/harbour-pedalo.cpp index f19a8fc..90df54e 100644 --- a/src/harbour-pedalo.cpp +++ b/src/harbour-pedalo.cpp @@ -16,6 +16,8 @@ #include "statshourjourneys.h" #include "statsweekdaycongestion.h" #include "statshourcongestion.h" +#include "statsyearjourneys.h" +#include "statsyearduration.h" #include "harbour-pedalo.h" @@ -50,6 +52,12 @@ int main(int argc, char *argv[]) StatsModel statsmodel; + StatsYearDuration statsyearduration(&journeys); + statsmodel.addStats(statsyearduration); + + StatsYearJourneys statsyearjourneys(&journeys); + statsmodel.addStats(statsyearjourneys); + StatsWeekdayAve statsweekdayave(&journeys); statsmodel.addStats(statsweekdayave); diff --git a/src/statshourcongestion.cpp b/src/statshourcongestion.cpp index 1d049e7..4debac7 100644 --- a/src/statshourcongestion.cpp +++ b/src/statshourcongestion.cpp @@ -1,5 +1,3 @@ -#include - #include "statshourcongestion.h" #define LOWESTHOUR (7) @@ -22,7 +20,6 @@ void StatsHourCongestion::update() { unsigned int count[24]; int pos; - qDebug() << "Calculating values"; barvalues.clear(); for (pos = 0; pos < 24; pos++) { @@ -62,6 +59,4 @@ void StatsHourCongestion::update() { } step = (maxval > 5.0) ? qRound(maxval / 5.0) : (maxval / 5.0); - - qDebug() << "Calculated values"; } diff --git a/src/statshourjourneys.cpp b/src/statshourjourneys.cpp index 270d436..9c20130 100644 --- a/src/statshourjourneys.cpp +++ b/src/statshourjourneys.cpp @@ -1,5 +1,3 @@ -#include - #include "statshourjourneys.h" #define LOWESTHOUR (7) @@ -8,7 +6,7 @@ StatsHourJourneys::StatsHourJourneys(JourneyModel * journeys) : journeys(journeys) { - title = "Journey proportions per hour (%)"; + title = "Journey proportion per hour (%)"; units = "%"; labels.clear(); @@ -22,7 +20,6 @@ void StatsHourJourneys::update() { quint64 totalmins; int pos; - qDebug() << "Calculating values"; barvalues.clear(); for (pos = 0; pos < 24; pos++) { @@ -55,6 +52,4 @@ void StatsHourJourneys::update() { } barvalues << result; } - - qDebug() << "Calculated values"; } diff --git a/src/statsweekdayave.cpp b/src/statsweekdayave.cpp index c0bbd2b..7d4987c 100644 --- a/src/statsweekdayave.cpp +++ b/src/statsweekdayave.cpp @@ -1,5 +1,3 @@ -#include - #include "statsweekdayave.h" StatsWeekdayAve::StatsWeekdayAve(JourneyModel * journeys) : @@ -15,7 +13,6 @@ void StatsWeekdayAve::update() { unsigned int count[7]; int pos; - qDebug() << "Calculating values"; barvalues.clear(); for (pos = 0; pos < 7; pos++) { @@ -45,8 +42,4 @@ void StatsWeekdayAve::update() { } step = maxval > 5.0 ? qRound(maxval / 5.0) : (maxval / 5.0); - - qDebug() << "Calculated values"; } - - diff --git a/src/statsweekdaycongestion.cpp b/src/statsweekdaycongestion.cpp index 3e19192..9b6eb81 100644 --- a/src/statsweekdaycongestion.cpp +++ b/src/statsweekdaycongestion.cpp @@ -1,5 +1,3 @@ -#include - #include "statsweekdaycongestion.h" StatsWeekdayCongestion::StatsWeekdayCongestion(JourneyModel * journeys) : @@ -15,7 +13,6 @@ void StatsWeekdayCongestion::update() { unsigned int count[7]; int pos; - qDebug() << "Calculating values"; barvalues.clear(); for (pos = 0; pos < 7; pos++) { @@ -46,6 +43,4 @@ void StatsWeekdayCongestion::update() { } step = maxval > 5.0 ? qRound(maxval / 5.0) : (maxval / 5.0); - - qDebug() << "Calculated values"; } diff --git a/src/statsyearduration.cpp b/src/statsyearduration.cpp new file mode 100644 index 0000000..19ad380 --- /dev/null +++ b/src/statsyearduration.cpp @@ -0,0 +1,61 @@ +#include "statsyearduration.h" + +#define WINDOW (3) + +StatsYearDuration::StatsYearDuration(JourneyModel * journeys) : + journeys(journeys) +{ + title = QString("Year view (hours/mon + moving ave)"); + units = ""; +} + +void StatsYearDuration::update() { + double duration[12]; + double average[11 + WINDOW]; + int pos; + QDate now; + QDate start; + QDate startave; + + now = QDate::currentDate(); + start = now.addMonths(-12); + startave = start.addMonths(1 - WINDOW); + + barvalues.clear(); + linevalues.clear(); + + for (pos = 0; pos < 12; pos++) { + duration[pos] = 0.0; + average[pos] = 0.0; + } + + foreach (Journey const &journey, journeys->getData()) { + QDate date = journey.getStartDate(); + if (date > start) { + duration[(date.month() - now.month() + 11) % 12] += journey.getDuration() / (60.0 * 60.0); + } + if (date > startave) { + int month = (date.month() - now.month() + 11) % 12; + for (pos = 0; pos < WINDOW; pos++) { + average[month + pos] += journey.getDuration() / (60.0 * 60.0); + } + } + } + + labels = QStringList{"J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"}; + for (pos = 0; pos < now.month(); pos++) { + // Rotate values + labels.push_back(labels.takeFirst()); + } + + maxval = 0.0; + for (pos = 0; pos < 12; pos++) { + if (duration[pos] > maxval) { + maxval = duration[pos]; + } + barvalues << duration[pos]; + linevalues << average[pos] / (double)WINDOW; + } + + step = maxval > 5.0 ? qRound(maxval / 5.0) : (maxval / 5.0); +} diff --git a/src/statsyearduration.h b/src/statsyearduration.h new file mode 100644 index 0000000..371e243 --- /dev/null +++ b/src/statsyearduration.h @@ -0,0 +1,18 @@ +#ifndef STATSYEARDURATION_H +#define STATSYEARDURATION_H + +#include "journeymodel.h" +#include "stats.h" + +class StatsYearDuration : public Stats +{ +public: + StatsYearDuration(JourneyModel * journeys); + + void update(); + +private: + JourneyModel * journeys; +}; + +#endif // STATSYEARDURATION_H diff --git a/src/statsyearjourneys.cpp b/src/statsyearjourneys.cpp new file mode 100644 index 0000000..f477c3b --- /dev/null +++ b/src/statsyearjourneys.cpp @@ -0,0 +1,61 @@ +#include "statsyearjourneys.h" + +#define WINDOW (3) + +StatsYearJourneys::StatsYearJourneys(JourneyModel * journeys) : + journeys(journeys) +{ + title = QString("Year view (journeys/mon + moving ave)"); + units = ""; +} + +void StatsYearJourneys::update() { + unsigned int count[12]; + unsigned int average[11 + WINDOW]; + int pos; + QDate now; + QDate start; + QDate startave; + + now = QDate::currentDate(); + start = now.addMonths(-12); + startave = start.addMonths(1 - WINDOW); + + barvalues.clear(); + linevalues.clear(); + + for (pos = 0; pos < 12; pos++) { + count[pos] = 0u; + average[pos] = 0u; + } + + foreach (Journey const &journey, journeys->getData()) { + QDate date = journey.getStartDate(); + if (date > start) { + count[(date.month() - now.month() + 11) % 12]++; + } + if (date > startave) { + int month = (date.month() - now.month() + 11) % 12; + for (pos = 0; pos < WINDOW; pos++) { + average[month + pos]++; + } + } + } + + labels = QStringList{"J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"}; + for (pos = 0; pos < now.month(); pos++) { + // Rotate values + labels.push_back(labels.takeFirst()); + } + + maxval = 0.0; + for (pos = 0; pos < 12; pos++) { + if (count[pos] > maxval) { + maxval = count[pos]; + } + barvalues << (float)count[pos]; + linevalues << (float)average[pos] / (float)WINDOW; + } + + step = maxval > 5.0 ? qRound(maxval / 5.0) : (maxval / 5.0); +} diff --git a/src/statsyearjourneys.h b/src/statsyearjourneys.h new file mode 100644 index 0000000..d06e778 --- /dev/null +++ b/src/statsyearjourneys.h @@ -0,0 +1,18 @@ +#ifndef STATSYEARJOURNEYS_H +#define STATSYEARJOURNEYS_H + +#include "journeymodel.h" +#include "stats.h" + +class StatsYearJourneys : public Stats +{ +public: + StatsYearJourneys(JourneyModel * journeys); + + void update(); + +private: + JourneyModel * journeys; +}; + +#endif // STATSYEARJOURNEYS_H -- 2.25.1