---
id: "0034"
title: "C++ scientific viz (treemap, sankey, chord, contour, voronoi)"
status: completado
type: feature
domain:
  - cpp-stack
scope: multi-app
priority: media
depends: []
blocks: []
related: []
created: 2026-05-17
updated: 2026-05-17
tags: []
---
# 0034 — C++ scientific viz (treemap, sankey, chord, contour, voronoi)

## APP Metadata

| Campo | Valor |
|-------|-------|
| **ID** | 0034 |
| **Estado** | pendiente |
| **Prioridad** | media |
| **Tipo** | feature — C++ viz (cpp/functions/viz) |

## Dependencias

`tokens_cpp_core`, `plot_theme_cpp_core`. ImPlot ya vendoreado. Sin bloqueos por otros issues.

**Desbloquea:** dashboards con tipos de visualizacion mas alla de bar/line/scatter — utiles para jerarquias, flujos, relaciones, distribuciones 2D continuas.

---

## Objetivo

Cinco componentes nuevos en `cpp/functions/viz/`, cada uno con su demo en gallery:

1. **`treemap_cpp_viz`** — squarified treemap (Bruls, Huijbrechts, van Wijk) para jerarquias planas con valores. Click hace zoom (opcional MVP: solo render).
2. **`sankey_cpp_viz`** — sankey diagram para flujos `source → target` con magnitudes.
3. **`chord_cpp_viz`** — chord diagram para matrices de relaciones N×N (ej: flujos entre N entidades).
4. **`contour_cpp_viz`** — contour plot de un grid 2D escalar (marching squares con N niveles).
5. **`voronoi_cpp_viz`** — diagrama de Voronoi (Fortune o aproximacion via ImGui draw): regiones coloreadas a partir de N seeds.

Todos los layouts/algoritmos deben ser **puros**; el render usa primitivas ImGui DrawList (`AddTriangleFilled`, `AddBezierQuadratic`, etc.).

## Contexto

`cpp/functions/viz/` cubre charts standard (bar/line/scatter/heatmap/histogram/pie/candlestick/sparkline + table + graph). Faltan las visualizaciones "narrativas" tipicas de dashboards mas avanzados.

Implementar 5 a la vez es viable porque comparten la misma estructura: `compute_layout` puro + `render` con DrawList.

## Arquitectura

```
cpp/functions/viz/
├── treemap.h/.cpp/.md           # NEW
├── sankey.h/.cpp/.md            # NEW
├── chord.h/.cpp/.md             # NEW
├── contour.h/.cpp/.md           # NEW
└── voronoi.h/.cpp/.md           # NEW
cpp/apps/primitives_gallery/
├── demos_scientific.cpp         # NEW (5 demos en un archivo)
├── demos.h                      # MOD
├── main.cpp                     # MOD
└── CMakeLists.txt               # MOD
```

### API propuesta

```cpp
namespace fn {

// --- treemap ---
struct TreemapItem { std::string label; float value; ImU32 color; };
struct TreemapRect { ImVec2 min, max; const TreemapItem* item; };
std::vector<TreemapRect> treemap_layout(const std::vector<TreemapItem>&, ImVec2 region);  // pure
void treemap(const char* id, const std::vector<TreemapItem>&, ImVec2 size = {-1, 300});

// --- sankey ---
struct SankeyNode { std::string label; };
struct SankeyLink { int src, dst; float value; };
void sankey(const char* id,
            const std::vector<SankeyNode>&, const std::vector<SankeyLink>&,
            ImVec2 size = {-1, 400});

// --- chord ---
void chord(const char* id,
           const float* matrix, int n, const char* const* labels,
           ImVec2 size = {400, 400});

// --- contour ---
struct ContourLine { std::vector<ImVec2> pts; float level; };
std::vector<ContourLine> contour_compute(const float* grid, int nx, int ny, const float* levels, int n_levels);  // pure (marching squares)
void contour(const char* id, const float* grid, int nx, int ny, const float* levels, int n_levels,
             ImVec2 size = {-1, 300});

// --- voronoi ---
struct VoronoiCell { std::vector<ImVec2> polygon; ImVec2 seed; ImU32 color; };
std::vector<VoronoiCell> voronoi_layout(const ImVec2* seeds, int n, ImVec2 region);  // pure
void voronoi(const char* id, const ImVec2* seeds, int n, const ImU32* colors, ImVec2 size = {-1, 300});
}
```

## Tareas

### Fase 1 — treemap

- 1.1 Implementar squarified algorithm (recursivo, O(n log n)).
- 1.2 Render con `AddRectFilled` + `AddText` (label si cabe).
- 1.3 Tests con 5 items conocidos.
- 1.4 `.md`.

### Fase 2 — sankey

- 2.1 Asignar nodos a columnas via topological levels (BFS desde sources).
- 2.2 Stack vertical de cada columna por valor; calcular Y offset por link.
- 2.3 Render: rectangulos para nodos + bezier cubic para links.
- 2.4 `.md`.

### Fase 3 — chord

- 3.1 Calcular angulos por nodo proporcionales a `sum(matrix[i,*])`.
- 3.2 Arcos en el borde del circulo + bezier interno entre arcos.
- 3.3 `.md`.

### Fase 4 — contour

- 4.1 `contour_compute` con marching squares clasico (16 casos), interp lineal entre celdas.
- 4.2 Render: `AddPolyline` por cada level, color por level (gradiente).
- 4.3 Tests con grid conocido (gaussiana → contornos circulares).
- 4.4 `.md`.

### Fase 5 — voronoi

- 5.1 MVP: implementacion brute-force (para cada pixel, encontrar seed mas cercana). Para N pequeño (<200) y region <500², es < 1ms.
- 5.2 Para layout poligonal: usar half-plane intersections (mas complejo). MVP puede renderizar como raster a una textura cacheada.
- 5.3 `.md`.

### Fase 6 — Gallery demos

- 6.1 `demos_scientific.cpp` con 5 funciones, una por chart, datos sinteticos coherentes (treemap: gastos por categoria; sankey: flujos cliente→producto; chord: relaciones entre paises; contour: gaussiana mezcla; voronoi: 30 seeds aleatorios).
- 6.2 Registrar en gallery.

### Fase 7 — Tests + docs

- 7.1 Tests por componente (algorithm puro, no render).
- 7.2 `./fn index` + `./fn show` para los 5.

## Ejemplo de uso

```cpp
std::vector<fn::TreemapItem> items = {
    {"comida", 320, IM_COL32(120,180,200,255)},
    {"vivienda", 950, IM_COL32(180,120,200,255)},
    {"transporte", 180, IM_COL32(200,180,120,255)},
};
fn::treemap("##gastos", items);
```

## Decisiones de diseño

- **Render con DrawList** (no ImPlot) para chart types que ImPlot no soporta nativo.
- **Layout puro separado del render**: facilita tests y reuso (treemap → exportar a SVG futuro).
- **Voronoi raster en MVP**: simple, suficiente. Si hace falta poligonos, otro issue.

## Riesgos

- **Tamaño del issue**: 5 charts es mucho. Mitigacion: comparten patron y un archivo `demos_scientific.cpp`. Si un agente no termina, sub-issue por chart.
- **Voronoi performance**: documentar limite practico N <= 200.
- **Sankey con grafo ciclico**: assumir DAG; documentar.
