feat(cpp/viz): kpi_card v1.1 + bar_chart v1.1 — contenedor y altura fijas
kpi_card: - v1.1: envuelve el contenido en BeginChild con surface bg + border + radius::md + padding::md (tokens). Replica Mantine Paper withBorder radius="md" p="md" usado en @fn_library/kpi_card.tsx. - Ancho adaptativo via GetContentRegionAvail — requiere contenedor que propague ancho constrained (ImGui::BeginTable). dashboard_grid / BeginGroup no funcionan porque no constrainen ancho y la card desborda la celda. - Linea de trend SIEMPRE visible: delta, sparkline, o em dash (text_dim) como placeholder, para que un grid de KPIs quede alineado vertical. - Colores del delta via tokens (success/error) en vez de hardcoded ImVec4. bar_chart: - v1.1: altura explicita como parametro (default 200px). Sin esto, ImPlot con ImVec2(-1, 0) entra en feedback loop cuando esta dentro de un dashboard_panel (BeginChild con AutoResizeY): plot pide espacio -> padre se redimensiona -> plot recalcula. Efecto visual: las barras se deslizan los primeros frames. - Ejes blindados: Lock + NoInitialFit + Cond_Always ademas de los flags previos. Y max pre-calculado con 15% de headroom. - Sin inputs (NoInputs|NoFrame|NoBoxSelect|NoMouseText): estos charts son de resumen, no de exploracion. Actualizados los .md correspondientes con el contrato visual + requisitos de contenedor, para que cualquier dashboard que componga estos primitivos obtenga el mismo look. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,12 +5,19 @@
|
||||
|
||||
namespace {
|
||||
|
||||
// Plot bars con ejes pineados (no se mueven entre frames) y labels categoricos.
|
||||
// ImPlot por defecto auto-fitea Y en cada frame, lo que provoca oscilacion visual.
|
||||
// Lo resolvemos calculando y_max una vez y forzandolo con ImPlotCond_Always.
|
||||
// Render bars con ejes fijos y tamano de plot explicito. Dos cosas clave:
|
||||
//
|
||||
// 1) Limites pineados con ImPlotCond_Always + Lock: ImPlot por defecto
|
||||
// auto-fitea Y cada frame, lo que provoca oscilacion visual.
|
||||
//
|
||||
// 2) Altura explicita (height > 0 -> ImVec2(-1, height)): sin esto, ImPlot
|
||||
// toma el espacio disponible del contenedor. Si el contenedor es un
|
||||
// BeginChild con AutoResizeY (como dashboard_panel), aparece un feedback
|
||||
// loop: plot pide espacio al padre -> padre se redimensiona al plot ->
|
||||
// plot recalcula -> las barras "se deslizan" en los primeros frames.
|
||||
template <typename T>
|
||||
void draw_bars(const char* title, const char* const* labels, const T* values,
|
||||
int count, double bar_width) {
|
||||
int count, double bar_width, float height) {
|
||||
if (count <= 0) return;
|
||||
|
||||
double y_max = 0.0;
|
||||
@@ -21,13 +28,21 @@ void draw_bars(const char* title, const char* const* labels, const T* values,
|
||||
y_max *= 1.15; // 15% headroom sobre la barra mas alta
|
||||
|
||||
const ImPlotFlags plot_flags =
|
||||
ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText;
|
||||
const ImPlotAxisFlags x_flags =
|
||||
ImPlotAxisFlags_NoMenus | ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoGridLines;
|
||||
const ImPlotAxisFlags y_flags =
|
||||
ImPlotAxisFlags_NoMenus | ImPlotAxisFlags_Lock;
|
||||
ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText
|
||||
| ImPlotFlags_NoInputs | ImPlotFlags_NoFrame;
|
||||
|
||||
if (ImPlot::BeginPlot(title, ImVec2(-1, 0), plot_flags)) {
|
||||
const ImPlotAxisFlags x_flags =
|
||||
ImPlotAxisFlags_NoMenus | ImPlotAxisFlags_Lock
|
||||
| ImPlotAxisFlags_NoInitialFit | ImPlotAxisFlags_NoGridLines
|
||||
| ImPlotAxisFlags_NoHighlight;
|
||||
|
||||
const ImPlotAxisFlags y_flags =
|
||||
ImPlotAxisFlags_NoMenus | ImPlotAxisFlags_Lock
|
||||
| ImPlotAxisFlags_NoInitialFit | ImPlotAxisFlags_NoHighlight;
|
||||
|
||||
const ImVec2 plot_size(-1.0f, height > 0.0f ? height : 200.0f);
|
||||
|
||||
if (ImPlot::BeginPlot(title, plot_size, plot_flags)) {
|
||||
std::vector<double> positions(count);
|
||||
for (int i = 0; i < count; i++) positions[i] = i;
|
||||
|
||||
@@ -45,11 +60,11 @@ void draw_bars(const char* title, const char* const* labels, const T* values,
|
||||
} // namespace
|
||||
|
||||
void bar_chart(const char* title, const char* const* labels, const float* values,
|
||||
int count, float bar_width) {
|
||||
draw_bars<float>(title, labels, values, count, static_cast<double>(bar_width));
|
||||
int count, float bar_width, float height) {
|
||||
draw_bars<float>(title, labels, values, count, static_cast<double>(bar_width), height);
|
||||
}
|
||||
|
||||
void bar_chart(const char* title, const char* const* labels, const double* values,
|
||||
int count, double bar_width) {
|
||||
draw_bars<double>(title, labels, values, count, bar_width);
|
||||
int count, double bar_width, float height) {
|
||||
draw_bars<double>(title, labels, values, count, bar_width, height);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user