19 std::vector<std::span<const double>> result;
20 for (
size_t i = 0; i < dims.size() && i < data.size(); ++i) {
21 if (dims[i].role != role)
23 const auto* vec = std::get_if<std::vector<double>>(&data[i]);
24 if (!vec || vec->empty())
26 result.emplace_back(vec->data(), vec->size());
40 double lo = std::numeric_limits<double>::max();
41 double hi = std::numeric_limits<double>::lowest();
50 return {
static_cast<float>(lo),
static_cast<float>(hi) };
54 const std::vector<std::span<const double>>&
series)
56 if (!range.auto_scaling ||
series.empty())
58 if (range.scale_predicate && !range.scale_predicate())
61 float lo = std::numeric_limits<float>::max();
62 float hi = std::numeric_limits<float>::lowest();
63 for (
const auto& s :
series) {
65 lo = std::min(lo, slo);
66 hi = std::max(hi, shi);
77 size_t index)
noexcept
80 return glm::vec3(1.F);
81 return palette[index % palette.size()];
91 const std::shared_ptr<Core::VKImage>& texture)
93 return [bounds, color, texture](
95 std::vector<uint8_t>& out,
101 const std::array<std::pair<glm::vec3, glm::vec2>, 4> verts = { {
102 { { bounds.
min.x, bounds.
min.y, 0.F }, { 0.F, 1.F } },
103 { { bounds.
max.x, bounds.
min.y, 0.F }, { 1.F, 1.F } },
104 { { bounds.
min.x, bounds.
max.y, 0.F }, { 0.F, 0.F } },
105 { { bounds.
max.x, bounds.
max.y, 0.F }, { 1.F, 0.F } },
107 out.resize(
static_cast<size_t>(4) * stride);
108 for (
size_t i = 0; i < 4; ++i) {
109 uint8_t* v = out.data() + i * stride;
110 std::memcpy(v, &verts[i].first, 12);
111 std::memcpy(v + 12, &verts[i].second, 8);
115 constexpr glm::vec3 k_normal { 0.F, 0.F, 1.F };
116 constexpr glm::vec3 k_tangent { 1.F, 0.F, 0.F };
117 constexpr glm::vec2 k_uv { 0.F, 0.F };
118 constexpr float k_weight = 0.F;
120 const std::array<glm::vec3, 4> positions = { {
121 { bounds.
min.x, bounds.
min.y, 0.F },
122 { bounds.
max.x, bounds.
min.y, 0.F },
123 { bounds.
min.x, bounds.
max.y, 0.F },
124 { bounds.
max.x, bounds.
max.y, 0.F },
127 out.resize(
static_cast<size_t>(4) * stride, 0);
128 for (
size_t i = 0; i < 4; ++i) {
129 uint8_t* v = out.data() + i * stride;
130 std::memcpy(v, &positions[i], 12);
131 std::memcpy(v + 12, &color, 12);
132 std::memcpy(v + 24, &k_weight, 4);
133 std::memcpy(v + 28, &k_uv, 8);
134 std::memcpy(v + 36, &k_normal, 12);
135 std::memcpy(v + 48, &k_tangent, 12);
139 el.bounds_hint = bounds;
145 uint32_t x_divisions,
146 uint32_t y_divisions,
150 std::vector<Kakshya::LineVertex> out;
151 out.reserve((
static_cast<size_t>(x_divisions + y_divisions)) * 2);
153 auto lv = [&](glm::vec2 p) {
157 .thickness = thickness,
161 for (uint32_t i = 0; i < x_divisions; ++i) {
162 const float t = (x_divisions > 1)
163 ?
static_cast<float>(i) /
static_cast<float>(x_divisions - 1)
165 const float x = bounds.
min.x + t * bounds.
width();
166 out.push_back(lv({ x, bounds.
min.y }));
167 out.push_back(lv({ x, bounds.
max.y }));
170 for (uint32_t i = 0; i < y_divisions; ++i) {
171 const float t = (y_divisions > 1)
172 ?
static_cast<float>(i) /
static_cast<float>(y_divisions - 1)
174 const float y = bounds.
min.y + t * bounds.
height();
175 out.push_back(lv({ bounds.
min.x, y }));
176 out.push_back(lv({ bounds.
max.x, y }));
188 return [bounds, vertical, color, thickness](
189 float v, std::vector<uint8_t>& out,
Element& el) {
190 const float t = std::clamp(v, 0.F, 1.F);
192 std::array<V, 2> verts;
194 const float x = bounds.
min.x + t * bounds.
width();
196 { .position = { x, bounds.
min.y, 0.F }, .color = color, .thickness = thickness },
197 { .position = { x, bounds.
max.y, 0.F }, .color = color, .thickness = thickness },
200 .
min = { x - 0.01F, bounds.
min.y },
201 .max = { x + 0.01F, bounds.
max.y },
204 const float y = bounds.
min.y + t * bounds.
height();
206 { .position = { bounds.
min.x, y, 0.F }, .color = color, .thickness = thickness },
207 { .position = { bounds.
max.x, y, 0.F }, .color = color, .thickness = thickness },
210 .
min = { bounds.
min.x, y - 0.01F },
211 .max = { bounds.
max.x, y + 0.01F },
229 .
text = std::move(text),
232 .name = std::move(name),
233 .interactive =
false,
239 const uint32_t
count = std::max(spec.
count, 2U);
242 std::vector<LabelSpec> labels;
243 labels.reserve(
count);
245 for (uint32_t i = 0; i <
count; ++i) {
246 const float t =
static_cast<float>(i) /
static_cast<float>(
count - 1);
248 const std::string text = std::format(
"{:.{}f}", value,
286 .bounds = label_bounds,
288 .name = spec.
name_prefix +
"_" + std::to_string(i),
289 .interactive =
false,
302 uint8_t decimal_places,
312 .decimal_places = decimal_places,
320 std::span<const std::string> labels,
321 std::span<const glm::vec3> colors,
324 glm::vec4 text_color)
326 const size_t n = std::min(labels.size(), colors.size());
331 .swatch_w = swatch_w,
332 .text_color = text_color,
334 spec.entries.reserve(n);
336 for (
size_t i = 0; i < n; ++i) {
352 for (
size_t i = 0; i < spec.
entries.size(); ++i) {
353 const float y_top = spec.
origin.y
354 -
static_cast<float>(i) * (spec.
row_h + spec.
gap);
355 const float y_bot = y_top - spec.
row_h;
369 .color = spec.
entries[i].color,
370 .name = spec.
name_prefix +
"_swatch_" + std::to_string(i),
376 .bounds = text_bounds,
378 .name = spec.
name_prefix +
"_label_" + std::to_string(i),
Illustrative geometry functions for common Mapped use cases.
std::vector< DataVariant > & get_processed_data() override
Get a mutable reference to the processed data buffer.
ContainerDataStructure & get_structure() override
Get the data structure defining this container's layout.
SignalSourceContainer holding N named scalar series for plotting and signal use.
std::vector< DataDimension > dimensions
Role
Semantic role of the dimension.
Vertex type for line primitives (LINE_LIST / LINE_STRIP topology)
uint32_t stride_bytes
Total bytes per vertex (stride in Vulkan terms) e.g., 3 floats (position) + 3 floats (normal) = 24 by...
static VertexLayout for_textured_quad(uint32_t vertex_count=4)
Factory: Create layout for textured quad primitives (position, texcoord).
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)
float height() const noexcept
float width() const noexcept
Axis-aligned bounding rectangle in a 2D coordinate space.