实时分块控制

This commit is contained in:
2026-08-26 21:32:17 +08:00
parent ef9e36c4b9
commit c50afae9c5
24 changed files with 621 additions and 203 deletions
+13 -14
View File
@@ -606,7 +606,7 @@ std::shared_ptr<Plot> make_spectrum_plot() {
constexpr Size canvas{720, 420};
auto frequency = make_frequency_axis();
auto vertical = make_numeric_axis(Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-110.0, 0.0});
auto spectrum = *Impl<Spectrum>::Builder(frequency.get(), vertical.get())
auto spectrum = *Impl<Spectrum>::Builder(frequency.get(), vertical.get(), 4u)
.set(&Spectrum::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set(&Spectrum::Prop::max_hold_visible, true)
.build();
@@ -644,7 +644,6 @@ std::shared_ptr<Plot> make_spectrum_plot() {
Prop_Field<&Spectrum::Prop::visible_range_only, "visible_range_only", "Restricts sample preparation to the frequency range currently visible on the axis.">,
Prop_Field<&Spectrum::Prop::frequency_range, "frequency_range", "Maps the complete input sample span onto frequency coordinates.">,
Prop_Field<&Spectrum::Prop::sweep_frequency_range, "sweep_frequency_range", "Defines the frequency interval rendered as the sweep region.">,
Prop_Field<&Spectrum::Prop::partition_mode, "partition_mode", "Selects how samples are divided between preparation tasks.">,
Prop_Field<&Spectrum::Prop::interpolation_mode, "interpolation_mode", "Selects the interpolation algorithm used between adjacent spectrum samples.">,
Prop_Field<&Spectrum::Prop::max_brush, "max_brush", "Fill brush used for the maximum-hold area.">,
Prop_Field<&Spectrum::Prop::current_brush, "current_brush", "Fill brush used for the current spectrum area.">,
@@ -670,7 +669,7 @@ std::shared_ptr<Plot> make_frequency_trace_plot() {
Axis_Orientation::horizontal, {64.0, 370.0}, 620.0);
auto vertical = make_numeric_axis(
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-1.2, 1.2});
auto trace = *Impl<Frequency_Trace>::Builder(time.get(), vertical.get()).build();
auto trace = *Impl<Frequency_Trace>::Builder(time.get(), vertical.get(), 4u).build();
auto selection = selection_overlay(time.get(), vertical.get());
auto scene = *Scene_2D::Builder{}
.set(&Render_Scene_2D::Prop::viewport, canvas)
@@ -696,8 +695,7 @@ std::shared_ptr<Plot> make_frequency_trace_plot() {
};
auto view = make_scene_view<
Prop_Field<&Frequency_Trace::Prop::partition_count, "partition_count", "Number of partitions used to prepare the time-ordered trace.">,
Prop_Field<&Frequency_Trace::Prop::pen, "pen", "Stroke style used to draw the frequency trace.">,
Prop_Field<&Frequency_Trace::Prop::partition_mode, "partition_mode", "Selects how trace samples are divided between preparation tasks.">>(
Prop_Field<&Frequency_Trace::Prop::pen, "pen", "Stroke style used to draw the frequency trace.">>(
*trace, *scene, std::move(update), std::move(time), std::move(vertical), std::move(trace), std::move(selection));
return std::make_shared<Plot>(std::move(scene), std::move(view));
}
@@ -706,7 +704,7 @@ std::shared_ptr<Plot> make_sweep_spectrum_plot() {
auto frequency = make_frequency_axis();
auto vertical = make_numeric_axis(
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-110.0, 0.0});
auto sweep = *Impl<Sweep_Spectrum>::Builder(frequency.get(), vertical.get())
auto sweep = *Impl<Sweep_Spectrum>::Builder(frequency.get(), vertical.get(), 4u)
.set(&Sweep_Spectrum::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set(&Sweep_Spectrum::Prop::bins_per_block, std::size_t{8})
.set(&Sweep_Spectrum::Prop::block_count, std::size_t{64})
@@ -743,7 +741,6 @@ std::shared_ptr<Plot> make_sweep_spectrum_plot() {
Prop_Field<&Sweep_Spectrum::Prop::partition_count, "partition_count", "Number of partitions used during sweep preparation.">,
Prop_Field<&Sweep_Spectrum::Prop::visible_range_only, "visible_range_only", "Restricts preparation to the frequency interval visible on the axis.">,
Prop_Field<&Sweep_Spectrum::Prop::frequency_range, "frequency_range", "Maps the complete sweep span onto frequency coordinates.">,
Prop_Field<&Sweep_Spectrum::Prop::partition_mode, "partition_mode", "Selects how sweep blocks are divided between preparation tasks.">,
Prop_Field<&Sweep_Spectrum::Prop::pen, "pen", "Stroke style used for the completed sweep curve.">,
Prop_Field<&Sweep_Spectrum::Prop::current_frequency_pen, "current_frequency_pen", "Stroke style used for the current sweep-frequency indicator.">,
Prop_Field<&Sweep_Spectrum::Prop::interpolation_mode, "interpolation_mode", "Selects interpolation between adjacent sweep bins.">>(
@@ -755,7 +752,8 @@ std::shared_ptr<Plot> make_afterglow_plot() {
auto frequency = make_frequency_axis();
auto vertical = make_numeric_axis(
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-110.0, 0.0});
auto afterglow = *Impl<Afterglow>::Builder(frequency.get(), vertical.get())
auto afterglow = *Impl<Afterglow>::Builder(
frequency.get(), vertical.get(), Plot_Partition_Grid{4, 3})
.set(&Afterglow::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set(&Afterglow::Prop::power_range, Axis_Range{-110.0, 0.0})
.set(&Afterglow::Prop::power_point_size, 96)
@@ -784,12 +782,11 @@ std::shared_ptr<Plot> make_afterglow_plot() {
auto view = make_scene_view<
Prop_Field<&Afterglow::Prop::frequency_point_size, "frequency_point_size", "Number of frequency cells allocated across each afterglow row.">,
Prop_Field<&Afterglow::Prop::power_point_size, "power_point_size", "Number of power cells allocated along the vertical afterglow range.">,
Prop_Field<&Afterglow::Prop::partition_count, "partition_count", "Number of partitions used to prepare afterglow history.">,
Prop_Field<&Afterglow::Prop::partition_grid, "partition_grid", "Framebuffer partition grid expressed as column count by row count.">,
Prop_Field<&Afterglow::Prop::interpolate, "interpolate", "Enables interpolation when mapping samples into the afterglow grid.">,
Prop_Field<&Afterglow::Prop::attenuation_rate, "attenuation_rate", "Controls how quickly historical energy fades between updates.">,
Prop_Field<&Afterglow::Prop::frequency_range, "frequency_range", "Maps input samples onto the afterglow frequency axis.">,
Prop_Field<&Afterglow::Prop::power_range, "power_range", "Defines the minimum and maximum power represented by the color grid.">,
Prop_Field<&Afterglow::Prop::partition_mode, "partition_mode", "Selects how afterglow cells are divided between preparation tasks.">,
Prop_Field<&Afterglow::Prop::color_map, "color_map", "Maps accumulated energy values to rendered colors.">>(
*afterglow, *scene, std::move(update), std::move(frequency), std::move(vertical), std::move(afterglow), std::move(selection));
return std::make_shared<Plot>(std::move(scene), std::move(view));
@@ -799,7 +796,8 @@ std::shared_ptr<Plot> make_waterfall_plot() {
auto frequency = make_frequency_axis();
auto time = make_time_axis(
Axis_Orientation::vertical, {64.0, 370.0}, -320.0);
auto waterfall = *Impl<Waterfall>::Builder(frequency.get(), time.get())
auto waterfall = *Impl<Waterfall>::Builder(
frequency.get(), time.get(), Plot_Partition_Grid{4, 3})
.set(&Waterfall::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set(&Waterfall::Prop::power_range, Axis_Range{-110.0, 0.0})
.build();
@@ -837,11 +835,10 @@ std::shared_ptr<Plot> make_waterfall_plot() {
Prop_Field<&Waterfall::Prop::tooltip_text_pen, "tooltip_text_pen", "Pen used to draw tooltip text and its foreground color.">,
Prop_Field<&Waterfall::Prop::tooltip_background_brush, "tooltip_background_brush", "Brush used to fill the tooltip background panel.">,
Prop_Field<&Waterfall::Prop::frequency_bin_count, "frequency_bin_count", "Number of frequency bins expected in each waterfall row.">,
Prop_Field<&Waterfall::Prop::partition_count, "partition_count", "Number of partitions used to prepare waterfall cells.">,
Prop_Field<&Waterfall::Prop::partition_grid, "partition_grid", "Framebuffer partition grid expressed as column count by row count.">,
Prop_Field<&Waterfall::Prop::visible_range_only, "visible_range_only", "Restricts preparation to frequencies visible on the current axis.">,
Prop_Field<&Waterfall::Prop::frequency_range, "frequency_range", "Maps row samples onto waterfall frequency coordinates.">,
Prop_Field<&Waterfall::Prop::power_range, "power_range", "Defines the power interval mapped through the waterfall color map.">,
Prop_Field<&Waterfall::Prop::partition_mode, "partition_mode", "Selects how waterfall rows are divided between preparation tasks.">,
Prop_Field<&Waterfall::Prop::interpolation_mode, "interpolation_mode", "Selects interpolation when samples are mapped to raster cells.">,
Prop_Field<&Waterfall::Prop::color_map, "color_map", "Maps sample power values to waterfall colors.">>(
*waterfall, *scene, std::move(update), std::move(frequency), std::move(time), std::move(waterfall), std::move(selection));
@@ -853,7 +850,8 @@ std::shared_ptr<Plot> make_constellation_plot() {
Axis_Orientation::horizontal, {64.0, 370.0}, 620.0, {-1.2, 1.2});
auto vertical = make_numeric_axis(
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-1.2, 1.2});
auto constellation = *Impl<Constellation_Diagram>::Builder(horizontal.get(), vertical.get())
auto constellation = *Impl<Constellation_Diagram>::Builder(
horizontal.get(), vertical.get(), 4u)
.set(&Constellation_Diagram::Prop::i_range, Axis_Range{-1.2, 1.2})
.set(&Constellation_Diagram::Prop::q_range, Axis_Range{-1.2, 1.2})
.build();
@@ -891,6 +889,7 @@ std::shared_ptr<Plot> make_constellation_plot() {
raw->template mark_dirty<Prepare_Data_Tag>();
};
auto view = make_scene_view<
Prop_Field<&Constellation_Diagram::Prop::partition_count, "partition_count", "Number of partitions used to render received constellation points.">,
Prop_Field<&Constellation_Diagram::Prop::point_lifetime_ms, "point_lifetime_ms", "Time in milliseconds that an appended constellation point remains visible.">,
Prop_Field<&Constellation_Diagram::Prop::type, "type", "Selects the modulation constellation used to generate reference anchors.">,
Prop_Field<&Constellation_Diagram::Prop::phase_offset_radians, "phase_offset_radians", "Rotates constellation points and anchors by the specified phase angle.">,
+2 -1
View File
@@ -231,6 +231,7 @@ constexpr std::string_view protocol_editor() {
if constexpr (std::same_as<Type, render_2d::Size> || std::same_as<Type, render_3d::Extent>) return "size";
if constexpr (std::same_as<Type, render_2d::Rect_F>) return "rect";
if constexpr (std::same_as<Type, render_2d::Axis_Range>) return "range";
if constexpr (std::same_as<Type, render_2d::Plot_Partition_Grid>) return "partition-grid";
if constexpr (std::same_as<Type, render_2d::Pen>) return "pen";
if constexpr (std::same_as<Type, render_2d::Brush>) return "brush";
if constexpr (std::same_as<Type, render_2d::Font>) return "font";
@@ -259,7 +260,7 @@ inline std::string_view protocol_field_label(std::string_view key) {
{"visible_count", "可见数量"}, {"tick_label_spacing_px", "刻度文字间距"},
{"estimated_label_width_px", "预计标签宽度"}, {"format", "时间格式"},
{"newest_at_start", "最新数据置于起点"}, {"center_frequency", "中心频率"},
{"partition_count", "分区数量"}, {"partition_mode", "分区模式"},
{"partition_count", "分区数量"}, {"partition_grid", "分区网格"},
{"interpolation_mode", "插值模式"}, {"visible_range_only", "仅处理可见范围"},
{"frequency_range", "频率范围"}, {"power_range", "功率范围"}, {"i_range", "同相范围"},
{"q_range", "正交范围"}, {"phase_offset_radians", "相位偏移"}, {"pen", "画笔"},