data_table v1.3.0: Dots renderer for status timelines + fix dag_engine_ui antipattern + pitfalls doc (issue 0081-O.5)

PARTE A - CellRenderer::Dots (v1.3.0):
- Add Dots=8 to CellRenderer enum (data_table_types.h)
- Add dots_separator/dots_max/dots_show_count/dots_glyph_size fields to ColumnSpec
- Implement draw_cell_custom case Dots in data_table.cpp
  - Parses comma-separated cell value into tokens
  - Looks up each token in badges for color + optional glyph override
  - Per-dot tooltip via tooltip_on_hover
- tql_emit: serialize renderer="dots" + dots_max/dots_show_count/dots_glyph_size/dots_separator
- tql_apply: deserialize all Dots fields
- tql_emit_test: +6 assertions (58 total, 0 failed)
- tql_apply_test: +8 assertions (114 total, 0 failed)
- test_column_specs: +2 tests (10/10 pass)

PARTE B - dag_engine_ui fix: 10 cols -> 6 cols (submodule commit 61314b7)

PARTE C - docs/capabilities/data_table_renderers.md:
- Update to v1.3.0
- Add decision tree for renderer selection
- Add CellRenderer::Dots section with canonical example
- Add Common pitfalls section (multiple columns, badge for free-text, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-15 17:24:53 +02:00
parent 67fff0d677
commit 5974484bd4
10 changed files with 389 additions and 18 deletions
+59 -2
View File
@@ -327,15 +327,72 @@ static void draw_cell_custom(const ColumnSpec& spec, const char* value,
break;
}
case CellRenderer::Dots: {
// Parse cell value as separator-delimited tokens.
std::string s = value; // value is guaranteed non-null (checked at top)
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 (!cur.empty()) tokens.push_back(cur);
}
int limit = (spec.dots_max > 0)
? std::min((int)tokens.size(), spec.dots_max)
: (int)tokens.size();
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 ●
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();
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());
}
}
if (spec.dots_show_count) {
ImGui::SameLine(0, 6.0f);
ImGui::TextDisabled("(%d)", (int)tokens.size());
}
break;
}
default:
// CellRenderer::Text or unknown — plain text.
ImGui::TextUnformatted(value);
break;
}
// Tooltip: show on hover if tooltip_on_hover is set.
// Tooltip: show on hover if tooltip_on_hover is set (non-Dots renderers).
// For Dots, per-dot tooltips are handled inline above.
// "auto" shows the raw cell value (useful for truncated text columns).
if (spec.tooltip_on_hover && ImGui::IsItemHovered()) {
if (spec.renderer != CellRenderer::Dots &&
spec.tooltip_on_hover && ImGui::IsItemHovered()) {
const char* tip = (spec.tooltip == "auto") ? value : spec.tooltip.c_str();
if (tip && tip[0]) ImGui::SetTooltip("%s", tip);
}
+6 -2
View File
@@ -3,10 +3,10 @@ name: data_table
kind: function
lang: cpp
domain: viz
version: "1.2.0"
version: "1.3.0"
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. Entry-point publica del stack data_table. Muta State segun interaccion del usuario."
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."
tags: [tables, viz, ui, imgui, tql, cpp-tables]
uses_functions:
- compute_stage_cpp_core
@@ -70,6 +70,8 @@ tests:
- "Button: TableEvent struct constructible; render() with events_out links"
- "Tooltip: ColumnSpec with tooltip_on_hover=true compiles and links"
- "Back-compat: both render() signatures (with/without events_out) link"
- "Dots: ColumnSpec with CellRenderer::Dots + badges constructs correctly"
- "Dots TQL roundtrip: State::aux_column_specs accepts Dots spec"
test_file_path: "cpp/tests/test_column_specs.cpp"
file_path: "cpp/functions/viz/data_table.cpp"
params:
@@ -180,5 +182,7 @@ v1.1.0 (2026-05-15) — declarative CellRenderer (Badge/Progress/Duration/Icon)
v1.2.0 (2026-05-15) — Button renderer + event sink (ButtonClick/RowDoubleClick/RowRightClick) + tooltip per cell + column_specs persisted in TQL (aux_column_specs roundtrip). Back-compat preserved: events_out=nullptr by default; existing render() callers unchanged.
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).
---
Promovido desde `cpp/apps/primitives_gallery/playground/tables/data_table.{h,cpp}` — issue 0081-H.