74 lines
2.9 KiB
C++
74 lines
2.9 KiB
C++
#include "Frequency_Trace.h"
|
|
#include "Plottable_Real_Time_Data.h"
|
|
#include "Heatmap_Utils.h"
|
|
#include "../render/Blend2D_Cache.h"
|
|
#include "../renderable/Renderable_p.h"
|
|
#include <algorithm>
|
|
#include <deque>
|
|
#include <optional>
|
|
#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 : Renderable::Impl {
|
|
struct Prepare_Buffer {
|
|
std::vector<PointF> points;
|
|
};
|
|
Impl(renderive_Owner<Time_Axis> time, renderive_Owner<Axis> value)
|
|
: time_axis(std::move(time)), value_axis(std::move(value)) {}
|
|
renderive_Owner<Time_Axis> time_axis;
|
|
renderive_Owner<Axis> value_axis;
|
|
std::optional<Frequency_Trace_History> samples;
|
|
Prepare_Buffer prepare_buffer;
|
|
};
|
|
Frequency_Trace_Control::Frequency_Trace_Control(const Frequency_Trace_Properties& properties, renderive_Owner<Time_Axis> time_axis, renderive_Owner<Axis> value_axis)
|
|
: Plottable_State(properties, std::make_unique<Impl>(
|
|
std::move(time_axis), std::move(value_axis))) {
|
|
d_func<Impl>().samples.emplace(*this);
|
|
}
|
|
Frequency_Trace_Control::~Frequency_Trace_Control() = default;
|
|
void Frequency_Trace_Control::append_sample(int tick, double value) {
|
|
auto& d = d_func<Impl>();
|
|
const int limit = std::max(2, d.time_axis->get<&Time_Axis_Properties::visible_count>());
|
|
d.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(d_func<Impl>().time_axis->append_time(time), value);
|
|
}
|
|
std::size_t Frequency_Trace_Control::sample_count() const {
|
|
return d_func<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);
|
|
auto& d = d_func<Impl>();
|
|
const auto& samples = view.get(*d.samples);
|
|
auto& output = d.prepare_buffer;
|
|
output = {};
|
|
if (samples.size() < 2)
|
|
return;
|
|
const Axis_Transform x = d.time_axis->transform(view);
|
|
const Axis_Transform y = d.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(d_func<Impl>().prepare_buffer.points,
|
|
render_properties(view).pen);
|
|
}
|
|
}
|
|
}
|