diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 94d61a45d..1ed616972 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -5,6 +5,8 @@ #### Improvements 🧹 +- Dagre edges are spaced apart to prevent label overlap. [#618](https://github.com/terrastruct/d2/pull/618) + #### Bugfixes ⛑️ - Appendix seperator line no longer added to PNG export when appendix doesn't exist. [#582](https://github.com/terrastruct/d2/pull/582) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 9969d2080..0d5c5d569 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -149,7 +149,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err // for `b <- a`, edge.Edge is `a -> b` and we expect this routing result src, dst = dst, src } - loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID()) + loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID(), edge.LabelDimensions.Width, edge.LabelDimensions.Height) } if debugJS { @@ -320,7 +320,6 @@ func generateAddParentLine(childID, parentID string) string { return fmt.Sprintf("g.setParent(`%s`, `%s`);\n", escapeID(childID), escapeID(parentID)) } -func generateAddEdgeLine(fromID, toID, edgeID string) string { - // in dagre v is from, w is to, name is to uniquely identify - return fmt.Sprintf("g.setEdge({v:`%s`, w:`%s`, name:`%s` });\n", escapeID(fromID), escapeID(toID), escapeID(edgeID)) +func generateAddEdgeLine(fromID, toID, edgeID string, width, height int) string { + return fmt.Sprintf("g.setEdge({v:`%s`, w:`%s`, name:`%s`}, { width:%d, height:%d, labelpos: `c` });\n", escapeID(fromID), escapeID(toID), escapeID(edgeID), width, height) } diff --git a/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg b/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg index 5bc3c0273..93a126788 100644 --- a/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/connection_label/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="319" height="556" viewBox="-102 -102 319 556">Kubernetesopensvck8s-master1k8s-master2k8s-master3k8s-worker1k8s-worker2k8s-worker3VM1VM2 keycloakheptapodharborvault + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/overlapping-edge-label/elk/board.exp.json b/e2etests/testdata/regression/overlapping-edge-label/elk/board.exp.json new file mode 100644 index 000000000..6fd038717 --- /dev/null +++ b/e2etests/testdata/regression/overlapping-edge-label/elk/board.exp.json @@ -0,0 +1,588 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "k8s", + "type": "", + "pos": { + "x": 12, + "y": 12 + }, + "width": 1405, + "height": 276, + "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": "Kubernetes", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 138, + "labelHeight": 41, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "k8s.m1", + "type": "", + "pos": { + "x": 87, + "y": 87 + }, + "width": 192, + "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": "k8s-master1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 92, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k8s.m2", + "type": "", + "pos": { + "x": 299, + "y": 87 + }, + "width": 192, + "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": "k8s-master2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 92, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k8s.m3", + "type": "", + "pos": { + "x": 511, + "y": 87 + }, + "width": 192, + "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": "k8s-master3", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 92, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k8s.w1", + "type": "", + "pos": { + "x": 723, + "y": 87 + }, + "width": 193, + "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": "k8s-worker1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 93, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k8s.w2", + "type": "", + "pos": { + "x": 936, + "y": 87 + }, + "width": 193, + "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": "k8s-worker2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 93, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k8s.w3", + "type": "", + "pos": { + "x": 1149, + "y": 87 + }, + "width": 193, + "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": "k8s-worker3", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 93, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "osvc", + "type": "", + "pos": { + "x": 397, + "y": 519 + }, + "width": 442, + "height": 276, + "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": "opensvc", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 102, + "labelHeight": 41, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "osvc.vm1", + "type": "", + "pos": { + "x": 472, + "y": 594 + }, + "width": 136, + "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": "VM1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "osvc.vm2", + "type": "", + "pos": { + "x": 628, + "y": 594 + }, + "width": 136, + "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": "VM2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "(k8s -> osvc)[0]", + "src": "k8s", + "srcArrow": "none", + "srcLabel": "", + "dst": "osvc", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "keycloak", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 59, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 293, + "y": 288 + }, + { + "x": 293, + "y": 459 + }, + { + "x": 485.6, + "y": 459 + }, + { + "x": 485.6, + "y": 519 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k8s -> osvc)[1]", + "src": "k8s", + "srcArrow": "none", + "srcLabel": "", + "dst": "osvc", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "heptapod", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 65, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 574, + "y": 288 + }, + { + "x": 574, + "y": 519 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k8s -> osvc)[2]", + "src": "k8s", + "srcArrow": "none", + "srcLabel": "", + "dst": "osvc", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "harbor", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 47, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 855, + "y": 288 + }, + { + "x": 855, + "y": 459 + }, + { + "x": 662.4000000000001, + "y": 459 + }, + { + "x": 662.4000000000001, + "y": 519 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k8s -> osvc)[3]", + "src": "k8s", + "srcArrow": "none", + "srcLabel": "", + "dst": "osvc", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "vault", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 35, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 1136, + "y": 288 + }, + { + "x": 1136, + "y": 469 + }, + { + "x": 750.8, + "y": 469 + }, + { + "x": 750.8, + "y": 519 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/regression/overlapping-edge-label/elk/sketch.exp.svg b/e2etests/testdata/regression/overlapping-edge-label/elk/sketch.exp.svg new file mode 100644 index 000000000..c81e90cf4 --- /dev/null +++ b/e2etests/testdata/regression/overlapping-edge-label/elk/sketch.exp.svg @@ -0,0 +1,69 @@ + +Kubernetesopensvck8s-master1k8s-master2k8s-master3k8s-worker1k8s-worker2k8s-worker3VM1VM2 keycloakheptapodharborvault + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/sanity/connection_label/dagre/board.exp.json b/e2etests/testdata/sanity/connection_label/dagre/board.exp.json index d2e114820..4e7beb287 100644 --- a/e2etests/testdata/sanity/connection_label/dagre/board.exp.json +++ b/e2etests/testdata/sanity/connection_label/dagre/board.exp.json @@ -47,7 +47,7 @@ "type": "", "pos": { "x": 0, - "y": 226 + "y": 247 }, "width": 113, "height": 126, @@ -115,15 +115,15 @@ }, { "x": 56.5, - "y": 166 + "y": 174.4 }, { "x": 56.5, - "y": 186 + "y": 198.7 }, { "x": 56.5, - "y": 226 + "y": 247.5 } ], "isCurve": true, diff --git a/e2etests/testdata/sanity/connection_label/dagre/sketch.exp.svg b/e2etests/testdata/sanity/connection_label/dagre/sketch.exp.svg index 719702277..51ae8878c 100644 --- a/e2etests/testdata/sanity/connection_label/dagre/sketch.exp.svg +++ b/e2etests/testdata/sanity/connection_label/dagre/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="317" height="556" viewBox="-102 -102 317 556">aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - - - - - - - +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 + + + + + + + + + mixed togethersugarsolution we get - - +mixed togethersugarsolution we get + +