120 lines
5.1 KiB
C++
120 lines
5.1 KiB
C++
#pragma once
|
|
#include <cstddef>
|
|
#include <memory_resource>
|
|
#include <span>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include "../architecture/Update_Completion.h"
|
|
#include "../base/Memory.h"
|
|
#include "../base/Time_Of_Day.h"
|
|
#include "../primitive/Color_Bar.h"
|
|
#include "../primitive/Color_Scale.h"
|
|
#include "Hover_Tooltip.h"
|
|
#include "Interpolation.h"
|
|
namespace renderive {
|
|
struct Waterfall_Private;
|
|
class Frequency_Axis;
|
|
class Time_Axis;
|
|
/// @brief Policy for consuming pending waterfall rows.
|
|
enum class Waterfall_Row_Update_Policy : std::uint8_t {
|
|
/// @brief Consume every currently pending row in submit order.
|
|
All_Pending,
|
|
/// @brief Consume only the latest pending row and drop older pending rows.
|
|
Latest_Only,
|
|
/// @brief Consume only the latest row while enforcing a minimum interval between commits.
|
|
Rate_Limited_Latest
|
|
};
|
|
/// @brief 瀑布图图元,按时间行保存二维频谱强度。
|
|
class LIB_DECL Waterfall : public Renderable, public Hover_Tooltip_Mixin<Waterfall> {
|
|
public:
|
|
/// @brief 创建瀑布图图元。
|
|
Waterfall();
|
|
/// @brief 写入指定 tick 对应的一行频谱数据。
|
|
void append_row(int tick, std::span<const double> data);
|
|
/// @brief 移动写入指定 tick 对应的一行频谱数据。
|
|
void append_row(int tick, std::pmr::vector<double>&& data);
|
|
/// @brief 写入指定时间对应的一行频谱数据。
|
|
void append_row(Time_Of_Day time, std::span<const double> data);
|
|
/// @brief 移动写入指定时间对应的一行频谱数据。
|
|
void append_row(Time_Of_Day time, std::pmr::vector<double>&& data);
|
|
/// @brief 提交指定 tick 对应的一行频谱数据并返回完成票据。
|
|
Update_Ticket submit_data(int tick, std::span<const double> data);
|
|
/// @brief 移动提交指定 tick 对应的一行频谱数据并返回完成票据。
|
|
Update_Ticket submit_data(int tick, std::pmr::vector<double>&& data);
|
|
/// @brief 用 writer 填充并写入指定 tick 对应的一行频谱数据。
|
|
template <typename Writer>
|
|
void write_data(int tick, std::size_t count, Writer&& writer) {
|
|
std::pmr::vector<double> values(memory_resource(Memory_Domain::Waterfall));
|
|
values.resize(count);
|
|
std::forward<Writer>(writer)(std::span<double>(values.data(), values.size()));
|
|
append_row(tick, std::move(values));
|
|
}
|
|
/// @brief 绑定频率轴。
|
|
PROP(std::shared_ptr<Frequency_Axis>, frequency_axis)
|
|
/// @brief 绑定时间轴。
|
|
PROP(std::shared_ptr<Time_Axis>, time_axis)
|
|
/// @brief 频率数据范围。
|
|
PROP(Range, frequency_range)
|
|
/// @brief 功率数据范围。
|
|
PROP(Range, power_range)
|
|
/// @brief 每行频率采样点数。
|
|
PROP(int, frequency_bin_count)
|
|
/// @brief 是否只生成当前可见频率范围。
|
|
PROP(bool, visible_range_only)
|
|
/// @brief 图像缩放插值模式。
|
|
PROP(Image_Interpolation_Mode, interpolation_mode)
|
|
/// @brief 瀑布图增量更新模式。
|
|
PROP(Waterfall_Row_Update_Policy, row_update_policy)
|
|
/// @brief Timed_Latest 模式下的最小更新间隔。
|
|
PROP(int, latest_row_min_interval_ms)
|
|
/// @brief 颜色映射表。
|
|
PROP(Color_Map, color_map)
|
|
/// @brief 返回构造时启用的颜色条。
|
|
std::shared_ptr<Color_Bar> get_color_bar() const;
|
|
struct Builder;
|
|
private:
|
|
Waterfall_Private* d();
|
|
Render_Object_Owner create_render_data() override;
|
|
Render_Object_Owner create_render_state() override;
|
|
Render_Object_Owner create_input_data() override;
|
|
};
|
|
struct Waterfall_Prop {
|
|
std::weak_ptr<Frequency_Axis> frequency_axis{};
|
|
std::weak_ptr<Time_Axis> time_axis{};
|
|
Range frequency_range{0, 10};
|
|
int frequency_bin_count{};
|
|
bool visible_range_only = true;
|
|
Image_Interpolation_Mode interpolation_mode = Image_Interpolation_Mode::Nearest;
|
|
Waterfall_Row_Update_Policy row_update_policy = Waterfall_Row_Update_Policy::All_Pending;
|
|
int latest_row_min_interval_ms = 10;
|
|
Color_Scale color_scale{Color_Map{}, Range{0, 10}};
|
|
bool color_bar_enabled = false;
|
|
};
|
|
/// @brief 瀑布图构造器。
|
|
struct LIB_DECL Waterfall::Builder : Waterfall_Prop {
|
|
PROP_B(std::shared_ptr<Frequency_Axis>, frequency_axis)
|
|
PROP_B(std::shared_ptr<Time_Axis>, time_axis)
|
|
PROP_B(Range, frequency_range)
|
|
Builder& set_power_range(Range value) {
|
|
color_scale.set_range(value);
|
|
return *this;
|
|
}
|
|
PROP_B(int, frequency_bin_count)
|
|
PROP_B(bool, visible_range_only)
|
|
PROP_B(Image_Interpolation_Mode, interpolation_mode)
|
|
PROP_B(Waterfall_Row_Update_Policy, row_update_policy)
|
|
PROP_B(int, latest_row_min_interval_ms)
|
|
Builder& set_color_map(Color_Map value) {
|
|
color_scale.set_color_map(std::move(value));
|
|
return *this;
|
|
}
|
|
PROP_B(Color_Scale, color_scale)
|
|
PROP_B(bool, color_bar_enabled)
|
|
/// 创建瀑布图构造器。
|
|
Builder(std::shared_ptr<Renderable> parent, std::shared_ptr<Frequency_Axis> frequency_axis, std::shared_ptr<Time_Axis> time_axis);
|
|
/// 构建并返回瀑布图对象。
|
|
std::shared_ptr<Waterfall> build();
|
|
std::shared_ptr<Renderable> parent{};
|
|
};
|
|
} // namespace renderive
|