#include "TimeChart.h" #include "ChartScene.h" #include "DataPoint.h" const QList TimeChart::TimeUnits = QList() << 1 << 7 << 30 << 92 << 183; TimeChart::TimeChart() { } void TimeChart::setDates(const QList& dates, int period, int dataDirection) { this->dates = dates; scene->setDataDirection(dataDirection); TimeUnit timeUnit = findTimeUnit(period); QDate thisIntervalStart = getIntervalStart(QDate::currentDate(), timeUnit); QList 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; }