diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index da2797bf4..11102d489 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -17,6 +17,7 @@ Sketch mode's subtle hand-drawn texture adapts to background colors. - CLI reports when a feature is incompatible with layout engine, instead of silently ignoring. [#845](https://github.com/terrastruct/d2/pull/845) - `near` key set to direct parent or ancestor throws an appropriate error message. [#851](https://github.com/terrastruct/d2/pull/851) - Dimensions and positions are able to be set from API. [#853](https://github.com/terrastruct/d2/pull/853) +- Improves label legibility for dagre containers by stopping container edges early if they would run into the label. [#880](https://github.com/terrastruct/d2/pull/880) #### Bugfixes ⛑️ diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index d46da1e7c..a1b279d83 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -425,7 +425,36 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err // trace the edge to the specific shape's border points[startIndex] = shape.TraceToShapeBorder(srcShape, start, points[startIndex+1]) - points[endIndex] = shape.TraceToShapeBorder(dstShape, end, points[endIndex-1]) + + // if an edge to a container runs into its label, stop the edge at the label instead + overlapsContainerLabel := false + if edge.Dst.IsContainer() && edge.Dst.Attributes.Label.Value != "" { + // assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label + labelWidth := float64(*edge.Dst.LabelWidth) + labelHeight := float64(*edge.Dst.LabelHeight) + labelTL := label.Position(*edge.Dst.LabelPosition). + GetPointOnBox(edge.Dst.Box, label.PADDING, labelWidth, labelHeight) + + endingSegment := geo.Segment{Start: points[endIndex-1], End: points[endIndex]} + labelBox := geo.NewBox(labelTL, labelWidth, labelHeight) + // add left/right padding to box + labelBox.TopLeft.X -= label.PADDING + labelBox.Width += 2 * label.PADDING + if intersections := labelBox.Intersections(endingSegment); len(intersections) > 0 { + overlapsContainerLabel = true + // move ending segment to label intersection point + points[endIndex] = intersections[0] + endingSegment.End = intersections[0] + // if the segment becomes too short, just merge it with the previous segment + if endIndex-1 > 0 && endingSegment.Length() < MIN_SEGMENT_LEN { + points[endIndex-1] = points[endIndex] + endIndex-- + } + } + } + if !overlapsContainerLabel { + points[endIndex] = shape.TraceToShapeBorder(dstShape, end, points[endIndex-1]) + } points = points[startIndex : endIndex+1] // build a curved path from the dagre route diff --git a/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/board.exp.json b/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/board.exp.json index 46f9a77c0..1c875fbb8 100644 --- a/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/board.exp.json +++ b/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/board.exp.json @@ -333,11 +333,11 @@ }, { "x": 179, - "y": 326.4 + "y": 248 }, { "x": 179, - "y": 356 + "y": 320 } ], "isCurve": true, diff --git a/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/sketch.exp.svg b/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/sketch.exp.svg index 09df89c52..7e1f2e0a4 100644 --- a/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/sketch.exp.svg @@ -51,7 +51,7 @@ svgEl.setAttribute("height", height * ratio - 16); } }); -]]>abc12d line 1line 2line 3line 4 +]]>abc12d line 1line 2line 3line 4 \ No newline at end of file diff --git a/e2etests/testdata/regression/overlapping-edge-label/dagre/board.exp.json b/e2etests/testdata/regression/overlapping-edge-label/dagre/board.exp.json index 4a30d438f..09a8de6d8 100644 --- a/e2etests/testdata/regression/overlapping-edge-label/dagre/board.exp.json +++ b/e2etests/testdata/regression/overlapping-edge-label/dagre/board.exp.json @@ -545,11 +545,11 @@ }, { "x": 217, - "y": 246.9 + "y": 238.7 }, { "x": 217, - "y": 328.5 + "y": 287.5 } ], "isCurve": true, diff --git a/e2etests/testdata/regression/overlapping-edge-label/dagre/sketch.exp.svg b/e2etests/testdata/regression/overlapping-edge-label/dagre/sketch.exp.svg index b6c7ee69f..a0bbd2cf2 100644 --- a/e2etests/testdata/regression/overlapping-edge-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/overlapping-edge-label/dagre/sketch.exp.svg @@ -51,10 +51,10 @@ svgEl.setAttribute("height", height * ratio - 16); } }); -]]>Kubernetesopensvck8s-master1k8s-master2k8s-master3k8s-worker1k8s-worker2k8s-worker3VM1VM2 keycloakheptapodharborvault +]]>Kubernetesopensvck8s-master1k8s-master2k8s-master3k8s-worker1k8s-worker2k8s-worker3VM1VM2 keycloakheptapodharborvault - + \ No newline at end of file diff --git a/e2etests/testdata/stable/direction/dagre/board.exp.json b/e2etests/testdata/stable/direction/dagre/board.exp.json index da7c82b71..9ebda9816 100644 --- a/e2etests/testdata/stable/direction/dagre/board.exp.json +++ b/e2etests/testdata/stable/direction/dagre/board.exp.json @@ -654,11 +654,11 @@ }, { "x": 140.25, - "y": 134.2 + "y": 126 }, { "x": 140.25, - "y": 207 + "y": 166 } ], "isCurve": true, @@ -837,11 +837,11 @@ }, { "x": 97, - "y": 369.7 + "y": 362.5 }, { "x": 97, - "y": 438.5 + "y": 402.5 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/direction/dagre/sketch.exp.svg b/e2etests/testdata/stable/direction/dagre/sketch.exp.svg index 51e859c8a..d71065442 100644 --- a/e2etests/testdata/stable/direction/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/direction/dagre/sketch.exp.svg @@ -44,7 +44,7 @@ svgEl.setAttribute("height", height * ratio - 16); } }); -]]>abcde12345abcde +]]>abcde12345abcde \ No newline at end of file diff --git a/e2etests/testdata/todo/container_label_edge_adjustment/dagre/board.exp.json b/e2etests/testdata/todo/container_label_edge_adjustment/dagre/board.exp.json new file mode 100644 index 000000000..b07c4e59e --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment/dagre/board.exp.json @@ -0,0 +1,535 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 14, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "cloud", + "pos": { + "x": 0, + "y": 207 + }, + "width": 397, + "height": 125, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a container label", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 195, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.c", + "type": "rectangle", + "pos": { + "x": 183, + "y": 236 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 182, + "y": 432 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 127, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 240, + "y": 0 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "g", + "type": "rectangle", + "pos": { + "x": 351, + "y": 0 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b.c)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.c", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 40, + "y": 66 + }, + { + "x": 40, + "y": 106 + }, + { + "x": 68.5, + "y": 184.09704142011833 + }, + { + "x": 182.5, + "y": 256.4852071005917 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b.c -> d)[0]", + "src": "b.c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 209, + "y": 302.5 + }, + { + "x": 209, + "y": 326.1 + }, + { + "x": 209, + "y": 392 + }, + { + "x": 209, + "y": 432 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> b.c)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.c", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 153, + "y": 66 + }, + { + "x": 153, + "y": 106 + }, + { + "x": 159.8, + "y": 180.1 + }, + { + "x": 187, + "y": 236.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(f -> b)[0]", + "src": "f", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "red", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 265, + "y": 66 + }, + { + "x": 265, + "y": 106 + }, + { + "x": 265, + "y": 126 + }, + { + "x": 265, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(g -> b)[0]", + "src": "g", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 377.5, + "y": 66 + }, + { + "x": 377.5, + "y": 106 + }, + { + "x": 377.6, + "y": 145.2 + }, + { + "x": 378, + "y": 262 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/container_label_edge_adjustment/dagre/sketch.exp.svg b/e2etests/testdata/todo/container_label_edge_adjustment/dagre/sketch.exp.svg new file mode 100644 index 000000000..eef6f80c8 --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment/dagre/sketch.exp.svg @@ -0,0 +1,50 @@ +aa container labeldefgc + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/container_label_edge_adjustment/elk/board.exp.json b/e2etests/testdata/todo/container_label_edge_adjustment/elk/board.exp.json new file mode 100644 index 000000000..c124141e8 --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment/elk/board.exp.json @@ -0,0 +1,514 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "cloud", + "pos": { + "x": 26, + "y": 213 + }, + "width": 155, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a container label", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 195, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.c", + "type": "rectangle", + "pos": { + "x": 76, + "y": 263 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 75, + "y": 454 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 85, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 158, + "y": 12 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "g", + "type": "rectangle", + "pos": { + "x": 229, + "y": 12 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b.c)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.c", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 38.5, + "y": 78 + }, + { + "x": 38.5, + "y": 118 + }, + { + "x": 93.83333333333333, + "y": 118 + }, + { + "x": 93.83333333333333, + "y": 263 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b.c -> d)[0]", + "src": "b.c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 102.66666666666666, + "y": 329 + }, + { + "x": 102.66666666666666, + "y": 454 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> b.c)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.c", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 111.5, + "y": 78 + }, + { + "x": 111.5, + "y": 263 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(f -> b)[0]", + "src": "f", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "red", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 183.5, + "y": 78 + }, + { + "x": 183.5, + "y": 118 + }, + { + "x": 121.5, + "y": 118 + }, + { + "x": 122, + "y": 213 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(g -> b)[0]", + "src": "g", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "filled-diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 256, + "y": 78 + }, + { + "x": 256, + "y": 168 + }, + { + "x": 131.5, + "y": 168 + }, + { + "x": 131, + "y": 218 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/container_label_edge_adjustment/elk/sketch.exp.svg b/e2etests/testdata/todo/container_label_edge_adjustment/elk/sketch.exp.svg new file mode 100644 index 000000000..934011400 --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment/elk/sketch.exp.svg @@ -0,0 +1,50 @@ +aa container labeldefgc + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/container_label_edge_adjustment2/dagre/board.exp.json b/e2etests/testdata/todo/container_label_edge_adjustment2/dagre/board.exp.json new file mode 100644 index 000000000..d4f3880c9 --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment2/dagre/board.exp.json @@ -0,0 +1,179 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "x", + "type": "rectangle", + "pos": { + "x": 40, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y", + "type": "rectangle", + "pos": { + "x": 0, + "y": 207 + }, + "width": 132, + "height": 125, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "bar", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y.z", + "type": "rectangle", + "pos": { + "x": 40, + "y": 236 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "(x -> y)[0]", + "src": "x", + "srcArrow": "none", + "srcLabel": "", + "dst": "y", + "dstArrow": "filled-diamond", + "dstLabel": "foo", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 66, + "y": 66 + }, + { + "x": 66, + "y": 106 + }, + { + "x": 66, + "y": 126 + }, + { + "x": 66, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/container_label_edge_adjustment2/dagre/sketch.exp.svg b/e2etests/testdata/todo/container_label_edge_adjustment2/dagre/sketch.exp.svg new file mode 100644 index 000000000..76828dacf --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment2/dagre/sketch.exp.svg @@ -0,0 +1,57 @@ +xbarz foo + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/container_label_edge_adjustment2/elk/board.exp.json b/e2etests/testdata/todo/container_label_edge_adjustment2/elk/board.exp.json new file mode 100644 index 000000000..219d55620 --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment2/elk/board.exp.json @@ -0,0 +1,170 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "x", + "type": "rectangle", + "pos": { + "x": 61, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y", + "type": "rectangle", + "pos": { + "x": 12, + "y": 148 + }, + "width": 152, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "bar", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y.z", + "type": "rectangle", + "pos": { + "x": 62, + "y": 198 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "(x -> y)[0]", + "src": "x", + "srcArrow": "none", + "srcLabel": "", + "dst": "y", + "dstArrow": "filled-diamond", + "dstLabel": "foo", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 88, + "y": 78 + }, + { + "x": 88, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/container_label_edge_adjustment2/elk/sketch.exp.svg b/e2etests/testdata/todo/container_label_edge_adjustment2/elk/sketch.exp.svg new file mode 100644 index 000000000..af97bacba --- /dev/null +++ b/e2etests/testdata/todo/container_label_edge_adjustment2/elk/sketch.exp.svg @@ -0,0 +1,57 @@ +xbarz foo + + + \ No newline at end of file diff --git a/e2etests/todo_test.go b/e2etests/todo_test.go index 17903edbd..24b52e03d 100644 --- a/e2etests/todo_test.go +++ b/e2etests/todo_test.go @@ -220,6 +220,37 @@ Office chatter: { a } } +`, + }, + { + name: "container_label_edge_adjustment", + script: ` +a -> b.c -> d: {style.stroke-width: 8; target-arrowhead.shape: diamond; target-arrowhead.style.filled: true} +b.shape: cloud +e -> b.c: {style.stroke-width: 8; target-arrowhead.shape: diamond; target-arrowhead.style.filled: true} +f -> b: { + style: { + stroke: red + stroke-width: 8 + } + target-arrowhead.shape: diamond + target-arrowhead.style.filled: true +} +g -> b: {style.stroke-width: 8; target-arrowhead.shape: diamond; target-arrowhead.style.filled: true} +b: a container label +`, + }, + { + name: "container_label_edge_adjustment2", + script: ` +x -> y: { + target-arrowhead: foo { + shape: diamond + style.filled: true + } +} + +y: bar {z} `, }, }