#include "barseriesadapter.h" #include BarSeriesAdapter::BarSeriesAdapter(QObject *parent) : QObject(parent) { } LogsModel *BarSeriesAdapter::logsModel() const { return m_logsModel; } void BarSeriesAdapter::setLogsModel(LogsModel *logsModel) { if (m_logsModel != logsModel) { m_logsModel = logsModel; emit logsModelChanged(); update(); connect(logsModel, &LogsModel::logEntryAdded, this, &BarSeriesAdapter::logEntryAdded); } } QtCharts::QAbstractBarSeries *BarSeriesAdapter::barSeries() const { return m_barSeries; } void BarSeriesAdapter::setBarSeries(QtCharts::QAbstractBarSeries *barSeries) { if (m_barSeries != barSeries) { m_barSeries = barSeries; emit barSeriesChanged(); update(); } } BarSeriesAdapter::Interval BarSeriesAdapter::interval() const { return m_interval; } void BarSeriesAdapter::setInterval(BarSeriesAdapter::Interval interval) { if (m_interval != interval) { m_interval = interval; emit intervalChanged(); } } void BarSeriesAdapter::update() { if (!m_barSeries || !m_logsModel) { return; } m_set = new QtCharts::QBarSet(m_barSeries->name()); m_barSeries->append(m_set); for (int i = 0; i < m_logsModel->rowCount(); i++) { LogEntry *entry = m_logsModel->get(i); qDebug() << "have entry" << entry->timestamp().toString(); } } void BarSeriesAdapter::ensureSlots(const QDateTime &start, const QDateTime &end) { if (!m_barSeries || !m_logsModel) { return; } QDateTime startTime = start; switch (m_interval) { case IntervalMinutes: startTime.setTime(QTime(startTime.time().hour(), startTime.time().minute())); break; case IntervalHours: startTime.setTime(QTime(startTime.time().hour(), 0)); break; case IntervalDays: startTime.setTime(QTime(0, 0)); break; } QDateTime endTime = end; if (!endTime.isValid()) { endTime = QDateTime::currentDateTime(); } endTime.setTime(QTime(endTime.time().hour(), endTime.time().minute())); QDateTime oldestExistingSlot; if (m_timeslots.isEmpty()) { oldestExistingSlot = endTime; } else { oldestExistingSlot = m_timeslots.first().datetime; } if (startTime < oldestExistingSlot) { long duration = oldestExistingSlot.toMSecsSinceEpoch() - startTime.toMSecsSinceEpoch(); long slotCount = duration / (m_interval * 1000); qDebug() << "Need" << slotCount << "new slots appended"; for (int i = 0; i < slotCount; i++) { QDateTime slotTime = oldestExistingSlot.addSecs(-m_interval * (i + 1)); // qDebug() << "Adding" << slotTime.toString(); TimeSlot timeslot; timeslot.datetime = slotTime; m_set->insert(0, 0); m_timeslots.prepend(timeslot); } } QDateTime newestExistingSlot; if (m_timeslots.isEmpty()) { newestExistingSlot = startTime; } else { newestExistingSlot = m_timeslots.last().datetime; } if (endTime > newestExistingSlot) { long duration = endTime.toMSecsSinceEpoch() - newestExistingSlot.toMSecsSinceEpoch(); long slotCount = duration / (m_interval * 1000); // qDebug() << "Need" << slotCount << "new slots prepended"; for (int i = 0; i < slotCount; i++) { QDateTime slotTime = newestExistingSlot.addSecs(m_interval * (i + 1)); TimeSlot timeslot; timeslot.datetime = slotTime; m_set->append(0); m_timeslots.append(timeslot); } } if (m_timeslots.isEmpty()) { // qDebug() << "Need to initialize list with 1 entry"; TimeSlot timeslot; timeslot.datetime = startTime; m_set->append(0); m_timeslots.append(timeslot); } qDebug() << "Ensuring slots from" << start << "to" << end << "oldest" << oldestExistingSlot << "newest" << newestExistingSlot; } void BarSeriesAdapter::logEntryAdded(LogEntry *entry) { qDebug() << "****" << m_barSeries << m_logsModel; if (!m_barSeries || !m_logsModel) { return; } ensureSlots(QDateTime::fromMSecsSinceEpoch(qMin(m_logsModel->startTime().toMSecsSinceEpoch(), entry->timestamp().toMSecsSinceEpoch())), QDateTime::fromMSecsSinceEpoch(qMax(m_logsModel->endTime().toMSecsSinceEpoch(), entry->timestamp().toMSecsSinceEpoch()))); QDateTime timestamp = entry->timestamp(); QDateTime timeSlotStart = timestamp; switch (m_interval) { case IntervalMinutes: timeSlotStart.setTime(QTime(timestamp.time().hour(), timestamp.time().minute())); break; case IntervalHours: timeSlotStart.setTime(QTime(timestamp.time().hour(), 0)); break; case IntervalDays: timeSlotStart.setTime(QTime(0, 0)); break; } // qDebug() << "Item time:" << timeSlotStart; TimeSlot first = m_timeslots.first(); TimeSlot last = m_timeslots.last(); long slotIdx = (timeSlotStart.toMSecsSinceEpoch() - first.datetime.toMSecsSinceEpoch()) / (m_interval * 1000); qDebug() << "first" << first.datetime.toString(); qDebug() << "last" << last.datetime.toString(); qDebug() << "this" << timeSlotStart.toString(); qDebug() << "idx" << slotIdx; m_timeslots[slotIdx].entries.append(entry); m_set->replace(slotIdx, m_timeslots[slotIdx].value()); // qDebug() << "Adding entry" << entry->timestamp() << "timestlot" << timeSlotStart << "at" << slotIdx << "value" << m_timeslots[slotIdx].value(); // if (!m_timeslots.contains(timeSlotStart)) { // TimeSlot timeslot; // timeslot.startTime = timeSlotStart; // } // TimeSlot timeslot = m_timeslots.value(timeSlotStart); // timeslot.entries.append(entry); } qreal BarSeriesAdapter::TimeSlot::value() const { qreal value = 0; foreach (LogEntry *entry, entries) { value += entry->value().toDouble(); } if (entries.count() > 1) { value /= entries.count(); } return value; }