---
name: GraphNode
lang: cpp
domain: viz
version: "2.0.0"
algebraic: product
definition: |
  struct GraphNode {
      float    x, y, vx, vy;
      uint16_t type_id;
      uint8_t  shape_override;
      uint8_t  flags;
      uint32_t color_override;
      float    size_override;
      uint32_t label_idx;
      uint64_t user_data;
  };
description: "Vertice del grafo: posicion, velocidad, type_id (apariencia per tipo), overrides per-nodo (color/shape/size), flags (NF_PINNED/VISIBLE/SELECTED/HOVERED), label_idx y user_data opaco para mapear a la entidad real del backend."
tags: [graph, node, vertex, type-id, flags, override, user-data]
uses_types: []
file_path: "cpp/functions/viz/graph_types.h"
---

## Campos

| Campo | Descripcion |
|---|---|
| `x, y` | Posicion en world space, modificada por el force layout |
| `vx, vy` | Velocidad usada por el integrador del layout |
| `type_id` | Indice en `GraphData::types`. Determina color/shape/size por defecto |
| `shape_override` | `SHAPE_*`. `SHAPE_USE_TYPE` (0) = heredar del EntityType |
| `flags` | Mascara `NodeFlags`: `NF_PINNED`, `NF_VISIBLE`, `NF_SELECTED`, `NF_HOVERED` |
| `color_override` | RGBA8. 0 = usar EntityType |
| `size_override` | Pixels. <= 0 = usar EntityType |
| `label_idx` | Indice en el string pool del consumer. 0 = sin label |
| `user_data` | Opaco. La app lo usa para volver a la entidad del backend (ej: id de la BD) |

## Helper

```cpp
GraphNode n = graph_node(/*x*/100.f, /*y*/200.f, /*type_id*/3);
n.flags |= NF_PINNED;
```

`graph_node()` deja `flags = NF_VISIBLE` y todos los `*_override` a 0 — el nodo
hereda apariencia del EntityType correspondiente.

## Notas de diseño

- El campo `id` (v1) desaparece. Las apps que necesiten un identificador
  estable usan `user_data` (uint64_t) — encaja IDs SQLite, hashes o
  punteros opaco-cast.
- Los overrides son sentinel-based para que un nodo creado con `graph_node()`
  herede apariencia automaticamente sin tocar mas campos.
- Tamaño: 40 bytes en x86_64. Para 100k nodos = ~4 MB.
