a11a58dab0
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>
157 lines
6.0 KiB
Markdown
157 lines
6.0 KiB
Markdown
# 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.
|