feat: add C++ ImGui functions for core UI and visualization
Funciones C++/ImGui para dashboards (grid, panel, docking, sidebar, tabs), visualizaciones (candlestick, gauge, histogram, pie, sparkline, heatmap, scatter, line, bar, surface3d, kpi, table), grafos (force layout, renderer, viewport, spatial hash, types) y utilidades (time series buffer, tracy zones, memory/fps overlay, plot theme). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
---
|
||||
name: graph_viewport
|
||||
kind: component
|
||||
lang: cpp
|
||||
domain: viz
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "bool graph_viewport(const char* id, GraphData& graph, GraphViewportState& state, ImVec2 size)"
|
||||
description: "Widget ImGui completo para visualizacion interactiva de grafos con pan, zoom, hover, seleccion y layout en vivo"
|
||||
tags: [graph, viewport, imgui, interactive, pan, zoom, dashboard]
|
||||
uses_functions: ["graph_renderer_cpp_viz", "graph_force_layout_cpp_viz", "graph_spatial_hash_cpp_core"]
|
||||
uses_types: ["GraphData_cpp_viz"]
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: [imgui]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "cpp/functions/viz/graph_viewport.cpp"
|
||||
framework: imgui
|
||||
props:
|
||||
- name: id
|
||||
type: "const char*"
|
||||
required: true
|
||||
description: "Identificador unico del widget ImGui"
|
||||
- name: graph
|
||||
type: "GraphData&"
|
||||
required: true
|
||||
description: "Referencia al grafo (lectura de datos, escritura de posiciones al drag)"
|
||||
- name: state
|
||||
type: "GraphViewportState&"
|
||||
required: true
|
||||
description: "Estado persistente del viewport (camera, seleccion, renderer). Debe vivir mas que los frames."
|
||||
- name: size
|
||||
type: "ImVec2"
|
||||
required: false
|
||||
description: "Tamanio del widget en pixeles. ImVec2(0,0) usa todo el espacio disponible."
|
||||
emits: []
|
||||
has_state: true
|
||||
params:
|
||||
- name: id
|
||||
desc: "Identificador unico del widget ImGui. Debe ser estable entre frames."
|
||||
- name: graph
|
||||
desc: "Grafo a visualizar. Las posiciones de nodos se modifican al arrastrar."
|
||||
- name: state
|
||||
desc: "Estado persistente: camara (cam_x, cam_y, zoom), nodo seleccionado/hovereado, renderer GPU, spatial hash. Alojado por el caller."
|
||||
- name: size
|
||||
desc: "Tamanio del widget en pixeles. (0,0) ocupa todo el espacio disponible en la ventana ImGui."
|
||||
output: "true si hubo alguna interaccion del usuario en el frame actual (hover, click, drag, zoom, teclado)"
|
||||
---
|
||||
|
||||
# graph_viewport
|
||||
|
||||
Widget ImGui self-contained para visualizar grafos interactivos. Integra rendering GPU, force-directed layout y hit-testing espacial en una sola llamada por frame.
|
||||
|
||||
## Uso basico
|
||||
|
||||
```cpp
|
||||
// Declarar estado persistente (fuera del loop de render)
|
||||
GraphViewportState vp_state;
|
||||
|
||||
// En el loop de render (dentro de una ventana ImGui):
|
||||
if (graph_viewport("mi_grafo", my_graph, vp_state)) {
|
||||
// hubo interaccion este frame
|
||||
if (vp_state.selected_node >= 0) {
|
||||
auto& n = my_graph.nodes[vp_state.selected_node];
|
||||
// mostrar panel de detalle de n
|
||||
}
|
||||
}
|
||||
|
||||
// Al terminar:
|
||||
graph_viewport_destroy(vp_state);
|
||||
```
|
||||
|
||||
## Estado de camara
|
||||
|
||||
La camara usa coordenadas del espacio del grafo:
|
||||
|
||||
- `cam_x`, `cam_y`: centro de la camara en espacio del grafo
|
||||
- `zoom`: pixeles por unidad de grafo
|
||||
|
||||
`graph_viewport_fit()` centra y ajusta el zoom para que el grafo quepa con 10% de padding.
|
||||
|
||||
## Controles
|
||||
|
||||
| Accion | Control |
|
||||
|--------|---------|
|
||||
| Pan | Boton medio o derecho + arrastrar |
|
||||
| Zoom | Rueda del raton (hacia el cursor) |
|
||||
| Seleccionar nodo | Click izquierdo |
|
||||
| Arrastrar nodo | Click izquierdo sobre nodo |
|
||||
| Toggle layout | Barra espaciadora |
|
||||
| Fit camara | F |
|
||||
|
||||
## Force layout
|
||||
|
||||
El layout se ejecuta automaticamente cada frame mientras `state.layout_running == true`. Se detiene solo cuando la energia cinetica cae por debajo de `0.01`. Se puede pausar/reanudar con la barra espaciadora.
|
||||
|
||||
Los nodos arrastrados se marcan como `pinned = true` durante el drag, impidiendo que el force layout los mueva. Al soltar, `pinned` vuelve a `false`.
|
||||
|
||||
## Tooltip
|
||||
|
||||
Al hacer hover sobre un nodo se muestra un tooltip con: label, id numerico, community, degree (aristas conectadas) y value.
|
||||
|
||||
## Status bar
|
||||
|
||||
En la parte inferior del widget aparece: numero de nodos, aristas, zoom actual, energia del layout y recordatorio de atajos de teclado.
|
||||
|
||||
## Inicializacion lazy
|
||||
|
||||
El renderer OpenGL y el spatial hash se crean en el primer frame. La camara se ajusta automaticamente con `graph_viewport_fit` en la inicializacion.
|
||||
|
||||
## Notas de implementacion
|
||||
|
||||
- Usa `ImGui::InvisibleButton` con flags para los tres botones del raton, capturando input sin dibujar ningun boton visible.
|
||||
- La textura del renderer se muestra con UV volteado en Y (`ImVec2(0,1)` a `ImVec2(1,0)`) para corregir la convencion de coordenadas de OpenGL vs ImGui.
|
||||
- El spatial hash se reconstruye cada frame desde las posiciones actuales de los nodos, garantizando hit-testing correcto despues de drag o layout.
|
||||
- El zoom hacia el cursor mantiene el punto del grafo bajo el cursor fijo en pantalla ajustando `cam_x`/`cam_y`.
|
||||
Reference in New Issue
Block a user