feat(plot): nice-number ticks, axes, grid, traces, cursors, measurement queries

This commit is contained in:
Martino Ferrari committed 2026-09-27 22:21:22 +02:00
1 parent b4e88fe0c1
commit 93fc06f050
18 files changed
+1582

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
#include "harness.hpp"
#include <plot/plot/measure.hpp>
#include <plot/data/array_series.hpp>
#include <algorithm>
#include <chrono>
#include <cmath>
#include <vector>
PLOT_TEST(measurement_over_interval_matches_direct_computation) {
std::vector<f32> y; for (int i = 0; i < 1000; ++i) y.push_back(f32(std::sin(static_cast<double>(i) * 0.01)));
plot::data::ArraySeries s(std::move(y), 0.0, 1.0);
const auto m = plot::Measure::evaluate(s, 100, 800);
double sum = 0, sumsq = 0, integral = 0; float lo = 1e30f, hi = -1e30f;
for (u64 i = 100; i < 800; ++i) {
const double v = std::sin(static_cast<double>(i) * 0.01);
sum += v; sumsq += v * v; integral += v; // dx == 1
lo = std::min(lo, float(v)); hi = std::max(hi, float(v));
}
const double n = 700;
PLOT_CHECK_NEAR(m.mean, sum / n, 1e-5);
PLOT_CHECK_NEAR(m.rms, std::sqrt(sumsq / n), 1e-5);
PLOT_CHECK_NEAR(m.integral, integral, 1e-3);
PLOT_CHECK_NEAR(m.ymin, lo, 1e-6);
PLOT_CHECK_NEAR(m.ymax, hi, 1e-6);
PLOT_CHECK_NEAR(m.dx, 699.0, 1e-9);
}
PLOT_TEST(measurement_uses_pyramid_not_scan) {
// Guard against a future regression that linear-scans the series: a huge
// series must evaluate a 1-sample-wide interval in well under a millisecond.
std::vector<f32> y(1u << 22, 1.0f); // 4M samples
plot::data::ArraySeries s(std::move(y), 0.0, 1.0);
const auto t0 = std::chrono::steady_clock::now();
for (int i = 0; i < 1000; ++i) (void)plot::Measure::evaluate(s, 1'000'000, 1'000'001);
const auto us = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - t0).count();
PLOT_CHECK(us < 50'000); // 1000 evals in < 50 ms
}
PLOT_TEST(empty_and_single_sample_intervals_are_valid_false) {
std::vector<f32> y{3.0f};
plot::data::ArraySeries s(std::move(y), 0.0, 1.0);
PLOT_CHECK(!plot::Measure::evaluate(s, 0, 0).valid);
PLOT_CHECK(!plot::Measure::evaluate(s, 1, 1).valid);
}