# 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 treemap_layout(const std::vector&, ImVec2 region); // pure void treemap(const char* id, const std::vector&, 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&, const std::vector&, 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 pts; float level; }; std::vector 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 polygon; ImVec2 seed; ImU32 color; }; std::vector 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 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.