From de5c00ac23a9126c2731dc70e845a728c8ebd5ea Mon Sep 17 00:00:00 2001 From: Apostolis Anastasiou Date: Fri, 20 Jan 2023 03:09:16 +0200 Subject: [PATCH 01/31] Add test to see if command exists with POSIX 'command' --- ci/e2ereport.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ci/e2ereport.sh b/ci/e2ereport.sh index ebf45b912..a787aa354 100755 --- a/ci/e2ereport.sh +++ b/ci/e2ereport.sh @@ -9,7 +9,13 @@ FORCE_COLOR=1 DEBUG=1 go run ./e2etests/report/main.go "$@"; if [ -z "${NO_OPEN:-}" ]; then if [ -s "$REPORT_OUTPUT" ]; then - open "$REPORT_OUTPUT" + if [ -x "$(command -v open)" ]; then + open $REPORT_OUTPUT + elif [ -x "$(command -v xdg-open)" ]; then + xdg-open $REPORT_OUTPUT + else + echo "Please open $REPORT_OUTPUT" + fi else echo "The report is empty" fi From 3cc8ab1cb829d3787f6bfb8b0e0cc3581c885c16 Mon Sep 17 00:00:00 2001 From: Apostolis A Date: Fri, 20 Jan 2023 04:29:47 +0200 Subject: [PATCH 02/31] Update ci/e2ereport.sh Co-authored-by: Anmol Sethi --- ci/e2ereport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/e2ereport.sh b/ci/e2ereport.sh index a787aa354..0223dc46d 100755 --- a/ci/e2ereport.sh +++ b/ci/e2ereport.sh @@ -9,7 +9,7 @@ FORCE_COLOR=1 DEBUG=1 go run ./e2etests/report/main.go "$@"; if [ -z "${NO_OPEN:-}" ]; then if [ -s "$REPORT_OUTPUT" ]; then - if [ -x "$(command -v open)" ]; then + if command -v open >/dev/null; then open $REPORT_OUTPUT elif [ -x "$(command -v xdg-open)" ]; then xdg-open $REPORT_OUTPUT From ec9617eafe18d52bae58108ac8f835dc97ef8ddb Mon Sep 17 00:00:00 2001 From: Apostolis Anastasiou Date: Sat, 21 Jan 2023 19:02:55 +0200 Subject: [PATCH 03/31] Add redirection of output to /dev/null for xdg-open Signed-off-by: Apostolis Anastasiou --- ci/e2ereport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/e2ereport.sh b/ci/e2ereport.sh index 0223dc46d..b88260ff9 100755 --- a/ci/e2ereport.sh +++ b/ci/e2ereport.sh @@ -11,7 +11,7 @@ if [ -z "${NO_OPEN:-}" ]; then if [ -s "$REPORT_OUTPUT" ]; then if command -v open >/dev/null; then open $REPORT_OUTPUT - elif [ -x "$(command -v xdg-open)" ]; then + elif [ -x "$(command -v xdg-open >/dev/null)" ]; then xdg-open $REPORT_OUTPUT else echo "Please open $REPORT_OUTPUT" From 4aee9da4331245d32498df285d9da46f0397c155 Mon Sep 17 00:00:00 2001 From: Apostolis A Date: Mon, 23 Jan 2023 03:12:26 +0200 Subject: [PATCH 04/31] Update ci/e2ereport.sh Co-authored-by: Anmol Sethi --- ci/e2ereport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/e2ereport.sh b/ci/e2ereport.sh index b88260ff9..f27949969 100755 --- a/ci/e2ereport.sh +++ b/ci/e2ereport.sh @@ -11,7 +11,7 @@ if [ -z "${NO_OPEN:-}" ]; then if [ -s "$REPORT_OUTPUT" ]; then if command -v open >/dev/null; then open $REPORT_OUTPUT - elif [ -x "$(command -v xdg-open >/dev/null)" ]; then + elif command -v xdg-open >/dev/null; then xdg-open $REPORT_OUTPUT else echo "Please open $REPORT_OUTPUT" From b6078ed3426463b9e920ba461d88434203725d90 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Thu, 9 Feb 2023 19:23:00 -0800 Subject: [PATCH 05/31] build: Passthrough $VERSION explicitly to docker/build.sh --- ci/release/build.sh | 5 ++++- ci/release/docker/build.sh | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ci/release/build.sh b/ci/release/build.sh index 2335a513e..d1c7d8e66 100755 --- a/ci/release/build.sh +++ b/ci/release/build.sh @@ -257,6 +257,7 @@ ARCHIVE=$ARCHIVE \ build_docker() { if [ -n "${LOCAL-}" ]; then sh_c ./ci/release/docker/build.sh \ + --version="$VERSION" \ ${PUSH_DOCKER:+--push} \ ${LATEST_DOCKER:+--latest} return 0 @@ -264,8 +265,10 @@ build_docker() { sh_c lockfile_ssh "$CI_D2_LINUX_AMD64" .d2-build-lock sh_c gitsync "$CI_D2_LINUX_AMD64" src/d2 - sh_c ssh "$CI_D2_LINUX_AMD64" "D2_DOCKER_IMAGE=${D2_DOCKER_IMAGE-}" \ + sh_c ssh "$CI_D2_LINUX_AMD64" \ + "D2_DOCKER_IMAGE=${D2_DOCKER_IMAGE-}" \ ./src/d2/ci/release/docker/build.sh \ + --version="$VERSION" \ ${PUSH_DOCKER:+--push} \ ${LATEST_DOCKER:+--latest} } diff --git a/ci/release/docker/build.sh b/ci/release/docker/build.sh index 0f7475d4f..849712ffe 100755 --- a/ci/release/docker/build.sh +++ b/ci/release/docker/build.sh @@ -6,7 +6,7 @@ cd -- "$(dirname "$0")/../../.." help() { cat < Date: Thu, 9 Feb 2023 19:32:27 -0800 Subject: [PATCH 06/31] build: Passthrough $RELEASE to docker build --- ci/release/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/build.sh b/ci/release/build.sh index d1c7d8e66..944dea20e 100755 --- a/ci/release/build.sh +++ b/ci/release/build.sh @@ -267,6 +267,7 @@ build_docker() { sh_c gitsync "$CI_D2_LINUX_AMD64" src/d2 sh_c ssh "$CI_D2_LINUX_AMD64" \ "D2_DOCKER_IMAGE=${D2_DOCKER_IMAGE-}" \ + "RELEASE=${RELEASE-}" \ ./src/d2/ci/release/docker/build.sh \ --version="$VERSION" \ ${PUSH_DOCKER:+--push} \ From 5ee68852c57b3d3419f568beac751cfb62b112e2 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Thu, 9 Feb 2023 19:50:18 -0800 Subject: [PATCH 07/31] docker/build.sh: More fixes --- ci/release/aws/ensure.sh | 9 ++++++++- ci/release/build.sh | 3 +++ ci/release/docker/build.sh | 8 ++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ci/release/aws/ensure.sh b/ci/release/aws/ensure.sh index 8ee2afffb..d941273fa 100755 --- a/ci/release/aws/ensure.sh +++ b/ci/release/aws/ensure.sh @@ -331,6 +331,13 @@ sudo -E apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose- sudo groupadd docker || true sudo usermod -aG docker \$USER +printf %s '$CI_DOCKER_TOKEN' | docker login -u terrastruct --password-stdin +# For building images cross platform. +sudo -E apt-get install -y qemu qemu-user-static +if docker buildx ls | grep -q 'default \*'; then + docker buildx create --use +fi + mkdir -p \$HOME/.local/bin mkdir -p \$HOME/.local/share/man EOF @@ -387,7 +394,7 @@ init_remote_env() { sh_c ssh "$REMOTE_HOST" "sudo systemctl restart sshd" # ubuntu has $PATH hard coded in /etc/environment for some reason. It takes precedence # over ~/.ssh/environment. - sh_c ssh "$REMOTE_HOST" "sudo rm /etc/environment" + sh_c ssh "$REMOTE_HOST" "sudo rm -f /etc/environment" fi } diff --git a/ci/release/build.sh b/ci/release/build.sh index 944dea20e..63122b379 100755 --- a/ci/release/build.sh +++ b/ci/release/build.sh @@ -265,6 +265,9 @@ build_docker() { sh_c lockfile_ssh "$CI_D2_LINUX_AMD64" .d2-build-lock sh_c gitsync "$CI_D2_LINUX_AMD64" src/d2 + sh_c rsync --archive --human-readable \ + "$BUILD_DIR/d2-$VERSION"-linux-*.tar.gz \ + "$CI_D2_LINUX_AMD64:src/d2/$BUILD_DIR/" sh_c ssh "$CI_D2_LINUX_AMD64" \ "D2_DOCKER_IMAGE=${D2_DOCKER_IMAGE-}" \ "RELEASE=${RELEASE-}" \ diff --git a/ci/release/docker/build.sh b/ci/release/docker/build.sh index 849712ffe..2b3477e24 100755 --- a/ci/release/docker/build.sh +++ b/ci/release/docker/build.sh @@ -42,8 +42,12 @@ main() { D2_DOCKER_IMAGE=${D2_DOCKER_IMAGE:-terrastruct/d2} sh_c mkdir -p "./ci/release/build/$VERSION/docker" - sh_c cp "./ci/release/build/$VERSION/d2-$VERSION"-linux-*.tar.gz "./ci/release/build/$VERSION/docker/" - sh_c cp ./ci/release/docker/entrypoint.sh "./ci/release/build/$VERSION/docker/entrypoint.sh" + sh_c cp \ + "./ci/release/build/$VERSION/d2-$VERSION"-linux-*.tar.gz \ + "./ci/release/build/$VERSION/docker/" + sh_c cp \ + ./ci/release/docker/entrypoint.sh \ + "./ci/release/build/$VERSION/docker/entrypoint.sh" flags='--load' if [ -n "${PUSH-}" -o -n "${RELEASE-}" ]; then From 97e73cf3fd07b430176026eae7d81d36a7aa42ef Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Thu, 9 Feb 2023 20:09:20 -0800 Subject: [PATCH 08/31] Update ci/e2ereport.sh --- ci/e2ereport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/e2ereport.sh b/ci/e2ereport.sh index f27949969..8dfe5d6a3 100755 --- a/ci/e2ereport.sh +++ b/ci/e2ereport.sh @@ -10,7 +10,7 @@ FORCE_COLOR=1 DEBUG=1 go run ./e2etests/report/main.go "$@"; if [ -z "${NO_OPEN:-}" ]; then if [ -s "$REPORT_OUTPUT" ]; then if command -v open >/dev/null; then - open $REPORT_OUTPUT + open "$REPORT_OUTPUT" elif command -v xdg-open >/dev/null; then xdg-open $REPORT_OUTPUT else From ecd2ed2be044aee8c60ebfd88e1cb7406df37a89 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Thu, 9 Feb 2023 20:09:27 -0800 Subject: [PATCH 09/31] Update ci/e2ereport.sh --- ci/e2ereport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/e2ereport.sh b/ci/e2ereport.sh index 8dfe5d6a3..c92f83e26 100755 --- a/ci/e2ereport.sh +++ b/ci/e2ereport.sh @@ -12,7 +12,7 @@ if [ -z "${NO_OPEN:-}" ]; then if command -v open >/dev/null; then open "$REPORT_OUTPUT" elif command -v xdg-open >/dev/null; then - xdg-open $REPORT_OUTPUT + xdg-open "$REPORT_OUTPUT" else echo "Please open $REPORT_OUTPUT" fi From 939a5ca088553f5b7fe410566bd4d9e54beb3a60 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 12:18:50 -0800 Subject: [PATCH 10/31] ok --- d2layouts/d2dagrelayout/layout.go | 97 ++++++- .../d2sketch/testdata/animated/sketch.exp.svg | 6 +- .../testdata/child_to_child/sketch.exp.svg | 6 +- e2etests/stable_test.go | 7 + .../dagre/board.exp.json | 44 +-- .../dagre/sketch.exp.svg | 8 +- .../dagre/board.exp.json | 48 ++-- .../dagre/sketch.exp.svg | 14 +- .../elk_alignment/dagre/board.exp.json | 104 +++---- .../elk_alignment/dagre/sketch.exp.svg | 22 +- .../elk_loop_panic/dagre/board.exp.json | 36 +-- .../elk_loop_panic/dagre/sketch.exp.svg | 6 +- .../dagre/board.exp.json | 28 +- .../dagre/sketch.exp.svg | 6 +- .../child_to_child/dagre/board.exp.json | 20 +- .../child_to_child/dagre/sketch.exp.svg | 6 +- .../stable/chaos1/dagre/board.exp.json | 20 +- .../stable/chaos1/dagre/sketch.exp.svg | 10 +- .../stable/chaos2/dagre/board.exp.json | 190 ++++++------- .../stable/chaos2/dagre/sketch.exp.svg | 22 +- .../child_parent_edges/dagre/board.exp.json | 76 ++--- .../child_parent_edges/dagre/sketch.exp.svg | 6 +- .../complex-layers/dagre/board.exp.json | 10 +- .../connected_container/dagre/board.exp.json | 38 +-- .../connected_container/dagre/sketch.exp.svg | 6 +- .../container_edges/dagre/board.exp.json | 36 +-- .../container_edges/dagre/sketch.exp.svg | 2 +- .../container_label_loop/dagre/board.exp.json | 263 ++++++++++++++++++ .../container_label_loop/dagre/sketch.exp.svg | 59 ++++ .../container_label_loop/elk/board.exp.json | 217 +++++++++++++++ .../container_label_loop/elk/sketch.exp.svg | 59 ++++ .../different_subgraphs/dagre/board.exp.json | 48 ++-- .../different_subgraphs/dagre/sketch.exp.svg | 6 +- .../stable/direction/dagre/board.exp.json | 90 +++--- .../stable/direction/dagre/sketch.exp.svg | 2 +- .../stable/investigate/dagre/board.exp.json | 144 +++++----- .../stable/investigate/dagre/sketch.exp.svg | 14 +- .../stable/large_arch/dagre/board.exp.json | 258 ++++++++--------- .../stable/large_arch/dagre/sketch.exp.svg | 6 +- .../markdown_stroke_fill/dagre/board.exp.json | 8 +- .../markdown_stroke_fill/dagre/sketch.exp.svg | 10 +- .../md_2space_newline/dagre/board.exp.json | 8 +- .../md_2space_newline/dagre/sketch.exp.svg | 8 +- .../md_backslash_newline/dagre/board.exp.json | 8 +- .../md_backslash_newline/dagre/sketch.exp.svg | 8 +- .../one_container_loop/dagre/board.exp.json | 14 +- .../one_container_loop/dagre/sketch.exp.svg | 6 +- .../dagre/board.exp.json | 28 +- .../dagre/sketch.exp.svg | 6 +- .../dagre/board.exp.json | 94 +++---- .../dagre/sketch.exp.svg | 14 +- .../sequence_diagrams/dagre/board.exp.json | 234 ++++++++-------- .../sequence_diagrams/dagre/sketch.exp.svg | 26 +- .../dagre/board.exp.json | 126 ++++----- .../dagre/sketch.exp.svg | 2 +- .../container_child_edge/dagre/board.exp.json | 26 +- .../container_child_edge/dagre/sketch.exp.svg | 10 +- .../dagre/board.exp.json | 26 +- .../dagre/sketch.exp.svg | 6 +- .../dagre/board.exp.json | 38 +-- .../dagre/sketch.exp.svg | 8 +- 61 files changed, 1726 insertions(+), 1028 deletions(-) create mode 100644 e2etests/testdata/stable/container_label_loop/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/container_label_loop/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/container_label_loop/elk/board.exp.json create mode 100644 e2etests/testdata/stable/container_label_loop/elk/sketch.exp.svg diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 7ac2a44e4..7004496cd 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "regexp" + "sort" "strings" "cdr.dev/slog" @@ -104,6 +105,16 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err rootAttrs.rankdir = "TB" } + maxContainerLabelHeight := 0 + for _, obj := range g.Objects { + if len(obj.ChildrenArray) == 0 { + continue + } + if obj.LabelHeight != nil { + maxContainerLabelHeight = go2.Max(maxContainerLabelHeight, *obj.LabelHeight) + } + } + maxLabelSize := 0 for _, edge := range g.Edges { size := edge.LabelDimensions.Width @@ -112,7 +123,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } maxLabelSize = go2.Max(maxLabelSize, size) } - rootAttrs.ranksep = go2.Max(100, maxLabelSize+40) + rootAttrs.ranksep = go2.Max(go2.Max(100, maxLabelSize+40), maxContainerLabelHeight) configJS := setGraphAttrs(rootAttrs) if _, err := vm.RunString(configJS); err != nil { @@ -130,6 +141,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err if obj.Attributes.Shape.Value == d2target.ShapeImage || obj.Attributes.Icon != nil { height += float64(*obj.LabelHeight) + label.PADDING } + if len(obj.ChildrenArray) > 0 { + obj.Height += float64(*obj.LabelHeight) + } } loadScript += generateAddNodeLine(id, int(obj.Width), int(height)) if obj.Parent != g.Root { @@ -191,7 +205,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err if obj.LabelWidth != nil && obj.LabelHeight != nil { if len(obj.ChildrenArray) > 0 { - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + obj.LabelPosition = go2.Pointer(string(label.OutsideTopCenter)) } else if obj.Attributes.Shape.Value == d2target.ShapeImage { obj.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter)) // remove the extra height we added to the node when passing to dagre @@ -327,6 +341,85 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } + // TODO probably don't need + byLevels := make([]*d2graph.Object, len(g.Objects)) + copy(byLevels, g.Objects) + sort.SliceStable(byLevels, func(i, j int) bool { + return byLevels[i].Level() > byLevels[j].Level() + }) + + for _, obj := range byLevels { + if obj.LabelHeight == nil || len(obj.ChildrenArray) <= 0 { + continue + } + + // This was artifically added to make dagre consider label height + obj.Height -= float64(*obj.LabelHeight) + + movedEdges := make(map[*d2graph.Edge]struct{}) + for _, e := range g.Edges { + currSrc := e.Src + currDst := e.Dst + + isSrcDesc := false + isDstDesc := false + + for currSrc != nil { + if currSrc == obj { + isSrcDesc = true + break + } + currSrc = currSrc.Parent + } + for currDst != nil { + if currDst == obj { + isDstDesc = true + break + } + currDst = currDst.Parent + } + if isSrcDesc && isDstDesc { + stepSize := float64(*obj.LabelHeight) + if e.Src != obj || e.Dst != obj { + stepSize /= 2. + } + movedEdges[e] = struct{}{} + for _, p := range e.Route { + p.Y += stepSize + } + } + } + + // Downshift descendents + q := []*d2graph.Object{obj} + for len(q) > 0 { + curr := q[0] + q = q[1:] + + stepSize := float64(*obj.LabelHeight) + if curr != obj { + stepSize /= 2. + } + curr.TopLeft.Y += stepSize + if curr != obj { + for _, e := range g.Edges { + if _, ok := movedEdges[e]; ok { + continue + } + if e.Src == curr { + e.Route[0].Y += stepSize + } + if e.Dst == curr { + e.Route[len(e.Route)-1].Y += stepSize + } + } + } + for _, c := range curr.ChildrenArray { + q = append(q, c) + } + } + } + return nil } diff --git a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg index 51a2b7396..4ea57e1cb 100644 --- a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/animated/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="486" height="802" viewBox="-102 -102 486 802">aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - - - - - - - +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 + + + + + + + + + If we were meant to fly, we wouldn't keep losing our luggagebc + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/container_label_loop/elk/board.exp.json b/e2etests/testdata/stable/container_label_loop/elk/board.exp.json new file mode 100644 index 000000000..9e87e945d --- /dev/null +++ b/e2etests/testdata/stable/container_label_loop/elk/board.exp.json @@ -0,0 +1,217 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 62, + "y": 12 + }, + "width": 203, + "height": 382, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "If we were meant to fly, we wouldn't keep losing our luggage", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 702, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": 137, + "y": 87 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": 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": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.c", + "type": "rectangle", + "pos": { + "x": 137, + "y": 253 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "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": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "a.(b -> c)[0]", + "src": "a.b", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.c", + "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": 163.5, + "y": 153 + }, + { + "x": 163.5, + "y": 253 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> a)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "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": 62, + "y": 139.33333333333331 + }, + { + "x": 12, + "y": 139.33333333333331 + }, + { + "x": 12, + "y": 266.66666666666663 + }, + { + "x": 62, + "y": 266.66666666666663 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/stable/container_label_loop/elk/sketch.exp.svg b/e2etests/testdata/stable/container_label_loop/elk/sketch.exp.svg new file mode 100644 index 000000000..95bc08d82 --- /dev/null +++ b/e2etests/testdata/stable/container_label_loop/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +If we were meant to fly, we wouldn't keep losing our luggagebc + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/different_subgraphs/dagre/board.exp.json b/e2etests/testdata/stable/different_subgraphs/dagre/board.exp.json index a0924a33c..3e1e67cc4 100644 --- a/e2etests/testdata/stable/different_subgraphs/dagre/board.exp.json +++ b/e2etests/testdata/stable/different_subgraphs/dagre/board.exp.json @@ -499,10 +499,10 @@ "type": "rectangle", "pos": { "x": 821, - "y": 0 + "y": 36 }, "width": 368, - "height": 664, + "height": 628, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -531,7 +531,7 @@ "underline": false, "labelWidth": 72, "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", + "labelPosition": "OUTSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -704,7 +704,7 @@ "type": "rectangle", "pos": { "x": 1056, - "y": 216 + "y": 234 }, "width": 53, "height": 66, @@ -745,7 +745,7 @@ "type": "rectangle", "pos": { "x": 891, - "y": 382 + "y": 400 }, "width": 74, "height": 66, @@ -786,7 +786,7 @@ "type": "rectangle", "pos": { "x": 1038, - "y": 50 + "y": 68 }, "width": 88, "height": 66, @@ -827,7 +827,7 @@ "type": "rectangle", "pos": { "x": 871, - "y": 548 + "y": 566 }, "width": 113, "height": 66, @@ -868,7 +868,7 @@ "type": "rectangle", "pos": { "x": 1025, - "y": 382 + "y": 400 }, "width": 75, "height": 66, @@ -1587,19 +1587,19 @@ "route": [ { "x": 1055.5, - "y": 263.23624595469255 + "y": 281.23624595469255 }, { "x": 953.1, - "y": 318.24724919093853 + "y": 336.24724919093853 }, { "x": 927.5, - "y": 342 + "y": 360 }, { "x": 927.5, - "y": 382 + "y": 400 } ], "isCurve": true, @@ -1635,19 +1635,19 @@ "route": [ { "x": 1082, - "y": 116 + "y": 134 }, { "x": 1082, - "y": 156 + "y": 174 }, { "x": 1082, - "y": 176 + "y": 194 }, { "x": 1082, - "y": 216 + "y": 234 } ], "isCurve": true, @@ -1683,19 +1683,19 @@ "route": [ { "x": 927.5, - "y": 448 + "y": 466 }, { "x": 927.5, - "y": 488 + "y": 506 }, { "x": 927.5, - "y": 508 + "y": 526 }, { "x": 927.5, - "y": 548 + "y": 566 } ], "isCurve": true, @@ -1731,19 +1731,19 @@ "route": [ { "x": 1074.0481927710844, - "y": 282 + "y": 300 }, { "x": 1064.4096385542168, - "y": 322 + "y": 340 }, { "x": 1062, - "y": 342 + "y": 360 }, { "x": 1062, - "y": 382 + "y": 400 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/different_subgraphs/dagre/sketch.exp.svg b/e2etests/testdata/stable/different_subgraphs/dagre/sketch.exp.svg index cfccd3094..f0c7957ea 100644 --- a/e2etests/testdata/stable/different_subgraphs/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/different_subgraphs/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="1696" height="868" viewBox="-102 -102 1696 868">container

they did it in style

-

a header

+container

they did it in style

+

a header

a line of text and an

{
 	indented: "block",
@@ -805,8 +805,8 @@ width="516" height="686" viewBox="-102 -102 516 686">markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- +
+ markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- +
+ containerscloudtall cylinderclass- +containerscloudtall cylinderclass- num int- timeout @@ -823,8 +823,8 @@ width="2482" height="2672" viewBox="-102 -102 2482 2672">aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - - - - - - + + + + + + + + eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one - - - - - - \ No newline at end of file diff --git a/e2etests/testdata/todo/font_sizes_large/elk/board.exp.json b/e2etests/testdata/todo/font_sizes_large/elk/board.exp.json deleted file mode 100644 index 463f68094..000000000 --- a/e2etests/testdata/todo/font_sizes_large/elk/board.exp.json +++ /dev/null @@ -1,369 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "eight", - "type": "rectangle", - "pos": { - "x": 244, - "y": 12 - }, - "width": 64, - "height": 56, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "eight", - "fontSize": 8, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 19, - "labelHeight": 11, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "sixteen", - "type": "rectangle", - "pos": { - "x": 228, - "y": 284 - }, - "width": 97, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "sixteen", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 52, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "thirty two", - "type": "rectangle", - "pos": { - "x": 183, - "y": 581 - }, - "width": 187, - "height": 86, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "thirty two", - "fontSize": 32, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 142, - "labelHeight": 41, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "sixty four", - "type": "rectangle", - "pos": { - "x": 119, - "y": 928 - }, - "width": 314, - "height": 126, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "sixty four", - "fontSize": 64, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 269, - "labelHeight": 81, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "ninety nine", - "type": "rectangle", - "pos": { - "x": 12, - "y": 1356 - }, - "width": 529, - "height": 170, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "ninety nine", - "fontSize": 99, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 484, - "labelHeight": 125, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - } - ], - "connections": [ - { - "id": "(eight -> sixteen)[0]", - "src": "eight", - "srcArrow": "none", - "srcLabel": "", - "dst": "sixteen", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "twelve", - "fontSize": 12, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 33, - "labelHeight": 16, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 276.5, - "y": 68 - }, - { - "x": 276.5, - "y": 284 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(sixteen -> thirty two)[0]", - "src": "sixteen", - "srcArrow": "none", - "srcLabel": "", - "dst": "thirty two", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "twenty four", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 114, - "labelHeight": 31, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 276.5, - "y": 350 - }, - { - "x": 276.5, - "y": 581 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(thirty two -> sixty four)[0]", - "src": "thirty two", - "srcArrow": "none", - "srcLabel": "", - "dst": "sixty four", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "forty eight", - "fontSize": 48, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 202, - "labelHeight": 61, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 276.5, - "y": 667 - }, - { - "x": 276.5, - "y": 928 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(sixty four -> ninety nine)[0]", - "src": "sixty four", - "srcArrow": "none", - "srcLabel": "", - "dst": "ninety nine", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "eighty one", - "fontSize": 81, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 341, - "labelHeight": 102, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 276.5, - "y": 1054 - }, - { - "x": 276.5, - "y": 1356 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg b/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg deleted file mode 100644 index 28c54832a..000000000 --- a/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg +++ /dev/null @@ -1,62 +0,0 @@ - -eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one - - - - - - \ No newline at end of file diff --git a/e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json b/e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json deleted file mode 100644 index bafced325..000000000 --- a/e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "a", - "type": "rectangle", - "pos": { - "x": 0, - "y": 0 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "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": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 0, - "y": 372 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": 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": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - } - ], - "connections": [ - { - "id": "(a -> b)[0]", - "src": "a", - "srcArrow": "none", - "srcLabel": "", - "dst": "b", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "There\nonce\nwas\na\nvery\ntall\nedge\nlabel", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 38, - "labelHeight": 133, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 26.5, - "y": 66 - }, - { - "x": 26.5, - "y": 188.4 - }, - { - "x": 26.5, - "y": 249.6 - }, - { - "x": 26.5, - "y": 372 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg b/e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg deleted file mode 100644 index 231114a5f..000000000 --- a/e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg +++ /dev/null @@ -1,59 +0,0 @@ - -ab Thereoncewasaverytalledgelabel - - - \ No newline at end of file diff --git a/e2etests/testdata/todo/tall_edge_label/elk/board.exp.json b/e2etests/testdata/todo/tall_edge_label/elk/board.exp.json deleted file mode 100644 index 6f0851cca..000000000 --- a/e2etests/testdata/todo/tall_edge_label/elk/board.exp.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "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": "#F7F8FE", - "stroke": "#0D32B2", - "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": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 12, - "y": 411 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": 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": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - } - ], - "connections": [ - { - "id": "(a -> b)[0]", - "src": "a", - "srcArrow": "none", - "srcLabel": "", - "dst": "b", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "There\nonce\nwas\na\nvery\ntall\nedge\nlabel", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 38, - "labelHeight": 133, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 38.5, - "y": 78 - }, - { - "x": 38.5, - "y": 411 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg b/e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg deleted file mode 100644 index ce817e41e..000000000 --- a/e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg +++ /dev/null @@ -1,59 +0,0 @@ - -ab Thereoncewasaverytalledgelabel - - - \ No newline at end of file diff --git a/e2etests/todo_test.go b/e2etests/todo_test.go index a1a413206..32c45f052 100644 --- a/e2etests/todo_test.go +++ b/e2etests/todo_test.go @@ -16,57 +16,19 @@ container -> container.second: c->2 `, }, { - // issue https://github.com/terrastruct/d2/issues/263 - name: "tall_edge_label", - script: ` -a -> b: There\nonce\nwas\na\nvery\ntall\nedge\nlabel -`, + name: "child_parent_edges", + script: `a.b -> a +a.b -> a.b.c +a.b.c.d -> a.b`, }, { - // issue https://github.com/terrastruct/d2/issues/263 - name: "font_sizes_large", - script: ` -eight.style.font-size: 8 -sixteen.style.font-size: 16 -thirty two.style.font-size: 32 -sixty four.style.font-size: 64 -ninety nine.style.font-size: 99 - -eight -> sixteen : twelve { - style.font-size: 12 + name: "container_label_loop", + script: `a: "If we were meant to fly, we wouldn't keep losing our luggage" { + b -> c } -sixteen -> thirty two : twenty four { - style.font-size: 24 -} -thirty two -> sixty four: forty eight { - style.font-size: 48 -} -sixty four -> ninety nine: eighty one { - style.font-size: 81 -} -`, +a -> a`, }, { - // issue https://github.com/terrastruct/d2/issues/19 - name: "font_sizes_containers_large", - script: ` -ninety nine: { - style.font-size: 99 - sixty four: { - style.font-size: 64 - thirty two:{ - style.font-size: 32 - sixteen: { - style.font-size: 16 - eight: { - style.font-size: 8 - } - } - } - } -} -`, - }, { // as nesting gets deeper, the groups advance towards `c` and may overlap its lifeline // needs to consider the group size when computing the distance from `a` to `c` // a similar effect can be seen for spans From aab194f56454b2597d33847554b3186dc91d1079 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 10 Feb 2023 13:35:28 -0800 Subject: [PATCH 13/31] fix e2ereport to ensure test paths are relative to report --- e2etests/report/main.go | 39 +++++++++++++++++++++++++++++------ e2etests/report/template.html | 8 +++---- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/e2etests/report/main.go b/e2etests/report/main.go index f71c7f1cd..632841700 100644 --- a/e2etests/report/main.go +++ b/e2etests/report/main.go @@ -100,7 +100,11 @@ func main() { } if matchTestSet && matchTestCase { - fullPath := filepath.Join(path, testFile.Name()) + absPath, err := filepath.Abs(path) + if err != nil { + stdlog.Fatal(err) + } + fullPath := filepath.Join(absPath, testFile.Name()) hasGot := false gotPath := strings.Replace(fullPath, "exp.svg", "got.svg", 1) if _, err := os.Stat(gotPath); err == nil { @@ -143,10 +147,6 @@ func main() { panic(err) } - tmplData := TemplateData{ - Tests: tests, - } - path := os.Getenv("REPORT_OUTPUT") if path == "" { path = filepath.Join(testDir, "./out/e2e_report.html") @@ -159,7 +159,34 @@ func main() { if err != nil { panic(fmt.Errorf("error creating file `%s`. %v", path, err)) } - if err := tmpl.Execute(f, tmplData); err != nil { + absReportDir, err := filepath.Abs(filepath.Dir(path)) + if err != nil { + stdlog.Fatal(err) + } + + // get the test path relative to the report + reportRelPath := func(testPath string) string { + absTestPath, err := filepath.Abs(testPath) + if err != nil { + stdlog.Fatal(err) + } + relTestPath, err := filepath.Rel(absReportDir, absTestPath) + if err != nil { + stdlog.Fatal(err) + } + return relTestPath + } + + // update test paths to be relative to report file + for i := range tests { + testItem := &tests[i] + testItem.GotSVG = reportRelPath(testItem.GotSVG) + if testItem.ExpSVG != nil { + *testItem.ExpSVG = reportRelPath(*testItem.ExpSVG) + } + } + + if err := tmpl.Execute(f, TemplateData{Tests: tests}); err != nil { panic(err) } } diff --git a/e2etests/report/template.html b/e2etests/report/template.html index 28ed677ed..24a62582f 100644 --- a/e2etests/report/template.html +++ b/e2etests/report/template.html @@ -10,16 +10,16 @@
{{range .Tests}}
-

{{.Name}}

+

{{.Name}}

{{ if .ExpSVG }}

Expected

{{ end }}

Got

{{ if .ExpSVG }} - + {{ end }} - +
{{end}} @@ -41,7 +41,7 @@ .case img { width: 600px; } - .case-got { + .case-exp + .case-got { position: absolute; left: 600px; } From 4229f52f1f56ffaa145e34c2c07f547dcdb9773a Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 13:38:31 -0800 Subject: [PATCH 14/31] oops --- d2layouts/d2dagrelayout/layout.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 6df8e9288..bb5bbe506 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -372,10 +372,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } if isSrcDesc && isDstDesc { stepSize := float64(*obj.LabelHeight) - // Container self edges don't work right now, but when they do, this should be uncommented - // if e.Src != obj || e.Dst != obj { - // stepSize /= 2. - // } + if e.Src != obj || e.Dst != obj { + stepSize /= 2. + } movedEdges[e] = struct{}{} for _, p := range e.Route { p.Y += stepSize From 9463c6755528fddb4a1dc0cad547daebeac20e92 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 13:40:12 -0800 Subject: [PATCH 15/31] test --- .../dagre/board.exp.json | 24 +-- .../dagre/sketch.exp.svg | 4 +- .../dagre/board.exp.json | 32 ++-- .../dagre/sketch.exp.svg | 10 +- .../elk_alignment/dagre/board.exp.json | 64 +++---- .../elk_alignment/dagre/sketch.exp.svg | 18 +- .../elk_loop_panic/dagre/board.exp.json | 26 +-- .../elk_loop_panic/dagre/sketch.exp.svg | 2 +- .../stable/chaos1/dagre/board.exp.json | 8 +- .../stable/chaos1/dagre/sketch.exp.svg | 4 +- .../stable/chaos2/dagre/board.exp.json | 140 +++++++-------- .../stable/chaos2/dagre/sketch.exp.svg | 18 +- .../different_subgraphs/dagre/board.exp.json | 32 ++-- .../different_subgraphs/dagre/sketch.exp.svg | 2 +- .../stable/direction/dagre/board.exp.json | 60 +++---- .../stable/direction/dagre/sketch.exp.svg | 2 +- .../stable/investigate/dagre/board.exp.json | 24 +-- .../stable/investigate/dagre/sketch.exp.svg | 2 +- .../stable/large_arch/dagre/board.exp.json | 160 +++++++++--------- .../stable/large_arch/dagre/sketch.exp.svg | 2 +- .../dagre/board.exp.json | 48 +++--- .../dagre/sketch.exp.svg | 14 +- .../child_parent_edges/dagre/board.exp.json | 56 +++--- .../child_parent_edges/dagre/sketch.exp.svg | 2 +- .../container_child_edge/dagre/board.exp.json | 16 +- .../container_child_edge/dagre/sketch.exp.svg | 6 +- .../container_label_loop/dagre/board.exp.json | 8 +- .../container_label_loop/dagre/sketch.exp.svg | 2 +- 28 files changed, 393 insertions(+), 393 deletions(-) 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 df4e0a899..9fa93bf6e 100644 --- a/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/board.exp.json +++ b/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/board.exp.json @@ -277,19 +277,19 @@ "route": [ { "x": 120, - "y": 157.5 + "y": 139.5 }, { "x": 120, - "y": 227.9 + "y": 209.9 }, { "x": 120, - "y": 263.5 + "y": 245.5 }, { "x": 120, - "y": 335.5 + "y": 317.5 } ], "isCurve": true, @@ -325,19 +325,19 @@ "route": [ { "x": 232.5, - "y": 157.5 + "y": 139.5 }, { "x": 232.5, - "y": 227.9 + "y": 209.9 }, { "x": 232.5, - "y": 263.5 + "y": 245.5 }, { "x": 232.5, - "y": 335.5 + "y": 317.5 } ], "isCurve": true, @@ -373,19 +373,19 @@ "route": [ { "x": 345, - "y": 157.5 + "y": 139.5 }, { "x": 345, - "y": 227.9 + "y": 209.9 }, { "x": 345, - "y": 263.5 + "y": 245.5 }, { "x": 345, - "y": 335.5 + "y": 317.5 } ], "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 03d845992..7af02a256 100644 --- a/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/dagre_broken_arrowhead/dagre/sketch.exp.svg @@ -39,9 +39,9 @@ width="629" height="735" viewBox="-102 -105 629 735">aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - - - - - - + + + + + + + + aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - - - - - - - +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 + + + + + + + + + container

they did it in style

-

a header

+container

they did it in style

+

a header

a line of text and an

{
 	indented: "block",
@@ -805,8 +805,8 @@ width="516" height="689" viewBox="-102 -105 516 689">markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- +
+ markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- +
+ containerscloudtall cylinderclass- +containerscloudtall cylinderclass- num int- timeout @@ -823,8 +823,8 @@ width="2482" height="2675" viewBox="-102 -105 2482 2675">Big fontabca + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/container_icon_label/elk/board.exp.json b/e2etests/testdata/todo/container_icon_label/elk/board.exp.json new file mode 100644 index 000000000..d1347e8a9 --- /dev/null +++ b/e2etests/testdata/todo/container_icon_label/elk/board.exp.json @@ -0,0 +1,302 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 353, + "height": 698, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/essentials/004-picture.svg", + "RawPath": "", + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Big font", + "fontSize": 30, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 96, + "labelHeight": 38, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.a", + "type": "rectangle", + "pos": { + "x": 87, + "y": 87 + }, + "width": 203, + "height": 216, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "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": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 10, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": 162, + "y": 403 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": 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": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.c", + "type": "rectangle", + "pos": { + "x": 162, + "y": 569 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "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": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.a.a", + "type": "rectangle", + "pos": { + "x": 162, + "y": 162 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "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": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + } + ], + "connections": [ + { + "id": "a.(a -> b)[0]", + "src": "a.a", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.b", + "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": 188.5, + "y": 303 + }, + { + "x": 188.5, + "y": 403 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(b -> c)[0]", + "src": "a.b", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.c", + "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": 188.5, + "y": 469 + }, + { + "x": 188.5, + "y": 569 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/container_icon_label/elk/sketch.exp.svg b/e2etests/testdata/todo/container_icon_label/elk/sketch.exp.svg new file mode 100644 index 000000000..c37c34e2e --- /dev/null +++ b/e2etests/testdata/todo/container_icon_label/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +Big fontabca + + + \ No newline at end of file diff --git a/e2etests/todo_test.go b/e2etests/todo_test.go index 32c45f052..5d5953cdd 100644 --- a/e2etests/todo_test.go +++ b/e2etests/todo_test.go @@ -204,6 +204,19 @@ Office chatter: { } } } +`, + }, + { + // https://github.com/terrastruct/d2/issues/791 + name: "container_icon_label", + script: `a: Big font { + icon: https://icons.terrastruct.com/essentials/004-picture.svg + style.font-size: 30 + a -> b -> c + a: { + a + } +} `, }, } From a677194a08d25429e2ffe65085c300b8ff5850c2 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 14:15:39 -0800 Subject: [PATCH 22/31] changelog --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index fd95f04a1..e34faad22 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -23,6 +23,7 @@ - Code snippets use bold and italic font styles as determined by highlighter [#710](https://github.com/terrastruct/d2/issues/710), [#741](https://github.com/terrastruct/d2/issues/741) - Reduces default padding of shapes. [#702](https://github.com/terrastruct/d2/pull/702) - 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) - 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) From 279b82b5c6aba528bd4bd59f7bb13ad7ca05a77c Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 14:28:43 -0800 Subject: [PATCH 23/31] comments --- d2layouts/d2dagrelayout/layout.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 8233dce79..ea23ec1d3 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -345,11 +345,14 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err continue } - subtract := go2.Min(rootAttrs.ranksep/2, *obj.LabelHeight+label.PADDING) + // usually you don't want to take away here more than what was added, which is the label height + // however, if the label height is more than the ranksep/2, we'll have no padding around children anymore + // so cap the amount taken off at ranksep/2 + subtract := float64(go2.Min(rootAttrs.ranksep/2, *obj.LabelHeight+label.PADDING)) - // This was artifically added to make dagre consider label height - obj.Height -= float64(subtract) + obj.Height -= subtract + // If the edge is connected to two descendants that are about to be downshifted, their whole route gets downshifted movedEdges := make(map[*d2graph.Edge]struct{}) for _, e := range g.Edges { currSrc := e.Src @@ -373,7 +376,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err currDst = currDst.Parent } if isSrcDesc && isDstDesc { - stepSize := float64(subtract) + stepSize := subtract + // loops if e.Src != obj || e.Dst != obj { stepSize /= 2. } @@ -384,13 +388,13 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } - // Downshift descendents + // Downshift descendents and edges that have one endpoint connected to a descendant q := []*d2graph.Object{obj} for len(q) > 0 { curr := q[0] q = q[1:] - stepSize := float64(subtract) + stepSize := subtract if curr != obj { stepSize /= 2. } From 2e5612697f70c8b66aa9e84ce084acc3002ffea6 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 14:28:52 -0800 Subject: [PATCH 24/31] ooops --- d2layouts/d2dagrelayout/layout.go | 1 - 1 file changed, 1 deletion(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index ea23ec1d3..fd2423644 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -377,7 +377,6 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } if isSrcDesc && isDstDesc { stepSize := subtract - // loops if e.Src != obj || e.Dst != obj { stepSize /= 2. } From 0877c349ad1aeca3a4800ca74b091f83fef54912 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 14:30:05 -0800 Subject: [PATCH 25/31] comments --- d2layouts/d2dagrelayout/layout.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index fd2423644..e7776d0b7 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -394,6 +394,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err q = q[1:] stepSize := subtract + // The object itself needs to move down the height it was just subtracted + // all descendents move half, to maintain vertical padding if curr != obj { stepSize /= 2. } From 94bf92a28bc8ad613b79f72337943a1db31e75c1 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 10 Feb 2023 16:19:19 -0800 Subject: [PATCH 26/31] use per-axis padding --- d2renderers/d2svg/d2svg.go | 5 +++++ lib/shape/shape.go | 6 +++--- lib/shape/shape_circle.go | 4 ++-- lib/shape/shape_cloud.go | 14 +++++++------- lib/shape/shape_oval.go | 6 +++--- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 91cc687a8..a86e38960 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -863,6 +863,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske } } + // to examine GetInsidePlacement + // padX, padY := s.GetDefaultPadding() + // innerTL := s.GetInsidePlacement(s.GetInnerBox().Width, s.GetInnerBox().Height, padX, padY) + // fmt.Fprint(writer, renderOval(&innerTL, 5, 5, "fill:red;")) + // Closes the class=shape fmt.Fprint(writer, ``) diff --git a/lib/shape/shape.go b/lib/shape/shape.go index 52784ddd7..d3dc97114 100644 --- a/lib/shape/shape.go +++ b/lib/shape/shape.go @@ -47,7 +47,7 @@ type Shape interface { GetInnerBox() *geo.Box // placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft - GetInsidePlacement(width, height, padding float64) geo.Point + GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) GetDefaultPadding() (paddingX, paddingY float64) @@ -88,9 +88,9 @@ func (s baseShape) GetInnerBox() *geo.Box { return s.Box } -func (s baseShape) GetInsidePlacement(_, _, padding float64) geo.Point { +func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point { innerTL := (*s.FullShape).GetInnerBox().TopLeft - return *geo.NewPoint(innerTL.X+padding/2, innerTL.Y+padding/2) + return *geo.NewPoint(innerTL.X+paddingX/2, innerTL.Y+paddingY/2) } // return the minimum shape dimensions needed to fit content (width x height) diff --git a/lib/shape/shape_circle.go b/lib/shape/shape_circle.go index 254b23aff..72526eecb 100644 --- a/lib/shape/shape_circle.go +++ b/lib/shape/shape_circle.go @@ -25,7 +25,7 @@ func NewCircle(box *geo.Box) Shape { func (s shapeCircle) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - insideTL := s.GetInsidePlacement(width, height, 0) + insideTL := s.GetInsidePlacement(width, height, 0, 0) tl := s.Box.TopLeft.Copy() width -= 2 * (insideTL.X - tl.X) height -= 2 * (insideTL.Y - tl.Y) @@ -41,7 +41,7 @@ func (s shapeCircle) GetDimensionsToFit(width, height, paddingX, paddingY float6 return diameter, diameter } -func (s shapeCircle) GetInsidePlacement(width, height, padding float64) geo.Point { +func (s shapeCircle) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point { return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(s.Box.Width/2-width/2), s.Box.TopLeft.Y+math.Ceil(s.Box.Height/2-height/2)) } diff --git a/lib/shape/shape_cloud.go b/lib/shape/shape_cloud.go index 98925db75..656003368 100644 --- a/lib/shape/shape_cloud.go +++ b/lib/shape/shape_cloud.go @@ -46,7 +46,7 @@ func NewCloud(box *geo.Box) Shape { func (s shapeCloud) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - insideTL := s.GetInsidePlacement(width, height, 0) + insideTL := s.GetInsidePlacement(width, height, 0, 0) aspectRatio := width / height if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY { width *= CLOUD_WIDE_INNER_WIDTH @@ -75,17 +75,17 @@ func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64 } } -func (s shapeCloud) GetInsidePlacement(width, height, padding float64) geo.Point { +func (s shapeCloud) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point { r := s.Box - width += padding - height += padding + width += paddingX + height += paddingY aspectRatio := width / height if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY { - return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_WIDE_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_WIDE_INNER_Y+padding/2)) + return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_WIDE_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_WIDE_INNER_Y+paddingY/2)) } else if aspectRatio < CLOUD_TALL_ASPECT_BOUNDARY { - return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_TALL_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_TALL_INNER_Y+padding/2)) + return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_TALL_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_TALL_INNER_Y+paddingY/2)) } else { - return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_SQUARE_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_SQUARE_INNER_Y+padding/2)) + return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_SQUARE_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_SQUARE_INNER_Y+paddingY/2)) } } diff --git a/lib/shape/shape_oval.go b/lib/shape/shape_oval.go index 5a8ef5a59..9e75242eb 100644 --- a/lib/shape/shape_oval.go +++ b/lib/shape/shape_oval.go @@ -25,7 +25,7 @@ func NewOval(box *geo.Box) Shape { func (s shapeOval) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - insideTL := s.GetInsidePlacement(width, height, 0) + insideTL := s.GetInsidePlacement(width, height, 0, 0) tl := s.Box.TopLeft.Copy() width -= 2 * (insideTL.X - tl.X) height -= 2 * (insideTL.Y - tl.Y) @@ -41,7 +41,7 @@ func (s shapeOval) GetDimensionsToFit(width, height, paddingX, paddingY float64) return math.Ceil(math.Sqrt2 * paddedWidth), math.Ceil(math.Sqrt2 * paddedHeight) } -func (s shapeOval) GetInsidePlacement(width, height, padding float64) geo.Point { +func (s shapeOval) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point { // showing the top left arc of the ellipse (drawn with '*') // ┌──────────────────* ┬ // │ * │ │ry @@ -60,7 +60,7 @@ func (s shapeOval) GetInsidePlacement(width, height, padding float64) geo.Point // see https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo r := rx * ry / math.Sqrt(math.Pow(rx*sin, 2)+math.Pow(ry*cos, 2)) // we want to offset r-padding/2 away from the center - return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(rx-cos*(r-padding/2)), s.Box.TopLeft.Y+math.Ceil(ry-sin*(r-padding/2))) + return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(rx-cos*(r-paddingX/2)), s.Box.TopLeft.Y+math.Ceil(ry-sin*(r-paddingY/2))) } func (s shapeOval) Perimeter() []geo.Intersectable { From bb47f98bf0cc54bd1c9aef7b3508c28eddc6d96d Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 3 Feb 2023 17:20:12 -0800 Subject: [PATCH 27/31] testing chaos with more readable/simpler ids and labels --- d2chaos/d2chaos.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/d2chaos/d2chaos.go b/d2chaos/d2chaos.go index c26ea3c80..efa4ecc9a 100644 --- a/d2chaos/d2chaos.go +++ b/d2chaos/d2chaos.go @@ -62,7 +62,7 @@ func (gs *dslGenState) gen(maxi int) error { } func (gs *dslGenState) genNode(containerID string) (string, error) { - nodeID := gs.randStr(32, true) + nodeID := gs.randStr(8, true) if containerID != "" { nodeID = containerID + "." + nodeID } @@ -95,7 +95,7 @@ func (gs *dslGenState) node() error { if gs.roll(25, 75) == 0 { // 25% chance of adding a label. - gs.g, err = d2oracle.Set(gs.g, nodeID, nil, go2.Pointer(gs.randStr(256, false))) + gs.g, err = d2oracle.Set(gs.g, nodeID, nil, go2.Pointer(gs.randStr(8, false))) if err != nil { return err } @@ -154,7 +154,7 @@ func (gs *dslGenState) edge() error { return err } if gs.randBool() { - gs.g, err = d2oracle.Set(gs.g, key, nil, go2.Pointer(gs.randStr(128, false))) + gs.g, err = d2oracle.Set(gs.g, key, nil, go2.Pointer(gs.randStr(8, false))) if err != nil { return err } @@ -191,11 +191,7 @@ func (gs *dslGenState) randBool() bool { // TODO go back to using xrand.String, currently some incompatibility with // stuffing these strings into a script for dagre func randRune() rune { - if mathrand.Int31n(100) == 0 { - // Generate newline 1% of the time. - return '\n' - } - return mathrand.Int31n(128) + 1 + return mathrand.Int31n(26) + 97 } func (gs *dslGenState) findOuterSequenceDiagram(nodeID string) string { From bbeacf637dc649352b49ef3db3f26134a66be55f Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 10 Feb 2023 17:30:34 -0800 Subject: [PATCH 28/31] add complexIDs bool for configuring --- d2chaos/d2chaos.go | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/d2chaos/d2chaos.go b/d2chaos/d2chaos.go index efa4ecc9a..910c99935 100644 --- a/d2chaos/d2chaos.go +++ b/d2chaos/d2chaos.go @@ -15,6 +15,8 @@ import ( "oss.terrastruct.com/d2/d2target" ) +const complexIDs = false + func GenDSL(maxi int) (_ string, err error) { gs := &dslGenState{ rand: mathrand.New(mathrand.NewSource(time.Now().UnixNano())), @@ -62,7 +64,11 @@ func (gs *dslGenState) gen(maxi int) error { } func (gs *dslGenState) genNode(containerID string) (string, error) { - nodeID := gs.randStr(8, true) + maxLen := 8 + if complexIDs { + maxLen = 32 + } + nodeID := gs.randStr(maxLen, true) if containerID != "" { nodeID = containerID + "." + nodeID } @@ -95,7 +101,11 @@ func (gs *dslGenState) node() error { if gs.roll(25, 75) == 0 { // 25% chance of adding a label. - gs.g, err = d2oracle.Set(gs.g, nodeID, nil, go2.Pointer(gs.randStr(8, false))) + maxLen := 8 + if complexIDs { + maxLen = 256 + } + gs.g, err = d2oracle.Set(gs.g, nodeID, nil, go2.Pointer(gs.randStr(maxLen, false))) if err != nil { return err } @@ -154,7 +164,11 @@ func (gs *dslGenState) edge() error { return err } if gs.randBool() { - gs.g, err = d2oracle.Set(gs.g, key, nil, go2.Pointer(gs.randStr(8, false))) + maxLen := 8 + if complexIDs { + maxLen = 128 + } + gs.g, err = d2oracle.Set(gs.g, key, nil, go2.Pointer(gs.randStr(maxLen, false))) if err != nil { return err } @@ -191,7 +205,15 @@ func (gs *dslGenState) randBool() bool { // TODO go back to using xrand.String, currently some incompatibility with // stuffing these strings into a script for dagre func randRune() rune { - return mathrand.Int31n(26) + 97 + if complexIDs { + if mathrand.Int31n(100) == 0 { + // Generate newline 1% of the time. + return '\n' + } + return mathrand.Int31n(128) + 1 + } else { + return mathrand.Int31n(26) + 97 + } } func (gs *dslGenState) findOuterSequenceDiagram(nodeID string) string { From 5e156b93fda3cd68023ae8c0f2741f777d90f819 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Fri, 10 Feb 2023 20:13:54 -0800 Subject: [PATCH 29/31] Makefile: Unset GITHUB_TOKEN on fmt call See https://github.com/terrastruct/d2/commit/335d925b7c937d4e7cac7e26de993f60840eb116#commitcomment-98101131 --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8fd431900..cff1068c0 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ all: fmt gen lint build test .PHONY: fmt fmt: - prefix "$@" ./ci/sub/bin/fmt.sh + # Unset GITHUB_TOKEN, see https://github.com/terrastruct/d2/commit/335d925b7c937d4e7cac7e26de993f60840eb116#commitcomment-98101131 + GITHUB_TOKEN= prefix "$@" ./ci/sub/bin/fmt.sh .PHONY: gen gen: prefix "$@" ./ci/gen.sh From 8ff4cf97ad4568611028cefc7f94707541386c46 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 20:41:17 -0800 Subject: [PATCH 30/31] continue connecting directly --- d2layouts/d2dagrelayout/layout.go | 178 +++++++++++++++++------------- 1 file changed, 99 insertions(+), 79 deletions(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index e7776d0b7..f391bf8ff 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -261,6 +261,105 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } } + points = points[startIndex:endIndex] + points[0] = start + points[len(points)-1] = end + + edge.Route = points + } + + for _, obj := range g.Objects { + if obj.LabelHeight == nil || len(obj.ChildrenArray) <= 0 { + continue + } + + // usually you don't want to take away here more than what was added, which is the label height + // however, if the label height is more than the ranksep/2, we'll have no padding around children anymore + // so cap the amount taken off at ranksep/2 + subtract := float64(go2.Min(rootAttrs.ranksep/2, *obj.LabelHeight+label.PADDING)) + + obj.Height -= subtract + + // If the edge is connected to two descendants that are about to be downshifted, their whole route gets downshifted + movedEdges := make(map[*d2graph.Edge]struct{}) + for _, e := range g.Edges { + currSrc := e.Src + currDst := e.Dst + + isSrcDesc := false + isDstDesc := false + + for currSrc != nil { + if currSrc == obj { + isSrcDesc = true + break + } + currSrc = currSrc.Parent + } + for currDst != nil { + if currDst == obj { + isDstDesc = true + break + } + currDst = currDst.Parent + } + if isSrcDesc && isDstDesc { + stepSize := subtract + if e.Src != obj || e.Dst != obj { + stepSize /= 2. + } + movedEdges[e] = struct{}{} + for _, p := range e.Route { + p.Y += stepSize + } + } + } + + // Downshift descendents and edges that have one endpoint connected to a descendant + q := []*d2graph.Object{obj} + for len(q) > 0 { + curr := q[0] + q = q[1:] + + stepSize := subtract + // The object itself needs to move down the height it was just subtracted + // all descendents move half, to maintain vertical padding + if curr != obj { + stepSize /= 2. + } + curr.TopLeft.Y += stepSize + // Edge should only move if it's not connected to the bottom side of the shrinking container + shouldMove := func(p *geo.Point) bool { + if curr != obj { + return true + } + return p.Y != obj.TopLeft.Y+obj.Height + } + for _, e := range g.Edges { + if _, ok := movedEdges[e]; ok { + continue + } + if e.Src == curr { + if shouldMove(e.Route[0]) { + e.Route[0].Y += stepSize + } + } + if e.Dst == curr { + if shouldMove(e.Route[len(e.Route)-1]) { + e.Route[len(e.Route)-1].Y += stepSize + } + } + } + for _, c := range curr.ChildrenArray { + q = append(q, c) + } + } + } + + for _, edge := range g.Edges { + points := edge.Route + startIndex, endIndex := 0, len(points)-1 + start, end := points[startIndex], points[endIndex] // arrowheads can appear broken if segments are very short from dagre routing a point just outside the shape // to fix this, we try extending the previous segment into the shape instead of having a very short segment @@ -340,85 +439,6 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } - for _, obj := range g.Objects { - if obj.LabelHeight == nil || len(obj.ChildrenArray) <= 0 { - continue - } - - // usually you don't want to take away here more than what was added, which is the label height - // however, if the label height is more than the ranksep/2, we'll have no padding around children anymore - // so cap the amount taken off at ranksep/2 - subtract := float64(go2.Min(rootAttrs.ranksep/2, *obj.LabelHeight+label.PADDING)) - - obj.Height -= subtract - - // If the edge is connected to two descendants that are about to be downshifted, their whole route gets downshifted - movedEdges := make(map[*d2graph.Edge]struct{}) - for _, e := range g.Edges { - currSrc := e.Src - currDst := e.Dst - - isSrcDesc := false - isDstDesc := false - - for currSrc != nil { - if currSrc == obj { - isSrcDesc = true - break - } - currSrc = currSrc.Parent - } - for currDst != nil { - if currDst == obj { - isDstDesc = true - break - } - currDst = currDst.Parent - } - if isSrcDesc && isDstDesc { - stepSize := subtract - if e.Src != obj || e.Dst != obj { - stepSize /= 2. - } - movedEdges[e] = struct{}{} - for _, p := range e.Route { - p.Y += stepSize - } - } - } - - // Downshift descendents and edges that have one endpoint connected to a descendant - q := []*d2graph.Object{obj} - for len(q) > 0 { - curr := q[0] - q = q[1:] - - stepSize := subtract - // The object itself needs to move down the height it was just subtracted - // all descendents move half, to maintain vertical padding - if curr != obj { - stepSize /= 2. - } - curr.TopLeft.Y += stepSize - if curr != obj { - for _, e := range g.Edges { - if _, ok := movedEdges[e]; ok { - continue - } - if e.Src == curr { - e.Route[0].Y += stepSize - } - if e.Dst == curr { - e.Route[len(e.Route)-1].Y += stepSize - } - } - } - for _, c := range curr.ChildrenArray { - q = append(q, c) - } - } - } - return nil } From c33676a41689faa1a484dfd414ccd445dd502c93 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 10 Feb 2023 20:47:58 -0800 Subject: [PATCH 31/31] ok --- d2layouts/d2dagrelayout/layout.go | 4 +- .../d2sketch/testdata/animated/sketch.exp.svg | 2 +- .../testdata/child_to_child/sketch.exp.svg | 2 +- .../dagre/board.exp.json | 20 +- .../dagre/sketch.exp.svg | 4 +- .../dagre/board.exp.json | 16 +- .../dagre/sketch.exp.svg | 10 +- .../child_to_child/dagre/board.exp.json | 4 +- .../child_to_child/dagre/sketch.exp.svg | 2 +- .../stable/chaos1/dagre/board.exp.json | 2 +- .../stable/chaos1/dagre/sketch.exp.svg | 4 +- .../stable/chaos2/dagre/board.exp.json | 46 +- .../stable/chaos2/dagre/sketch.exp.svg | 12 +- .../child_parent_edges/dagre/board.exp.json | 379 ++++++++++++++++ .../child_parent_edges/dagre/sketch.exp.svg | 59 +++ .../child_parent_edges/elk/board.exp.json | 297 +++++++++++++ .../child_parent_edges/elk/sketch.exp.svg | 59 +++ .../connected_container/dagre/board.exp.json | 8 +- .../connected_container/dagre/sketch.exp.svg | 2 +- .../container_edges/dagre/board.exp.json | 14 +- .../container_edges/dagre/sketch.exp.svg | 2 +- .../different_subgraphs/dagre/board.exp.json | 4 +- .../different_subgraphs/dagre/sketch.exp.svg | 2 +- .../stable/direction/dagre/board.exp.json | 12 +- .../stable/direction/dagre/sketch.exp.svg | 2 +- .../stable/investigate/dagre/board.exp.json | 88 ++-- .../stable/investigate/dagre/sketch.exp.svg | 8 +- .../stable/large_arch/dagre/board.exp.json | 34 +- .../stable/large_arch/dagre/sketch.exp.svg | 2 +- .../one_container_loop/dagre/board.exp.json | 4 +- .../one_container_loop/dagre/sketch.exp.svg | 2 +- .../dagre/board.exp.json | 12 +- .../dagre/sketch.exp.svg | 2 +- .../dagre/board.exp.json | 14 +- .../dagre/sketch.exp.svg | 2 +- .../sequence_diagrams/dagre/board.exp.json | 10 +- .../sequence_diagrams/dagre/sketch.exp.svg | 2 +- .../dagre/board.exp.json | 42 +- .../dagre/sketch.exp.svg | 2 +- .../child_parent_edges/dagre/board.exp.json | 8 +- .../child_parent_edges/dagre/sketch.exp.svg | 2 +- .../dagre/board.exp.json | 212 +++++++++ .../dagre/sketch.exp.svg | 59 +++ .../elk/board.exp.json | 212 +++++++++ .../elk/sketch.exp.svg | 59 +++ .../font_sizes_large/dagre/board.exp.json | 405 ++++++++++++++++++ .../font_sizes_large/dagre/sketch.exp.svg | 62 +++ .../todo/font_sizes_large/elk/board.exp.json | 369 ++++++++++++++++ .../todo/font_sizes_large/elk/sketch.exp.svg | 62 +++ .../todo/tall_edge_label/dagre/board.exp.json | 138 ++++++ .../todo/tall_edge_label/dagre/sketch.exp.svg | 59 +++ .../todo/tall_edge_label/elk/board.exp.json | 129 ++++++ .../todo/tall_edge_label/elk/sketch.exp.svg | 59 +++ 53 files changed, 2823 insertions(+), 204 deletions(-) create mode 100644 e2etests/testdata/stable/child_parent_edges/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/child_parent_edges/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/child_parent_edges/elk/board.exp.json create mode 100644 e2etests/testdata/stable/child_parent_edges/elk/sketch.exp.svg create mode 100644 e2etests/testdata/todo/font_sizes_containers_large/dagre/board.exp.json create mode 100644 e2etests/testdata/todo/font_sizes_containers_large/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/todo/font_sizes_containers_large/elk/board.exp.json create mode 100644 e2etests/testdata/todo/font_sizes_containers_large/elk/sketch.exp.svg create mode 100644 e2etests/testdata/todo/font_sizes_large/dagre/board.exp.json create mode 100644 e2etests/testdata/todo/font_sizes_large/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/todo/font_sizes_large/elk/board.exp.json create mode 100644 e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg create mode 100644 e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json create mode 100644 e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/todo/tall_edge_label/elk/board.exp.json create mode 100644 e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index f391bf8ff..4e018b11f 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -261,7 +261,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } } - points = points[startIndex:endIndex] + points = points[startIndex : endIndex+1] points[0] = start points[len(points)-1] = end @@ -328,11 +328,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err stepSize /= 2. } curr.TopLeft.Y += stepSize - // Edge should only move if it's not connected to the bottom side of the shrinking container shouldMove := func(p *geo.Point) bool { if curr != obj { return true } + // Edge should only move if it's not connected to the bottom side of the shrinking container return p.Y != obj.TopLeft.Y+obj.Height } for _, e := range g.Edges { diff --git a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg index 847193776..921626327 100644 --- a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg @@ -51,7 +51,7 @@ width="486" height="800" viewBox="-102 -100 486 800">aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - + + + - - + + abcd + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/child_parent_edges/elk/board.exp.json b/e2etests/testdata/stable/child_parent_edges/elk/board.exp.json new file mode 100644 index 000000000..987db0ad6 --- /dev/null +++ b/e2etests/testdata/stable/child_parent_edges/elk/board.exp.json @@ -0,0 +1,297 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 514, + "height": 621, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": 87, + "y": 87 + }, + "width": 364, + "height": 471, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.b.c", + "type": "rectangle", + "pos": { + "x": 172, + "y": 162 + }, + "width": 204, + "height": 216, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "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": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 9, + "labelHeight": 26, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.b.c.d", + "type": "rectangle", + "pos": { + "x": 247, + "y": 237 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "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": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 4 + } + ], + "connections": [ + { + "id": "(a.b -> a)[0]", + "src": "a.b", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "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": 162, + "y": 558 + }, + { + "x": 162, + "y": 633 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(b -> b.c)[0]", + "src": "a.b", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.b.c", + "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": 247, + "y": 87 + }, + { + "x": 247, + "y": 162 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(b.c.d -> b)[0]", + "src": "a.b.c.d", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.b", + "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": 274, + "y": 303 + }, + { + "x": 274, + "y": 433 + }, + { + "x": 162, + "y": 433 + }, + { + "x": 162, + "y": 87 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/stable/child_parent_edges/elk/sketch.exp.svg b/e2etests/testdata/stable/child_parent_edges/elk/sketch.exp.svg new file mode 100644 index 000000000..0a488aa47 --- /dev/null +++ b/e2etests/testdata/stable/child_parent_edges/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +abcd + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/connected_container/dagre/board.exp.json b/e2etests/testdata/stable/connected_container/dagre/board.exp.json index b170fadfd..498947c77 100644 --- a/e2etests/testdata/stable/connected_container/dagre/board.exp.json +++ b/e2etests/testdata/stable/connected_container/dagre/board.exp.json @@ -322,7 +322,7 @@ }, { "x": 120, - "y": 156 + "y": 160.1 }, { "x": 120, @@ -338,7 +338,7 @@ }, { "x": 120, - "y": 276 + "y": 280.1 }, { "x": 120, @@ -382,7 +382,7 @@ }, { "x": 120, - "y": 422 + "y": 426.1 }, { "x": 120, @@ -410,7 +410,7 @@ }, { "x": 120, - "y": 592 + "y": 599.7 }, { "x": 120, diff --git a/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg b/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg index 47b408e8e..b7cf42a18 100644 --- a/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg @@ -39,7 +39,7 @@ width="441" height="1000" viewBox="-102 -100 441 1000">ninety ninesixty fourthirty twosixteeneight + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/font_sizes_containers_large/elk/board.exp.json b/e2etests/testdata/todo/font_sizes_containers_large/elk/board.exp.json new file mode 100644 index 000000000..dcdae1536 --- /dev/null +++ b/e2etests/testdata/todo/font_sizes_containers_large/elk/board.exp.json @@ -0,0 +1,212 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "ninety nine", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 664, + "height": 656, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ninety nine", + "fontSize": 99, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 452, + "labelHeight": 125, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "ninety nine.sixty four", + "type": "rectangle", + "pos": { + "x": 87, + "y": 87 + }, + "width": 514, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "sixty four", + "fontSize": 64, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 246, + "labelHeight": 81, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "ninety nine.sixty four.thirty two", + "type": "rectangle", + "pos": { + "x": 162, + "y": 162 + }, + "width": 364, + "height": 356, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "thirty two", + "fontSize": 32, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 130, + "labelHeight": 41, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "ninety nine.sixty four.thirty two.sixteen", + "type": "rectangle", + "pos": { + "x": 237, + "y": 237 + }, + "width": 214, + "height": 206, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "sixteen", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 4 + }, + { + "id": "ninety nine.sixty four.thirty two.sixteen.eight", + "type": "rectangle", + "pos": { + "x": 312, + "y": 312 + }, + "width": 64, + "height": 56, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "eight", + "fontSize": 8, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 19, + "labelHeight": 11, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 5 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/todo/font_sizes_containers_large/elk/sketch.exp.svg b/e2etests/testdata/todo/font_sizes_containers_large/elk/sketch.exp.svg new file mode 100644 index 000000000..1fe80d81c --- /dev/null +++ b/e2etests/testdata/todo/font_sizes_containers_large/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +ninety ninesixty fourthirty twosixteeneight + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/font_sizes_large/dagre/board.exp.json b/e2etests/testdata/todo/font_sizes_large/dagre/board.exp.json new file mode 100644 index 000000000..2fb12da96 --- /dev/null +++ b/e2etests/testdata/todo/font_sizes_large/dagre/board.exp.json @@ -0,0 +1,405 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "eight", + "type": "rectangle", + "pos": { + "x": 233, + "y": 0 + }, + "width": 64, + "height": 56, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "eight", + "fontSize": 8, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 19, + "labelHeight": 11, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "sixteen", + "type": "rectangle", + "pos": { + "x": 216, + "y": 214 + }, + "width": 97, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "sixteen", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 52, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "thirty two", + "type": "rectangle", + "pos": { + "x": 171, + "y": 453 + }, + "width": 187, + "height": 86, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "thirty two", + "fontSize": 32, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 142, + "labelHeight": 41, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "sixty four", + "type": "rectangle", + "pos": { + "x": 108, + "y": 742 + }, + "width": 314, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "sixty four", + "fontSize": 64, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 269, + "labelHeight": 81, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "ninety nine", + "type": "rectangle", + "pos": { + "x": 0, + "y": 1112 + }, + "width": 529, + "height": 170, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ninety nine", + "fontSize": 99, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 484, + "labelHeight": 125, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(eight -> sixteen)[0]", + "src": "eight", + "srcArrow": "none", + "srcLabel": "", + "dst": "sixteen", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "twelve", + "fontSize": 12, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 33, + "labelHeight": 16, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 264.5, + "y": 56 + }, + { + "x": 264.5, + "y": 119.2 + }, + { + "x": 264.5, + "y": 150.8 + }, + { + "x": 264.5, + "y": 214 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(sixteen -> thirty two)[0]", + "src": "sixteen", + "srcArrow": "none", + "srcLabel": "", + "dst": "thirty two", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "twenty four", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 114, + "labelHeight": 31, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 264.5, + "y": 280 + }, + { + "x": 264.5, + "y": 349.2 + }, + { + "x": 264.5, + "y": 383.9 + }, + { + "x": 264.5, + "y": 453.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(thirty two -> sixty four)[0]", + "src": "thirty two", + "srcArrow": "none", + "srcLabel": "", + "dst": "sixty four", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "forty eight", + "fontSize": 48, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 202, + "labelHeight": 61, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 264.5, + "y": 539 + }, + { + "x": 264.5, + "y": 620.2 + }, + { + "x": 264.5, + "y": 660.9 + }, + { + "x": 264.5, + "y": 742.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(sixty four -> ninety nine)[0]", + "src": "sixty four", + "srcArrow": "none", + "srcLabel": "", + "dst": "ninety nine", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "eighty one", + "fontSize": 81, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 341, + "labelHeight": 102, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 264.5, + "y": 868 + }, + { + "x": 264.5, + "y": 965.6 + }, + { + "x": 264.5, + "y": 1014.4 + }, + { + "x": 264.5, + "y": 1112 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/font_sizes_large/dagre/sketch.exp.svg b/e2etests/testdata/todo/font_sizes_large/dagre/sketch.exp.svg new file mode 100644 index 000000000..6d10c903d --- /dev/null +++ b/e2etests/testdata/todo/font_sizes_large/dagre/sketch.exp.svg @@ -0,0 +1,62 @@ + +eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/font_sizes_large/elk/board.exp.json b/e2etests/testdata/todo/font_sizes_large/elk/board.exp.json new file mode 100644 index 000000000..463f68094 --- /dev/null +++ b/e2etests/testdata/todo/font_sizes_large/elk/board.exp.json @@ -0,0 +1,369 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "eight", + "type": "rectangle", + "pos": { + "x": 244, + "y": 12 + }, + "width": 64, + "height": 56, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "eight", + "fontSize": 8, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 19, + "labelHeight": 11, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "sixteen", + "type": "rectangle", + "pos": { + "x": 228, + "y": 284 + }, + "width": 97, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "sixteen", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 52, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "thirty two", + "type": "rectangle", + "pos": { + "x": 183, + "y": 581 + }, + "width": 187, + "height": 86, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "thirty two", + "fontSize": 32, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 142, + "labelHeight": 41, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "sixty four", + "type": "rectangle", + "pos": { + "x": 119, + "y": 928 + }, + "width": 314, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "sixty four", + "fontSize": 64, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 269, + "labelHeight": 81, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "ninety nine", + "type": "rectangle", + "pos": { + "x": 12, + "y": 1356 + }, + "width": 529, + "height": 170, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ninety nine", + "fontSize": 99, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 484, + "labelHeight": 125, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(eight -> sixteen)[0]", + "src": "eight", + "srcArrow": "none", + "srcLabel": "", + "dst": "sixteen", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "twelve", + "fontSize": 12, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 33, + "labelHeight": 16, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 276.5, + "y": 68 + }, + { + "x": 276.5, + "y": 284 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(sixteen -> thirty two)[0]", + "src": "sixteen", + "srcArrow": "none", + "srcLabel": "", + "dst": "thirty two", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "twenty four", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 114, + "labelHeight": 31, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 276.5, + "y": 350 + }, + { + "x": 276.5, + "y": 581 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(thirty two -> sixty four)[0]", + "src": "thirty two", + "srcArrow": "none", + "srcLabel": "", + "dst": "sixty four", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "forty eight", + "fontSize": 48, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 202, + "labelHeight": 61, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 276.5, + "y": 667 + }, + { + "x": 276.5, + "y": 928 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(sixty four -> ninety nine)[0]", + "src": "sixty four", + "srcArrow": "none", + "srcLabel": "", + "dst": "ninety nine", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "eighty one", + "fontSize": 81, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 341, + "labelHeight": 102, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 276.5, + "y": 1054 + }, + { + "x": 276.5, + "y": 1356 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg b/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg new file mode 100644 index 000000000..28c54832a --- /dev/null +++ b/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg @@ -0,0 +1,62 @@ + +eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json b/e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json new file mode 100644 index 000000000..bafced325 --- /dev/null +++ b/e2etests/testdata/todo/tall_edge_label/dagre/board.exp.json @@ -0,0 +1,138 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "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": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 0, + "y": 372 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": 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": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "There\nonce\nwas\na\nvery\ntall\nedge\nlabel", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 133, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 26.5, + "y": 66 + }, + { + "x": 26.5, + "y": 188.4 + }, + { + "x": 26.5, + "y": 249.6 + }, + { + "x": 26.5, + "y": 372 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg b/e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg new file mode 100644 index 000000000..231114a5f --- /dev/null +++ b/e2etests/testdata/todo/tall_edge_label/dagre/sketch.exp.svg @@ -0,0 +1,59 @@ + +ab Thereoncewasaverytalledgelabel + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/tall_edge_label/elk/board.exp.json b/e2etests/testdata/todo/tall_edge_label/elk/board.exp.json new file mode 100644 index 000000000..6f0851cca --- /dev/null +++ b/e2etests/testdata/todo/tall_edge_label/elk/board.exp.json @@ -0,0 +1,129 @@ +{ + "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": "#F7F8FE", + "stroke": "#0D32B2", + "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": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 12, + "y": 411 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": 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": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "There\nonce\nwas\na\nvery\ntall\nedge\nlabel", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 133, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 38.5, + "y": 78 + }, + { + "x": 38.5, + "y": 411 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg b/e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg new file mode 100644 index 000000000..ce817e41e --- /dev/null +++ b/e2etests/testdata/todo/tall_edge_label/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +ab Thereoncewasaverytalledgelabel + + + \ No newline at end of file