3D全部引入
This commit is contained in:
@@ -1,15 +1,3 @@
|
||||
#pragma once
|
||||
#include "Plot.hpp"
|
||||
namespace aethera::web {
|
||||
// 2D
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_spectrum_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_axes_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_frequency_trace_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_sweep_spectrum_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_afterglow_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_waterfall_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_constellation_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_selection_overlay_plot(asio::any_io_executor executor);
|
||||
// 3D
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_point_plot(asio::any_io_executor executor);
|
||||
}
|
||||
#include "Gallery_Plots_2D.hpp"
|
||||
#include "Gallery_Plots_3D.hpp"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "Plot.hpp"
|
||||
|
||||
namespace aethera::web {
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_spectrum_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_axes_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_frequency_trace_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_sweep_spectrum_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_afterglow_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_waterfall_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_constellation_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_selection_overlay_plot(asio::any_io_executor executor);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
#include "Gallery_Plots.hpp"
|
||||
#include "Renderable_Adapter.hpp"
|
||||
#include <render_3D/Render_3D.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace aethera::web {
|
||||
namespace {
|
||||
using namespace render_3d;
|
||||
using Scene_3D = Impl<Render_Scene_3D>;
|
||||
|
||||
template <typename Visual_Object>
|
||||
class Visual_Scene_View final : public Plot::Scene_View {
|
||||
public:
|
||||
Visual_Scene_View(Scene_3D& scene, std::unique_ptr<Visual_Object> visual, std::string label)
|
||||
: visual_(std::move(visual)) {
|
||||
using Definition = typename Visual_Object::Attached_Object;
|
||||
using Prop = typename Definition::Prop;
|
||||
using State = typename Definition::State;
|
||||
using Scene_Adapter = detail::Renderable_Adapter<Scene_3D,
|
||||
detail::Prop_Field<&Render_Scene_3D::Prop::clear_color, "clear_color", "Linear scene clear color.">,
|
||||
detail::Prop_Field<&Render_Scene_3D::Prop::view_active, "view_active", "Whether the scene publishes rendered frames.">,
|
||||
detail::State_Field<Scene::Base_Tag, &Scene::State::renderable_count, "renderable_count", "Number of renderables attached to the scene.">,
|
||||
detail::State_Field<Scene::Base_Tag, &Scene::State::taskflow_task_count, "taskflow_task_count", "Number of tasks in the scene graph.">,
|
||||
detail::State_Field<Scene::Base_Tag, &Scene::State::taskflow_execution_time_ns, "taskflow_execution_time_ns", "Scene graph execution time in nanoseconds.">>;
|
||||
using Visual_Adapter = detail::Renderable_Adapter<Visual_Object,
|
||||
detail::Prop_Field<&Prop::transform, "transform", "World transform applied to the complete visual.">,
|
||||
detail::Prop_Field<&Prop::visible, "visible", "Whether the visual participates in rendering.">,
|
||||
detail::Prop_Field<&Prop::depth_test, "depth_test", "Whether fragments use depth testing.">,
|
||||
detail::Prop_Field<&Prop::items, "items", "Editable item collection represented by this visual.">,
|
||||
detail::State_Field<Definition::Base_Tag, &State::item_count, "item_count", "Number of published input items.">,
|
||||
detail::State_Field<Definition::Base_Tag, &State::prepared_item_count, "prepared_item_count", "Number of prepared backend items.">,
|
||||
detail::State_Field<Definition::Base_Tag, &State::prepared_revision, "prepared_revision", "Property revision represented by prepared GPU data.">>;
|
||||
descriptors_.push_back(detail::make_renderable_descriptor("scene", "3D 场景", "scene", Scene_Adapter{scene}));
|
||||
descriptors_.push_back(detail::make_renderable_descriptor("visual", std::move(label), "visual", Visual_Adapter{*visual_}));
|
||||
}
|
||||
|
||||
[[nodiscard]] nlohmann::json schema() const override {
|
||||
nlohmann::json components = nlohmann::json::array();
|
||||
for (const auto& descriptor : descriptors_) components.push_back(descriptor->schema());
|
||||
return {{"protocol", "aethera.plot.inspector"}, {"version", 2}, {"components", std::move(components)}};
|
||||
}
|
||||
|
||||
[[nodiscard]] nlohmann::json write_prop(std::string_view component, std::string_view key, const nlohmann::json& value) override {
|
||||
const auto found = std::ranges::find_if(descriptors_, [&](const auto& descriptor) { return descriptor->id() == component; });
|
||||
if (found == descriptors_.end()) return {{"success", false}, {"error", "unknown component"}};
|
||||
auto result = (*found)->write_prop(key, value);
|
||||
result["component"] = component;
|
||||
return result;
|
||||
}
|
||||
|
||||
void update(const Plot_Frame_Request&) override {}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Visual_Object> visual_; /* Scene 引用的 Visual 唯一所有者。 */
|
||||
std::vector<std::unique_ptr<detail::Renderable_Descriptor>> descriptors_; /* Prop/State 协议描述。 */
|
||||
};
|
||||
|
||||
template <typename Definition, typename Build_Result>
|
||||
std::shared_ptr<Plot> make_visual_plot(asio::any_io_executor executor, std::string label, Build_Result build_result) {
|
||||
using Visual_Object = Impl<Definition>;
|
||||
if (!build_result) throw std::logic_error("3D Gallery visual dependency graph is invalid");
|
||||
auto visual = std::move(build_result).value();
|
||||
auto scene_result = Scene_3D::Builder(visual.get())
|
||||
.set(&Render_Scene_3D::Prop::viewport, Extent{720, 420})
|
||||
.set(&Render_Scene_3D::Prop::clear_color, Linear_Color{0.018F, 0.027F, 0.047F, 1.0F})
|
||||
.set(&Render_Scene_3D::Prop::view_active, true)
|
||||
.build();
|
||||
if (!scene_result) throw std::logic_error("3D Gallery scene dependency graph is invalid");
|
||||
auto scene = std::move(scene_result).value();
|
||||
auto view = std::make_unique<Visual_Scene_View<Visual_Object>>(*scene, std::move(visual), std::move(label));
|
||||
return std::make_shared<Plot>(std::move(executor), std::move(scene), std::move(view));
|
||||
}
|
||||
|
||||
Color color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha = 255) {
|
||||
return {red, green, blue, alpha};
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_point_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Point_Visual>(std::move(executor), "Point Visual", Impl<Point_Visual>::Builder{}
|
||||
.set(&Point_Visual::Prop::items, std::vector<Point>{{{-0.65F, -0.25F, 0.05F}, color(255, 91, 110), 28.0F}, {{0.0F, 0.58F, 0.25F}, color(82, 226, 190), 34.0F}, {{0.62F, -0.12F, -0.15F}, color(75, 145, 255), 30.0F}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_splat_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Splat_Visual>(std::move(executor), "Splat Visual", Impl<Splat_Visual>::Builder{}
|
||||
.set(&Splat_Visual::Prop::items, std::vector<Splat>{{{-0.48F, 0.0F, 0.1F}, color(255, 98, 115, 210), {0.18F, 0.08F}, 0.45F}, {{0.28F, 0.15F, 0.0F}, color(66, 218, 188, 210), {0.12F, 0.22F}, -0.3F}, {{0.15F, -0.38F, 0.2F}, color(76, 132, 255, 210), {0.2F, 0.1F}, 0.9F}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_pixel_plot(asio::any_io_executor executor) {
|
||||
std::vector<Pixel> pixels;
|
||||
for (int y = -8; y <= 8; ++y) for (int x = -12; x <= 12; ++x) pixels.push_back({{x / 13.0F, y / 9.0F, 0.12F * std::sin(x * .45F) * std::cos(y * .35F)}, color(static_cast<std::uint8_t>(90 + 6 * (x + 12)), static_cast<std::uint8_t>(100 + 8 * (y + 8)), 230), 5.0F});
|
||||
return make_visual_plot<Pixel_Visual>(std::move(executor), "Pixel Visual", Impl<Pixel_Visual>::Builder{}.set(&Pixel_Visual::Prop::items, std::move(pixels)).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_marker_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Marker_Visual>(std::move(executor), "Marker Visual", Impl<Marker_Visual>::Builder{}
|
||||
.set(&Marker_Visual::Prop::items, std::vector<Marker>{{{-0.7F, 0.0F, 0.0F}, color(255, 93, 115), 34.0F, 0.0F, Marker_Shape::disc}, {{-0.35F, 0.25F, 0.1F}, color(91, 226, 193), 36.0F, 0.25F, Marker_Shape::square}, {{0.0F, -0.2F, 0.2F}, color(100, 158, 255), 38.0F, 0.5F, Marker_Shape::triangle}, {{0.35F, 0.25F, 0.1F}, color(250, 195, 92), 40.0F, 0.75F, Marker_Shape::diamond}, {{0.7F, 0.0F, 0.0F}, color(201, 132, 255), 42.0F, 1.0F, Marker_Shape::cross}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_sphere_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Sphere_Visual>(std::move(executor), "Sphere Visual", Impl<Sphere_Visual>::Builder{}
|
||||
.set(&Sphere_Visual::Prop::items, std::vector<Sphere>{{{-0.48F, -0.2F, 0.0F}, color(255, 91, 110), 0.28F}, {{0.08F, 0.25F, 0.18F}, color(82, 226, 190), 0.36F}, {{0.55F, -0.18F, -0.12F}, color(75, 145, 255), 0.24F}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_segment_plot(asio::any_io_executor executor) {
|
||||
std::vector<Segment> segments;
|
||||
for (int index = 0; index < 12; ++index) { const float angle = static_cast<float>(index) * std::numbers::pi_v<float> / 6.0F; segments.push_back({{0.0F, 0.0F, 0.0F}, {0.82F * std::cos(angle), 0.82F * std::sin(angle), 0.18F * std::sin(2 * angle)}, color(static_cast<std::uint8_t>(80 + index * 13), static_cast<std::uint8_t>(220 - index * 8), 240), 4.0F}); }
|
||||
return make_visual_plot<Segment_Visual>(std::move(executor), "Segment Visual", Impl<Segment_Visual>::Builder{}.set(&Segment_Visual::Prop::items, std::move(segments)).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_vector_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Vector_Visual>(std::move(executor), "Vector Visual", Impl<Vector_Visual>::Builder{}
|
||||
.set(&Vector_Visual::Prop::items, std::vector<Vector_Glyph>{{{-0.55F, -0.35F, 0.0F}, {0.55F, 0.2F, 0.25F}, color(255, 98, 115), 4.0F}, {{-0.1F, 0.0F, 0.0F}, {0.2F, 0.62F, 0.18F}, color(80, 225, 190), 5.0F}, {{0.35F, -0.25F, 0.0F}, {-0.12F, 0.25F, 0.65F}, color(78, 145, 255), 4.0F}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_primitive_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Primitive_Visual>(std::move(executor), "Primitive Visual", Impl<Primitive_Visual>::Builder{}
|
||||
.set(&Primitive_Visual::Prop::topology, Primitive_Topology::triangle_list)
|
||||
.set(&Primitive_Visual::Prop::items, std::vector<Primitive_Vertex>{{{-0.72F, -0.55F, 0.0F}, color(255, 86, 110), {0, 0, 1}}, {{0.72F, -0.55F, 0.0F}, color(75, 145, 255), {0, 0, 1}}, {{0.0F, 0.72F, 0.25F}, color(82, 226, 190), {0, 0, 1}}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_mesh_plot(asio::any_io_executor executor) {
|
||||
const std::vector<Mesh_Vertex> mesh{{{-0.65F, -0.55F, 0.0F}, color(255, 94, 112), {0, 0, 1}, {0, 0}}, {{0.65F, -0.55F, 0.0F}, color(75, 145, 255), {0, 0, 1}, {1, 0}}, {{0.65F, 0.55F, 0.0F}, color(82, 226, 190), {0, 0, 1}, {1, 1}}, {{-0.65F, -0.55F, 0.0F}, color(255, 94, 112), {0, 0, 1}, {0, 0}}, {{0.65F, 0.55F, 0.0F}, color(82, 226, 190), {0, 0, 1}, {1, 1}}, {{-0.65F, 0.55F, 0.0F}, color(244, 190, 86), {0, 0, 1}, {0, 1}}};
|
||||
return make_visual_plot<Mesh_Visual>(std::move(executor), "Mesh Visual", Impl<Mesh_Visual>::Builder{}.set(&Mesh_Visual::Prop::items, mesh).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_path_plot(asio::any_io_executor executor) {
|
||||
std::vector<Path_Vertex> path;
|
||||
for (int index = 0; index < 64; ++index) { const float t = static_cast<float>(index) / 63.0F; path.push_back({{-0.9F + 1.8F * t, 0.48F * std::sin(t * 4.0F * std::numbers::pi_v<float>), 0.25F * std::cos(t * 2.0F * std::numbers::pi_v<float>)}, color(static_cast<std::uint8_t>(70 + 170 * t), static_cast<std::uint8_t>(220 - 80 * t), 245), 5.0F}); }
|
||||
return make_visual_plot<Path_Visual>(std::move(executor), "Path Visual", Impl<Path_Visual>::Builder{}.set(&Path_Visual::Prop::items, std::move(path)).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_image_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Image_Visual>(std::move(executor), "Image Visual", Impl<Image_Visual>::Builder{}
|
||||
.set(&Image_Visual::Prop::field_width, 32U).set(&Image_Visual::Prop::field_height, 32U)
|
||||
.set(&Image_Visual::Prop::items, std::vector<Image>{{{0.0F, 0.0F, 0.0F}, {1.45F, 1.0F}, {0, 0, 1, 1}, color(255, 255, 255)}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_labels_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Labels_Visual>(std::move(executor), "Labels Visual", Impl<Labels_Visual>::Builder{}
|
||||
.set(&Labels_Visual::Prop::field_width, 8U).set(&Labels_Visual::Prop::field_height, 8U)
|
||||
.set(&Labels_Visual::Prop::items, std::vector<Label>{{{-0.55F, 0.28F, 0.0F}, 0, {72, 34}, color(255, 255, 255)}, {{0.5F, 0.25F, 0.1F}, 1, {72, 34}, color(255, 255, 255)}, {{-0.45F, -0.32F, 0.1F}, 2, {72, 34}, color(255, 255, 255)}, {{0.55F, -0.3F, 0.0F}, 3, {72, 34}, color(255, 255, 255)}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_glyph_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Glyph_Visual>(std::move(executor), "Glyph Visual", Impl<Glyph_Visual>::Builder{}
|
||||
.set(&Glyph_Visual::Prop::field_width, 32U).set(&Glyph_Visual::Prop::field_height, 32U)
|
||||
.set(&Glyph_Visual::Prop::items, std::vector<Glyph>{{{-0.55F, -0.15F, 0.0F}, {-0.18F, -0.18F, 0.18F, 0.18F}, {0, 0, 1, 1}, color(255, 100, 120), -0.2F}, {{0.0F, 0.22F, 0.1F}, {-0.22F, -0.22F, 0.22F, 0.22F}, {0, 0, 1, 1}, color(82, 226, 190), 0.25F}, {{0.55F, -0.15F, 0.0F}, {-0.2F, -0.2F, 0.2F, 0.2F}, {0, 0, 1, 1}, color(80, 145, 255), 0.55F}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_text_plot(asio::any_io_executor executor) {
|
||||
return make_visual_plot<Text_Visual>(std::move(executor), "Text Visual", Impl<Text_Visual>::Builder{}
|
||||
.set(&Text_Visual::Prop::items, std::vector<Text_Label>{{{-0.72F, 0.28F, 0.0F}, "Aethera", color(82, 226, 190), 28.0F}, {{-0.62F, -0.15F, 0.1F}, "Datoviz Visual", color(90, 155, 255), 22.0F}}).build());
|
||||
}
|
||||
|
||||
std::shared_ptr<Plot> make_datoviz_volume_plot(asio::any_io_executor executor) {
|
||||
std::vector<Voxel> voxels(16U * 16U * 16U);
|
||||
for (std::size_t index = 0; index < voxels.size(); ++index) voxels[index].value = static_cast<float>(index % 256U) / 255.0F;
|
||||
return make_visual_plot<Volume_Visual>(std::move(executor), "Volume Visual", Impl<Volume_Visual>::Builder{}
|
||||
.set(&Volume_Visual::Prop::field_width, 16U).set(&Volume_Visual::Prop::field_height, 16U).set(&Volume_Visual::Prop::field_depth, 16U)
|
||||
.set(&Volume_Visual::Prop::items, std::move(voxels)).build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "Plot.hpp"
|
||||
|
||||
namespace aethera::web {
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_point_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_splat_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_pixel_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_marker_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_sphere_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_segment_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_vector_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_primitive_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_mesh_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_path_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_image_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_labels_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_glyph_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_text_plot(asio::any_io_executor executor);
|
||||
[[nodiscard]] std::shared_ptr<Plot> make_datoviz_volume_plot(asio::any_io_executor executor);
|
||||
}
|
||||
+116
-144
@@ -335,34 +335,37 @@ std::unique_ptr<Plot::Scene_View> make_scene_view(
|
||||
std::move(update),
|
||||
std::forward<Owned_Objects>(owned_objects)...);
|
||||
}
|
||||
Frequency_Axis_Object::Builder frequency_axis_builder() {
|
||||
Frequency_Axis_Object::Builder builder;
|
||||
builder
|
||||
.set(&Abs_Axis::Prop::orientation, Axis_Orientation::horizontal)
|
||||
.set(&Abs_Axis::Prop::position, Point_F{64.0, 370.0})
|
||||
.set(&Abs_Axis::Prop::pixel_length, 620.0)
|
||||
.set(&Numeric_Axis::Prop::coordinate_range, Axis_Range{0.0, 100.0});
|
||||
return builder;
|
||||
std::unique_ptr<Frequency_Axis_Object> make_frequency_axis() {
|
||||
auto result = Frequency_Axis_Object::Builder{}
|
||||
.set(&Abs_Axis::Prop::orientation, Axis_Orientation::horizontal)
|
||||
.set(&Abs_Axis::Prop::position, Point_F{64.0, 370.0})
|
||||
.set(&Abs_Axis::Prop::pixel_length, 620.0)
|
||||
.set(&Numeric_Axis::Prop::coordinate_range, Axis_Range{0.0, 100.0})
|
||||
.build();
|
||||
if (!result) throw std::logic_error("frequency axis dependency graph is invalid");
|
||||
return std::move(result).value();
|
||||
}
|
||||
Numeric_Axis_Object::Builder numeric_axis_builder(
|
||||
std::unique_ptr<Numeric_Axis_Object> make_numeric_axis(
|
||||
Axis_Orientation orientation, Point_F position, Axis_Pixel_Length length,
|
||||
Axis_Range range) {
|
||||
Numeric_Axis_Object::Builder builder;
|
||||
builder
|
||||
.set(&Abs_Axis::Prop::orientation, orientation)
|
||||
.set(&Abs_Axis::Prop::position, position)
|
||||
.set(&Abs_Axis::Prop::pixel_length, length)
|
||||
.set(&Numeric_Axis::Prop::coordinate_range, range);
|
||||
return builder;
|
||||
auto result = Numeric_Axis_Object::Builder{}
|
||||
.set(&Abs_Axis::Prop::orientation, orientation)
|
||||
.set(&Abs_Axis::Prop::position, position)
|
||||
.set(&Abs_Axis::Prop::pixel_length, length)
|
||||
.set(&Numeric_Axis::Prop::coordinate_range, range)
|
||||
.build();
|
||||
if (!result) throw std::logic_error("numeric axis dependency graph is invalid");
|
||||
return std::move(result).value();
|
||||
}
|
||||
Time_Axis_Object::Builder time_axis_builder(
|
||||
std::unique_ptr<Time_Axis_Object> make_time_axis(
|
||||
Axis_Orientation orientation, Point_F position, Axis_Pixel_Length length) {
|
||||
Time_Axis_Object::Builder builder;
|
||||
builder
|
||||
.set(&Abs_Axis::Prop::orientation, orientation)
|
||||
.set(&Abs_Axis::Prop::position, position)
|
||||
.set(&Abs_Axis::Prop::pixel_length, length);
|
||||
return builder;
|
||||
auto result = Time_Axis_Object::Builder{}
|
||||
.set(&Abs_Axis::Prop::orientation, orientation)
|
||||
.set(&Abs_Axis::Prop::position, position)
|
||||
.set(&Abs_Axis::Prop::pixel_length, length)
|
||||
.build();
|
||||
if (!result) throw std::logic_error("time axis dependency graph is invalid");
|
||||
return std::move(result).value();
|
||||
}
|
||||
template <Axis_Object Horizontal_Axis, Axis_Object Vertical_Axis>
|
||||
std::unique_ptr<Selection_Object> selection_overlay(Horizontal_Axis* horizontal_axis, Vertical_Axis* vertical_axis) {
|
||||
@@ -444,19 +447,19 @@ void dispatch_plot_input(Scene_Object& scene, const Plot_Input_Event& input) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_axes_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto frequency = *frequency_axis_builder().build();
|
||||
auto frequency = make_frequency_axis();
|
||||
frequency->template set<&Abs_Axis::Prop::unit_text>("Hz");
|
||||
auto numeric = *numeric_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-100.0, 0.0}).build();
|
||||
auto numeric = make_numeric_axis(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-100.0, 0.0});
|
||||
numeric->template set<&Abs_Axis::Prop::unit_text>("dB");
|
||||
auto time = *time_axis_builder(
|
||||
Axis_Orientation::horizontal, {64.0, 190.0}, 620.0).build();
|
||||
auto time = make_time_axis(
|
||||
Axis_Orientation::horizontal, {64.0, 190.0}, 620.0);
|
||||
time->template set<&Abs_Axis::Prop::unit_text>("Time");
|
||||
Scene_2D::Builder scene_builder;
|
||||
scene_builder.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true);
|
||||
auto scene = *scene_builder.build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true)
|
||||
.build();
|
||||
const auto topology = scene->template edit_dependency_graph<Prepare_Data_Tag, Paint_Tag>([&](auto& prepare, auto& paint) {
|
||||
prepare.add(frequency.get());
|
||||
prepare.add(numeric.get());
|
||||
@@ -485,12 +488,12 @@ std::shared_ptr<Plot> make_axes_plot(asio::any_io_executor executor) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_spectrum_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto frequency = *frequency_axis_builder().build();
|
||||
auto vertical = *numeric_axis_builder(Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-110.0, 0.0}).build();
|
||||
Impl<Spectrum>::Builder spectrum_builder(frequency.get(), vertical.get());
|
||||
spectrum_builder.set(&Spectrum::Prop::frequency_range, Axis_Range{0.0, 100.0})
|
||||
.set(&Spectrum::Prop::max_hold_visible, true);
|
||||
auto spectrum = *spectrum_builder.build();
|
||||
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())
|
||||
.set(&Spectrum::Prop::frequency_range, Axis_Range{0.0, 100.0})
|
||||
.set(&Spectrum::Prop::max_hold_visible, true)
|
||||
.build();
|
||||
auto selection = selection_overlay(frequency.get(), vertical.get());
|
||||
auto scene = *Scene_2D::Builder()
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
@@ -543,19 +546,19 @@ std::shared_ptr<Plot> make_spectrum_plot(asio::any_io_executor executor) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_frequency_trace_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto time = *time_axis_builder(
|
||||
Axis_Orientation::horizontal, {64.0, 370.0}, 620.0).build();
|
||||
auto vertical = *numeric_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-1.2, 1.2}).build();
|
||||
auto time = make_time_axis(
|
||||
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 selection = selection_overlay(time.get(), vertical.get());
|
||||
Scene_2D::Builder scene_builder;
|
||||
scene_builder.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true);
|
||||
scene_builder.add_renderable(trace.get());
|
||||
scene_builder.add_renderable(selection.get());
|
||||
auto scene = *scene_builder.build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true)
|
||||
.add_renderable(trace.get())
|
||||
.add_renderable(selection.get())
|
||||
.build();
|
||||
place_selection_over(scene.get(), selection.get(), trace.get());
|
||||
auto update = [scene = scene.get(), raw = trace.get(), time = time.get(), vertical = vertical.get()](const Plot_Frame_Request& event) {
|
||||
resize_axes(scene, {static_cast<int>(event.width), static_cast<int>(event.height)}, time, vertical);
|
||||
@@ -580,22 +583,22 @@ std::shared_ptr<Plot> make_frequency_trace_plot(asio::any_io_executor executor)
|
||||
}
|
||||
std::shared_ptr<Plot> make_sweep_spectrum_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto frequency = *frequency_axis_builder().build();
|
||||
auto vertical = *numeric_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-110.0, 0.0}).build();
|
||||
Impl<Sweep_Spectrum>::Builder sweep_builder(frequency.get(), vertical.get());
|
||||
sweep_builder.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});
|
||||
auto sweep = *sweep_builder.build();
|
||||
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())
|
||||
.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})
|
||||
.build();
|
||||
auto selection = selection_overlay(frequency.get(), vertical.get());
|
||||
Scene_2D::Builder scene_builder;
|
||||
scene_builder.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true);
|
||||
scene_builder.add_renderable(sweep.get());
|
||||
scene_builder.add_renderable(selection.get());
|
||||
auto scene = *scene_builder.build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true)
|
||||
.add_renderable(sweep.get())
|
||||
.add_renderable(selection.get())
|
||||
.build();
|
||||
place_selection_over(scene.get(), selection.get(), sweep.get());
|
||||
auto update = [scene = scene.get(), raw = sweep.get(), frequency = frequency.get(), vertical = vertical.get()](const Plot_Frame_Request& event) {
|
||||
resize_axes(scene, {static_cast<int>(event.width), static_cast<int>(event.height)}, frequency, vertical);
|
||||
@@ -629,22 +632,22 @@ std::shared_ptr<Plot> make_sweep_spectrum_plot(asio::any_io_executor executor) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_afterglow_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto frequency = *frequency_axis_builder().build();
|
||||
auto vertical = *numeric_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-110.0, 0.0}).build();
|
||||
Impl<Afterglow>::Builder afterglow_builder(frequency.get(), vertical.get());
|
||||
afterglow_builder.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);
|
||||
auto afterglow = *afterglow_builder.build();
|
||||
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())
|
||||
.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)
|
||||
.build();
|
||||
auto selection = selection_overlay(frequency.get(), vertical.get());
|
||||
Scene_2D::Builder scene_builder;
|
||||
scene_builder.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true);
|
||||
scene_builder.add_renderable(afterglow.get());
|
||||
scene_builder.add_renderable(selection.get());
|
||||
auto scene = *scene_builder.build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true)
|
||||
.add_renderable(afterglow.get())
|
||||
.add_renderable(selection.get())
|
||||
.build();
|
||||
place_selection_over(scene.get(), selection.get(), afterglow.get());
|
||||
auto update = [scene = scene.get(), raw = afterglow.get(), frequency = frequency.get(), vertical = vertical.get()](const Plot_Frame_Request& event) {
|
||||
resize_axes(scene, {static_cast<int>(event.width), static_cast<int>(event.height)}, frequency, vertical);
|
||||
@@ -674,21 +677,21 @@ std::shared_ptr<Plot> make_afterglow_plot(asio::any_io_executor executor) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_waterfall_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto frequency = *frequency_axis_builder().build();
|
||||
auto time = *time_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0).build();
|
||||
Impl<Waterfall>::Builder waterfall_builder(frequency.get(), time.get());
|
||||
waterfall_builder.set(&Waterfall::Prop::frequency_range, Axis_Range{0.0, 100.0})
|
||||
.set(&Waterfall::Prop::power_range, Axis_Range{-110.0, 0.0});
|
||||
auto waterfall = *waterfall_builder.build();
|
||||
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())
|
||||
.set(&Waterfall::Prop::frequency_range, Axis_Range{0.0, 100.0})
|
||||
.set(&Waterfall::Prop::power_range, Axis_Range{-110.0, 0.0})
|
||||
.build();
|
||||
auto selection = selection_overlay(frequency.get(), time.get());
|
||||
Scene_2D::Builder scene_builder;
|
||||
scene_builder.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true);
|
||||
scene_builder.add_renderable(waterfall.get());
|
||||
scene_builder.add_renderable(selection.get());
|
||||
auto scene = *scene_builder.build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true)
|
||||
.add_renderable(waterfall.get())
|
||||
.add_renderable(selection.get())
|
||||
.build();
|
||||
place_selection_over(scene.get(), selection.get(), waterfall.get());
|
||||
auto update = [scene = scene.get(), raw = waterfall.get(), frequency = frequency.get(), time = time.get()](const Plot_Frame_Request& event) {
|
||||
resize_axes(scene, {static_cast<int>(event.width), static_cast<int>(event.height)}, frequency, time);
|
||||
@@ -726,22 +729,22 @@ std::shared_ptr<Plot> make_waterfall_plot(asio::any_io_executor executor) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_constellation_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto horizontal = *numeric_axis_builder(
|
||||
Axis_Orientation::horizontal, {64.0, 370.0}, 620.0, {-1.2, 1.2}).build();
|
||||
auto vertical = *numeric_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {-1.2, 1.2}).build();
|
||||
Impl<Constellation_Diagram>::Builder constellation_builder(horizontal.get(), vertical.get());
|
||||
constellation_builder.set(&Constellation_Diagram::Prop::i_range, Axis_Range{-1.2, 1.2})
|
||||
.set(&Constellation_Diagram::Prop::q_range, Axis_Range{-1.2, 1.2});
|
||||
auto constellation = *constellation_builder.build();
|
||||
auto horizontal = make_numeric_axis(
|
||||
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())
|
||||
.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();
|
||||
auto selection = selection_overlay(horizontal.get(), vertical.get());
|
||||
Scene_2D::Builder scene_builder;
|
||||
scene_builder.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true);
|
||||
scene_builder.add_renderable(constellation.get());
|
||||
scene_builder.add_renderable(selection.get());
|
||||
auto scene = *scene_builder.build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
.set(&Render_Scene_2D::Prop::background, Color{7, 13, 24, 255})
|
||||
.set(&Render_Scene_2D::Prop::view_active, true)
|
||||
.add_renderable(constellation.get())
|
||||
.add_renderable(selection.get())
|
||||
.build();
|
||||
place_selection_over(scene.get(), selection.get(), constellation.get());
|
||||
auto update = [scene = scene.get(), raw = constellation.get(), horizontal = horizontal.get(), vertical = vertical.get()](const Plot_Frame_Request& event) {
|
||||
resize_axes(scene, {static_cast<int>(event.width), static_cast<int>(event.height)}, horizontal, vertical);
|
||||
@@ -777,10 +780,10 @@ std::shared_ptr<Plot> make_constellation_plot(asio::any_io_executor executor) {
|
||||
}
|
||||
std::shared_ptr<Plot> make_selection_overlay_plot(asio::any_io_executor executor) {
|
||||
constexpr Size canvas{720, 420};
|
||||
auto horizontal = *numeric_axis_builder(
|
||||
Axis_Orientation::horizontal, {64.0, 370.0}, 620.0, {0.0, 100.0}).build();
|
||||
auto vertical = *numeric_axis_builder(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {0.0, 100.0}).build();
|
||||
auto horizontal = make_numeric_axis(
|
||||
Axis_Orientation::horizontal, {64.0, 370.0}, 620.0, {0.0, 100.0});
|
||||
auto vertical = make_numeric_axis(
|
||||
Axis_Orientation::vertical, {64.0, 370.0}, -320.0, {0.0, 100.0});
|
||||
auto selection = *Impl<Selection_Rectangle_Overlay>::Builder(horizontal.get(), vertical.get()).build();
|
||||
auto scene = *Scene_2D::Builder{}
|
||||
.set(&Render_Scene_2D::Prop::viewport, canvas)
|
||||
@@ -1002,35 +1005,4 @@ void Plot::async_write_prop(std::string component, std::string key, nlohmann::js
|
||||
}))
|
||||
throw std::runtime_error("plot input queue is unavailable");
|
||||
}
|
||||
std::shared_ptr<Plot> make_datoviz_point_plot(asio::any_io_executor executor) {
|
||||
using Visual_Object = Impl<Point_Visual>;
|
||||
auto visual = *Visual_Object::Builder{}.build();
|
||||
static_cast<void>(visual->update_items({
|
||||
render_3d::Point{.position = {-0.55F, -0.2F, 0.0F}, .color = Color::red_color(), .diameter_px = 24.0F},
|
||||
render_3d::Point{.position = {0.0F, 0.5F, 0.0F}, .color = Color::green_color(), .diameter_px = 30.0F},
|
||||
render_3d::Point{.position = {0.55F, -0.1F, 0.0F}, .color = Color{42, 120, 255, 255}, .diameter_px = 26.0F}
|
||||
}));
|
||||
visual->advance();
|
||||
auto scene_result = Scene_3D::Builder(visual.get())
|
||||
.set(&Render_Scene_3D::Prop::viewport, Extent{720, 420})
|
||||
.set(&Render_Scene_3D::Prop::view_active, true)
|
||||
.build();
|
||||
if (!scene_result) throw std::logic_error("Datoviz point plot dependency graph is invalid");
|
||||
auto scene = std::move(scene_result).value();
|
||||
using Adapter = detail::Renderable_Adapter<Visual_Object,
|
||||
detail::Prop_Field<&Point_Visual::Prop::transform, "transform", "World transform applied to every point in the visual.">,
|
||||
detail::Prop_Field<&Point_Visual::Prop::visible, "visible", "Controls whether the point visual participates in scene rendering.">,
|
||||
detail::Prop_Field<&Point_Visual::Prop::depth_test, "depth_test", "Enables depth testing when point fragments are rendered.">,
|
||||
detail::Prop_Field<&Point_Visual::Prop::items, "items", "Complete collection of 3D points submitted to the visual.">,
|
||||
detail::State_Field<Point_Visual::Base_Tag, &Point_Visual::State::item_count, "item_count", "Number of point items currently published by the visual.">,
|
||||
detail::State_Field<Point_Visual::Base_Tag, &Point_Visual::State::prepared_item_count, "prepared_item_count", "Number of point items prepared for the latest GPU submission.">,
|
||||
detail::State_Field<Point_Visual::Base_Tag, &Point_Visual::State::prepared_revision, "prepared_revision", "Property revision represented by the currently prepared GPU data.">>;
|
||||
std::vector<std::unique_ptr<detail::Renderable_Descriptor>> components;
|
||||
components.push_back(make_scene_component(*scene));
|
||||
components.push_back(detail::make_renderable_descriptor("plot", "主绘图组件", "visual", Adapter{*visual}));
|
||||
auto view = std::make_unique<Scene_View_Model<decltype(visual)>>(
|
||||
std::move(components),
|
||||
[](const Plot_Frame_Request&) {}, std::move(visual));
|
||||
return std::make_shared<Plot>(std::move(executor), std::move(scene), std::move(view));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,20 @@ int run_web_server(std::uint16_t port, const std::filesystem::path& asset_root)
|
||||
plots->emplace("constellation", make_constellation_plot(executor));
|
||||
plots->emplace("selection_overlay", make_selection_overlay_plot(executor));
|
||||
plots->emplace("datoviz_point", make_datoviz_point_plot(executor));
|
||||
plots->emplace("datoviz_splat", make_datoviz_splat_plot(executor));
|
||||
plots->emplace("datoviz_pixel", make_datoviz_pixel_plot(executor));
|
||||
plots->emplace("datoviz_marker", make_datoviz_marker_plot(executor));
|
||||
plots->emplace("datoviz_sphere", make_datoviz_sphere_plot(executor));
|
||||
plots->emplace("datoviz_segment", make_datoviz_segment_plot(executor));
|
||||
plots->emplace("datoviz_vector", make_datoviz_vector_plot(executor));
|
||||
plots->emplace("datoviz_primitive", make_datoviz_primitive_plot(executor));
|
||||
plots->emplace("datoviz_mesh", make_datoviz_mesh_plot(executor));
|
||||
plots->emplace("datoviz_path", make_datoviz_path_plot(executor));
|
||||
plots->emplace("datoviz_image", make_datoviz_image_plot(executor));
|
||||
plots->emplace("datoviz_labels", make_datoviz_labels_plot(executor));
|
||||
plots->emplace("datoviz_glyph", make_datoviz_glyph_plot(executor));
|
||||
plots->emplace("datoviz_text", make_datoviz_text_plot(executor));
|
||||
plots->emplace("datoviz_volume", make_datoviz_volume_plot(executor));
|
||||
|
||||
auto resolve_plot = [plots](std::string_view id) { return find_plot(*plots, id); };
|
||||
auto websocket = std::make_shared<Graph_WebSocket_Controller>(resolve_plot);
|
||||
@@ -61,7 +75,7 @@ int run_web_server(std::uint16_t port, const std::filesystem::path& asset_root)
|
||||
static_cast<void>(plot);
|
||||
result.push_back({
|
||||
{"id", id}, {"title", id}, {"category", "Plots"}, {"description", ""},
|
||||
{"dimension", ""}, {"websocket", "/ws/plot/" + id},
|
||||
{"dimension", id.starts_with("datoviz_") ? "3D" : "2D"}, {"websocket", "/ws/plot/" + id},
|
||||
{"schema", "/plot/" + id + "/schema"}});
|
||||
}
|
||||
callback(json_response(std::move(result)));
|
||||
|
||||
Reference in New Issue
Block a user