update grid layout with simple edge routing

This commit is contained in:
Gavin Nishizawa 2023-09-12 16:54:38 -07:00
parent c51834df24
commit a17013a323
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
2 changed files with 41 additions and 6 deletions

View file

@ -11,6 +11,7 @@ import (
type gridDiagram struct {
root *d2graph.Object
objects []*d2graph.Object
edges []*d2graph.Edge
rows int
columns int
@ -122,4 +123,7 @@ func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) {
restore(obj, child)
child.IterDescendants(restore)
}
for _, e := range gd.edges {
graph.Edges = append(graph.Edges, e)
}
}

View file

@ -31,7 +31,7 @@ const (
// 7. Put grid children back in correct location
func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d2graph.LayoutGraph {
return func(ctx context.Context, g *d2graph.Graph) error {
gridDiagrams, objectOrder, err := withoutGridDiagrams(ctx, g, layout)
gridDiagrams, objectOrder, edgeOrder, err := withoutGridDiagrams(ctx, g, layout)
if err != nil {
return err
}
@ -42,19 +42,24 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d
return err
}
cleanup(g, gridDiagrams, objectOrder)
cleanup(g, gridDiagrams, objectOrder, edgeOrder)
return nil
}
}
func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder map[string]int, err error) {
func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder, edgeOrder map[string]int, err error) {
toRemove := make(map[*d2graph.Object]struct{})
edgeToRemove := make(map[*d2graph.Edge]struct{})
gridDiagrams = make(map[string]*gridDiagram)
objectOrder = make(map[string]int)
for i, obj := range g.Objects {
objectOrder[obj.AbsID()] = i
}
edgeOrder = make(map[string]int)
for i, edge := range g.Edges {
edgeOrder[edge.AbsID()] = i
}
var processGrid func(obj *d2graph.Object) error
processGrid = func(obj *d2graph.Object) error {
@ -200,6 +205,22 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.L
for _, o := range gd.objects {
toRemove[o] = struct{}{}
}
// simple straight line edge routing between grid objects
for i, e := range g.Edges {
edgeOrder[e.AbsID()] = i
if e.Dst.ClosestGridDiagram() != obj {
continue
}
e.Route = []*geo.Point{e.Src.Center(), e.Dst.Center()}
e.TraceToShape(e.Route, 0, 1)
if e.Label.Value != "" {
e.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
}
gd.edges = append(gd.edges, e)
edgeToRemove[e] = struct{}{}
}
return nil
}
@ -218,7 +239,7 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.L
}
if err := processGrid(obj); err != nil {
return nil, nil, err
return nil, nil, nil, err
}
}
}
@ -230,8 +251,15 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.L
}
}
g.Objects = layoutObjects
layoutEdges := make([]*d2graph.Edge, 0, len(edgeToRemove))
for _, e := range g.Edges {
if _, exists := edgeToRemove[e]; !exists {
layoutEdges = append(layoutEdges, e)
}
}
g.Edges = layoutEdges
return gridDiagrams, objectOrder, nil
return gridDiagrams, objectOrder, edgeOrder, nil
}
func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) {
@ -940,11 +968,14 @@ func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, horizontalG
// - translating the grid to its position placed by the core layout engine
// - restore the children of the grid
// - sorts objects to their original graph order
func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objectsOrder map[string]int) {
func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objectsOrder, edgeOrder map[string]int) {
defer func() {
sort.SliceStable(graph.Objects, func(i, j int) bool {
return objectsOrder[graph.Objects[i].AbsID()] < objectsOrder[graph.Objects[j].AbsID()]
})
sort.SliceStable(graph.Edges, func(i, j int) bool {
return edgeOrder[graph.Edges[i].AbsID()] < edgeOrder[graph.Edges[j].AbsID()]
})
}()
var restore func(obj *d2graph.Object)