61 lines
2.6 KiB
C++
61 lines
2.6 KiB
C++
#include "Frequency_Trace.h"
|
|
#include "../render/Blend2D_Cache.h"
|
|
#include <algorithm>
|
|
#include <deque>
|
|
#include <vector>
|
|
namespace renderive {
|
|
namespace detail {
|
|
namespace {
|
|
struct Frequency_Trace_Runtime_Base {};
|
|
struct Frequency_Trace_Runtime {
|
|
std::deque<std::pair<int, double>> samples;
|
|
};
|
|
using Frequency_Trace_Runtime_State = Double_State_Strategy<Frequency_Trace_Runtime_Base, Frequency_Trace_Runtime>;
|
|
}
|
|
struct Frequency_Trace_Control::Impl {
|
|
Impl(std::shared_ptr<Time_Axis> time, std::shared_ptr<Axis> value) : time_axis(std::move(time)), value_axis(std::move(value)) {}
|
|
std::shared_ptr<Time_Axis> time_axis;
|
|
std::shared_ptr<Axis> value_axis;
|
|
Frequency_Trace_Runtime_State runtime;
|
|
};
|
|
Frequency_Trace_Control::Frequency_Trace_Control(Plot_Core& plot, const Frequency_Trace_Properties& properties, std::shared_ptr<Time_Axis> time_axis, std::shared_ptr<Axis> value_axis)
|
|
: Plottable_State(plot, properties), impl_(std::make_unique<Impl>(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->visible_time_point_count());
|
|
impl_->runtime.update([tick, value, limit](Frequency_Trace_Runtime& runtime) {
|
|
runtime.samples.emplace_back(tick, value);
|
|
while(runtime.samples.size() > static_cast<std::size_t>(limit))
|
|
runtime.samples.pop_front();
|
|
});
|
|
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_->runtime.read([](const Frequency_Trace_Runtime& runtime) { return runtime.samples.size(); });
|
|
}
|
|
std::size_t Frequency_Trace_Control::rendered_point_count() const {
|
|
return sample_count() >= 2 ? sample_count() : 0;
|
|
}
|
|
void Frequency_Trace_Control::publish() {
|
|
publish_properties();
|
|
impl_->runtime.publish();
|
|
}
|
|
void Frequency_Trace_Control::paint(Painter& painter) {
|
|
const auto state = render_properties();
|
|
const auto runtime = impl_->runtime.render_use_state();
|
|
if(runtime.samples.size() < 2)
|
|
return;
|
|
const Axis_Transform x = impl_->time_axis->transform();
|
|
const Axis_Transform y = impl_->value_axis->transform();
|
|
std::vector<PointF> points;
|
|
points.reserve(runtime.samples.size());
|
|
for(const auto& [tick, value] : runtime.samples)
|
|
points.push_back({x.coord_to_pixel(tick), y.coord_to_pixel(value)});
|
|
painter.polyline(points, state.pen);
|
|
}
|
|
}
|
|
}
|