Files
fn_registry/dev/issues/0034-cpp-scientific-viz.md
T
egutierrez 461bb77298 docs(issues): añadir 0025-0036 — features C++ para registry y primitives_gallery
12 issues nuevos para implementacion paralela: text_editor, file_watcher,
gl_texture_load, gl_compute+pingpong+DAG Compute, ImPlot3D, mesh_viewer,
audio reactivo, animation curves, sql_workbench, http+ws inspector,
scientific viz (5 charts), map_tiles, image_canvas + webcam_texture.

Cada issue añade funciones al registry y un demo propio en
primitives_gallery/demos_<feature>.cpp para minimizar conflictos en paralelo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 20:48:18 +02:00

6.0 KiB
Raw Blame History

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

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.
  • 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

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.