Files
graph_explorer/issues/0010-table-node.md
T

4.1 KiB

id, title, status, priority, created, depends_on
id title status priority created depends_on
0010 Nodo tabla — contenedor cuadrado con filas que son nodos del grafo pending medium 2026-04-30
0004
0005
0008

Objetivo

Un tipo especial de nodo, Table, que se renderiza en el viewport como un rectangulo (no circulo) y agrupa visualmente N entidades del grafo. Cada fila de la tabla = un nodo real del grafo (con su type_ref, sus fields, sus tags). Las filas se pueden extraer (salen al canvas como nodos sueltos) y meter (un nodo suelto entra como fila).

Distinto del issue 0004 (vista tabla global por tipo): ese es una ventana auxiliar que tabula entidades existentes; este es un nodo en el grafo que existe en entities y posee filas via relaciones.

Modelo de datos

  • El nodo tabla es una entidad normal con type_ref = 'Table' y metadata:
    {
      "row_type": "Person",                   // tipo esperado de las filas (puede ser vacio = mixto)
      "columns": ["name","age","email"],      // subset de fields del row_type a mostrar como columnas
      "expanded": true                         // estado de UI persistido
    }
    
  • La pertenencia se modela con relaciones:
    • name = "CONTAINS_ROW", from_entity = <table_id>, to_entity = <row_entity_id>, order = N.
  • Una fila puede pertenecer a varias tablas (varias relaciones CONTAINS_ROW apuntando al mismo nodo). Confirmado en la conversacion.
  • Las columnas pueden ser fijas (row_type definido → columnas = subset de los fields de ese tipo) o libres (definidas por el creador de la tabla en columns).

Render en viewport

  • Forma: square o rounded_square con tamano dependiente del numero de filas (clamp a min/max).
  • Cuando esta colapsada: caja con titulo + contador (Table · 23 filas).
  • Cuando esta expandida: caja crece y dibuja un grid interno (filas x columnas) con los valores principales. Las filas son arrastrables individualmente.
  • Las relaciones CONTAINS_ROW no se dibujan como aristas normales (serian ruido visual). En su lugar, una fila extraida muestra una arista fina punteada hacia su tabla de origen.
  • Aristas entrantes/salientes del nodo tabla se dibujan al borde del rectangulo, no al centro.

Operaciones

  • Crear tabla: en context menu del viewport, "New table here". Pide row_type opcional. Crea entidad Table y la posiciona donde el click.
  • Anadir fila (tabla expandida o seleccionada): boton "+ row" que crea una entidad nueva con type_ref = row_type (si esta definido) y la engancha via CONTAINS_ROW.
  • Extraer fila: borra la relacion CONTAINS_ROW. La fila queda como nodo libre, posicionada al lado de la tabla.
  • Extraer multiples: shift+click en filas dentro de la tabla expandida, "Extract selected".
  • Meter fila: drag de un nodo sobre el rectangulo de una tabla. Confirm dialog si su type_ref no coincide con row_type de la tabla.
  • Editar fila: doble-click en fila → abre Inspector con esa entidad seleccionada.

Cambios en codigo

  • entity_ops:
    • bool table_create(db_path, name, row_type, columns_csv, char* out_id).
    • bool table_add_row(db_path, table_id, char* out_row_id) (crea entidad + relacion CONTAINS_ROW).
    • bool table_extract_row(db_path, table_id, row_id) (borra solo la relacion).
    • bool table_attach_row(db_path, table_id, row_id, int order).
    • bool table_list_rows(db_path, table_id, vector<string>* out_row_ids).
  • Renderer del viewport (graph_viewport.cpp y/o graph_renderer): branch para is_table_node (detectado por type_ref == "Table") que dibuja rectangulo + grid expandido y devuelve hit-testing por filas individuales.
  • graph_load_from_operations: filtrar las aristas CONTAINS_ROW para que no entren en el layout fisico (no aplican fuerzas).

Definicion de hecho

  • Crear tabla, anadir filas, extraer y meter filas funciona round-trip via SQLite.
  • Tabla colapsada y expandida se renderizan correctamente en el viewport.
  • Doble-click en fila enfoca el Inspector con esa entidad.
  • Una fila puede pertenecer a varias tablas sin duplicarse.
  • Borrar la tabla pregunta: "borrar tabla y todas sus filas" o "extraer filas y borrar solo la tabla".