summaryrefslogtreecommitdiff
path: root/src/charts/TimeChart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts/TimeChart.cpp')
-rw-r--r--src/charts/TimeChart.cpp155
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;
+}