From b8355c7fa9c5a710e2ce1dda74837335e8925f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20C=C3=A9sar=20Batista?= Date: Mon, 28 Nov 2022 14:01:22 -0800 Subject: [PATCH] Add sequenceDiagram to hold values required to layout the diagram --- d2layouts/d2sequence/layout.go | 55 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index 5d1107a39..870eaa622 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -12,53 +12,64 @@ import ( ) func Layout(ctx context.Context, g *d2graph.Graph) (err error) { - edgeYStep := MIN_EDGE_DISTANCE - actorXStep := MIN_ACTOR_DISTANCE - maxActorHeight := 0. + sd := &sequenceDiagram{ + graph: g, + edgeYStep: MIN_EDGE_DISTANCE, + actorXStep: MIN_ACTOR_DISTANCE, + maxActorHeight: 0., + } actorRank := make(map[*d2graph.Object]int) for rank, actor := range g.Objects { actorRank[actor] = rank } for _, edge := range g.Edges { - edgeYStep = math.Max(edgeYStep, float64(edge.LabelDimensions.Height)+HORIZONTAL_PAD) - maxActorHeight = math.Max(maxActorHeight, edge.Src.Height+HORIZONTAL_PAD) - maxActorHeight = math.Max(maxActorHeight, edge.Dst.Height+HORIZONTAL_PAD) + sd.edgeYStep = math.Max(sd.edgeYStep, float64(edge.LabelDimensions.Height)+HORIZONTAL_PAD) + sd.maxActorHeight = math.Max(sd.maxActorHeight, edge.Src.Height+HORIZONTAL_PAD) + sd.maxActorHeight = math.Max(sd.maxActorHeight, edge.Dst.Height+HORIZONTAL_PAD) // ensures that long labels, spanning over multiple actors, don't make for large gaps between actors // by distributing the label length across the actors rank difference rankDiff := math.Abs(float64(actorRank[edge.Src]) - float64(actorRank[edge.Dst])) distributedLabelWidth := float64(edge.LabelDimensions.Width) / rankDiff - actorXStep = math.Max(actorXStep, distributedLabelWidth+HORIZONTAL_PAD) + sd.actorXStep = math.Max(sd.actorXStep, distributedLabelWidth+HORIZONTAL_PAD) } - placeActors(g.Objects, maxActorHeight, actorXStep) - routeEdges(g.Edges, maxActorHeight, edgeYStep) - addLifelineEdges(g, g.Objects, edgeYStep) + sd.placeActors() + sd.routeEdges() + sd.addLifelineEdges() return nil } +type sequenceDiagram struct { + graph *d2graph.Graph + + edgeYStep float64 + actorXStep float64 + maxActorHeight float64 +} + // placeActors places actors bottom aligned, side by side -func placeActors(actors []*d2graph.Object, maxHeight, xStep float64) { +func (sd *sequenceDiagram) placeActors() { x := 0. - for _, actors := range actors { - yOffset := maxHeight - actors.Height + for _, actors := range sd.graph.Objects { + yOffset := sd.maxActorHeight - actors.Height actors.TopLeft = geo.NewPoint(x, yOffset) - x += actors.Width + xStep + x += actors.Width + sd.actorXStep actors.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) } } // routeEdges routes horizontal edges from Src to Dst -func routeEdges(edgesInOrder []*d2graph.Edge, startY, yStep float64) { - edgeY := startY + yStep // in case the first edge has a tall label - for _, edge := range edgesInOrder { +func (sd *sequenceDiagram) routeEdges() { + edgeY := sd.maxActorHeight + sd.edgeYStep // in case the first edge has a tall label + for _, edge := range sd.graph.Edges { start := edge.Src.Center() start.Y = edgeY end := edge.Dst.Center() end.Y = edgeY edge.Route = []*geo.Point{start, end} - edgeY += yStep + edgeY += sd.edgeYStep if edge.Attributes.Label.Value != "" { isLeftToRight := edge.Src.TopLeft.X < edge.Dst.TopLeft.X @@ -80,14 +91,14 @@ func routeEdges(edgesInOrder []*d2graph.Edge, startY, yStep float64) { // │ lifeline // │ // │ -func addLifelineEdges(g *d2graph.Graph, actors []*d2graph.Object, yStep float64) { - endY := g.Edges[len(g.Edges)-1].Route[0].Y + yStep - for _, actor := range actors { +func (sd *sequenceDiagram) addLifelineEdges() { + endY := sd.graph.Edges[len(sd.graph.Edges)-1].Route[0].Y + sd.edgeYStep + for _, actor := range sd.graph.Objects { actorBottom := actor.Center() actorBottom.Y = actor.TopLeft.Y + actor.Height actorLifelineEnd := actor.Center() actorLifelineEnd.Y = endY - g.Edges = append(g.Edges, &d2graph.Edge{ + sd.graph.Edges = append(sd.graph.Edges, &d2graph.Edge{ Attributes: d2graph.Attributes{ Style: d2graph.Style{ StrokeDash: &d2graph.Scalar{Value: "10"},