* @brief Builds the sortable stats table. */
| 469 | * @brief Builds the sortable stats table. |
| 470 | */ |
| 471 | QString Sessions::HtmlReport::buildSummarySection() const |
| 472 | { |
| 473 | if (m_data.datasets.empty()) |
| 474 | return QString(); |
| 475 | |
| 476 | const bool anyUnits = std::any_of(m_data.datasets.begin(), |
| 477 | m_data.datasets.end(), |
| 478 | [](const DatasetStats& d) { return !d.units.isEmpty(); }); |
| 479 | |
| 480 | QString header = QStringLiteral("<thead><tr>") |
| 481 | + QStringLiteral("<th class=\"align-left\" data-sort-type=\"text\">%1</th>") |
| 482 | .arg(escapeHtml(tr("Parameter"))); |
| 483 | if (anyUnits) { |
| 484 | header += QStringLiteral("<th class=\"align-left\" data-sort-type=\"text\">%1</th>") |
| 485 | .arg(escapeHtml(tr("Units"))); |
| 486 | } |
| 487 | header += QStringLiteral("<th data-sort-type=\"numeric\">%1</th>" |
| 488 | "<th data-sort-type=\"numeric\">%2</th>" |
| 489 | "<th data-sort-type=\"numeric\">%3</th>" |
| 490 | "<th data-sort-type=\"numeric\">%4</th>" |
| 491 | "<th data-sort-type=\"numeric\">%5</th>" |
| 492 | "</tr></thead>") |
| 493 | .arg(escapeHtml(tr("Samples")), |
| 494 | escapeHtml(tr("Minimum")), |
| 495 | escapeHtml(tr("Maximum")), |
| 496 | escapeHtml(tr("Mean")), |
| 497 | escapeHtml(tr("Std. Deviation"))); |
| 498 | |
| 499 | QString body; |
| 500 | for (const auto& ds : m_data.datasets) { |
| 501 | QString fullName = |
| 502 | ds.group.isEmpty() ? ds.title : QStringLiteral("%1 / %2").arg(ds.group, ds.title); |
| 503 | if (!ds.sourceTitle.isEmpty()) |
| 504 | fullName = QStringLiteral("%1 / %2").arg(ds.sourceTitle, fullName); |
| 505 | |
| 506 | const bool numeric = ds.numericSamples > 0; |
| 507 | // code-verify off |
| 508 | const QString dash = QStringLiteral("—"); |
| 509 | // code-verify on |
| 510 | |
| 511 | auto numCell = [&](double v) { |
| 512 | if (!numeric) |
| 513 | return QStringLiteral("<td class=\"numeric dim\">%1</td>").arg(dash); |
| 514 | |
| 515 | return QStringLiteral("<td class=\"numeric\" data-sort-value=\"%1\">%2</td>") |
| 516 | .arg(QString::number(v, 'g', 17), escapeHtml(formatNumber(v))); |
| 517 | }; |
| 518 | |
| 519 | const qint64 totalSamples = ds.numericSamples + ds.stringSamples; |
| 520 | |
| 521 | QString row = QStringLiteral("<tr>") |
| 522 | + QStringLiteral("<td class=\"align-left\">%1</td>").arg(escapeHtml(fullName)); |
| 523 | if (anyUnits) { |
| 524 | row += QStringLiteral("<td class=\"align-left %1\">%2</td>") |
| 525 | .arg(ds.units.isEmpty() ? QStringLiteral("dim") : QString(), |
| 526 | escapeHtml(ds.units.isEmpty() ? dash : ds.units)); |
| 527 | } |
| 528 | row += QStringLiteral("<td class=\"numeric\" data-sort-value=\"%1\">%2</td>") |
nothing calls this directly
no test coverage detected