Files
Aethera/render_2D/render_2D/plottable/Waterfall.hpp
T
2026-08-20 23:04:59 +08:00

50 lines
3.5 KiB
C++

#pragma once
#include "../axis/Axis.hpp"
#include "../render/Blend2D_Cache.hpp"
#include "../scene/Render_Scene_2D.hpp"
#include "Hover_Tooltip.hpp"
#include "Plot_Types.hpp"
#include <expected>
#include <memory>
#include <memory_resource>
#include <span>
#include <vector>
namespace aethera::render_2d {
struct Waterfall_Row { Plot_Time_Tick tick{}; std::vector<Plot_Value> values{}; bool operator==(const Waterfall_Row&) const; };
struct Waterfall : Def<Waterfall, Renderable, Tagged_Buffer<Color_Cache, Blend2D_Cache>> {
using Scene_Object = Impl<Render_Scene_2D>; using Frequency_Object = Impl<Frequency_Axis>; using Time_Object = Impl<Time_Axis>;
struct Prop : Prev_Prop, Hover_Tooltip_Properties {
Axis_Range frequency_range{0.0, 10.0}; /* 每行频谱覆盖的频率范围。 */
Axis_Range power_range{0.0, 10.0}; /* 颜色映射使用的功率范围。 */
std::size_t frequency_bin_count{}; /* 目标频率列数;零值使用最新行尺寸。 */
Plot_Partition_Mode partition_mode{Plot_Partition_Mode::automatic}; /* Prepare 子图分块策略。 */
Plot_Partition_Count partition_count{1}; /* fixed 模式分块数。 */
bool visible_range_only{true}; /* 是否按频率轴范围裁剪。 */
Image_Interpolation_Mode interpolation_mode{Image_Interpolation_Mode::nearest}; /* 栅格放大时的图像插值方式。 */
Color_Map color_map{}; /* 功率到颜色的映射。 */
std::vector<Waterfall_Row> rows{}; /* 从旧到新的瀑布行唯一权威集合。 */
bool operator==(const Prop&) const;
};
struct State : Prev_State {
std::size_t row_count{}; /* 当前发布的瀑布行数。 */
std::size_t stored_point_count{}; /* 当前发布的功率点总数。 */
std::size_t rendered_cell_count{}; /* 最近一次 Prepare 生成的色块数。 */
bool operator==(const State&) const;
};
struct Private;
template <typename Object> struct Builder : Prev_Builder<Object> {
using Base = Prev_Builder<Object>;
Builder(Scene_Object* scene, Frequency_Object* frequency_axis, Time_Object* time_axis);
[[nodiscard]] std::expected<std::unique_ptr<Object>, Dependency_Graph_Error> build();
private:
Scene_Object* scene{}; /* 不拥有的所属 Scene;生命周期必须覆盖 Waterfall。 */
Frequency_Object* frequency_axis{}; /* 不拥有的频率轴;生命周期必须覆盖 Waterfall。 */
Time_Object* time_axis{}; /* 不拥有的时间轴;生命周期必须覆盖 Waterfall。 */
};
void append_row(Plot_Time_Tick tick, std::span<const Plot_Value> values); void append_row(Plot_Time_Tick tick, std::pmr::vector<Plot_Value>&& values); void append_row(Time_Of_Day time, std::span<const Plot_Value> values); void append_row(Time_Of_Day time, std::pmr::vector<Plot_Value>&& values);
template <typename Values> void append_row(Plot_Time_Tick tick, const Values& values); template <typename Values> void append_row(Time_Of_Day time, const Values& values);
[[nodiscard]] std::size_t row_count() const; [[nodiscard]] std::size_t stored_point_count() const; [[nodiscard]] std::size_t rendered_cell_count() const;
};
}
#include "Waterfall.ipp"