#include "Frequency_Trace.h" #include "Plottable_Real_Time_Data.h" #include "Heatmap_Utils.h" #include "../render/Blend2D_Cache.h" #include #include #include namespace renderive { namespace detail { namespace { using Frequency_Trace_History = Plottable_History_Real_Time_Data, std::deque>>; } struct Frequency_Trace_Control::Impl { Impl(Frequency_Trace_Control& owner, std::shared_ptr time, std::shared_ptr value) : time_axis(std::move(time)), value_axis(std::move(value)), samples(owner) {} std::shared_ptr time_axis; std::shared_ptr value_axis; Frequency_Trace_History samples; }; Frequency_Trace_Control::Frequency_Trace_Control(Plot_Core& plot, const Frequency_Trace_Properties& properties, std::shared_ptr time_axis, std::shared_ptr value_axis) : Plottable_State(plot, properties), impl_(std::make_unique(*this, std::move(time_axis), std::move(value_axis))) {} Frequency_Trace_Control::~Frequency_Trace_Control() = default; void Frequency_Trace_Control::append_sample(int tick, double value) { const int limit = std::max(2, impl_->time_axis->get<&Time_Axis_Properties::visible_count>()); impl_->samples.update({tick, value}, static_cast(limit)); changed(); } void Frequency_Trace_Control::append_sample(Time_Of_Day time, double value) { append_sample(impl_->time_axis->append_time(time), value); } std::size_t Frequency_Trace_Control::sample_count() const { return impl_->samples.size(); } std::size_t Frequency_Trace_Control::rendered_point_count() const { const std::size_t count = sample_count(); return count >= 2 ? count : 0; } void Frequency_Trace_Control::publish() { publish_properties(); } void Frequency_Trace_Control::paint(Painter& painter, const Render_State_View& view) { const auto& state = render_properties(view); const auto& samples = view.get(impl_->samples); if(samples.size() < 2) return; const Axis_Transform x = impl_->time_axis->transform(view); const Axis_Transform y = impl_->value_axis->transform(view); std::vector points; points.reserve(samples.size()); for(const auto& [tick, value] : samples) points.push_back(mapped_point(x, tick, y, value)); painter.polyline(points, state.pen); } } }