8e11c5cfce
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>
71 lines
2.7 KiB
C++
71 lines
2.7 KiB
C++
#include "viz/bar_chart.h"
|
|
#include "implot.h"
|
|
|
|
#include <vector>
|
|
|
|
namespace {
|
|
|
|
// 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, float height) {
|
|
if (count <= 0) return;
|
|
|
|
double y_max = 0.0;
|
|
for (int i = 0; i < count; i++) {
|
|
if (static_cast<double>(values[i]) > y_max) y_max = static_cast<double>(values[i]);
|
|
}
|
|
if (y_max <= 0.0) y_max = 1.0;
|
|
y_max *= 1.15; // 15% headroom sobre la barra mas alta
|
|
|
|
const ImPlotFlags plot_flags =
|
|
ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText
|
|
| ImPlotFlags_NoInputs | ImPlotFlags_NoFrame;
|
|
|
|
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;
|
|
|
|
ImPlot::SetupAxes(nullptr, nullptr, x_flags, y_flags);
|
|
ImPlot::SetupAxisLimits(ImAxis_X1, -0.5, static_cast<double>(count) - 0.5,
|
|
ImPlotCond_Always);
|
|
ImPlot::SetupAxisLimits(ImAxis_Y1, 0.0, y_max, ImPlotCond_Always);
|
|
ImPlot::SetupAxisTicks(ImAxis_X1, positions.data(), count, labels);
|
|
|
|
ImPlot::PlotBars("##data", values, count, bar_width);
|
|
ImPlot::EndPlot();
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void bar_chart(const char* title, const char* const* labels, const float* values,
|
|
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, float height) {
|
|
draw_bars<double>(title, labels, values, count, bar_width, height);
|
|
}
|