---
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
```
