63 lines
2.9 KiB
Markdown
63 lines
2.9 KiB
Markdown
---
|
|
name: bar_chart
|
|
kind: component
|
|
lang: cpp
|
|
domain: viz
|
|
version: "1.2.0"
|
|
purity: pure
|
|
signature: "void bar_chart(const char* title, const char* const* labels, const float* values, int count, float bar_width = 0.67f, float height = 200.0f)"
|
|
description: "Barras verticales ImPlot con ejes pineados, altura explicita, tooltip al hover y auto-rotacion 45 de labels cuando no caben horizontales"
|
|
tags: [implot, chart, visualization, gpu, bar, tooltip, rotated-labels, locked-axes]
|
|
uses_functions: ["plot_static_cpp_viz"]
|
|
uses_types: []
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: ""
|
|
imports: [implot]
|
|
tested: true
|
|
tests:
|
|
- "y_range covers all positive values"
|
|
- "y_range includes zero baseline"
|
|
- "y_range with negatives extends below zero"
|
|
- "y_range with empty data is sane default"
|
|
- "y_range with single value still has span"
|
|
- "clamp_bar_width clamps to [0.05, 1.0]"
|
|
test_file_path: "cpp/tests/test_bar_chart_math.cpp"
|
|
file_path: "cpp/functions/viz/bar_chart.cpp"
|
|
framework: imgui
|
|
params:
|
|
- name: title
|
|
desc: "Titulo / id interno del plot"
|
|
- name: labels
|
|
desc: "Array de etiquetas para el eje X, una por barra"
|
|
- name: values
|
|
desc: "Array de valores numericos (altura de cada barra)"
|
|
- name: count
|
|
desc: "Numero de barras (longitud de labels y values)"
|
|
- name: bar_width
|
|
desc: "Ancho de cada barra como fraccion del hueco de celda (default 0.67)"
|
|
- name: height
|
|
desc: "Altura del plot en pixeles (default 200). Explicita para evitar feedback loops con AutoResizeY"
|
|
output: "Renderiza barras, tooltip al hover con label+valor, y si los labels horizontales no caben los dibuja rotados 45 grados"
|
|
notes: "consumido por cpp/apps/chart_demo/main.cpp; scaffolding/demo en primitives_gallery"
|
|
---
|
|
|
|
# bar_chart
|
|
|
|
Barras verticales ImPlot pensadas para dashboards. Tres cosas no triviales:
|
|
|
|
1. **Ejes pineados** — `plot_static::kPlotFlags` + `kAxisFlags` (Lock + NoInitialFit + Cond_Always) con `y_max` pre-calculado + 15% headroom. Sin esto ImPlot auto-fitea cada frame y las barras oscilan.
|
|
2. **Tooltip** — si `IsPlotHovered()`, detecta la barra bajo el cursor (`round(mouse.x)` con tolerancia `bar_width/2`) y muestra `label` + valor.
|
|
3. **Labels auto-rotados** — mide la suma de `CalcTextSize(label) + 12px` contra el ancho del plot; si no caben, dibuja los labels rotados 45° manualmente con `ImDrawList::PrimQuadUV` + glyphs del font atlas (`ImFontBaked::FindGlyph` — API ImGui 1.92+). Reserva 48px abajo del plot para los labels rotados. Si caben se usan los ticks horizontales normales de ImPlot.
|
|
|
|
Altura explicita (`height`) rompe el feedback loop con contenedores `AutoResizeY` (ver `viz/plot_static.h`).
|
|
|
|
## Ejemplo
|
|
|
|
```cpp
|
|
const char* domains[] = {"core", "finance", "cybersecurity", "datascience", "infra"};
|
|
float counts[] = {412, 187, 94, 63, 36};
|
|
bar_chart("##domains", domains, counts, 5); // horizontal si cabe
|
|
bar_chart("##domains", domains, counts, 5, 0.8f, 240); // rotated si no cabe
|
|
```
|