diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md
index f3c0d2a774..84d6618aa2 100644
--- a/ci/release/changelogs/next.md
+++ b/ci/release/changelogs/next.md
@@ -3,3 +3,5 @@
#### Improvements 🧹
#### Bugfixes ⛑️
+
+- Fixed sequence diagram span size for self-edges [#397](https://github.com/terrastruct/d2/pull/397)
\ No newline at end of file
diff --git a/d2layouts/d2sequence/sequence_diagram.go b/d2layouts/d2sequence/sequence_diagram.go
index 03abf99d69..2f65bc18c6 100644
--- a/d2layouts/d2sequence/sequence_diagram.go
+++ b/d2layouts/d2sequence/sequence_diagram.go
@@ -402,8 +402,7 @@ func (sd *sequenceDiagram) placeSpans() {
// finds the position if there are messages to this span
minMessageY := math.Inf(1)
if firstMessage, exists := sd.firstMessage[span]; exists {
- // needs to check Src/Dst because of self-edges or edges to/from descendants
- if span == firstMessage.Src {
+ if firstMessage.Src == firstMessage.Dst || span == firstMessage.Src {
minMessageY = firstMessage.Route[0].Y
} else {
minMessageY = firstMessage.Route[len(firstMessage.Route)-1].Y
@@ -411,10 +410,10 @@ func (sd *sequenceDiagram) placeSpans() {
}
maxMessageY := math.Inf(-1)
if lastMessage, exists := sd.lastMessage[span]; exists {
- if span == lastMessage.Src {
- maxMessageY = lastMessage.Route[0].Y
- } else {
+ if lastMessage.Src == lastMessage.Dst || span == lastMessage.Dst {
maxMessageY = lastMessage.Route[len(lastMessage.Route)-1].Y
+ } else {
+ maxMessageY = lastMessage.Route[0].Y
}
}
diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go
index 373ee5acde..a7eef68c17 100644
--- a/e2etests/regression_test.go
+++ b/e2etests/regression_test.go
@@ -28,8 +28,12 @@ B: goodbye {
shape: sequence_diagram
}
-A->B
-`,
+A->B`,
+ }, {
+ name: "sequence_diagram_span_cover",
+ script: `shape: sequence_diagram
+b.1 -> b.1
+b.1 -> b.1`,
},
}
diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/board.exp.json b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/board.exp.json
new file mode 100644
index 0000000000..8966eb315e
--- /dev/null
+++ b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/board.exp.json
@@ -0,0 +1,219 @@
+{
+ "name": "",
+ "shapes": [
+ {
+ "id": "b",
+ "type": "",
+ "pos": {
+ "x": 24,
+ "y": 74
+ },
+ "width": 150,
+ "height": 126,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 13,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "b.1",
+ "type": "rectangle",
+ "pos": {
+ "x": 93,
+ "y": 314
+ },
+ "width": 12,
+ "height": 242,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#E3E9FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 12,
+ "labelHeight": 26,
+ "zIndex": 2,
+ "level": 2
+ }
+ ],
+ "connections": [
+ {
+ "id": "b.(1 -> 1)[0]",
+ "src": "b.1",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "b.1",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 105,
+ "y": 330
+ },
+ {
+ "x": 199,
+ "y": 330
+ },
+ {
+ "x": 199,
+ "y": 410
+ },
+ {
+ "x": 105,
+ "y": 410
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 4
+ },
+ {
+ "id": "b.(1 -> 1)[1]",
+ "src": "b.1",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "b.1",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 105,
+ "y": 460
+ },
+ {
+ "x": 199,
+ "y": 460
+ },
+ {
+ "x": 199,
+ "y": 540
+ },
+ {
+ "x": 105,
+ "y": 540
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 4
+ },
+ {
+ "id": "(b -- )[0]",
+ "src": "b",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "b-lifeline-end-668380428",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 6,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 99,
+ "y": 200
+ },
+ {
+ "x": 99,
+ "y": 670
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 1
+ }
+ ]
+}
diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/sketch.exp.svg
new file mode 100644
index 0000000000..b1b935e3c0
--- /dev/null
+++ b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/sketch.exp.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/elk/board.exp.json b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/board.exp.json
new file mode 100644
index 0000000000..8966eb315e
--- /dev/null
+++ b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/board.exp.json
@@ -0,0 +1,219 @@
+{
+ "name": "",
+ "shapes": [
+ {
+ "id": "b",
+ "type": "",
+ "pos": {
+ "x": 24,
+ "y": 74
+ },
+ "width": 150,
+ "height": 126,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 13,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "b.1",
+ "type": "rectangle",
+ "pos": {
+ "x": 93,
+ "y": 314
+ },
+ "width": 12,
+ "height": 242,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#E3E9FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 12,
+ "labelHeight": 26,
+ "zIndex": 2,
+ "level": 2
+ }
+ ],
+ "connections": [
+ {
+ "id": "b.(1 -> 1)[0]",
+ "src": "b.1",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "b.1",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 105,
+ "y": 330
+ },
+ {
+ "x": 199,
+ "y": 330
+ },
+ {
+ "x": 199,
+ "y": 410
+ },
+ {
+ "x": 105,
+ "y": 410
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 4
+ },
+ {
+ "id": "b.(1 -> 1)[1]",
+ "src": "b.1",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "b.1",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 105,
+ "y": 460
+ },
+ {
+ "x": 199,
+ "y": 460
+ },
+ {
+ "x": 199,
+ "y": 540
+ },
+ {
+ "x": 105,
+ "y": 540
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 4
+ },
+ {
+ "id": "(b -- )[0]",
+ "src": "b",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "b-lifeline-end-668380428",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 6,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 99,
+ "y": 200
+ },
+ {
+ "x": 99,
+ "y": 670
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 1
+ }
+ ]
+}
diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/elk/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/sketch.exp.svg
new file mode 100644
index 0000000000..b1b935e3c0
--- /dev/null
+++ b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/sketch.exp.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file