feat(kpis): 4-col table + card container para cada KPI

Reemplaza dashboard_grid (BeginGroup) por ImGui::BeginTable de 4 columnas.
Las celdas de tabla si propagan ancho constrained al BeginChild interno de
kpi_card, cosa que BeginGroup no hace. Layout 2x4 en vez de 1x8 (mas legible
a anchos tipicos).

Reduce duplicacion iterando un array de {label,value,fmt}.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 20:52:24 +02:00
parent 570103d83e
commit 646b9463c0
+24 -18
View File
@@ -32,25 +32,31 @@ void draw_kpi_row(const RegistryStats& stats) {
float pure_pct = stats.total_functions > 0
? 100.0f * stats.pure_functions / stats.total_functions : 0.0f;
dashboard_grid_begin(8, 8.0f);
// ImGui::BeginTable da celdas con ancho constrained, algo que BeginGroup
// (dashboard_grid) no hace — necesario para que el BeginChild dentro de
// kpi_card ocupe exactamente la celda y no desborde.
const ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchSame
| ImGuiTableFlags_NoPadOuterX;
kpi_card("Functions", static_cast<float>(stats.total_functions), 0, nullptr, 0, "%.0f");
dashboard_grid_next();
kpi_card("Types", static_cast<float>(stats.total_types), 0, nullptr, 0, "%.0f");
dashboard_grid_next();
kpi_card("Apps", static_cast<float>(stats.total_apps), 0, nullptr, 0, "%.0f");
dashboard_grid_next();
kpi_card("Analysis", static_cast<float>(stats.total_analysis), 0, nullptr, 0, "%.0f");
dashboard_grid_next();
kpi_card("Unit Tests", static_cast<float>(stats.total_unit_tests), 0, nullptr, 0, "%.0f");
dashboard_grid_next();
kpi_card("Proposals", static_cast<float>(stats.total_proposals), 0, nullptr, 0, "%.0f");
dashboard_grid_next();
kpi_card("Tested", tested_pct, 0, nullptr, 0, "%.0f%%");
dashboard_grid_next();
kpi_card("Pure", pure_pct, 0, nullptr, 0, "%.0f%%");
dashboard_grid_end();
if (ImGui::BeginTable("##kpi_grid", 4, flags)) {
struct KPI { const char* label; float value; const char* fmt; };
const KPI cards[8] = {
{"Functions", static_cast<float>(stats.total_functions), "%.0f"},
{"Types", static_cast<float>(stats.total_types), "%.0f"},
{"Apps", static_cast<float>(stats.total_apps), "%.0f"},
{"Analysis", static_cast<float>(stats.total_analysis), "%.0f"},
{"Unit Tests", static_cast<float>(stats.total_unit_tests), "%.0f"},
{"Proposals", static_cast<float>(stats.total_proposals), "%.0f"},
{"Tested", tested_pct, "%.0f%%"},
{"Pure", pure_pct, "%.0f%%"},
};
for (int i = 0; i < 8; i++) {
if (i % 4 == 0) ImGui::TableNextRow();
ImGui::TableSetColumnIndex(i % 4);
kpi_card(cards[i].label, cards[i].value, 0.0f, nullptr, 0, cards[i].fmt);
}
ImGui::EndTable();
}
}
void draw_charts(RegistryData& data, float height) {