Extiende el modelo agnostico de graph_types.h para soportar shapes/iconos/ filtros/labels/streaming sin acoplar a backend. Migra el unico consumer (demos_graph) en el mismo cambio. - GraphNode v2: type_id + shape_override/color_override/size_override + flags (NF_PINNED/VISIBLE/SELECTED/HOVERED) + label_idx + user_data. - GraphEdge v2: type_id + style_override + flags (EF_DIRECTED/VISIBLE). - EntityType / RelationType: tablas en GraphData (types, rel_types). - Helpers de resolucion (resolve_node_color/shape/size, resolve_edge_*) y constructores ergonomicos (graph_node, graph_edge, entity_type, relation_type) — sentinel-based para herencia automatica del tipo. - graph_renderer v1.4: lee NF_VISIBLE / EF_VISIBLE, resuelve apariencia via override → EntityType → fallback indexado por type_id. Skipea aristas con endpoints invisibles. Shapes siguen pintandose como circulo (0049f cableara el dispatch real). - graph_force_layout v1.2: pinned ahora vive en flags & NF_PINNED. - graph_viewport v1.1: hover/seleccion publican NF_HOVERED/SELECTED en el grafo (clear-then-set). Drag usa NF_PINNED. Tooltip muestra Type/ user_data en lugar de community/value/label. - demos_graph: 8 EntityType (paleta antigua) + 1 RelationType. type_id por cluster. user_data = indice numerico del nodo. Apariencia visual identica al pre-cambio. - test_graph_types.cpp: 12 casos cubriendo helpers, defaults, bitmask manipulation y resoluciones override-vs-EntityType. test_graph_edge_ static actualizado al nuevo modelo (ya no tiene .color directo). - 4 .md de tipos nuevos (graph_node, graph_edge, entity_type, relation_type) + GraphData v2.0 actualizado. Tests: 31/31 ctest verdes (incluye test_visual golden). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.9 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, framework, props, emits, has_state, params, output
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | tested | tests | test_file_path | file_path | framework | props | emits | has_state | params | output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| graph_viewport | component | cpp | viz | 1.1.0 | impure | bool graph_viewport(const char* id, GraphData& graph, GraphViewportState& state, ImVec2 size) | Widget ImGui completo para visualizacion interactiva de grafos con pan, zoom, hover, seleccion y layout en vivo |
|
|
|
false | error_go_core |
|
false | cpp/functions/viz/graph_viewport.cpp | imgui |
|
true |
|
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
// 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 grafozoom: 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 version
- v1.1 (2026-04-29, issue 0049e): adapta el viewport al modelo extendido. Hover/seleccion ahora se publican tambien como
flags |= NF_HOVERED/NF_SELECTEDen el grafo (clear-then-set) — losstate.hovered_node/selected_nodesiguen siendo la API estable. El drag usaflags |= NF_PINNEDen lugar del campopinneddesaparecido. El tooltip muestraType(nombre del EntityType si esta) yuser_dataen lugar decommunity/value/label/id.
Notas de implementacion
- Usa
ImGui::InvisibleButtoncon 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)aImVec2(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.