data_table v1.3.1: Dots renderer via ImDrawList (font-independent) + recompile all apps with fn_table_viz (issue 0081-O.6)
- Replace TextColored+glyph with ImDrawList::AddCircleFilled in CellRenderer::Dots. Dots are now font-independent: no dependency on Unicode glyph coverage. Fixes "dots show as ?" on Karla/Roboto/Inter fonts that lack Geometric Shapes block. - dots_glyph_size now controls circle radius (px) instead of font scale. - BadgeRule.label is ignored for Dots (documented in data_table_types.h + docs). - data_table.md bumped to v1.3.1 with capability growth log entry. - docs/capabilities/data_table_renderers.md: Dots section updated + Common pitfalls entry added: "Asumir que cualquier glyph Unicode renderea". - dag_engine_ui/tabs.cpp: removed stale "● glyph" comment from BadgeRule. - Recompiled: dag_engine_ui, registry_dashboard, graph_explorer, navegator_dashboard, odr_console. All 5 apps deployed to Desktop/apps/. Build Linux + tests 4/4 green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
Submodule cpp/apps/dag_engine_ui updated: 61314b7f96...aec22ba594
@@ -208,8 +208,9 @@ struct ColumnSpec {
|
||||
|
||||
// Dots (Phase 2.5, v1.3.0): CellRenderer::Dots — inline status sparkline.
|
||||
// Cell value is a separator-delimited string of tokens, e.g. "ok,error,ok".
|
||||
// Each token is looked up in `badges` for color (and optional glyph override via label).
|
||||
// Default glyph: u8"●"; override by setting BadgeRule.label to another UTF-8 glyph.
|
||||
// Each token is looked up in `badges` for color. Dots are drawn as filled circles
|
||||
// via ImDrawList (font-independent — no Unicode glyph dependency).
|
||||
// Note: BadgeRule.label is ignored for Dots; it only applies to the Badge renderer.
|
||||
char dots_separator = ','; // separator between tokens
|
||||
float dots_glyph_size = 0.0f; // glyph size px; 0 = default font size
|
||||
int dots_max = 0; // hard limit on dots shown; 0 = no limit
|
||||
|
||||
@@ -329,18 +329,14 @@ static void draw_cell_custom(const ColumnSpec& spec, const char* value,
|
||||
|
||||
case CellRenderer::Dots: {
|
||||
// Parse cell value as separator-delimited tokens.
|
||||
std::string s = value; // value is guaranteed non-null (checked at top)
|
||||
std::string s = value;
|
||||
std::vector<std::string> tokens;
|
||||
{
|
||||
std::string cur;
|
||||
char sep = spec.dots_separator ? spec.dots_separator : ',';
|
||||
for (char c : s) {
|
||||
if (c == sep) {
|
||||
tokens.push_back(cur);
|
||||
cur.clear();
|
||||
} else {
|
||||
cur.push_back(c);
|
||||
}
|
||||
if (c == sep) { tokens.push_back(cur); cur.clear(); }
|
||||
else cur.push_back(c);
|
||||
}
|
||||
if (!cur.empty()) tokens.push_back(cur);
|
||||
}
|
||||
@@ -348,33 +344,46 @@ static void draw_cell_custom(const ColumnSpec& spec, const char* value,
|
||||
? std::min((int)tokens.size(), spec.dots_max)
|
||||
: (int)tokens.size();
|
||||
|
||||
// Draw filled circles via ImDrawList — font-independent, scales with font size.
|
||||
// BadgeRule.label is ignored for Dots (only relevant for Badge renderer).
|
||||
float font_h = ImGui::GetTextLineHeight();
|
||||
float radius = (spec.dots_glyph_size > 0.f ? spec.dots_glyph_size : font_h * 0.32f);
|
||||
float spacing = radius * 2.3f;
|
||||
ImVec2 origin = ImGui::GetCursorScreenPos();
|
||||
float dot_y = origin.y + font_h * 0.5f;
|
||||
ImDrawList* dl = ImGui::GetWindowDrawList();
|
||||
ImU32 default_col = IM_COL32(110, 110, 125, 255); // muted grey
|
||||
|
||||
for (int t = 0; t < limit; ++t) {
|
||||
if (t > 0) ImGui::SameLine(0, 2.0f); // tight spacing between dots
|
||||
// Look up color + optional glyph override in badges.
|
||||
ImVec4 color(0.4f, 0.4f, 0.45f, 1.0f); // default: muted grey
|
||||
const char* glyph = u8"\xe2\x97\x8f"; // UTF-8 for ●
|
||||
ImU32 col = default_col;
|
||||
for (const auto& br : spec.badges) {
|
||||
if (br.value == tokens[t]) {
|
||||
ImVec4 c = hex_to_imcolor(br.color_hex);
|
||||
if (c.x >= 0.f) color = c;
|
||||
if (!br.label.empty()) glyph = br.label.c_str();
|
||||
if (c.x >= 0.f) col = ImGui::ColorConvertFloat4ToU32(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Optional glyph size push.
|
||||
bool pushed_font_scale = false;
|
||||
if (spec.dots_glyph_size > 0.0f) {
|
||||
float scale = spec.dots_glyph_size / ImGui::GetFontSize();
|
||||
ImGui::SetWindowFontScale(scale);
|
||||
pushed_font_scale = true;
|
||||
}
|
||||
ImGui::TextColored(color, "%s", glyph);
|
||||
if (pushed_font_scale) ImGui::SetWindowFontScale(1.0f);
|
||||
// Per-dot tooltip: show the token string.
|
||||
if (spec.tooltip_on_hover && ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", tokens[t].c_str());
|
||||
float cx = origin.x + radius + t * spacing;
|
||||
dl->AddCircleFilled(ImVec2(cx, dot_y), radius, col, 18);
|
||||
}
|
||||
|
||||
// Reserve cursor space so layout flows correctly.
|
||||
float total_w = (limit > 0 ? (limit * spacing) : 0.f);
|
||||
ImGui::Dummy(ImVec2(total_w, font_h));
|
||||
|
||||
// Hit-test for tooltip per dot.
|
||||
if (spec.tooltip_on_hover && ImGui::IsItemHovered()) {
|
||||
ImVec2 mp = ImGui::GetMousePos();
|
||||
for (int t = 0; t < limit; ++t) {
|
||||
float cx = origin.x + radius + t * spacing;
|
||||
float dx = mp.x - cx, dy = mp.y - dot_y;
|
||||
if (dx*dx + dy*dy <= radius * radius * 1.5f) {
|
||||
ImGui::SetTooltip("%s", tokens[t].c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spec.dots_show_count) {
|
||||
ImGui::SameLine(0, 6.0f);
|
||||
ImGui::TextDisabled("(%d)", (int)tokens.size());
|
||||
|
||||
@@ -3,7 +3,7 @@ name: data_table
|
||||
kind: function
|
||||
lang: cpp
|
||||
domain: viz
|
||||
version: "1.3.0"
|
||||
version: "1.3.1"
|
||||
purity: impure
|
||||
signature: "void data_table::render(const char* id, const std::vector<TableInput>& tables, State& st, std::vector<TableEvent>* events_out = nullptr, bool show_chrome = true)"
|
||||
description: "Render UI completa de tabla TQL: chips bar, tabla, viz panels, column-stats inline, drill, color rules, joins, TQL editor, Ask AI, Button renderer, event sink (ButtonClick/RowDoubleClick/RowRightClick), tooltip per-cell, column_specs persisted in TQL. Dots renderer para sparkline-like de status (v1.3.0). Entry-point publica del stack data_table. Muta State segun interaccion del usuario."
|
||||
@@ -184,5 +184,7 @@ v1.2.0 (2026-05-15) — Button renderer + event sink (ButtonClick/RowDoubleClick
|
||||
|
||||
v1.3.0 (2026-05-15) — Dots renderer for inline status timelines (sparkline-like). Reuses badges for color mapping. dots_max/dots_separator/dots_show_count/dots_glyph_size fields. TQL roundtrip. dag_engine_ui canonical use case (10-col antipattern -> 6-col fix).
|
||||
|
||||
v1.3.1 (2026-05-15) — Dots renderer now draws filled circles via ImDrawList instead of Unicode glyph. Font-independent: works regardless of TTF glyph coverage. Closes "dots show as ?" bug in dag_engine_ui.
|
||||
|
||||
---
|
||||
Promovido desde `cpp/apps/primitives_gallery/playground/tables/data_table.{h,cpp}` — issue 0081-H.
|
||||
|
||||
Reference in New Issue
Block a user