diff options
author | Jedidiah Barber <contact@jedbarber.id.au> | 2021-07-14 11:49:10 +1200 |
---|---|---|
committer | Jedidiah Barber <contact@jedbarber.id.au> | 2021-07-14 11:49:10 +1200 |
commit | d24f813f3f2a05c112e803e4256b53535895fc98 (patch) | |
tree | 601e6ae9a1cd44bcfdcf91739a5ca36aedd827c9 /src/charts/TimeChart.cpp |
Diffstat (limited to 'src/charts/TimeChart.cpp')
-rw-r--r-- | src/charts/TimeChart.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/charts/TimeChart.cpp b/src/charts/TimeChart.cpp new file mode 100644 index 0000000..c6a60b9 --- /dev/null +++ b/src/charts/TimeChart.cpp @@ -0,0 +1,155 @@ +#include "TimeChart.h" +#include "ChartScene.h" +#include "DataPoint.h" + +const QList<int> TimeChart::TimeUnits = QList<int>() << + 1 << 7 << 30 << 92 << 183; + +TimeChart::TimeChart() +{ +} + +void TimeChart::setDates(const QList<QDateTime>& dates, int period, + int dataDirection) +{ + this->dates = dates; + scene->setDataDirection(dataDirection); + TimeUnit timeUnit = findTimeUnit(period); + QDate thisIntervalStart = getIntervalStart(QDate::currentDate(), timeUnit); + QList<DataPoint> dataSet; + int pointsNum = getDataPointsNum(period, timeUnit); + for(int i = 0; i < pointsNum; i++) + dataSet.append(createDataPoint(thisIntervalStart, timeUnit, i)); + scene->setDataSet(dataSet, getTicksInterval(pointsNum)); +} + +int TimeChart::getDataPointsNum(int period, TimeUnit timeUnit) +{ + return period / TimeUnits.at(timeUnit); +} + +int TimeChart::getTicksInterval(int pointsNum) +{ + int ticksInterval = 1; + while(pointsNum / ticksInterval > MaxXTicks) + ticksInterval *= 2; + return ticksInterval; +} + +TimeChart::TimeUnit TimeChart::findTimeUnit(int period) +{ + for(int unit = Day; unit < (int)TimeUnitsNum; unit++) + if(getDataPointsNum(period, (TimeUnit)unit) <= MaxDataPoints) + return (TimeUnit)unit; + return HalfYear; +} + +QDate TimeChart::getIntervalStart(const QDate& date, TimeUnit timeUnit) +{ + switch(timeUnit) + { + case Day: + return date; + case Week: + return date.addDays(-date.dayOfWeek() + 1); + case Month: + return QDate(date.year(), date.month(), 1); + case Quarter: + return getQuarterStart(date); + case HalfYear: + return getHalfYearStart(date); + default: + return date; + } +} + +QDate TimeChart::getQuarterStart(const QDate& date) +{ + const int quarterLen = 3; + int quarter = (date.month() - 1) / quarterLen; + int startMonth = quarter * quarterLen + 1; + return QDate(date.year(), startMonth, 1); +} + +QDate TimeChart::getHalfYearStart(const QDate& date) +{ + const int secondHalfStart = 7; + int startMonth = date.month() < secondHalfStart ? 1 : secondHalfStart; + return QDate(date.year(), startMonth, 1); +} + +QDate TimeChart::getInterval(const QDate& start, TimeUnit timeUnit, + int num) +{ + switch(timeUnit) + { + case Day: + return start.addDays(num); + case Week: + return start.addDays(7 * num); + case Month: + return start.addMonths(num); + case Quarter: + return start.addMonths(3 * num); + case HalfYear: + return start.addMonths(6 * num); + default: + return start; + } +} + +QDate TimeChart::getIntervalEnd(const QDate& start, TimeUnit timeUnit) +{ + return getInterval(start, timeUnit, 1).addDays(-1); +} + +DataPoint TimeChart::createDataPoint(const QDate& thisIntervalStart, TimeUnit timeUnit, + int intervalIndex) +{ + QDate startDate = getInterval(thisIntervalStart, timeUnit, + scene->getDataDirection() * intervalIndex); + QDate endDate = getIntervalEnd(startDate, timeUnit); + QString xLabel = getDateLabel(startDate, timeUnit); + int value = getCardsNumForDate(startDate, endDate); + QString toolTipLabel = getIntervalLabel(startDate, endDate, timeUnit); + return DataPoint(xLabel, value, toolTipLabel); +} + +QString TimeChart::getDateLabel(const QDate& date, TimeUnit timeUnit) +{ + return date.toString(getIntervalFormat(timeUnit)); +} + +QString TimeChart::getIntervalFormat(TimeUnit timeUnit) +{ + switch(timeUnit) + { + case Day: + case Week: + return "dd.MM"; + case Month: + case Quarter: + case HalfYear: + return "MM/yy"; + default: + return "dd.MM"; + } +} + +QString TimeChart::getIntervalLabel(const QDate& startDate, + const QDate& endDate, TimeUnit timeUnit) +{ + QString startLabel = getDateLabel(startDate, timeUnit); + if(timeUnit == Day || timeUnit == Month) + return startLabel; + return startLabel + " - " + getDateLabel(endDate, timeUnit); +} + +int TimeChart::getCardsNumForDate(const QDate& startDate, const QDate& endDate) +{ + int cardsNum = 0; + foreach(QDateTime date, dates) + if(date.date() >= startDate && date.date() <= endDate) + cardsNum++; + return cardsNum; +} |