Layout sequence diagrams before running the layout engine
This commit is contained in:
parent
30cd28fd39
commit
7f26540d64
3 changed files with 28 additions and 22 deletions
22
d2.go
22
d2.go
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"oss.terrastruct.com/d2/d2compiler"
|
"oss.terrastruct.com/d2/d2compiler"
|
||||||
"oss.terrastruct.com/d2/d2exporter"
|
"oss.terrastruct.com/d2/d2exporter"
|
||||||
"oss.terrastruct.com/d2/d2graph"
|
"oss.terrastruct.com/d2/d2graph"
|
||||||
|
"oss.terrastruct.com/d2/d2layouts/d2sequence"
|
||||||
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
||||||
"oss.terrastruct.com/d2/d2target"
|
"oss.terrastruct.com/d2/d2target"
|
||||||
)
|
)
|
||||||
|
|
@ -39,14 +40,11 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Layout != nil {
|
if layout, err := getLayout(opts); err == nil {
|
||||||
err = opts.Layout(ctx, g)
|
if err := d2sequence.Layout2(ctx, g, layout); err != nil {
|
||||||
} else if os.Getenv("D2_LAYOUT") == "dagre" && dagreLayout != nil {
|
return nil, err
|
||||||
err = dagreLayout(ctx, g)
|
|
||||||
} else {
|
|
||||||
err = errors.New("no available layout")
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
} else {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,5 +52,15 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target
|
||||||
return diagram, err
|
return diagram, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLayout(opts *CompileOptions) (func(context.Context, *d2graph.Graph) error, error) {
|
||||||
|
if opts.Layout != nil {
|
||||||
|
return opts.Layout, nil
|
||||||
|
} else if os.Getenv("D2_LAYOUT") == "dagre" && dagreLayout != nil {
|
||||||
|
return dagreLayout, nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("no available layout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See c.go
|
// See c.go
|
||||||
var dagreLayout func(context.Context, *d2graph.Graph) error
|
var dagreLayout func(context.Context, *d2graph.Graph) error
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Layout2(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Context, g *d2graph.Graph) error) error {
|
func Layout2(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Context, g *d2graph.Graph) error) error {
|
||||||
|
oldObjects := g.Objects
|
||||||
|
oldEdges := g.Edges
|
||||||
|
|
||||||
// new graph objects without sequence diagram objects and their replacement (rectangle node)
|
// new graph objects without sequence diagram objects and their replacement (rectangle node)
|
||||||
newObjects := make([]*d2graph.Object, 0, len(g.Objects))
|
newObjects := make([]*d2graph.Object, 0, len(g.Objects))
|
||||||
edgesToRemove := make(map[*d2graph.Edge]struct{})
|
edgesToRemove := make(map[*d2graph.Edge]struct{})
|
||||||
|
|
@ -30,7 +33,9 @@ func Layout2(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Cont
|
||||||
obj := queue[0]
|
obj := queue[0]
|
||||||
queue = queue[1:]
|
queue = queue[1:]
|
||||||
|
|
||||||
|
if obj != g.Root {
|
||||||
newObjects = append(newObjects, obj)
|
newObjects = append(newObjects, obj)
|
||||||
|
}
|
||||||
if obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram {
|
if obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram {
|
||||||
// TODO: should update obj.References too?
|
// TODO: should update obj.References too?
|
||||||
|
|
||||||
|
|
@ -76,22 +81,17 @@ func Layout2(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Cont
|
||||||
}
|
}
|
||||||
|
|
||||||
// restores objects & edges
|
// restores objects & edges
|
||||||
for edge := range edgesToRemove {
|
g.Edges = oldEdges
|
||||||
g.Edges = append(g.Edges, edge)
|
g.Objects = oldObjects
|
||||||
}
|
|
||||||
for obj, children := range objChildrenArray {
|
for obj, children := range objChildrenArray {
|
||||||
sdMock := obj.ChildrenArray[0]
|
sdMock := obj.ChildrenArray[0]
|
||||||
sequenceDiagrams[obj].shift(sdMock.TopLeft)
|
sequenceDiagrams[obj].shift(sdMock.TopLeft)
|
||||||
obj.Children = make(map[string]*d2graph.Object)
|
obj.Children = make(map[string]*d2graph.Object)
|
||||||
for _, child := range children {
|
for _, child := range children {
|
||||||
g.Objects = append(g.Objects, child)
|
|
||||||
obj.Children[child.ID] = child
|
obj.Children[child.ID] = child
|
||||||
}
|
}
|
||||||
obj.ChildrenArray = children
|
obj.ChildrenArray = children
|
||||||
|
g.Edges = append(g.Edges, sequenceDiagrams[obj].lifelines...)
|
||||||
for _, edge := range sequenceDiagrams[obj].lifelines {
|
|
||||||
g.Edges = append(g.Edges, edge)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -296,8 +296,8 @@ func TestNestedSequenceDiagrams(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutFn := func(ctx context.Context, g *d2graph.Graph) error {
|
layoutFn := func(ctx context.Context, g *d2graph.Graph) error {
|
||||||
// 4 because it replaces all `container` children with a rectangle for layout
|
// 3 because it replaces all `container` children with a rectangle for layout
|
||||||
if len(g.Objects) != 4 {
|
if len(g.Objects) != 3 {
|
||||||
t.Fatal("expected only diagram objects for layout")
|
t.Fatal("expected only diagram objects for layout")
|
||||||
}
|
}
|
||||||
for _, obj := range g.Objects {
|
for _, obj := range g.Objects {
|
||||||
|
|
@ -324,10 +324,8 @@ func TestNestedSequenceDiagrams(t *testing.T) {
|
||||||
|
|
||||||
// just set some position as if it had been properly placed
|
// just set some position as if it had been properly placed
|
||||||
for _, obj := range g.Objects {
|
for _, obj := range g.Objects {
|
||||||
if obj != g.Root {
|
|
||||||
obj.TopLeft = geo.NewPoint(0, 0)
|
obj.TopLeft = geo.NewPoint(0, 0)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for _, edge := range g.Edges {
|
for _, edge := range g.Edges {
|
||||||
edge.Route = []*geo.Point{geo.NewPoint(1, 1)}
|
edge.Route = []*geo.Point{geo.NewPoint(1, 1)}
|
||||||
|
|
@ -346,7 +344,7 @@ func TestNestedSequenceDiagrams(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range g.Objects {
|
for _, obj := range g.Objects {
|
||||||
if obj != g.Root && obj.TopLeft == nil {
|
if obj.TopLeft == nil {
|
||||||
t.Fatal("expected to have placed all objects")
|
t.Fatal("expected to have placed all objects")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue