radial sugiyama positioning integration

This commit is contained in:
Oxy8
2026-03-23 11:13:27 -03:00
parent 6b9115e43b
commit 696844f341
51 changed files with 10089 additions and 364 deletions

View File

@@ -168,40 +168,56 @@ func fetchGraphSnapshot(
nodes := acc.nodes
edges := acc.edges
routeSegments := []RouteSegment(nil)
layoutEngine := "go"
var layoutRootIRI *string
// Layout: invert edges for hierarchy (target -> source).
hierEdges := make([][2]int, 0, len(edges))
for _, e := range edges {
hierEdges = append(hierEdges, [2]int{int(e.Target), int(e.Source)})
}
layers, cycleErr := levelSynchronousKahnLayers(len(nodes), hierEdges)
if cycleErr != nil {
sample := make([]string, 0, 20)
for _, nid := range cycleErr.RemainingNodeIDs {
if len(sample) >= 20 {
break
}
if nid >= 0 && nid < len(nodes) {
sample = append(sample, nodes[nid].IRI)
}
if shouldUseRustHierarchyLayout(cfg, graphQueryID) {
layoutResult, err := layoutHierarchyWithRust(ctx, cfg, nodes, edges, preds)
if err != nil {
return GraphResponse{}, err
}
nodes = layoutResult.Nodes
edges = layoutResult.Edges
routeSegments = layoutResult.RouteSegments
layoutEngine = rustHierarchyLayoutEngineID
rootIRI := cfg.HierarchyLayoutRootIRI
layoutRootIRI = &rootIRI
} else {
// Layout: invert edges for hierarchy (target -> source).
hierEdges := make([][2]int, 0, len(edges))
for _, e := range edges {
hierEdges = append(hierEdges, [2]int{int(e.Target), int(e.Source)})
}
cycleErr.RemainingIRISample = sample
return GraphResponse{}, cycleErr
}
idToIRI := make([]string, len(nodes))
for i := range nodes {
idToIRI[i] = nodes[i].IRI
}
for _, layer := range layers {
sortLayerByIRI(layer, idToIRI)
}
layers, cycleErr := levelSynchronousKahnLayers(len(nodes), hierEdges)
if cycleErr != nil {
sample := make([]string, 0, 20)
for _, nid := range cycleErr.RemainingNodeIDs {
if len(sample) >= 20 {
break
}
if nid >= 0 && nid < len(nodes) {
sample = append(sample, nodes[nid].IRI)
}
}
cycleErr.RemainingIRISample = sample
return GraphResponse{}, cycleErr
}
xs, ys := radialPositionsFromLayers(len(nodes), layers, 5000.0)
for i := range nodes {
nodes[i].X = xs[i]
nodes[i].Y = ys[i]
idToIRI := make([]string, len(nodes))
for i := range nodes {
idToIRI[i] = nodes[i].IRI
}
for _, layer := range layers {
sortLayerByIRI(layer, idToIRI)
}
xs, ys := radialPositionsFromLayers(len(nodes), layers, 5000.0)
for i := range nodes {
nodes[i].X = xs[i]
nodes[i].Y = ys[i]
}
}
// Attach labels for URI nodes.
@@ -240,9 +256,11 @@ func fetchGraphSnapshot(
EdgeLimit: edgeLimit,
Nodes: len(nodes),
Edges: len(edges),
LayoutEngine: layoutEngine,
LayoutRootIRI: layoutRootIRI,
}
return GraphResponse{Nodes: nodes, Edges: edges, Meta: meta}, nil
return GraphResponse{Nodes: nodes, Edges: edges, RouteSegments: routeSegments, Meta: meta}, nil
}
type bestLabel struct {