diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md
index e34faad22..c8eb0dc2a 100644
--- a/ci/release/changelogs/next.md
+++ b/ci/release/changelogs/next.md
@@ -25,6 +25,7 @@
- Ensures labels fit inside shapes with shape-specific inner bounding boxes. [#702](https://github.com/terrastruct/d2/pull/702)
- dagre container labels changed positions to outside the shape. Many previously obscured container labels are now legible. [#788](https://github.com/terrastruct/d2/pull/788)
- Improves package shape dimensions with short height. [#702](https://github.com/terrastruct/d2/pull/702)
+- Sequence diagrams are rendered more compacted, both vertically and horizontally. [#796](https://github.com/terrastruct/d2/pull/796)
- Keeps person shape from becoming too distorted. [#702](https://github.com/terrastruct/d2/pull/702)
- Ensures shapes with icons have enough padding for their labels. [#702](https://github.com/terrastruct/d2/pull/702)
- `--force-appendix` flag adds an appendix to SVG outputs with tooltips or links. [#761](https://github.com/terrastruct/d2/pull/761)
@@ -37,5 +38,6 @@
- Fixes groups overlapping in sequence diagrams when they end in a self loop. [#728](https://github.com/terrastruct/d2/pull/728)
- Fixes dimensions of unlabeled squares or circles with only a set width or height. [#702](https://github.com/terrastruct/d2/pull/702)
- Fixes scaling of actor shapes in sequence diagrams. [#702](https://github.com/terrastruct/d2/pull/702)
+- Sequence diagram note ordering was sometimes wrong. [#796](https://github.com/terrastruct/d2/pull/796)
- Images can now be set to sizes smaller than 128x128. [#702](https://github.com/terrastruct/d2/pull/702)
- Fixes class height when there are no rows. [#756](https://github.com/terrastruct/d2/pull/756)
diff --git a/d2layouts/d2sequence/constants.go b/d2layouts/d2sequence/constants.go
index 95de80681..8e4b4e5e5 100644
--- a/d2layouts/d2sequence/constants.go
+++ b/d2layouts/d2sequence/constants.go
@@ -1,21 +1,24 @@
package d2sequence
-// leaves at least 25 units of space on the left/right when computing the space required between actors
-const HORIZONTAL_PAD = 50.
+// units of space on the left/right when computing the space required between actors
+const HORIZONTAL_PAD = 40.
-// leaves at least 25 units of space on the top/bottom when computing the space required between messages
-const VERTICAL_PAD = 50.
+// units of space on the top/bottom when computing the space required between messages
+// TODO lower
+const VERTICAL_PAD = 40.
-const MIN_ACTOR_DISTANCE = 250.
+const MIN_ACTOR_DISTANCE = 150.
-const MIN_ACTOR_WIDTH = 150.
+const MIN_ACTOR_WIDTH = 100.
-const SELF_MESSAGE_HORIZONTAL_TRAVEL = 100.
+const SELF_MESSAGE_HORIZONTAL_TRAVEL = 80.
-const GROUP_CONTAINER_PADDING = 24.
+const GROUP_CONTAINER_PADDING = 12.
+
+const EDGE_GROUP_LABEL_PADDING = 20.
// min vertical distance between messages
-const MIN_MESSAGE_DISTANCE = 80.
+const MIN_MESSAGE_DISTANCE = 30.
// default size
const SPAN_BASE_WIDTH = 12.
@@ -24,9 +27,9 @@ const SPAN_BASE_WIDTH = 12.
const SPAN_DEPTH_GROWTH_FACTOR = 8.
// when a span has a single messages
-const MIN_SPAN_HEIGHT = 80.
+const MIN_SPAN_HEIGHT = 30.
-const SPAN_MESSAGE_PAD = 16.
+const SPAN_MESSAGE_PAD = 10.
const LIFELINE_STROKE_WIDTH int = 2
diff --git a/d2layouts/d2sequence/layout_test.go b/d2layouts/d2sequence/layout_test.go
index 20220ce03..8be43712d 100644
--- a/d2layouts/d2sequence/layout_test.go
+++ b/d2layouts/d2sequence/layout_test.go
@@ -407,8 +407,8 @@ func TestSelfEdges(t *testing.T) {
t.Fatalf("route does not end at the same actor, start at %.5f, end at %.5f", route[0].X, route[3].X)
}
- if route[3].Y-route[0].Y != d2sequence.MIN_MESSAGE_DISTANCE {
- t.Fatalf("expected route height to be %.f5, got %.5f", d2sequence.MIN_MESSAGE_DISTANCE, route[3].Y-route[0].Y)
+ if route[3].Y-route[0].Y != d2sequence.MIN_MESSAGE_DISTANCE*1.5 {
+ t.Fatalf("expected route height to be %.5f, got %.5f", d2sequence.MIN_MESSAGE_DISTANCE*1.5, route[3].Y-route[0].Y)
}
}
diff --git a/d2layouts/d2sequence/sequence_diagram.go b/d2layouts/d2sequence/sequence_diagram.go
index c1dd1de2a..53cdc8e86 100644
--- a/d2layouts/d2sequence/sequence_diagram.go
+++ b/d2layouts/d2sequence/sequence_diagram.go
@@ -156,6 +156,7 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
for _, message := range sd.messages {
sd.verticalIndices[message.AbsID()] = getEdgeEarliestLineNum(message)
+ // TODO this should not be global yStep, only affect the neighbors
sd.yStep = math.Max(sd.yStep, float64(message.LabelDimensions.Height))
// ensures that long labels, spanning over multiple actors, don't make for large gaps between actors
@@ -176,7 +177,6 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
if _, exists := sd.firstMessage[message.Dst]; !exists {
sd.firstMessage[message.Dst] = message
}
-
}
sd.yStep += VERTICAL_PAD
@@ -209,6 +209,9 @@ func (sd *sequenceDiagram) placeGroups() {
group.ZIndex = GROUP_Z_INDEX
sd.placeGroup(group)
}
+ for _, group := range sd.groups {
+ sd.adjustGroupLabel(group)
+ }
}
func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
@@ -273,6 +276,56 @@ func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
)
}
+func (sd *sequenceDiagram) adjustGroupLabel(group *d2graph.Object) {
+ if group.LabelHeight == nil {
+ return
+ }
+
+ heightAdd := (*group.LabelHeight + EDGE_GROUP_LABEL_PADDING) - GROUP_CONTAINER_PADDING
+ if heightAdd < 0 {
+ return
+ }
+
+ group.Height += float64(heightAdd)
+
+ // Extend stuff within this group
+ for _, g := range sd.groups {
+ if g.TopLeft.Y < group.TopLeft.Y && g.TopLeft.Y+g.Height > group.TopLeft.Y {
+ g.Height += float64(heightAdd)
+ }
+ }
+ for _, s := range sd.spans {
+ if s.TopLeft.Y < group.TopLeft.Y && s.TopLeft.Y+s.Height > group.TopLeft.Y {
+ s.Height += float64(heightAdd)
+ }
+ }
+
+ // Move stuff down
+ for _, m := range sd.messages {
+ if go2.Min(m.Route[0].Y, m.Route[len(m.Route)-1].Y) > group.TopLeft.Y {
+ for _, p := range m.Route {
+ p.Y += float64(heightAdd)
+ }
+ }
+ }
+ for _, s := range sd.spans {
+ if s.TopLeft.Y > group.TopLeft.Y {
+ s.TopLeft.Y += float64(heightAdd)
+ }
+ }
+ for _, g := range sd.groups {
+ if g.TopLeft.Y > group.TopLeft.Y {
+ g.TopLeft.Y += float64(heightAdd)
+ }
+ }
+ for _, n := range sd.notes {
+ if n.TopLeft.Y > group.TopLeft.Y {
+ n.TopLeft.Y += float64(heightAdd)
+ }
+ }
+
+}
+
// placeActors places actors bottom aligned, side by side with centers spaced by sd.actorXStep
func (sd *sequenceDiagram) placeActors() {
centerX := sd.actors[0].Width / 2.
@@ -354,7 +407,7 @@ func (sd *sequenceDiagram) placeNotes() {
rankToX[sd.objectRank[actor]] = actor.Center().X
}
- for i, note := range sd.notes {
+ for _, note := range sd.notes {
verticalIndex := sd.verticalIndices[note.AbsID()]
y := sd.maxActorHeight + sd.yStep
@@ -363,8 +416,10 @@ func (sd *sequenceDiagram) placeNotes() {
y += sd.yStep
}
}
- for _, otherNote := range sd.notes[:i] {
- y += otherNote.Height + sd.yStep
+ for _, otherNote := range sd.notes {
+ if sd.verticalIndices[otherNote.AbsID()] < verticalIndex {
+ y += otherNote.Height + sd.yStep
+ }
}
x := rankToX[sd.objectRank[note]] - (note.Width / 2.)
@@ -499,7 +554,7 @@ func (sd *sequenceDiagram) routeMessages() error {
if isSelfMessage || isToDescendant || isFromDescendant || isToSibling {
midX := startX + SELF_MESSAGE_HORIZONTAL_TRAVEL
- endY := startY + MIN_MESSAGE_DISTANCE
+ endY := startY + MIN_MESSAGE_DISTANCE*1.5
message.Route = []*geo.Point{
geo.NewPoint(startX, startY),
geo.NewPoint(midX, startY),
diff --git a/d2renderers/d2svg/appendix/testdata/diagram_wider_than_tooltip/sketch.exp.svg b/d2renderers/d2svg/appendix/testdata/diagram_wider_than_tooltip/sketch.exp.svg
index f174f6658..d2aee73c9 100644
--- a/d2renderers/d2svg/appendix/testdata/diagram_wider_than_tooltip/sketch.exp.svg
+++ b/d2renderers/d2svg/appendix/testdata/diagram_wider_than_tooltip/sketch.exp.svg
@@ -3,7 +3,7 @@
id="d2-svg"
style="background: white;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
-width="1932" height="2282" viewBox="-134 -49 1932 2282">1Like starbucks or something
-2I'm not sure what this is
+}]]>1Like starbucks or something
+2I'm not sure what this is