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>
6.0 KiB
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:
treemap_cpp_viz— squarified treemap (Bruls, Huijbrechts, van Wijk) para jerarquias planas con valores. Click hace zoom (opcional MVP: solo render).sankey_cpp_viz— sankey diagram para flujossource → targetcon magnitudes.chord_cpp_viz— chord diagram para matrices de relaciones N×N (ej: flujos entre N entidades).contour_cpp_viz— contour plot de un grid 2D escalar (marching squares con N niveles).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_computecon marching squares clasico (16 casos), interp lineal entre celdas. - 4.2 Render:
AddPolylinepor 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.cppcon 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 showpara 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.