d3da1416f3
- AppState anade `group_expanded` (unordered_map<string,bool>) en RAM,
default vacio = todos los grupos colapsados al arranque. Sin
persistencia entre sesiones (fase 1).
- `apply_group_filter(GraphData*, db_path, expanded)` consulta
entities (id, group_id, type_ref) de operations.db, marca como
ocultos los nodos cuyo group_id apunta a un grupo no expandido,
compacta `g->nodes` y re-mapea indices de aristas.
- Aristas:
* Cross-edge (un extremo oculto, otro fuera): se redirige el
extremo oculto al nodo del grupo. Sin dedup (issue 0035 dec. 5).
* Internas (ambos extremos en el mismo grupo colapsado): se ocultan.
* Inter-grupo (ambos en grupos colapsados distintos): dedup por
par no ordenado (group_a, group_b) + rel_type, una linea por par.
* Orfanas (group_id apunta a un grupo no presente en grafo): el
nodo se oculta y sus aristas se descartan.
- Centralizado: el filtro corre en `reload_graph()` cuando se le
pasa `group_expanded`, y en `load_input()` tras el load inicial.
Cubre las 4 rutas de carga del app (toolbar reload, mutaciones,
inspector save, primera carga / switch project).
- Idempotente sobre un grafo ya filtrado y robusto frente a BDs sin
columna `group_id` (schema antiguo) — no toca el grafo.
Smoke test manual con 3 BDs sintéticas:
- Grupo + 2 children + edges cruzadas/internas: nodes 5→3, edges
4→3 (internal hidden, cross redirected).
- 2 grupos con 4 cross-edges entre ellos: edges 4→1 (dedup).
- group_id huerfano: nodo oculto + arista descartada.
Build clean en Windows. Tests verdes:
- WSL pytest: 32 passed.
- Windows pytest: 21 passed + 11 skipped.
Refs: issues/0035b-renderer-hides-grouped-children.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
2.2 KiB
C++
52 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include "viz/graph_sources.h"
|
|
#include "viz/graph_types.h"
|
|
|
|
namespace ge {
|
|
|
|
enum InputKind {
|
|
INPUT_NONE = 0,
|
|
INPUT_OPERATIONS,
|
|
// Futuro: INPUT_JSON, INPUT_JSONL, INPUT_GRAPHML, ...
|
|
};
|
|
|
|
struct InputArgs {
|
|
InputKind kind = INPUT_NONE;
|
|
const char* uri = nullptr; // path al SQLite (operations) o al fichero
|
|
};
|
|
|
|
// Dispatcher de sources. Devuelve true si la carga succeeded; en cualquier
|
|
// caso `stats` se rellena (errors > 0 ante fallo).
|
|
bool load_graph(const InputArgs& args, GraphData* out, graph::GraphLoadStats* stats);
|
|
|
|
// Reload helper — usa la misma uri que la ultima `load_graph` exitosa.
|
|
// Llama a `graph_free(out)` y vuelve a invocar `load_graph(args, out, stats)`.
|
|
// Si `group_expanded` no es null, aplica el filtro de grupos (issue 0035b)
|
|
// tras la carga: oculta hijos cuyo group_id apunta a un grupo no expandido,
|
|
// reescribe extremos de aristas que quedan dentro de grupos colapsados al
|
|
// cuadrado del grupo, y deduplica aristas grupo-a-grupo a una linea por par.
|
|
bool reload_graph(const InputArgs& args, GraphData* out, graph::GraphLoadStats* stats,
|
|
const std::unordered_map<std::string, bool>* group_expanded = nullptr);
|
|
|
|
// Aplica el filtro de grupos in-place sobre `g` consultando `db_path` para
|
|
// recuperar `group_id` por entidad. `group_expanded` mapea entity_id (string)
|
|
// del nodo Group → bool (true = expandido). Reglas:
|
|
// - Nodo con group_id != NULL y grupo padre no expandido → oculto (NF_VISIBLE
|
|
// limpiado y removido del array, indices de aristas re-mapeados).
|
|
// - Arista cuyo extremo cae en grupo colapsado → extremo redirigido al
|
|
// nodo del grupo. Si el otro extremo tambien cae en el MISMO grupo
|
|
// colapsado → arista interna, se descarta.
|
|
// - Aristas con AMBOS extremos en grupos colapsados distintos → dedup por
|
|
// par (group_a, group_b) sin orden, una sola linea por par + relacion.
|
|
// Idempotente sobre un grafo ya filtrado (no quedan group_id ocultos).
|
|
// Retorna true si tuvo exito; en caso de error de DB devuelve false sin
|
|
// alterar el grafo.
|
|
bool apply_group_filter(GraphData* g, const char* db_path,
|
|
const std::unordered_map<std::string, bool>& group_expanded);
|
|
|
|
} // namespace ge
|