#include "viz/line_plot.h" #include "viz/plot_static.h" #include "implot.h" namespace { template void draw_line(const char* title, const T* xs, const T* ys, int count, float height, bool auto_x, double x_lo_in, double x_hi_in, bool auto_y, double y_lo_in, double y_hi_in) { if (count <= 0) return; double x_lo, x_hi; if (auto_x) { T x_min = xs[0], x_max = xs[0]; for (int i = 1; i < count; i++) { if (xs[i] < x_min) x_min = xs[i]; if (xs[i] > x_max) x_max = xs[i]; } x_lo = static_cast(x_min); x_hi = static_cast(x_max); } else { x_lo = x_lo_in; x_hi = x_hi_in; } if (x_hi - x_lo < 1e-9) x_hi = x_lo + 1.0; double y_lo, y_hi; if (auto_y) { T y_min = ys[0], y_max = ys[0]; for (int i = 1; i < count; i++) { if (ys[i] < y_min) y_min = ys[i]; if (ys[i] > y_max) y_max = ys[i]; } double dy = static_cast(y_max) - static_cast(y_min); if (dy < 1e-9) dy = 1.0; y_lo = static_cast(y_min) - dy * 0.05; y_hi = static_cast(y_max) + dy * 0.05; } else { y_lo = y_lo_in; y_hi = y_hi_in; if (y_hi - y_lo < 1e-9) y_hi = y_lo + 1.0; } const ImVec2 plot_size(-1.0f, height > 0.0f ? height : 200.0f); if (ImPlot::BeginPlot(title, plot_size, plot_static::kPlotFlags)) { ImPlot::SetupAxes(nullptr, nullptr, plot_static::kAxisFlags, plot_static::kAxisFlags); ImPlot::SetupAxisLimits(ImAxis_X1, x_lo, x_hi, ImPlotCond_Always); ImPlot::SetupAxisLimits(ImAxis_Y1, y_lo, y_hi, ImPlotCond_Always); ImPlot::PlotLine("##data", xs, ys, count); ImPlot::EndPlot(); } } } // namespace void line_plot(const char* title, const float* xs, const float* ys, int count, float height) { draw_line(title, xs, ys, count, height, /*auto_x=*/true, 0.0, 0.0, /*auto_y=*/true, 0.0, 0.0); } void line_plot(const char* title, const double* xs, const double* ys, int count, float height) { draw_line(title, xs, ys, count, height, /*auto_x=*/true, 0.0, 0.0, /*auto_y=*/true, 0.0, 0.0); } void line_plot(const char* title, const float* xs, const float* ys, int count, float y_min, float y_max, float height) { draw_line(title, xs, ys, count, height, /*auto_x=*/true, 0.0, 0.0, /*auto_y=*/false, (double)y_min, (double)y_max); } void line_plot(const char* title, const double* xs, const double* ys, int count, double y_min, double y_max, float height) { draw_line(title, xs, ys, count, height, /*auto_x=*/true, 0.0, 0.0, /*auto_y=*/false, y_min, y_max); } void line_plot(const char* title, const float* xs, const float* ys, int count, float x_min, float x_max, float y_min, float y_max, float height) { draw_line(title, xs, ys, count, height, /*auto_x=*/false, (double)x_min, (double)x_max, /*auto_y=*/false, (double)y_min, (double)y_max); } void line_plot(const char* title, const double* xs, const double* ys, int count, double x_min, double x_max, double y_min, double y_max, float height) { draw_line(title, xs, ys, count, height, /*auto_x=*/false, x_min, x_max, /*auto_y=*/false, y_min, y_max); }