fix reconnecting nested edges through serialization
This commit is contained in:
parent
bd16b04244
commit
f9060a90d6
1 changed files with 32 additions and 18 deletions
|
|
@ -83,6 +83,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
extracted := make(map[string]*d2graph.Graph)
|
extracted := make(map[string]*d2graph.Graph)
|
||||||
var extractedOrder []string
|
var extractedOrder []string
|
||||||
var extractedEdges []*d2graph.Edge
|
var extractedEdges []*d2graph.Edge
|
||||||
|
var extractedEdgeIDs []edgeIDs
|
||||||
|
|
||||||
var constantNears []*d2graph.Graph
|
var constantNears []*d2graph.Graph
|
||||||
restoreOrder := SaveOrder(g)
|
restoreOrder := SaveOrder(g)
|
||||||
|
|
@ -114,7 +115,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
// │ │ │ │ └──┘ └──┘ │ │ │ │ │ │
|
// │ │ │ │ └──┘ └──┘ │ │ │ │ │ │
|
||||||
// │ └────┘ └───────────────┘ │ │ └────┘ │
|
// │ └────┘ └───────────────┘ │ │ └────┘ │
|
||||||
// └───────────────────────────────┘ └───────────────────────────────┘
|
// └───────────────────────────────┘ └───────────────────────────────┘
|
||||||
nestedGraph, externalEdges := ExtractSubgraph(curr, true)
|
nestedGraph, externalEdges, externalEdgeIDs := ExtractSubgraph(curr, true)
|
||||||
|
|
||||||
// Then we layout curr as a nested graph and re-inject it
|
// Then we layout curr as a nested graph and re-inject it
|
||||||
id := curr.AbsID()
|
id := curr.AbsID()
|
||||||
|
|
@ -142,13 +143,13 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, e := range externalEdges {
|
for i, e := range externalEdges {
|
||||||
src, err := lookup(e.Src.AbsID())
|
src, err := lookup(externalEdgeIDs[i].srcID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.Src = src
|
e.Src = src
|
||||||
dst, err := lookup(e.Dst.AbsID())
|
dst, err := lookup(externalEdgeIDs[i].dstID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -182,8 +183,9 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
// │ │ │ │ └──┘ └──┘ │ │ │ │ │ │ │ │
|
// │ │ │ │ └──┘ └──┘ │ │ │ │ │ │ │ │
|
||||||
// │ └────┘ └───────────────┘ │ │ └────┘ └───────────────┘ │
|
// │ └────┘ └───────────────┘ │ │ └────┘ └───────────────┘ │
|
||||||
// └───────────────────────────────┘ └───────────────────────────────┘
|
// └───────────────────────────────┘ └───────────────────────────────┘
|
||||||
nestedGraph, externalEdges = ExtractSubgraph(curr, false)
|
nestedGraph, externalEdges, externalEdgeIDs = ExtractSubgraph(curr, false)
|
||||||
extractedEdges = append(extractedEdges, externalEdges...)
|
extractedEdges = append(extractedEdges, externalEdges...)
|
||||||
|
extractedEdgeIDs = append(extractedEdgeIDs, externalEdgeIDs...)
|
||||||
|
|
||||||
extracted[id] = nestedGraph
|
extracted[id] = nestedGraph
|
||||||
extractedOrder = append(extractedOrder, id)
|
extractedOrder = append(extractedOrder, id)
|
||||||
|
|
@ -197,8 +199,9 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a nested diagram here, so extract its contents and process in the same way
|
// There is a nested diagram here, so extract its contents and process in the same way
|
||||||
nestedGraph, externalEdges := ExtractSubgraph(curr, gi.IsConstantNear)
|
nestedGraph, externalEdges, externalEdgeIDs := ExtractSubgraph(curr, gi.IsConstantNear)
|
||||||
extractedEdges = append(extractedEdges, externalEdges...)
|
extractedEdges = append(extractedEdges, externalEdges...)
|
||||||
|
extractedEdgeIDs = append(extractedEdgeIDs, externalEdgeIDs...)
|
||||||
|
|
||||||
log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID()), slog.F("gi", gi))
|
log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID()), slog.F("gi", gi))
|
||||||
nestedInfo := gi
|
nestedInfo := gi
|
||||||
|
|
@ -299,16 +302,17 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
|
|
||||||
// Restore cross-graph edges and route them
|
// Restore cross-graph edges and route them
|
||||||
g.Edges = append(g.Edges, extractedEdges...)
|
g.Edges = append(g.Edges, extractedEdges...)
|
||||||
for _, e := range extractedEdges {
|
for i, e := range extractedEdges {
|
||||||
|
ids := extractedEdgeIDs[i]
|
||||||
// update object references
|
// update object references
|
||||||
src, exists := idToObj[e.Src.AbsID()]
|
src, exists := idToObj[ids.srcID]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("could not find object %#v after layout", e.Src.AbsID())
|
return fmt.Errorf("could not find object %#v after layout", ids.srcID)
|
||||||
}
|
}
|
||||||
e.Src = src
|
e.Src = src
|
||||||
dst, exists := idToObj[e.Dst.AbsID()]
|
dst, exists := idToObj[ids.dstID]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("could not find object %#v after layout", e.Dst.AbsID())
|
return fmt.Errorf("could not find object %#v after layout", ids.dstID)
|
||||||
}
|
}
|
||||||
e.Dst = dst
|
e.Dst = dst
|
||||||
}
|
}
|
||||||
|
|
@ -318,15 +322,16 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// need to update pointers if plugin performs edge routing
|
// need to update pointers if plugin performs edge routing
|
||||||
for _, e := range extractedEdges {
|
for i, e := range extractedEdges {
|
||||||
src, exists := idToObj[e.Src.AbsID()]
|
ids := extractedEdgeIDs[i]
|
||||||
|
src, exists := idToObj[ids.srcID]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("could not find object %#v after routing", e.Src.AbsID())
|
return fmt.Errorf("could not find object %#v after routing", ids.srcID)
|
||||||
}
|
}
|
||||||
e.Src = src
|
e.Src = src
|
||||||
dst, exists := idToObj[e.Dst.AbsID()]
|
dst, exists := idToObj[ids.dstID]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("could not find object %#v after routing", e.Dst.AbsID())
|
return fmt.Errorf("could not find object %#v after routing", ids.dstID)
|
||||||
}
|
}
|
||||||
e.Dst = dst
|
e.Dst = dst
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +365,11 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) {
|
||||||
return gi
|
return gi
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractSubgraph(container *d2graph.Object, includeSelf bool) (nestedGraph *d2graph.Graph, externalEdges []*d2graph.Edge) {
|
type edgeIDs struct {
|
||||||
|
srcID, dstID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractSubgraph(container *d2graph.Object, includeSelf bool) (nestedGraph *d2graph.Graph, externalEdges []*d2graph.Edge, externalEdgeIDs []edgeIDs) {
|
||||||
// includeSelf: when we have a constant near or a grid cell that is a container,
|
// includeSelf: when we have a constant near or a grid cell that is a container,
|
||||||
// we want to include itself in the nested graph, not just its descendants,
|
// we want to include itself in the nested graph, not just its descendants,
|
||||||
nestedGraph = d2graph.NewGraph()
|
nestedGraph = d2graph.NewGraph()
|
||||||
|
|
@ -399,6 +408,11 @@ func ExtractSubgraph(container *d2graph.Object, includeSelf bool) (nestedGraph *
|
||||||
nestedGraph.Edges = append(nestedGraph.Edges, edge)
|
nestedGraph.Edges = append(nestedGraph.Edges, edge)
|
||||||
} else if srcIsNested || dstIsNested {
|
} else if srcIsNested || dstIsNested {
|
||||||
externalEdges = append(externalEdges, edge)
|
externalEdges = append(externalEdges, edge)
|
||||||
|
// we need these AbsIDs when reconnecting since parent references may become stale
|
||||||
|
externalEdgeIDs = append(externalEdgeIDs, edgeIDs{
|
||||||
|
srcID: edge.Src.AbsID(),
|
||||||
|
dstID: edge.Dst.AbsID(),
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
remainingEdges = append(remainingEdges, edge)
|
remainingEdges = append(remainingEdges, edge)
|
||||||
}
|
}
|
||||||
|
|
@ -446,7 +460,7 @@ func ExtractSubgraph(container *d2graph.Object, includeSelf bool) (nestedGraph *
|
||||||
container.ChildrenArray = nil
|
container.ChildrenArray = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nestedGraph, externalEdges
|
return nestedGraph, externalEdges, externalEdgeIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph, isRoot bool) {
|
func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph, isRoot bool) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue