From 68638899bfe5a1cbbc42492afb96cb8dd0454982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20C=C3=A9sar=20Batista?= Date: Tue, 29 Nov 2022 15:40:43 -0800 Subject: [PATCH] Span boxes -> spans --- d2layouts/d2sequence/constants.go | 12 ++++---- d2layouts/d2sequence/layout.go | 48 ++++++++++++++--------------- d2layouts/d2sequence/layout_test.go | 28 ++++++++--------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/d2layouts/d2sequence/constants.go b/d2layouts/d2sequence/constants.go index 16b5baf48..4c36086b2 100644 --- a/d2layouts/d2sequence/constants.go +++ b/d2layouts/d2sequence/constants.go @@ -12,13 +12,13 @@ const MIN_ACTOR_DISTANCE = 200. const MIN_EDGE_DISTANCE = 100. // default size -const SPAN_BOX_WIDTH = 20. +const SPAN_WIDTH = 20. -// small pad so that edges don't touch lifelines and span boxes -const SPAN_BOX_EDGE_PAD = 5. +// small pad so that edges don't touch lifelines and spans +const SPAN_EDGE_PAD = 5. -// as the span boxes start getting nested, their size grows +// as the spans start getting nested, their size grows const SPAN_BOX_DEPTH_GROW_FACTOR = 10. -// when a span box has a single edge -const MIN_SPAN_BOX_HEIGHT = MIN_EDGE_DISTANCE / 2. +// when a span has a single edge +const MIN_SPAN_HEIGHT = MIN_EDGE_DISTANCE / 2. diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index f08ba6c21..dbba8328e 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -17,7 +17,7 @@ func Layout(ctx context.Context, g *d2graph.Graph) (err error) { sd := &sequenceDiagram{ graph: g, objectRank: make(map[*d2graph.Object]int), - objectDepth: make(map[*d2graph.Object]int), + objectLevel: make(map[*d2graph.Object]int), minEdgeRank: make(map[*d2graph.Object]int), maxEdgeRank: make(map[*d2graph.Object]int), edgeYStep: MIN_EDGE_DISTANCE, @@ -27,7 +27,7 @@ func Layout(ctx context.Context, g *d2graph.Graph) (err error) { sd.init() sd.placeActors() - sd.placeSpanBoxes() + sd.placeSpans() sd.routeEdges() sd.addLifelineEdges() @@ -41,11 +41,11 @@ type sequenceDiagram struct { actors []*d2graph.Object spans []*d2graph.Object - // can be either actors or span boxes - // rank: left to right position of actors/span boxes + // can be either actors or spans + // rank: left to right position of actors/spans (spans have the same rank as their parents) objectRank map[*d2graph.Object]int - // depth: the nested levels of a given actor/span - objectDepth map[*d2graph.Object]int + // similar to d2graph.Object.Level() just don't make the recursive calls + objectLevel map[*d2graph.Object]int // keep track of the first and last edge of a given actor // the edge rank is the order in which it appears from top to bottom @@ -70,15 +70,15 @@ func (sd *sequenceDiagram) init() { if sd.isActor(obj) { sd.actors = append(sd.actors, obj) sd.objectRank[obj] = len(sd.actors) - sd.objectDepth[obj] = 0 + sd.objectLevel[obj] = 0 sd.maxActorHeight = math.Max(sd.maxActorHeight, obj.Height) } else { - // span boxes are always rectangles and have no labels + // spans are always rectangles and have no labels obj.Attributes.Label = d2graph.Scalar{Value: ""} obj.Attributes.Shape = d2graph.Scalar{Value: shape.SQUARE_TYPE} sd.spans = append(sd.spans, obj) sd.objectRank[obj] = sd.objectRank[obj.Parent] - sd.objectDepth[obj] = sd.objectDepth[obj.Parent] + 1 + sd.objectLevel[obj] = sd.objectLevel[obj.Parent] + 1 } queue = append(queue, obj.ChildrenArray...) @@ -156,7 +156,7 @@ func (sd *sequenceDiagram) addLifelineEdges() { } } -// placeSpanBoxes places span boxes over the object lifeline +// placeSpans places spans over the object lifeline // ┌──────────┐ // │ actor │ // └────┬─────┘ @@ -168,22 +168,22 @@ func (sd *sequenceDiagram) addLifelineEdges() { // │ // lifeline // │ -func (sd *sequenceDiagram) placeSpanBoxes() { - // quickly find the span box center X +func (sd *sequenceDiagram) placeSpans() { + // quickly find the span center X rankToX := make(map[int]float64) for _, actor := range sd.actors { rankToX[sd.objectRank[actor]] = actor.Center().X } - // places span boxes from most to least nested - // the order is important because the only way a child span box exists is if there'e an edge to it + // places spans from most to least nested + // the order is important because the only way a child span exists is if there'e an edge to it // however, the parent span might not have an edge to it and then its position is based on the child position // or, there can be edge to it, but it comes after the child one meaning the top left position is still based on the child // and not on its own edge spanFromMostNested := make([]*d2graph.Object, len(sd.spans)) copy(spanFromMostNested, sd.spans) sort.SliceStable(spanFromMostNested, func(i, j int) bool { - return sd.objectDepth[spanFromMostNested[i]] > sd.objectDepth[spanFromMostNested[j]] + return sd.objectLevel[spanFromMostNested[i]] > sd.objectLevel[spanFromMostNested[j]] }) for _, span := range spanFromMostNested { // finds the position based on children @@ -194,7 +194,7 @@ func (sd *sequenceDiagram) placeSpanBoxes() { maxChildY = math.Max(maxChildY, child.TopLeft.Y+child.Height) } - // finds the position if there are edges to this span box + // finds the position if there are edges to this span minEdgeY := math.Inf(1) if minRank, exists := sd.minEdgeRank[span]; exists { minEdgeY = sd.getEdgeY(minRank) @@ -209,17 +209,17 @@ func (sd *sequenceDiagram) placeSpanBoxes() { if minY == minChildY { minY -= SPAN_BOX_DEPTH_GROW_FACTOR } else { - minY -= SPAN_BOX_EDGE_PAD + minY -= SPAN_EDGE_PAD } maxY := math.Max(maxEdgeY, maxChildY) if maxY == maxChildY { maxY += SPAN_BOX_DEPTH_GROW_FACTOR } else { - maxY += SPAN_BOX_EDGE_PAD + maxY += SPAN_EDGE_PAD } - height := math.Max(maxY-minY, MIN_SPAN_BOX_HEIGHT) - width := SPAN_BOX_WIDTH + (float64(sd.objectDepth[span]-1) * SPAN_BOX_DEPTH_GROW_FACTOR) + height := math.Max(maxY-minY, MIN_SPAN_HEIGHT) + width := SPAN_WIDTH + (float64(sd.objectLevel[span]-1) * SPAN_BOX_DEPTH_GROW_FACTOR) x := rankToX[sd.objectRank[span]] - (width / 2.) span.Box = geo.NewBox(geo.NewPoint(x, minY), width, height) } @@ -249,11 +249,11 @@ func (sd *sequenceDiagram) routeEdges() { } if isLeftToRight { - startX += SPAN_BOX_EDGE_PAD - endX -= SPAN_BOX_EDGE_PAD + startX += SPAN_EDGE_PAD + endX -= SPAN_EDGE_PAD } else { - startX -= SPAN_BOX_EDGE_PAD - endX += SPAN_BOX_EDGE_PAD + startX -= SPAN_EDGE_PAD + endX += SPAN_EDGE_PAD } edgeY := sd.getEdgeY(rank) diff --git a/d2layouts/d2sequence/layout_test.go b/d2layouts/d2sequence/layout_test.go index be2e83d85..26d88f9fe 100644 --- a/d2layouts/d2sequence/layout_test.go +++ b/d2layouts/d2sequence/layout_test.go @@ -92,19 +92,19 @@ func TestBasicSequenceDiagram(t *testing.T) { } if edge.Src.TopLeft.X < edge.Dst.TopLeft.X { // left to right - if edge.Route[0].X != edge.Src.Center().X+SPAN_BOX_EDGE_PAD { + if edge.Route[0].X != edge.Src.Center().X+SPAN_EDGE_PAD { t.Fatalf("expected edge[%d] x to be at the actor center", i) } - if edge.Route[1].X != edge.Dst.Center().X-SPAN_BOX_EDGE_PAD { + if edge.Route[1].X != edge.Dst.Center().X-SPAN_EDGE_PAD { t.Fatalf("expected edge[%d] x to be at the actor center", i) } } else { - if edge.Route[0].X != edge.Src.Center().X-SPAN_BOX_EDGE_PAD { + if edge.Route[0].X != edge.Src.Center().X-SPAN_EDGE_PAD { t.Fatalf("expected edge[%d] x to be at the actor center", i) } - if edge.Route[1].X != edge.Dst.Center().X+SPAN_BOX_EDGE_PAD { + if edge.Route[1].X != edge.Dst.Center().X+SPAN_EDGE_PAD { t.Fatalf("expected edge[%d] x to be at the actor center", i) } } @@ -146,7 +146,7 @@ func TestBasicSequenceDiagram(t *testing.T) { } } -func TestSpanBoxesSequenceDiagram(t *testing.T) { +func TestSpansSequenceDiagram(t *testing.T) { // ┌─────┐ ┌─────┐ // │ a │ │ b │ // └──┬──┘ └──┬──┘ @@ -197,11 +197,11 @@ func TestSpanBoxesSequenceDiagram(t *testing.T) { } if a_t1.Attributes.Label.Value != "" { - t.Fatalf("expected no label for span box, got %s", a_t1.Attributes.Label.Value) + t.Fatalf("expected no label for span, got %s", a_t1.Attributes.Label.Value) } if a_t1.Attributes.Shape.Value != shape.SQUARE_TYPE { - t.Fatalf("expected square shape for span box, got %s", a_t1.Attributes.Shape.Value) + t.Fatalf("expected square shape for span, got %s", a_t1.Attributes.Shape.Value) } if a_t1.Height != b_t1.Height { @@ -209,13 +209,13 @@ func TestSpanBoxesSequenceDiagram(t *testing.T) { } // Y diff of the 2 first edges - expectedHeight := g.Edges[1].Route[0].Y - g.Edges[0].Route[0].Y + (2 * SPAN_BOX_EDGE_PAD) + expectedHeight := g.Edges[1].Route[0].Y - g.Edges[0].Route[0].Y + (2 * SPAN_EDGE_PAD) if a_t1.Height != expectedHeight { t.Fatalf("expected a.t1 height to be %.5f, got %.5f", expectedHeight, a_t1.Height) } - if a_t1.Width != SPAN_BOX_WIDTH { - t.Fatalf("expected span box width to be %.5f, got %.5f", SPAN_BOX_WIDTH, a_t1.Width) + if a_t1.Width != SPAN_WIDTH { + t.Fatalf("expected span width to be %.5f, got %.5f", SPAN_WIDTH, a_t1.Width) } // check positions @@ -231,20 +231,20 @@ func TestSpanBoxesSequenceDiagram(t *testing.T) { if a_t1.TopLeft.Y != b_t1.TopLeft.Y { t.Fatal("expected a.t1 and b.t1 to be placed at the same Y") } - if a_t1.TopLeft.Y != g.Edges[0].Route[0].Y-SPAN_BOX_EDGE_PAD { + if a_t1.TopLeft.Y != g.Edges[0].Route[0].Y-SPAN_EDGE_PAD { t.Fatal("expected a.t1 to be placed at the same Y of the first edge") } // check routes - if g.Edges[0].Route[0].X != a_t1.TopLeft.X+a_t1.Width+SPAN_BOX_EDGE_PAD { + if g.Edges[0].Route[0].X != a_t1.TopLeft.X+a_t1.Width+SPAN_EDGE_PAD { t.Fatal("expected the first edge to start on a.t1 top right X") } - if g.Edges[0].Route[1].X != b_t1.TopLeft.X-SPAN_BOX_EDGE_PAD { + if g.Edges[0].Route[1].X != b_t1.TopLeft.X-SPAN_EDGE_PAD { t.Fatal("expected the first edge to end on b.t1 top left X") } - if g.Edges[2].Route[1].X != b.Center().X-SPAN_BOX_EDGE_PAD { + if g.Edges[2].Route[1].X != b.Center().X-SPAN_EDGE_PAD { t.Fatal("expected the third edge to end on b.t1 center X") } }