feat(primitives_gallery): demos para los 5 charts cientificos (issue 0034)
Anade 5 entradas a la gallery (treemap, sankey, chord, contour, voronoi) con datos sinteticos coherentes: - treemap: 6 items 'gastos por categoria' - sankey: 8 nodos clientes -> productos -> categorias (DAG) - chord: matriz 6x6 simetrica de flujos entre paises - contour: mezcla de 2 gaussianas 32x32 + 5 niveles - voronoi: 30 seeds aleatorias + colores aleatorios Wire-up additions only (demos.h, main.cpp k_demos[], CMakeLists.txt).
This commit is contained in:
@@ -8,6 +8,7 @@ add_imgui_app(primitives_gallery
|
||||
demos_text_editor.cpp
|
||||
demos_gl_texture.cpp
|
||||
demos_extras.cpp
|
||||
demos_scientific.cpp
|
||||
# text_editor + file_watcher (issue 0025)
|
||||
${CMAKE_SOURCE_DIR}/functions/core/text_editor.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/core/file_watcher.cpp
|
||||
@@ -39,6 +40,12 @@ add_imgui_app(primitives_gallery
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/gauge.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/heatmap.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/table_view.cpp
|
||||
# Scientific viz (issue 0034)
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/treemap.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/sankey.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/chord.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/contour.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/voronoi.cpp
|
||||
# Graph stack (instanced GPU + Barnes-Hut + spatial hash)
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/graph_types.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/viz/graph_renderer.cpp
|
||||
|
||||
@@ -34,6 +34,11 @@ void demo_candlestick();
|
||||
void demo_gauge();
|
||||
void demo_heatmap();
|
||||
void demo_table_view();
|
||||
void demo_treemap(); // issue 0034
|
||||
void demo_sankey(); // issue 0034
|
||||
void demo_chord(); // issue 0034
|
||||
void demo_contour(); // issue 0034
|
||||
void demo_voronoi(); // issue 0034
|
||||
|
||||
// --- Gfx ---
|
||||
void demo_shader_canvas();
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
// demos_scientific.cpp — demos para los 5 charts cientificos del issue 0034:
|
||||
// treemap, sankey, chord, contour, voronoi.
|
||||
|
||||
#include "demos.h"
|
||||
#include "demo.h"
|
||||
|
||||
#include "viz/treemap.h"
|
||||
#include "viz/sankey.h"
|
||||
#include "viz/chord.h"
|
||||
#include "viz/contour.h"
|
||||
#include "viz/voronoi.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
namespace gallery {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// treemap
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_treemap() {
|
||||
demo_header("treemap", "v1.0.0",
|
||||
"Squarified treemap (Bruls et al.) para jerarquias planas con valores. "
|
||||
"Algoritmo puro separado del render.");
|
||||
|
||||
section("Gastos por categoria");
|
||||
{
|
||||
std::vector<TreemapItem> items = {
|
||||
{"vivienda", 950.0f, IM_COL32(180, 120, 200, 255)},
|
||||
{"comida", 320.0f, IM_COL32(120, 180, 200, 255)},
|
||||
{"transporte", 180.0f, IM_COL32(200, 180, 120, 255)},
|
||||
{"ocio", 140.0f, IM_COL32(200, 120, 160, 255)},
|
||||
{"salud", 90.0f, IM_COL32(120, 200, 160, 255)},
|
||||
{"otros", 60.0f, IM_COL32(160, 160, 200, 255)},
|
||||
};
|
||||
treemap("##gastos", items, ImVec2(-1, 320));
|
||||
}
|
||||
|
||||
code_block(
|
||||
"std::vector<TreemapItem> items = {\n"
|
||||
" {\"vivienda\", 950.0f, IM_COL32(180,120,200,255)},\n"
|
||||
" {\"comida\", 320.0f, IM_COL32(120,180,200,255)},\n"
|
||||
" ...\n"
|
||||
"};\n"
|
||||
"treemap(\"##gastos\", items, ImVec2(-1, 320));"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// sankey
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_sankey() {
|
||||
demo_header("sankey", "v1.0.0",
|
||||
"Sankey diagram para flujos source -> target. BFS topologico para columnas, "
|
||||
"bandas curvas (bezier cubico) para los links. Asume DAG.");
|
||||
|
||||
section("Clientes -> productos -> categorias");
|
||||
{
|
||||
std::vector<SankeyNode> nodes = {
|
||||
{"premium"}, {"basicos"},
|
||||
{"laptops"}, {"phones"}, {"tablets"},
|
||||
{"hardware"}, {"software"}, {"servicios"},
|
||||
};
|
||||
std::vector<SankeyLink> links = {
|
||||
// clientes -> productos
|
||||
{0, 2, 80}, {0, 3, 30}, {0, 4, 15},
|
||||
{1, 3, 60}, {1, 4, 40}, {1, 2, 20},
|
||||
// productos -> categorias
|
||||
{2, 5, 70}, {2, 6, 30},
|
||||
{3, 5, 50}, {3, 7, 40},
|
||||
{4, 6, 35}, {4, 7, 20},
|
||||
};
|
||||
sankey("##flow", nodes, links, ImVec2(-1, 360));
|
||||
}
|
||||
|
||||
code_block(
|
||||
"std::vector<SankeyNode> nodes = {{\"premium\"}, {\"basicos\"}, ...};\n"
|
||||
"std::vector<SankeyLink> links = {{0, 2, 80}, {0, 3, 30}, ...};\n"
|
||||
"sankey(\"##flow\", nodes, links, ImVec2(-1, 360));"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// chord
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_chord() {
|
||||
demo_header("chord", "v1.0.0",
|
||||
"Chord diagram para matrices NxN. Arcos proporcionales a sum(row) + cuerdas "
|
||||
"internas con bezier cubico.");
|
||||
|
||||
section("Flujos entre paises (matriz 6x6 simetrica)");
|
||||
{
|
||||
constexpr int N = 6;
|
||||
// simetrica de "comercio" entre 6 paises
|
||||
static float M[N * N] = {
|
||||
0, 10, 6, 12, 4, 3,
|
||||
10, 0, 14, 3, 8, 2,
|
||||
6, 14, 0, 9, 11, 5,
|
||||
12, 3, 9, 0, 7, 6,
|
||||
4, 8, 11, 7, 0, 13,
|
||||
3, 2, 5, 6, 13, 0,
|
||||
};
|
||||
static const char* labels[N] = {"ESP", "FRA", "ITA", "DEU", "PRT", "GBR"};
|
||||
chord("##chord", M, N, labels, ImVec2(420, 420));
|
||||
}
|
||||
|
||||
code_block(
|
||||
"float M[N*N] = { // simetrica\n"
|
||||
" 0, 10, 6, 12, 4, 3,\n"
|
||||
" 10, 0, 14, 3, 8, 2,\n"
|
||||
" ...\n"
|
||||
"};\n"
|
||||
"const char* labels[6] = {\"ESP\",\"FRA\",\"ITA\",\"DEU\",\"PRT\",\"GBR\"};\n"
|
||||
"chord(\"##c\", M, 6, labels);"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// contour
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_contour() {
|
||||
demo_header("contour", "v1.0.0",
|
||||
"Contour plot 2D via marching squares. Para una gaussiana centrada los "
|
||||
"contornos resultantes son aproximadamente concentricos.");
|
||||
|
||||
constexpr int N = 32;
|
||||
static float grid[N * N];
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
// Mezcla de 2 gaussianas (peak central + secundario)
|
||||
for (int y = 0; y < N; y++) {
|
||||
for (int x = 0; x < N; x++) {
|
||||
float dx1 = x - N * 0.45f, dy1 = y - N * 0.5f;
|
||||
float dx2 = x - N * 0.75f, dy2 = y - N * 0.3f;
|
||||
float v = std::exp(-(dx1 * dx1 + dy1 * dy1) / 70.0f)
|
||||
+ 0.55f * std::exp(-(dx2 * dx2 + dy2 * dy2) / 30.0f);
|
||||
grid[y * N + x] = v;
|
||||
}
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
static const float levels[] = {0.15f, 0.30f, 0.50f, 0.70f, 0.90f};
|
||||
contour("##gauss", grid, N, N, levels, 5, ImVec2(-1, 320));
|
||||
|
||||
code_block(
|
||||
"constexpr int N = 32;\n"
|
||||
"float grid[N*N];\n"
|
||||
"for (int y = 0; y < N; y++)\n"
|
||||
" for (int x = 0; x < N; x++) {\n"
|
||||
" float dx = x - N/2.0f, dy = y - N/2.0f;\n"
|
||||
" grid[y*N + x] = std::exp(-(dx*dx + dy*dy) / 80.0f);\n"
|
||||
" }\n"
|
||||
"float levels[] = {0.15f, 0.30f, 0.50f, 0.70f, 0.90f};\n"
|
||||
"contour(\"##gauss\", grid, N, N, levels, 5);"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// voronoi
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_voronoi() {
|
||||
demo_header("voronoi", "v1.0.0",
|
||||
"Diagrama de Voronoi via raster brute-force (MVP). Tiles 4x4 px coloreados "
|
||||
"por el seed mas cercano. Suficiente para N <= 200.");
|
||||
|
||||
constexpr int N = 30;
|
||||
static ImVec2 seeds [N];
|
||||
static ImU32 colors[N];
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
unsigned seed = 7;
|
||||
auto rnd = [&]() {
|
||||
seed = seed * 1103515245u + 12345u;
|
||||
return (float)((seed >> 16) & 0x7fff) / 32768.0f;
|
||||
};
|
||||
// El render escala automaticamente; las posiciones se asumen en coords del rect.
|
||||
// Como no sabemos W/H aqui, usamos coords aproximadas para 600x300 y el clip
|
||||
// dentro de voronoi se encarga de mantenerlas en rango.
|
||||
for (int i = 0; i < N; i++) {
|
||||
seeds [i] = ImVec2(rnd() * 600.0f, rnd() * 300.0f);
|
||||
colors[i] = IM_COL32(40 + (int)(rnd() * 200),
|
||||
40 + (int)(rnd() * 200),
|
||||
60 + (int)(rnd() * 195),
|
||||
230);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
voronoi("##v", seeds, N, colors, ImVec2(-1, 300));
|
||||
|
||||
code_block(
|
||||
"ImVec2 seeds[30];\n"
|
||||
"ImU32 colors[30];\n"
|
||||
"for (int i = 0; i < 30; i++) {\n"
|
||||
" seeds [i] = ImVec2(rnd() * 600.0f, rnd() * 300.0f);\n"
|
||||
" colors[i] = IM_COL32(rnd_byte(), rnd_byte(), rnd_byte(), 230);\n"
|
||||
"}\n"
|
||||
"voronoi(\"##v\", seeds, 30, colors, ImVec2(-1, 300));"
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gallery
|
||||
@@ -61,6 +61,11 @@ static const DemoEntry k_demos[] = {
|
||||
{"gauge", "gauge", "Viz", &gallery::demo_gauge},
|
||||
{"heatmap", "heatmap", "Viz", &gallery::demo_heatmap},
|
||||
{"table_view", "table_view", "Viz", &gallery::demo_table_view},
|
||||
{"treemap", "treemap", "Viz", &gallery::demo_treemap},
|
||||
{"sankey", "sankey", "Viz", &gallery::demo_sankey},
|
||||
{"chord", "chord", "Viz", &gallery::demo_chord},
|
||||
{"contour", "contour", "Viz", &gallery::demo_contour},
|
||||
{"voronoi", "voronoi", "Viz", &gallery::demo_voronoi},
|
||||
// Gfx (shaders_lab core)
|
||||
{"shader_canvas", "shader_canvas", "Gfx", &gallery::demo_shader_canvas},
|
||||
{"gl_texture", "gl_texture_load", "Gfx", &gallery::demo_gl_texture}, // wave 1
|
||||
|
||||
Reference in New Issue
Block a user