* @brief Loads downsampled numeric time-series for every parameter. */
| 561 | * @brief Loads downsampled numeric time-series for every parameter. |
| 562 | */ |
| 563 | std::vector<Sessions::DatasetSeries> Sessions::loadChartSeries(QSqlDatabase& db, |
| 564 | int sessionId, |
| 565 | int maxSamples, |
| 566 | const QSet<int>& selectedUniqueIds) |
| 567 | { |
| 568 | std::vector<DatasetSeries> out; |
| 569 | if (!db.isOpen() || sessionId < 0 || maxSamples < 2) |
| 570 | return out; |
| 571 | |
| 572 | Q_ASSERT(maxSamples >= 2); |
| 573 | Q_ASSERT(db.isOpen()); |
| 574 | |
| 575 | const auto metas = loadChartParameters(db, sessionId); |
| 576 | if (metas.empty()) |
| 577 | return out; |
| 578 | |
| 579 | const auto [originNs, _] = loadSessionTimeSpan(db, sessionId); |
| 580 | const auto counts = loadSampleCounts(db, sessionId); |
| 581 | |
| 582 | DSP::AxisData x(16); |
| 583 | DSP::AxisData y(16); |
| 584 | |
| 585 | for (const auto& m : metas) { |
| 586 | if (!selectedUniqueIds.isEmpty() && !selectedUniqueIds.contains(m.uid)) |
| 587 | continue; |
| 588 | |
| 589 | const auto it = counts.find(m.uid); |
| 590 | const qint64 total = (it != counts.end()) ? it->second : 0; |
| 591 | if (total < 2) |
| 592 | continue; |
| 593 | |
| 594 | QSqlQuery rows(db); |
| 595 | rows.setForwardOnly(true); |
| 596 | rows.prepare("SELECT timestamp_ns, final_numeric_value FROM readings " |
| 597 | "WHERE session_id = ? AND unique_id = ? AND is_numeric = 1 " |
| 598 | "ORDER BY timestamp_ns, reading_id"); |
| 599 | rows.bindValue(0, sessionId); |
| 600 | rows.bindValue(1, m.uid); |
| 601 | if (!rows.exec()) { |
| 602 | qWarning() << "[Sessions::ReportData] readings query failed for uid" << m.uid << ":" |
| 603 | << rows.lastError().text(); |
| 604 | continue; |
| 605 | } |
| 606 | |
| 607 | double globalMin = 0.0; |
| 608 | double globalMax = 0.0; |
| 609 | const auto count = readAxisData(rows, originNs, total, x, y, globalMin, globalMax); |
| 610 | if (count < 2) |
| 611 | continue; |
| 612 | |
| 613 | DatasetSeries series; |
| 614 | series.uniqueId = m.uid; |
| 615 | series.totalSamples = total; |
| 616 | series.sourceTitle = m.sourceTitle; |
| 617 | series.group = m.group; |
| 618 | series.title = m.title; |
| 619 | series.units = m.units; |
| 620 | series.minValue = globalMin; |
nothing calls this directly
no test coverage detected