Files
Renderive/render_2D/plottable/Frequency_Trace.cpp
T
2026-08-13 06:20:13 +08:00

66 lines
2.7 KiB
C++

#include "Frequency_Trace.h"
#include "Plottable_Real_Time_Data.h"
#include "Heatmap_Utils.h"
#include "../render/Blend2D_Cache.h"
#include <algorithm>
#include <deque>
#include <vector>
namespace renderive {
namespace detail {
namespace {
using Frequency_Trace_History = Plottable_History_Real_Time_Data<std::pair<int, double>, std::deque<std::pair<int, double>>>;
}
struct Frequency_Trace_Control::Impl {
struct Prepare_Buffer {
std::vector<PointF> points;
};
Impl(Frequency_Trace_Control& owner, std::shared_ptr<Time_Axis> time, std::shared_ptr<Axis> value)
: time_axis(std::move(time)), value_axis(std::move(value)), samples(owner) {}
std::shared_ptr<Time_Axis> time_axis;
std::shared_ptr<Axis> value_axis;
Frequency_Trace_History samples;
Prepare_Buffer prepare_buffer;
};
Frequency_Trace_Control::Frequency_Trace_Control(::Scene_Base& scene, const Frequency_Trace_Properties& properties, std::shared_ptr<Time_Axis> time_axis, std::shared_ptr<Axis> value_axis)
: Plottable_State(scene, properties), impl_(std::make_unique<Impl>(*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<std::size_t>(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::prepare_frame(const Prepare_Render_Context& context) {
const auto& view = context.frame.render_state;
const auto& state = render_properties(view);
const auto& samples = view.get(impl_->samples);
auto& output = impl_->prepare_buffer;
output = {};
if (samples.size() < 2)
return;
const Axis_Transform x = impl_->time_axis->transform(view);
const Axis_Transform y = impl_->value_axis->transform(view);
output.points.reserve(samples.size());
for (const auto& [tick, value] : samples)
output.points.push_back(mapped_point(x, tick, y, value));
}
void Frequency_Trace_Control::paint(Painter& painter,
const Paint_Render_Context& context) {
const auto& view = context.frame.render_state;
painter.polyline(impl_->prepare_buffer.points, render_properties(view).pen);
}
}
}