Cuando una funcion del registry parte su .cpp en varios TUs por testabilidad o separacion ImGui-vs-puro, cada TU adicional se registra como entrada propia con su .md en lugar de extender file_path para listar varios archivos. Aplicado a: - graph_labels_select_cpp_viz: helpers puros (compute_degrees + labels_select). - graph_viewport_selection_cpp_viz: clear/add/toggle/is_selected puros. - graph_types_cpp_viz: TU de update_bounds + find_node_by_user_data. graph_labels y graph_viewport actualizados para declarar las nuevas entradas en uses_functions. Razon detallada en docs/adr/0003 + regla actualizada en .claude/rules/uses_functions.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.1 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, tested, tests, test_file_path, uses_types, returns, returns_optional, error_type, imports, file_path, framework, props, emits, has_state, params, output
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | tested | tests | test_file_path | uses_types | returns | returns_optional | error_type | imports | file_path | framework | props | emits | has_state | params | output | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| graph_viewport | component | cpp | viz | 1.2.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 |
|
|
true |
|
cpp/tests/test_graph_viewport.cpp |
|
false | error_go_core |
|
cpp/functions/viz/graph_viewport.cpp | imgui |
|
true |
|
true si hubo alguna interaccion del usuario en el frame actual (hover, click, drag, zoom, teclado, lasso, callbacks) |
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 (sobre area vacia) |
| Zoom | Rueda del raton (hacia el cursor) |
| Seleccionar nodo (single) | Click izquierdo sobre nodo |
| Toggle nodo en seleccion | Ctrl + Click izquierdo |
| Lasso (multi-seleccion) | Shift + Click izquierdo + arrastrar sobre area vacia |
| Arrastrar seleccion entera | Click izquierdo sobre nodo seleccionado + arrastrar |
| Menu contextual | Click derecho sobre nodo (callback on_context_menu) |
| Activar (double-click) | Doble click sobre nodo (callback on_double_click) |
| Limpiar seleccion | Esc, o click en area vacia |
| 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.2 (2026-04-29, issue 0049i): multi-seleccion con
state.selection, lasso (Shift+Drag sobre area vacia), drag de seleccion entera (todos los nodos seleccionados pinnean y se mueven juntos), Ctrl+click toggle, Esc limpia seleccion. Callbacks opcionalesGraphViewportCallbackspara right-click (menu contextual) y double-click. Los nodos arrastrados se quedan pinned al soltar. Tooltip suprimido durante drag/lasso. Helpers expuestos:graph_viewport_clear_selection,graph_viewport_add_to_selection,graph_viewport_toggle_selection,graph_viewport_is_selected. Tests:cpp/tests/test_graph_viewport.cpp. - 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.
Split de TU (2026-05-04, ADR 0003)
Los helpers puros graph_viewport_clear_selection, graph_viewport_is_selected,
graph_viewport_add_to_selection y graph_viewport_toggle_selection viven en
graph_viewport_selection.cpp y se indexan como entrada propia
graph_viewport_selection_cpp_viz. Esta entrada solo cubre el widget completo
con pan/zoom/click (impuro, ImGui).
Apps que reusan graph_viewport enlazan ambos .cpp y declaran ambas IDs en
su app.md. Apps que solo necesitan la maquinaria de seleccion (poco probable)
pueden declarar solo graph_viewport_selection_cpp_viz.