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 @@ + +b \ 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 @@ + +b \ No newline at end of file