From f483c62df2101132b607c4ea6c850746e68f2aa8 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 15 Sep 2023 14:44:26 -0700 Subject: [PATCH 01/35] add nested_diagram_types test --- e2etests/stable_test.go | 1 + .../testdata/files/nested_diagram_types.d2 | 47 + .../nested_diagram_types/dagre/board.exp.json | 941 ++++++++++++++++++ .../nested_diagram_types/dagre/sketch.exp.svg | 119 +++ .../nested_diagram_types/elk/board.exp.json | 941 ++++++++++++++++++ .../nested_diagram_types/elk/sketch.exp.svg | 119 +++ 6 files changed, 2168 insertions(+) create mode 100644 e2etests/testdata/files/nested_diagram_types.d2 create mode 100644 e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json create mode 100644 e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 0e82cb2a6..517fd91f2 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2835,6 +2835,7 @@ y: profits { loadFromFile(t, "dagre_spacing_right"), loadFromFile(t, "simple_grid_edges"), loadFromFile(t, "grid_nested_simple_edges"), + loadFromFile(t, "nested_diagram_types"), } runa(t, tcs) diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 new file mode 100644 index 000000000..2bb6aaafd --- /dev/null +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -0,0 +1,47 @@ +a +b +c + +a: { + grid-rows: 3 + + 1 + 2 + 3: { + shape: sequence_diagram + x + y + # TODO x -> y + } + + near: top-right +} + +b: { + shape: sequence_diagram + 1 -> 2 + + # TODO This should work + # near: bottom-left + # + + 2: { + # TODO compile error grid on sequence actor + grid-rows: 3 + x + y + z + } + + 1: { + x: { + # TODO compile error grid in sequence (anywhere) + grid-rows: 3 + u + v + w + } + y + z + } +} diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json new file mode 100644 index 000000000..f4fa59d99 --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json @@ -0,0 +1,941 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "b", + "type": "sequence_diagram", + "pos": { + "x": 0, + "y": 0 + }, + "width": 274, + "height": 1394, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 334, + "y": 664 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.1", + "type": "rectangle", + "pos": { + "x": 12, + "y": 88 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2", + "type": "rectangle", + "pos": { + "x": 162, + "y": 88 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2.x", + "type": "page", + "pos": { + "x": 186, + "y": 294 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.2.y", + "type": "page", + "pos": { + "x": 185, + "y": 430 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.2.z", + "type": "page", + "pos": { + "x": 186, + "y": 566 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.x", + "type": "rectangle", + "pos": { + "x": 56, + "y": 692 + }, + "width": 12, + "height": 358, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "zIndex": 2, + "level": 3 + }, + { + "id": "b.1.x.u", + "type": "page", + "pos": { + "x": 36, + "y": 702 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.v", + "type": "page", + "pos": { + "x": 35, + "y": 838 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "v", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.w", + "type": "page", + "pos": { + "x": 33, + "y": 974 + }, + "width": 57, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "w", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.y", + "type": "page", + "pos": { + "x": 35, + "y": 1110 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.z", + "type": "page", + "pos": { + "x": 36, + "y": 1246 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 407, + "y": -478 + }, + "width": 345, + "height": 458, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.1", + "type": "rectangle", + "pos": { + "x": 467, + "y": -418 + }, + "width": 225, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.2", + "type": "rectangle", + "pos": { + "x": 467, + "y": -312 + }, + "width": 225, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3", + "type": "sequence_diagram", + "pos": { + "x": 467, + "y": -206 + }, + "width": 225, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "3", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3.x", + "type": "rectangle", + "pos": { + "x": 497, + "y": -176 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.3.y", + "type": "rectangle", + "pos": { + "x": 609, + "y": -176 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + } + ], + "connections": [ + { + "id": "b.(1 -> 2)[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "b.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 62, + "y": 224 + }, + { + "x": 212, + "y": 224 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(b.1 -- )[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "1-lifeline-end-1719232319", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 62, + "y": 154 + }, + { + "x": 62, + "y": 1382 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.2 -- )[0]", + "src": "b.2", + "srcArrow": "none", + "dst": "2-lifeline-end-1739547740", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 212, + "y": 154 + }, + { + "x": 212, + "y": 1382 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg new file mode 100644 index 000000000..9c4b87f3c --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg @@ -0,0 +1,119 @@ +bca12123xy xyzyzuvw + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json new file mode 100644 index 000000000..3ca671d1c --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json @@ -0,0 +1,941 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "b", + "type": "sequence_diagram", + "pos": { + "x": 12, + "y": 12 + }, + "width": 274, + "height": 1394, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 306, + "y": 676 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.1", + "type": "rectangle", + "pos": { + "x": 24, + "y": 100 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2", + "type": "rectangle", + "pos": { + "x": 174, + "y": 100 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2.x", + "type": "page", + "pos": { + "x": 198, + "y": 306 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.2.y", + "type": "page", + "pos": { + "x": 197, + "y": 442 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.2.z", + "type": "page", + "pos": { + "x": 198, + "y": 578 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.x", + "type": "rectangle", + "pos": { + "x": 68, + "y": 704 + }, + "width": 12, + "height": 358, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "zIndex": 2, + "level": 3 + }, + { + "id": "b.1.x.u", + "type": "page", + "pos": { + "x": 48, + "y": 714 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.v", + "type": "page", + "pos": { + "x": 47, + "y": 850 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "v", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.w", + "type": "page", + "pos": { + "x": 45, + "y": 986 + }, + "width": 57, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "w", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.y", + "type": "page", + "pos": { + "x": 47, + "y": 1122 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.z", + "type": "page", + "pos": { + "x": 48, + "y": 1258 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 379, + "y": -506 + }, + "width": 345, + "height": 498, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.1", + "type": "rectangle", + "pos": { + "x": 439, + "y": -446 + }, + "width": 225, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.2", + "type": "rectangle", + "pos": { + "x": 439, + "y": -340 + }, + "width": 225, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3", + "type": "sequence_diagram", + "pos": { + "x": 439, + "y": -234 + }, + "width": 225, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "3", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3.x", + "type": "rectangle", + "pos": { + "x": 489, + "y": -184 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.3.y", + "type": "rectangle", + "pos": { + "x": 561, + "y": -184 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + } + ], + "connections": [ + { + "id": "b.(1 -> 2)[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "b.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 74, + "y": 236 + }, + { + "x": 224, + "y": 236 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(b.1 -- )[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "1-lifeline-end-1719232319", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 74, + "y": 166 + }, + { + "x": 74, + "y": 1394 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.2 -- )[0]", + "src": "b.2", + "srcArrow": "none", + "dst": "2-lifeline-end-1739547740", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 224, + "y": 166 + }, + { + "x": 224, + "y": 1394 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg new file mode 100644 index 000000000..7979d68d6 --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg @@ -0,0 +1,119 @@ +bca12123xy xyzyzuvw + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 140f3c77fca732a8933c551b1f3ea74fdc491d2e Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 14 Sep 2023 13:38:59 -0700 Subject: [PATCH 02/35] add nested layout design --- d2layouts/d2layouts.go | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 d2layouts/d2layouts.go diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go new file mode 100644 index 000000000..bbddba0cd --- /dev/null +++ b/d2layouts/d2layouts.go @@ -0,0 +1,61 @@ +package d2layouts + +import "oss.terrastruct.com/d2/d2graph" + +func LayoutNested(g *d2graph.Graph, graphType string, coreLayout d2graph.LayoutGraph) { + // Before we can layout these nodes, we need to handle all nested diagrams first. + extracted := make(map[*d2graph.Object]*d2graph.Graph) + + // Iterate top-down from Root so all nested diagrams can process their own contents + queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) + queue = append(queue, g.Root.ChildrenArray...) + + for _, child := range queue { + if graphType := NestedGraphType(child); graphType != nil { + // There is a nested diagram here, so extract its contents and process in the same way + nestedGraph := ExtractNested(child) + + // Layout of nestedGraph is completed + LayoutNested(nestedGraph, *graphType, coreLayout) + + // Fit child to size of nested layout + FitToGraph(child, nestedGraph) + + // We will restore the contents after running layout with child as the placeholder + extracted[child] = nestedGraph + } else if len(child.Children) > 0 { + queue = append(queue, child.ChildrenArray...) + } + } + + // We can now run layout with accurate sizes of nested layout containers + // Layout according to the type of diagram + LayoutDiagram(g, graphType, coreLayout) + + // With the layout set, inject all the extracted graphs + for n, nestedGraph := range extracted { + InjectNested(n, nestedGraph) + } +} + +func NestedGraphType(container *d2graph.Object) *string { + // TODO + return nil +} + +func ExtractNested(container *d2graph.Object) *d2graph.Graph { + // TODO + return nil +} + +func InjectNested(container *d2graph.Object, graph *d2graph.Graph) { + // TODO +} + +func FitToGraph(container *d2graph.Object, graph *d2graph.Graph) { + // TODO +} + +func LayoutDiagram(graph *d2graph.Graph, graphType string, coreLayout d2graph.LayoutGraph) { + // TODO +} From 37adab4803e62e43c227c30208fceb26b7346fb4 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 14 Sep 2023 14:17:18 -0700 Subject: [PATCH 03/35] nested graph types --- d2layouts/d2layouts.go | 36 ++++++++++++++++++++++++++++-------- d2layouts/d2near/layout.go | 15 +++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index bbddba0cd..60da6c0c7 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -1,8 +1,20 @@ package d2layouts -import "oss.terrastruct.com/d2/d2graph" +import ( + "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts/d2near" +) -func LayoutNested(g *d2graph.Graph, graphType string, coreLayout d2graph.LayoutGraph) { +type GraphType string + +const ( + DefaultGraphType GraphType = "" + ConstantNearGraph GraphType = "constant-near" + GridDiagram GraphType = "grid-diagram" + SequenceDiagram GraphType = "sequence-diagram" +) + +func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph, isRoot bool) { // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) @@ -11,12 +23,12 @@ func LayoutNested(g *d2graph.Graph, graphType string, coreLayout d2graph.LayoutG queue = append(queue, g.Root.ChildrenArray...) for _, child := range queue { - if graphType := NestedGraphType(child); graphType != nil { + if graphType := NestedGraphType(child, isRoot); graphType != DefaultGraphType { // There is a nested diagram here, so extract its contents and process in the same way nestedGraph := ExtractNested(child) // Layout of nestedGraph is completed - LayoutNested(nestedGraph, *graphType, coreLayout) + LayoutNested(nestedGraph, graphType, coreLayout, false) // Fit child to size of nested layout FitToGraph(child, nestedGraph) @@ -38,9 +50,17 @@ func LayoutNested(g *d2graph.Graph, graphType string, coreLayout d2graph.LayoutG } } -func NestedGraphType(container *d2graph.Object) *string { - // TODO - return nil +func NestedGraphType(container *d2graph.Object, isRoot bool) GraphType { + if isRoot && d2near.IsConstantNear(container) { + return ConstantNearGraph + } + if container.IsGridDiagram() { + return GridDiagram + } + if container.IsSequenceDiagram() { + return SequenceDiagram + } + return DefaultGraphType } func ExtractNested(container *d2graph.Object) *d2graph.Graph { @@ -56,6 +76,6 @@ func FitToGraph(container *d2graph.Object, graph *d2graph.Graph) { // TODO } -func LayoutDiagram(graph *d2graph.Graph, graphType string, coreLayout d2graph.LayoutGraph) { +func LayoutDiagram(graph *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) { // TODO } diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 190317542..2f1444f46 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -223,3 +223,18 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { return geo.NewPoint(x1, y1), geo.NewPoint(x2, y2) } + +func IsConstantNear(obj *d2graph.Object) bool { + if obj.NearKey == nil { + return false + } + keyPath := d2graph.Key(obj.NearKey) + + // interesting if there is a shape with id=top-left, then top-left isn't treated a constant near + _, isKey := obj.Graph.Root.HasChild(keyPath) + if isKey { + return false + } + _, isConst := d2graph.NearConstants[keyPath[0]] + return isConst +} From 799311877afba3338211353f6befcb05ad21a12b Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 14 Sep 2023 14:55:52 -0700 Subject: [PATCH 04/35] refactor --- d2graph/d2graph.go | 15 +++++++++++++++ d2layouts/d2layouts.go | 15 +++++++-------- d2layouts/d2near/layout.go | 15 --------------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 1452cf4bc..a3e0bf760 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1090,6 +1090,21 @@ func (obj *Object) OuterNearContainer() *Object { return nil } +func (obj *Object) IsConstantNear() bool { + if obj.NearKey == nil { + return false + } + keyPath := Key(obj.NearKey) + + // interesting if there is a shape with id=top-left, then top-left isn't treated a constant near + _, isKey := obj.Graph.Root.HasChild(keyPath) + if isKey { + return false + } + _, isConst := NearConstants[keyPath[0]] + return isConst +} + type Edge struct { Index int `json:"index"` diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 60da6c0c7..a92b9542b 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -2,7 +2,6 @@ package d2layouts import ( "oss.terrastruct.com/d2/d2graph" - "oss.terrastruct.com/d2/d2layouts/d2near" ) type GraphType string @@ -14,7 +13,7 @@ const ( SequenceDiagram GraphType = "sequence-diagram" ) -func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph, isRoot bool) { +func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) { // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) @@ -23,12 +22,12 @@ func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.Layo queue = append(queue, g.Root.ChildrenArray...) for _, child := range queue { - if graphType := NestedGraphType(child, isRoot); graphType != DefaultGraphType { + if graphType := NestedGraphType(child); graphType != DefaultGraphType { // There is a nested diagram here, so extract its contents and process in the same way nestedGraph := ExtractNested(child) // Layout of nestedGraph is completed - LayoutNested(nestedGraph, graphType, coreLayout, false) + LayoutNested(nestedGraph, graphType, coreLayout) // Fit child to size of nested layout FitToGraph(child, nestedGraph) @@ -50,14 +49,14 @@ func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.Layo } } -func NestedGraphType(container *d2graph.Object, isRoot bool) GraphType { - if isRoot && d2near.IsConstantNear(container) { +func NestedGraphType(obj *d2graph.Object) GraphType { + if obj.Graph.RootLevel == 0 && obj.IsConstantNear() { return ConstantNearGraph } - if container.IsGridDiagram() { + if obj.IsGridDiagram() { return GridDiagram } - if container.IsSequenceDiagram() { + if obj.IsSequenceDiagram() { return SequenceDiagram } return DefaultGraphType diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 2f1444f46..190317542 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -223,18 +223,3 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { return geo.NewPoint(x1, y1), geo.NewPoint(x2, y2) } - -func IsConstantNear(obj *d2graph.Object) bool { - if obj.NearKey == nil { - return false - } - keyPath := d2graph.Key(obj.NearKey) - - // interesting if there is a shape with id=top-left, then top-left isn't treated a constant near - _, isKey := obj.Graph.Root.HasChild(keyPath) - if isKey { - return false - } - _, isConst := d2graph.NearConstants[keyPath[0]] - return isConst -} From dc6e0644b94767d91639698d1035ae737974e22b Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 14 Sep 2023 15:38:52 -0700 Subject: [PATCH 05/35] extract nested graph from container --- d2layouts/d2layouts.go | 48 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index a92b9542b..30ff31b68 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -1,6 +1,8 @@ package d2layouts import ( + "strings" + "oss.terrastruct.com/d2/d2graph" ) @@ -63,8 +65,50 @@ func NestedGraphType(obj *d2graph.Object) GraphType { } func ExtractNested(container *d2graph.Object) *d2graph.Graph { - // TODO - return nil + tempGraph := d2graph.NewGraph() + tempGraph.RootLevel = int(container.Level()) + + // separate out nested edges + g := container.Graph + remainingEdges := make([]*d2graph.Edge, 0, len(g.Edges)) + for _, edge := range g.Edges { + if edge.Src.Parent.IsDescendantOf(container) && edge.Dst.Parent.IsDescendantOf(container) { + tempGraph.Edges = append(tempGraph.Edges, edge) + } else { + remainingEdges = append(remainingEdges, edge) + } + } + g.Edges = remainingEdges + + // separate out nested objects + remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) + for _, obj := range g.Objects { + if obj.IsDescendantOf(container) { + tempGraph.Objects = append(tempGraph.Objects, obj) + } else { + remainingObjects = append(remainingObjects, obj) + } + } + g.Objects = remainingObjects + + // update object and new root references + for _, o := range tempGraph.Objects { + o.Graph = tempGraph + } + // set root references + tempGraph.Root.ChildrenArray = append(tempGraph.Root.ChildrenArray, container.ChildrenArray...) + for _, child := range container.ChildrenArray { + child.Parent = tempGraph.Root + tempGraph.Root.Children[strings.ToLower(child.ID)] = child + } + + // remove container's references + for k := range container.Children { + delete(container.Children, k) + } + container.ChildrenArray = nil + + return tempGraph } func InjectNested(container *d2graph.Object, graph *d2graph.Graph) { From 477015d408339d6c7e7fb6777330482172ed68f3 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 14 Sep 2023 17:00:44 -0700 Subject: [PATCH 06/35] inject nested graph, fit, spacing --- d2layouts/d2layouts.go | 95 +++++++++++++++++++++++++++++++++--------- lib/geo/spacing.go | 5 +++ 2 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 lib/geo/spacing.go diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 30ff31b68..46590f8b1 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -1,9 +1,11 @@ package d2layouts import ( + "math" "strings" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/lib/geo" ) type GraphType string @@ -15,7 +17,7 @@ const ( SequenceDiagram GraphType = "sequence-diagram" ) -func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) { +func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) geo.Spacing { // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) @@ -29,10 +31,10 @@ func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.Layo nestedGraph := ExtractNested(child) // Layout of nestedGraph is completed - LayoutNested(nestedGraph, graphType, coreLayout) + spacing := LayoutNested(nestedGraph, graphType, coreLayout) // Fit child to size of nested layout - FitToGraph(child, nestedGraph) + FitToGraph(child, nestedGraph, spacing) // We will restore the contents after running layout with child as the placeholder extracted[child] = nestedGraph @@ -43,12 +45,14 @@ func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.Layo // We can now run layout with accurate sizes of nested layout containers // Layout according to the type of diagram - LayoutDiagram(g, graphType, coreLayout) + spacing := LayoutDiagram(g, graphType, coreLayout) // With the layout set, inject all the extracted graphs for n, nestedGraph := range extracted { InjectNested(n, nestedGraph) } + + return spacing } func NestedGraphType(obj *d2graph.Object) GraphType { @@ -65,15 +69,15 @@ func NestedGraphType(obj *d2graph.Object) GraphType { } func ExtractNested(container *d2graph.Object) *d2graph.Graph { - tempGraph := d2graph.NewGraph() - tempGraph.RootLevel = int(container.Level()) + nestedGraph := d2graph.NewGraph() + nestedGraph.RootLevel = int(container.Level()) // separate out nested edges g := container.Graph remainingEdges := make([]*d2graph.Edge, 0, len(g.Edges)) for _, edge := range g.Edges { if edge.Src.Parent.IsDescendantOf(container) && edge.Dst.Parent.IsDescendantOf(container) { - tempGraph.Edges = append(tempGraph.Edges, edge) + nestedGraph.Edges = append(nestedGraph.Edges, edge) } else { remainingEdges = append(remainingEdges, edge) } @@ -84,7 +88,7 @@ func ExtractNested(container *d2graph.Object) *d2graph.Graph { remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) for _, obj := range g.Objects { if obj.IsDescendantOf(container) { - tempGraph.Objects = append(tempGraph.Objects, obj) + nestedGraph.Objects = append(nestedGraph.Objects, obj) } else { remainingObjects = append(remainingObjects, obj) } @@ -92,14 +96,14 @@ func ExtractNested(container *d2graph.Object) *d2graph.Graph { g.Objects = remainingObjects // update object and new root references - for _, o := range tempGraph.Objects { - o.Graph = tempGraph + for _, o := range nestedGraph.Objects { + o.Graph = nestedGraph } // set root references - tempGraph.Root.ChildrenArray = append(tempGraph.Root.ChildrenArray, container.ChildrenArray...) + nestedGraph.Root.ChildrenArray = append(nestedGraph.Root.ChildrenArray, container.ChildrenArray...) for _, child := range container.ChildrenArray { - child.Parent = tempGraph.Root - tempGraph.Root.Children[strings.ToLower(child.ID)] = child + child.Parent = nestedGraph.Root + nestedGraph.Root.Children[strings.ToLower(child.ID)] = child } // remove container's references @@ -108,17 +112,68 @@ func ExtractNested(container *d2graph.Object) *d2graph.Graph { } container.ChildrenArray = nil - return tempGraph + // position contents relative to 0,0 + dx := -container.TopLeft.X + dy := -container.TopLeft.Y + for _, o := range nestedGraph.Objects { + o.TopLeft.X += dx + o.TopLeft.Y += dy + } + for _, e := range nestedGraph.Edges { + e.Move(dx, dy) + } + return nestedGraph } -func InjectNested(container *d2graph.Object, graph *d2graph.Graph) { - // TODO +func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { + g := container.Graph + for _, obj := range nestedGraph.Root.ChildrenArray { + obj.Parent = container + container.Children[strings.ToLower(obj.ID)] = obj + container.ChildrenArray = append(container.ChildrenArray, obj) + } + for _, obj := range nestedGraph.Objects { + obj.Graph = g + } + g.Objects = append(g.Objects, nestedGraph.Objects...) + g.Edges = append(g.Edges, nestedGraph.Edges...) + + // Note: assumes nestedGraph's layout has contents positioned relative to 0,0 + dx := container.TopLeft.X + dy := container.TopLeft.Y + for _, o := range nestedGraph.Objects { + o.TopLeft.X += dx + o.TopLeft.Y += dy + } + for _, e := range nestedGraph.Edges { + e.Move(dx, dy) + } } -func FitToGraph(container *d2graph.Object, graph *d2graph.Graph) { - // TODO +func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { + if len(g.Objects) == 0 { + return geo.NewPoint(0, 0), geo.NewPoint(0, 0) + } + tl = geo.NewPoint(math.Inf(1), math.Inf(1)) + br = geo.NewPoint(math.Inf(-1), math.Inf(-1)) + + for _, obj := range g.Objects { + tl.X = math.Min(tl.X, obj.TopLeft.X) + tl.Y = math.Min(tl.Y, obj.TopLeft.Y) + br.X = math.Max(br.X, obj.TopLeft.X+obj.Width) + br.Y = math.Max(br.Y, obj.TopLeft.Y+obj.Height) + } + + return tl, br } -func LayoutDiagram(graph *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) { - // TODO +func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding geo.Spacing) { + tl, br := boundingBox(nestedGraph) + container.Width = padding.Left + br.X - tl.X + padding.Right + container.Height = padding.Top + br.Y - tl.Y + padding.Bottom +} + +func LayoutDiagram(graph *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) geo.Spacing { + // TODO + return geo.Spacing{} } diff --git a/lib/geo/spacing.go b/lib/geo/spacing.go new file mode 100644 index 000000000..2684ee582 --- /dev/null +++ b/lib/geo/spacing.go @@ -0,0 +1,5 @@ +package geo + +type Spacing struct { + Top, Bottom, Left, Right float64 +} From 9074b29f116eb26527f31bd42db77129b639933e Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 15 Sep 2023 14:44:20 -0700 Subject: [PATCH 07/35] wip --- d2graph/layout.go | 4 +- d2layouts/d2layouts.go | 238 ++++++++++++++++++++++++++++++------- d2layouts/d2near/layout.go | 4 + d2lib/d2.go | 34 +++--- 4 files changed, 222 insertions(+), 58 deletions(-) diff --git a/d2graph/layout.go b/d2graph/layout.go index 9f2702df7..8c705b713 100644 --- a/d2graph/layout.go +++ b/d2graph/layout.go @@ -26,7 +26,7 @@ func (obj *Object) MoveWithDescendantsTo(x, y float64) { obj.MoveWithDescendants(dx, dy) } -func (parent *Object) removeChild(child *Object) { +func (parent *Object) RemoveChild(child *Object) { delete(parent.Children, strings.ToLower(child.ID)) for i := 0; i < len(parent.ChildrenArray); i++ { if parent.ChildrenArray[i] == child { @@ -51,7 +51,7 @@ func (g *Graph) ExtractAsNestedGraph(obj *Object) *Graph { tempGraph.Objects = descendantObjects tempGraph.Edges = edges - obj.Parent.removeChild(obj) + obj.Parent.RemoveChild(obj) obj.Parent = tempGraph.Root return tempGraph diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 46590f8b1..0075a8142 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -1,43 +1,80 @@ package d2layouts import ( + "context" "math" "strings" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts/d2grid" + "oss.terrastruct.com/d2/d2layouts/d2near" + "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/lib/geo" ) -type GraphType string +type DiagramType string +// a grid diagram at a constant near is const ( - DefaultGraphType GraphType = "" - ConstantNearGraph GraphType = "constant-near" - GridDiagram GraphType = "grid-diagram" - SequenceDiagram GraphType = "sequence-diagram" + DefaultGraphType DiagramType = "" + ConstantNearGraph DiagramType = "constant-near" + GridDiagram DiagramType = "grid-diagram" + SequenceDiagram DiagramType = "sequence-diagram" ) -func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) geo.Spacing { +type GraphInfo struct { + IsConstantNear bool + DiagramType DiagramType +} + +func (gi GraphInfo) isDefault() bool { + return !gi.IsConstantNear && gi.DiagramType == DefaultGraphType +} + +func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { + // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) + extractedInfo := make(map[*d2graph.Object]GraphInfo) + + var constantNears []*d2graph.Graph // Iterate top-down from Root so all nested diagrams can process their own contents queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) - queue = append(queue, g.Root.ChildrenArray...) + if graphInfo.IsConstantNear { + near := g.Root.ChildrenArray[0] + if len(near.Children) > 0 { + queue = append(queue, near.ChildrenArray...) + } + } else { + queue = append(queue, g.Root.ChildrenArray...) + } for _, child := range queue { - if graphType := NestedGraphType(child); graphType != DefaultGraphType { - // There is a nested diagram here, so extract its contents and process in the same way - nestedGraph := ExtractNested(child) + if gi := NestedGraphInfo(child); !gi.isDefault() { + extractedInfo[child] = gi + + var nestedGraph *d2graph.Graph + if gi.IsConstantNear { + nestedGraph = ExtractSelf(child) + } else { + // There is a nested diagram here, so extract its contents and process in the same way + nestedGraph = ExtractDescendants(child) + } // Layout of nestedGraph is completed - spacing := LayoutNested(nestedGraph, graphType, coreLayout) - - // Fit child to size of nested layout - FitToGraph(child, nestedGraph, spacing) + spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout) + if !gi.IsConstantNear { + // Fit child to size of nested layout + FitToGraph(child, nestedGraph, spacing) + } // We will restore the contents after running layout with child as the placeholder - extracted[child] = nestedGraph + if gi.IsConstantNear { + constantNears = append(constantNears, nestedGraph) + } else { + extracted[child] = nestedGraph + } } else if len(child.Children) > 0 { queue = append(queue, child.ChildrenArray...) } @@ -45,30 +82,119 @@ func LayoutNested(g *d2graph.Graph, graphType GraphType, coreLayout d2graph.Layo // We can now run layout with accurate sizes of nested layout containers // Layout according to the type of diagram - spacing := LayoutDiagram(g, graphType, coreLayout) + LayoutDiagram := func(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { + spacing := geo.Spacing{} + var err error + // TODO + + switch graphInfo.DiagramType { + case GridDiagram: + layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) + if err = layoutWithGrids(ctx, g); err != nil { + panic(err) + } + + case SequenceDiagram: + err = d2sequence.Layout(ctx, g, coreLayout) + if err != nil { + panic(err) + } + default: + err := coreLayout(ctx, g) + if err != nil { + panic(err) + } + } + return spacing + } + spacing := LayoutDiagram(ctx, g, graphInfo, coreLayout) // With the layout set, inject all the extracted graphs for n, nestedGraph := range extracted { - InjectNested(n, nestedGraph) + if !extractedInfo[n].IsConstantNear { + InjectNested(n, nestedGraph) + PositionNested(n, nestedGraph) + } + } + + // if there are + if len(constantNears) > 0 { + err := d2near.Layout(ctx, g, constantNears) + if err != nil { + panic(err) + } } return spacing } -func NestedGraphType(obj *d2graph.Object) GraphType { +// TODO multiple types at same (e.g. constant nears with grid at root level) +// e.g. constant nears with sequence diagram at root level +func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { if obj.Graph.RootLevel == 0 && obj.IsConstantNear() { - return ConstantNearGraph - } - if obj.IsGridDiagram() { - return GridDiagram + gi.IsConstantNear = true } + // if obj.Graph.RootLevel == -1 { + // for _, obj := range obj.Graph.Root.ChildrenArray { + // if obj.IsConstantNear() { + // return ConstantNearGraph + // } + // } + // } if obj.IsSequenceDiagram() { - return SequenceDiagram + gi.DiagramType = SequenceDiagram + } else if obj.IsGridDiagram() { + gi.DiagramType = GridDiagram } - return DefaultGraphType + return gi } -func ExtractNested(container *d2graph.Object) *d2graph.Graph { +func ExtractSelf(container *d2graph.Object) *d2graph.Graph { + nestedGraph := d2graph.NewGraph() + nestedGraph.RootLevel = int(container.Level()) - 1 + + // separate out nested edges + g := container.Graph + remainingEdges := make([]*d2graph.Edge, 0, len(g.Edges)) + for _, edge := range g.Edges { + if edge.Src.IsDescendantOf(container) && edge.Dst.IsDescendantOf(container) { + nestedGraph.Edges = append(nestedGraph.Edges, edge) + } else { + remainingEdges = append(remainingEdges, edge) + } + } + g.Edges = remainingEdges + + // separate out nested objects + remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) + for _, obj := range g.Objects { + if obj.IsDescendantOf(container) { + nestedGraph.Objects = append(nestedGraph.Objects, obj) + } else { + remainingObjects = append(remainingObjects, obj) + } + } + g.Objects = remainingObjects + + // update object and new root references + for _, o := range nestedGraph.Objects { + o.Graph = nestedGraph + } + + // remove container parent's references + if container.Parent != nil { + container.Parent.RemoveChild(container) + } + + // set root references + nestedGraph.Root.ChildrenArray = []*d2graph.Object{container} + container.Parent = nestedGraph.Root + nestedGraph.Root.Children[strings.ToLower(container.ID)] = container + + return nestedGraph +} + +func ExtractDescendants(container *d2graph.Object) *d2graph.Graph { nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) @@ -87,7 +213,7 @@ func ExtractNested(container *d2graph.Object) *d2graph.Graph { // separate out nested objects remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) for _, obj := range g.Objects { - if obj.IsDescendantOf(container) { + if obj.Parent.IsDescendantOf(container) { nestedGraph.Objects = append(nestedGraph.Objects, obj) } else { remainingObjects = append(remainingObjects, obj) @@ -112,16 +238,6 @@ func ExtractNested(container *d2graph.Object) *d2graph.Graph { } container.ChildrenArray = nil - // position contents relative to 0,0 - dx := -container.TopLeft.X - dy := -container.TopLeft.Y - for _, o := range nestedGraph.Objects { - o.TopLeft.X += dx - o.TopLeft.Y += dy - } - for _, e := range nestedGraph.Edges { - e.Move(dx, dy) - } return nestedGraph } @@ -138,9 +254,13 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { g.Objects = append(g.Objects, nestedGraph.Objects...) g.Edges = append(g.Edges, nestedGraph.Edges...) +} + +func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { + tl, _ := boundingBox(nestedGraph) // Note: assumes nestedGraph's layout has contents positioned relative to 0,0 - dx := container.TopLeft.X - dy := container.TopLeft.Y + dx := container.TopLeft.X - tl.X + dy := container.TopLeft.Y - tl.Y for _, o := range nestedGraph.Objects { o.TopLeft.X += dx o.TopLeft.Y += dy @@ -173,7 +293,41 @@ func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding g container.Height = padding.Top + br.Y - tl.Y + padding.Bottom } -func LayoutDiagram(graph *d2graph.Graph, graphType GraphType, coreLayout d2graph.LayoutGraph) geo.Spacing { - // TODO - return geo.Spacing{} -} +// func LayoutDiagram(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { +// spacing := geo.Spacing{} +// var err error +// // TODO + +// // Need subgraphs? + +// // if graphInfo.IsConstantNear +// // case ConstantNearGraph: +// // // constantNearGraphs := d2near.WithoutConstantNears(ctx, g) +// // constantNearGraphs := d2near.WithoutConstantNears(ctx, g) + +// // err = d2near.Layout(ctx, g, constantNearGraphs) +// // if err != nil { +// // panic(err) +// // } + +// switch graphInfo.DiagramType { +// case GridDiagram: +// layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) +// if err = layoutWithGrids(ctx, g); err != nil { +// panic(err) +// } + +// case SequenceDiagram: +// err = d2sequence.Layout(ctx, g, coreLayout) +// if err != nil { +// panic(err) +// } +// default: +// err := coreLayout(ctx, g) +// if err != nil { +// panic(err) +// } +// } + +// return spacing +// } diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 190317542..cb8301e0a 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -91,6 +91,10 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNearGraphs []*d2graph return nil } +func Place(obj *d2graph.Object) (float64, float64) { + return place(obj) +} + // place returns the position of obj, taking into consideration its near value and the diagram func place(obj *d2graph.Object) (float64, float64) { tl, br := boundingBox(obj.Graph) diff --git a/d2lib/d2.go b/d2lib/d2.go index c34eb9206..88fcd643e 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -10,6 +10,7 @@ import ( "oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2layouts/d2grid" "oss.terrastruct.com/d2/d2layouts/d2near" @@ -84,25 +85,30 @@ func compile(ctx context.Context, g *d2graph.Graph, compileOpts *CompileOptions, return nil, err } - constantNearGraphs := d2near.WithoutConstantNears(ctx, g) + graphInfo := d2layouts.NestedGraphInfo(g.Root) + d2layouts.LayoutNested(ctx, g, graphInfo, coreLayout) - layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) + if false { + constantNearGraphs := d2near.WithoutConstantNears(ctx, g) - // run core layout for constantNears - for _, tempGraph := range constantNearGraphs { - if err = layoutWithGrids(ctx, tempGraph); err != nil { + layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) + + // run core layout for constantNears + for _, tempGraph := range constantNearGraphs { + if err = layoutWithGrids(ctx, tempGraph); err != nil { + return nil, err + } + } + + err = d2sequence.Layout(ctx, g, layoutWithGrids) + if err != nil { return nil, err } - } - err = d2sequence.Layout(ctx, g, layoutWithGrids) - if err != nil { - return nil, err - } - - err = d2near.Layout(ctx, g, constantNearGraphs) - if err != nil { - return nil, err + err = d2near.Layout(ctx, g, constantNearGraphs) + if err != nil { + return nil, err + } } } From e83ac4c3ac76e2b92d15da085aea076352b90c41 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 15 Sep 2023 16:50:27 -0700 Subject: [PATCH 08/35] seq wip --- d2layouts/d2layouts.go | 3 ++- d2layouts/d2sequence/layout.go | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 0075a8142..dfd5703a6 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -95,7 +95,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } case SequenceDiagram: - err = d2sequence.Layout(ctx, g, coreLayout) + err = d2sequence.Layout2(ctx, g, coreLayout) if err != nil { panic(err) } @@ -197,6 +197,7 @@ func ExtractSelf(container *d2graph.Object) *d2graph.Graph { func ExtractDescendants(container *d2graph.Object) *d2graph.Graph { nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) + nestedGraph.Root.Box = &geo.Box{} // separate out nested edges g := container.Graph diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index 24427914b..cdf204606 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -40,6 +40,50 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) e return nil } +func Layout2(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) error { + // used in layout code + g.Root.Shape.Value = d2target.ShapeSequenceDiagram + + sd, err := layoutSequenceDiagram(g, g.Root) + if err != nil { + return err + } + g.Root.Box = geo.NewBox(nil, sd.getWidth()+GROUP_CONTAINER_PADDING*2, sd.getHeight()+GROUP_CONTAINER_PADDING*2) + + // the sequence diagram is the only layout engine if the whole diagram is + // shape: sequence_diagram + g.Root.TopLeft = geo.NewPoint(0, 0) + + obj := g.Root + + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + + // shift the sequence diagrams as they are always placed at (0, 0) with some padding + sd.shift( + geo.NewPoint( + obj.TopLeft.X+GROUP_CONTAINER_PADDING, + obj.TopLeft.Y+GROUP_CONTAINER_PADDING, + ), + ) + + obj.Children = make(map[string]*d2graph.Object) + obj.ChildrenArray = make([]*d2graph.Object, 0) + for _, child := range sd.actors { + obj.Children[strings.ToLower(child.ID)] = child + obj.ChildrenArray = append(obj.ChildrenArray, child) + } + for _, child := range sd.groups { + if child.Parent.AbsID() == obj.AbsID() { + obj.Children[strings.ToLower(child.ID)] = child + obj.ChildrenArray = append(obj.ChildrenArray, child) + } + } + + g.Edges = append(g.Edges, sd.lifelines...) + + return nil +} + func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]*sequenceDiagram, map[string]int, map[string]int, error) { objectsToRemove := make(map[*d2graph.Object]struct{}) edgesToRemove := make(map[*d2graph.Edge]struct{}) From b7791c83ea7a65e752e38890a8e20283a44353a0 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 15 Sep 2023 22:07:06 -0700 Subject: [PATCH 09/35] wip --- d2graph/d2graph.go | 2 +- d2layouts/d2grid/layout.go | 158 ++++++ d2layouts/d2layouts.go | 92 ++-- .../testdata/files/nested_diagram_types.d2 | 6 +- .../nested_diagram_types/dagre/board.exp.json | 462 ++++++++---------- .../nested_diagram_types/dagre/sketch.exp.svg | 197 ++++---- .../nested_diagram_types/elk/board.exp.json | 453 +++++++---------- .../nested_diagram_types/elk/sketch.exp.svg | 197 ++++---- 8 files changed, 810 insertions(+), 757 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index a3e0bf760..36d206e41 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1925,7 +1925,7 @@ func (g *Graph) PrintString() string { buf := &bytes.Buffer{} fmt.Fprint(buf, "Objects: [") for _, obj := range g.Objects { - fmt.Fprintf(buf, "%#v @(%v)", obj.AbsID(), obj.TopLeft.ToString()) + fmt.Fprintf(buf, "%v, ", obj.AbsID()) } fmt.Fprint(buf, "]") return buf.String() diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 9e9109453..853a691e7 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -47,6 +47,164 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d } } +func Layout2(ctx context.Context, g *d2graph.Graph) error { + + obj := g.Root + + gd, err := layoutGrid(g, obj) + if err != nil { + return err + } + // obj.Children = make(map[string]*d2graph.Object) + // obj.ChildrenArray = nil + + if obj.Box != nil { + // CONTAINER_PADDING is default, but use gap value if set + horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING + if obj.GridGap != nil || obj.HorizontalGap != nil { + horizontalPadding = gd.horizontalGap + } + if obj.GridGap != nil || obj.VerticalGap != nil { + verticalPadding = gd.verticalGap + } + + // size shape according to grid + obj.SizeToContent(gd.width, gd.height, float64(2*horizontalPadding), float64(2*verticalPadding)) + + // compute where the grid should be placed inside shape + s := obj.ToShape() + innerBox := s.GetInnerBox() + if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 { + gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y) + } + + // compute how much space the label and icon occupy + var occupiedWidth, occupiedHeight float64 + if obj.Icon != nil { + iconSpace := float64(d2target.MAX_ICON_SIZE + 2*label.PADDING) + occupiedWidth = iconSpace + occupiedHeight = iconSpace + } + + var dx, dy float64 + if obj.LabelDimensions.Height != 0 { + occupiedHeight = math.Max( + occupiedHeight, + float64(obj.LabelDimensions.Height)+2*label.PADDING, + ) + } + if obj.LabelDimensions.Width != 0 { + // . ├────┤───────├────┤ + // . icon label icon + // with an icon in top left we need 2x the space to fit the label in the center + occupiedWidth *= 2 + occupiedWidth += float64(obj.LabelDimensions.Width) + 2*label.PADDING + if occupiedWidth > obj.Width { + dx = (occupiedWidth - obj.Width) / 2 + obj.Width = occupiedWidth + } + } + + // also check for grid cells with outside top labels or icons + // the first grid object is at the top (and always exists) + topY := gd.objects[0].TopLeft.Y + highestOutside := topY + for _, o := range gd.objects { + // we only want to compute label positions for objects at the top of the grid + if o.TopLeft.Y > topY { + if gd.rowDirected { + // if the grid is rowDirected (row1, row2, etc) we can stop after finishing the first row + break + } else { + // otherwise we continue until the next column + continue + } + } + if o.LabelPosition != nil { + labelPosition := label.Position(*o.LabelPosition) + if labelPosition.IsOutside() { + labelTL := o.GetLabelTopLeft() + if labelTL.Y < highestOutside { + highestOutside = labelTL.Y + } + } + } + if o.IconPosition != nil { + switch label.Position(*o.IconPosition) { + case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight: + iconSpace := float64(d2target.MAX_ICON_SIZE + label.PADDING) + if topY-iconSpace < highestOutside { + highestOutside = topY - iconSpace + } + } + } + } + if highestOutside < topY { + occupiedHeight += topY - highestOutside + 2*label.PADDING + } + if occupiedHeight > float64(verticalPadding) { + // if the label doesn't fit within the padding, we need to add more + dy = occupiedHeight - float64(verticalPadding) + obj.Height += dy + } + + // we need to center children if we have to expand to fit the container label + if dx != 0 || dy != 0 { + gd.shift(dx, dy) + } + } + + if obj.HasLabel() { + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + } + if obj.Icon != nil { + obj.IconPosition = go2.Pointer(string(label.InsideTopLeft)) + } + + // simple straight line edge routing between grid objects + for _, e := range g.Edges { + // edgeOrder[e.AbsID()] = i + if !e.Src.Parent.IsDescendantOf(obj) && !e.Dst.Parent.IsDescendantOf(obj) { + continue + } + // if edge is within grid, remove it from outer layout + gd.edges = append(gd.edges, e) + // edgeToRemove[e] = struct{}{} + + if e.Src.Parent != obj || e.Dst.Parent != obj { + continue + } + // if edge is grid child, use simple routing + e.Route = []*geo.Point{e.Src.Center(), e.Dst.Center()} + e.TraceToShape(e.Route, 0, 1) + if e.Label.Value != "" { + e.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } + } + + if g.Root.IsGridDiagram() && len(g.Root.ChildrenArray) != 0 { + g.Root.TopLeft = geo.NewPoint(0, 0) + } + + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + + horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING + if obj.GridGap != nil || obj.HorizontalGap != nil { + horizontalPadding = gd.horizontalGap + } + if obj.GridGap != nil || obj.VerticalGap != nil { + verticalPadding = gd.verticalGap + } + + // shift the grid from (0, 0) + gd.shift( + obj.TopLeft.X+float64(horizontalPadding), + obj.TopLeft.Y+float64(verticalPadding), + ) + gd.cleanup(obj, g) + return nil +} + func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder, edgeOrder map[string]int, err error) { toRemove := make(map[*d2graph.Object]struct{}) edgeToRemove := make(map[*d2graph.Edge]struct{}) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index dfd5703a6..a3001cf4f 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -5,11 +5,13 @@ import ( "math" "strings" + "cdr.dev/slog" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2grid" "oss.terrastruct.com/d2/d2layouts/d2near" "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/lib/geo" + "oss.terrastruct.com/d2/lib/log" ) type DiagramType string @@ -33,6 +35,7 @@ func (gi GraphInfo) isDefault() bool { func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { + log.Warn(ctx, "ln info", slog.F("gi", graphInfo)) // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) extractedInfo := make(map[*d2graph.Object]GraphInfo) @@ -53,28 +56,39 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co for _, child := range queue { if gi := NestedGraphInfo(child); !gi.isDefault() { extractedInfo[child] = gi + // log.Warn(ctx, "nested", slog.F("child", child.AbsID()), slog.F("gi", gi)) - var nestedGraph *d2graph.Graph - if gi.IsConstantNear { - nestedGraph = ExtractSelf(child) - } else { - // There is a nested diagram here, so extract its contents and process in the same way - nestedGraph = ExtractDescendants(child) - } + // There is a nested diagram here, so extract its contents and process in the same way + nestedGraph := ExtractDescendants(child) // Layout of nestedGraph is completed + // log.Error(ctx, "recurse", slog.F("child", child.AbsID()), slog.F("level", child.Level())) spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout) - if !gi.IsConstantNear { - // Fit child to size of nested layout - FitToGraph(child, nestedGraph, spacing) + log.Warn(ctx, "fitting child", slog.F("child", child.AbsID())) + // Fit child to size of nested layout + FitToGraph(child, nestedGraph, spacing) + + var nearGraph *d2graph.Graph + if gi.IsConstantNear { + nearGraph = ExtractSelf(child) + child.TopLeft = geo.NewPoint(0, 0) + child.Width = nestedGraph.Root.Width + child.Width = nestedGraph.Root.Height } + // if gi.IsConstantNear { + // // FitToGraph(child, nestedGraph, spacing) + // if nestedGraph.Root.Box != nil { + // child.Width = nestedGraph.Root.Width + // child.Height = nestedGraph.Root.Height + // } + // } + // We will restore the contents after running layout with child as the placeholder if gi.IsConstantNear { - constantNears = append(constantNears, nestedGraph) - } else { - extracted[child] = nestedGraph + constantNears = append(constantNears, nearGraph) } + extracted[child] = nestedGraph } else if len(child.Children) > 0 { queue = append(queue, child.ChildrenArray...) } @@ -89,17 +103,21 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co switch graphInfo.DiagramType { case GridDiagram: - layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) - if err = layoutWithGrids(ctx, g); err != nil { + log.Warn(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + // layoutWithGrids := d2grid.Layout2(ctx, g, coreLayout) + // layoutWithGrids(ctx, g) + if err = d2grid.Layout2(ctx, g); err != nil { panic(err) } case SequenceDiagram: + log.Warn(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) err = d2sequence.Layout2(ctx, g, coreLayout) if err != nil { panic(err) } default: + log.Warn(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) err := coreLayout(ctx, g) if err != nil { panic(err) @@ -109,14 +127,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } spacing := LayoutDiagram(ctx, g, graphInfo, coreLayout) - // With the layout set, inject all the extracted graphs - for n, nestedGraph := range extracted { - if !extractedInfo[n].IsConstantNear { - InjectNested(n, nestedGraph) - PositionNested(n, nestedGraph) - } - } - // if there are if len(constantNears) > 0 { err := d2near.Layout(ctx, g, constantNears) @@ -125,6 +135,15 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } } + // With the layout set, inject all the extracted graphs + for n, nestedGraph := range extracted { + // if !extractedInfo[n].IsConstantNear { + InjectNested(n, nestedGraph) + PositionNested(n, nestedGraph) + // } + } + + log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel)) return spacing } @@ -152,6 +171,7 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { func ExtractSelf(container *d2graph.Object) *d2graph.Graph { nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) - 1 + // nestedGraph.Root.Box = &geo.Box{} // separate out nested edges g := container.Graph @@ -255,13 +275,16 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { g.Objects = append(g.Objects, nestedGraph.Objects...) g.Edges = append(g.Edges, nestedGraph.Edges...) + if g.Root.LabelPosition != nil { + container.LabelPosition = g.Root.LabelPosition + } } func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { - tl, _ := boundingBox(nestedGraph) + // _, _ := boundingBox(nestedGraph) // Note: assumes nestedGraph's layout has contents positioned relative to 0,0 - dx := container.TopLeft.X - tl.X - dy := container.TopLeft.Y - tl.Y + dx := container.TopLeft.X //- tl.X + dy := container.TopLeft.Y //- tl.Y for _, o := range nestedGraph.Objects { o.TopLeft.X += dx o.TopLeft.Y += dy @@ -279,6 +302,9 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { br = geo.NewPoint(math.Inf(-1), math.Inf(-1)) for _, obj := range g.Objects { + if obj.TopLeft == nil { + panic(obj.AbsID()) + } tl.X = math.Min(tl.X, obj.TopLeft.X) tl.Y = math.Min(tl.Y, obj.TopLeft.Y) br.X = math.Max(br.X, obj.TopLeft.X+obj.Width) @@ -289,9 +315,17 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { } func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding geo.Spacing) { - tl, br := boundingBox(nestedGraph) - container.Width = padding.Left + br.X - tl.X + padding.Right - container.Height = padding.Top + br.Y - tl.Y + padding.Bottom + var width, height float64 + // if nestedGraph.Root.Box != nil { + width = nestedGraph.Root.Width + height = nestedGraph.Root.Height + if width == 0 || height == 0 { + tl, br := boundingBox(nestedGraph) + width = br.X - tl.X + height = br.Y - tl.Y + } + container.Width = padding.Left + width + padding.Right + container.Height = padding.Top + height + padding.Bottom } // func LayoutDiagram(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 index 2bb6aaafd..701a8ff53 100644 --- a/e2etests/testdata/files/nested_diagram_types.d2 +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -22,12 +22,12 @@ b: { 1 -> 2 # TODO This should work - # near: bottom-left + near: bottom-right # 2: { # TODO compile error grid on sequence actor - grid-rows: 3 + # grid-rows: 3 x y z @@ -36,7 +36,7 @@ b: { 1: { x: { # TODO compile error grid in sequence (anywhere) - grid-rows: 3 + # grid-rows: 3 u v w diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json index f4fa59d99..678409ed9 100644 --- a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json @@ -10,8 +10,8 @@ "x": 0, "y": 0 }, - "width": 274, - "height": 1394, + "width": 699, + "height": 393, "opacity": 1, "strokeDash": 0, "strokeWidth": 0, @@ -40,7 +40,7 @@ "underline": false, "labelWidth": 13, "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 1 }, @@ -48,8 +48,8 @@ "id": "c", "type": "rectangle", "pos": { - "x": 334, - "y": 664 + "x": 759, + "y": 164 }, "width": 53, "height": 66, @@ -89,11 +89,11 @@ "id": "b.1", "type": "rectangle", "pos": { - "x": 12, - "y": 88 + "x": 0, + "y": 0 }, - "width": 100, - "height": 66, + "width": 617, + "height": 187, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -122,7 +122,7 @@ "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPosition": "OUTSIDE_TOP_CENTER", "zIndex": 0, "level": 2 }, @@ -130,10 +130,10 @@ "id": "b.2", "type": "rectangle", "pos": { - "x": 162, - "y": 88 + "x": 422, + "y": 327 }, - "width": 100, + "width": 277, "height": 66, "opacity": 1, "strokeDash": 0, @@ -168,19 +168,19 @@ "level": 2 }, { - "id": "b.2.x", - "type": "page", + "id": "b.1.x", + "type": "rectangle", "pos": { - "x": 186, - "y": 294 + "x": 30, + "y": 31 }, - "width": 52, - "height": 66, + "width": 342, + "height": 126, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "N7", + "fill": "B4", "stroke": "B1", "shadow": false, "3d": false, @@ -204,138 +204,16 @@ "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, - "level": 3 - }, - { - "id": "b.2.y", - "type": "page", - "pos": { - "x": 185, - "y": 430 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "y", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, - "level": 3 - }, - { - "id": "b.2.z", - "type": "page", - "pos": { - "x": 186, - "y": 566 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, - "level": 3 - }, - { - "id": "b.1.x", - "type": "rectangle", - "pos": { - "x": 56, - "y": 692 - }, - "width": 12, - "height": 358, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "zIndex": 2, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, "level": 3 }, { "id": "b.1.x.u", - "type": "page", + "type": "rectangle", "pos": { - "x": 36, - "y": 702 + "x": 60, + "y": 61 }, "width": 52, "height": 66, @@ -368,15 +246,15 @@ "labelWidth": 7, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 4 }, { "id": "b.1.x.v", - "type": "page", + "type": "rectangle", "pos": { - "x": 35, - "y": 838 + "x": 172, + "y": 61 }, "width": 53, "height": 66, @@ -409,15 +287,15 @@ "labelWidth": 8, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 4 }, { "id": "b.1.x.w", - "type": "page", + "type": "rectangle", "pos": { - "x": 33, - "y": 974 + "x": 285, + "y": 61 }, "width": 57, "height": 66, @@ -450,15 +328,15 @@ "labelWidth": 12, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 4 }, { "id": "b.1.y", - "type": "page", + "type": "rectangle", "pos": { - "x": 35, - "y": 1110 + "x": 534, + "y": 61 }, "width": 53, "height": 66, @@ -491,15 +369,15 @@ "labelWidth": 8, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 3 }, { "id": "b.1.z", - "type": "page", + "type": "rectangle", "pos": { - "x": 36, - "y": 1246 + "x": 422, + "y": 61 }, "width": 52, "height": 66, @@ -532,18 +410,141 @@ "labelWidth": 7, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.x", + "type": "rectangle", + "pos": { + "x": 422, + "y": 327 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.y", + "type": "rectangle", + "pos": { + "x": 534, + "y": 327 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.z", + "type": "rectangle", + "pos": { + "x": 647, + "y": 327 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, "level": 3 }, { "id": "a", "type": "rectangle", "pos": { - "x": 407, - "y": -478 + "x": 832, + "y": -444 }, - "width": 345, - "height": 458, + "width": 285, + "height": 398, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -580,10 +581,10 @@ "id": "a.1", "type": "rectangle", "pos": { - "x": 467, - "y": -418 + "x": 892, + "y": -384 }, - "width": 225, + "width": 165, "height": 66, "opacity": 1, "strokeDash": 0, @@ -621,10 +622,10 @@ "id": "a.2", "type": "rectangle", "pos": { - "x": 467, - "y": -312 + "x": 892, + "y": -278 }, - "width": 225, + "width": 165, "height": 66, "opacity": 1, "strokeDash": 0, @@ -662,11 +663,11 @@ "id": "a.3", "type": "sequence_diagram", "pos": { - "x": 467, - "y": -206 + "x": 892, + "y": -172 }, - "width": 225, - "height": 126, + "width": 165, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 0, @@ -695,7 +696,7 @@ "underline": false, "labelWidth": 11, "labelHeight": 31, - "labelPosition": "OUTSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, @@ -703,8 +704,8 @@ "id": "a.3.x", "type": "rectangle", "pos": { - "x": 497, - "y": -176 + "x": 892, + "y": -172 }, "width": 52, "height": 66, @@ -744,8 +745,8 @@ "id": "a.3.y", "type": "rectangle", "pos": { - "x": 609, - "y": -176 + "x": 1004, + "y": -172 }, "width": 53, "height": 66, @@ -808,94 +809,27 @@ "labelPercentage": 0, "route": [ { - "x": 62, - "y": 224 + "x": 560.5, + "y": 187 }, { - "x": 212, - "y": 224 + "x": 560.5, + "y": 259 + }, + { + "x": 560.5, + "y": 287 + }, + { + "x": 560.5, + "y": 327 } ], + "isCurve": true, "animated": false, "tooltip": "", "icon": null, - "zIndex": 4 - }, - { - "id": "(b.1 -- )[0]", - "src": "b.1", - "srcArrow": "none", - "dst": "1-lifeline-end-1719232319", - "dstArrow": "none", - "opacity": 1, - "strokeDash": 6, - "strokeWidth": 2, - "stroke": "B2", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 62, - "y": 154 - }, - { - "x": 62, - "y": 1382 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 1 - }, - { - "id": "(b.2 -- )[0]", - "src": "b.2", - "srcArrow": "none", - "dst": "2-lifeline-end-1739547740", - "dstArrow": "none", - "opacity": 1, - "strokeDash": 6, - "strokeWidth": 2, - "stroke": "B2", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 212, - "y": 154 - }, - { - "x": 212, - "y": 1382 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 1 + "zIndex": 0 } ], "root": { diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg index 9c4b87f3c..10abb5e04 100644 --- a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -bca12123xy xyzyzuvw - - - - - - - - - - - - - - - - - - - + .d2-1661882471 .fill-N1{fill:#0A0F25;} + .d2-1661882471 .fill-N2{fill:#676C7E;} + .d2-1661882471 .fill-N3{fill:#9499AB;} + .d2-1661882471 .fill-N4{fill:#CFD2DD;} + .d2-1661882471 .fill-N5{fill:#DEE1EB;} + .d2-1661882471 .fill-N6{fill:#EEF1F8;} + .d2-1661882471 .fill-N7{fill:#FFFFFF;} + .d2-1661882471 .fill-B1{fill:#0D32B2;} + .d2-1661882471 .fill-B2{fill:#0D32B2;} + .d2-1661882471 .fill-B3{fill:#E3E9FD;} + .d2-1661882471 .fill-B4{fill:#E3E9FD;} + .d2-1661882471 .fill-B5{fill:#EDF0FD;} + .d2-1661882471 .fill-B6{fill:#F7F8FE;} + .d2-1661882471 .fill-AA2{fill:#4A6FF3;} + .d2-1661882471 .fill-AA4{fill:#EDF0FD;} + .d2-1661882471 .fill-AA5{fill:#F7F8FE;} + .d2-1661882471 .fill-AB4{fill:#EDF0FD;} + .d2-1661882471 .fill-AB5{fill:#F7F8FE;} + .d2-1661882471 .stroke-N1{stroke:#0A0F25;} + .d2-1661882471 .stroke-N2{stroke:#676C7E;} + .d2-1661882471 .stroke-N3{stroke:#9499AB;} + .d2-1661882471 .stroke-N4{stroke:#CFD2DD;} + .d2-1661882471 .stroke-N5{stroke:#DEE1EB;} + .d2-1661882471 .stroke-N6{stroke:#EEF1F8;} + .d2-1661882471 .stroke-N7{stroke:#FFFFFF;} + .d2-1661882471 .stroke-B1{stroke:#0D32B2;} + .d2-1661882471 .stroke-B2{stroke:#0D32B2;} + .d2-1661882471 .stroke-B3{stroke:#E3E9FD;} + .d2-1661882471 .stroke-B4{stroke:#E3E9FD;} + .d2-1661882471 .stroke-B5{stroke:#EDF0FD;} + .d2-1661882471 .stroke-B6{stroke:#F7F8FE;} + .d2-1661882471 .stroke-AA2{stroke:#4A6FF3;} + .d2-1661882471 .stroke-AA4{stroke:#EDF0FD;} + .d2-1661882471 .stroke-AA5{stroke:#F7F8FE;} + .d2-1661882471 .stroke-AB4{stroke:#EDF0FD;} + .d2-1661882471 .stroke-AB5{stroke:#F7F8FE;} + .d2-1661882471 .background-color-N1{background-color:#0A0F25;} + .d2-1661882471 .background-color-N2{background-color:#676C7E;} + .d2-1661882471 .background-color-N3{background-color:#9499AB;} + .d2-1661882471 .background-color-N4{background-color:#CFD2DD;} + .d2-1661882471 .background-color-N5{background-color:#DEE1EB;} + .d2-1661882471 .background-color-N6{background-color:#EEF1F8;} + .d2-1661882471 .background-color-N7{background-color:#FFFFFF;} + .d2-1661882471 .background-color-B1{background-color:#0D32B2;} + .d2-1661882471 .background-color-B2{background-color:#0D32B2;} + .d2-1661882471 .background-color-B3{background-color:#E3E9FD;} + .d2-1661882471 .background-color-B4{background-color:#E3E9FD;} + .d2-1661882471 .background-color-B5{background-color:#EDF0FD;} + .d2-1661882471 .background-color-B6{background-color:#F7F8FE;} + .d2-1661882471 .background-color-AA2{background-color:#4A6FF3;} + .d2-1661882471 .background-color-AA4{background-color:#EDF0FD;} + .d2-1661882471 .background-color-AA5{background-color:#F7F8FE;} + .d2-1661882471 .background-color-AB4{background-color:#EDF0FD;} + .d2-1661882471 .background-color-AB5{background-color:#F7F8FE;} + .d2-1661882471 .color-N1{color:#0A0F25;} + .d2-1661882471 .color-N2{color:#676C7E;} + .d2-1661882471 .color-N3{color:#9499AB;} + .d2-1661882471 .color-N4{color:#CFD2DD;} + .d2-1661882471 .color-N5{color:#DEE1EB;} + .d2-1661882471 .color-N6{color:#EEF1F8;} + .d2-1661882471 .color-N7{color:#FFFFFF;} + .d2-1661882471 .color-B1{color:#0D32B2;} + .d2-1661882471 .color-B2{color:#0D32B2;} + .d2-1661882471 .color-B3{color:#E3E9FD;} + .d2-1661882471 .color-B4{color:#E3E9FD;} + .d2-1661882471 .color-B5{color:#EDF0FD;} + .d2-1661882471 .color-B6{color:#F7F8FE;} + .d2-1661882471 .color-AA2{color:#4A6FF3;} + .d2-1661882471 .color-AA4{color:#EDF0FD;} + .d2-1661882471 .color-AA5{color:#F7F8FE;} + .d2-1661882471 .color-AB4{color:#EDF0FD;} + .d2-1661882471 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>bca12123xyzxyzxyuvw + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json index 3ca671d1c..8f5124b95 100644 --- a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json +++ b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json @@ -10,8 +10,8 @@ "x": 12, "y": 12 }, - "width": 274, - "height": 1394, + "width": 547, + "height": 402, "opacity": 1, "strokeDash": 0, "strokeWidth": 0, @@ -40,7 +40,7 @@ "underline": false, "labelWidth": 13, "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 1 }, @@ -48,8 +48,8 @@ "id": "c", "type": "rectangle", "pos": { - "x": 306, - "y": 676 + "x": 579, + "y": 180 }, "width": 53, "height": 66, @@ -89,11 +89,11 @@ "id": "b.1", "type": "rectangle", "pos": { - "x": 24, - "y": 100 + "x": 12, + "y": 12 }, - "width": 100, - "height": 66, + "width": 547, + "height": 266, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -122,7 +122,7 @@ "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 2 }, @@ -130,10 +130,10 @@ "id": "b.2", "type": "rectangle", "pos": { - "x": 174, - "y": 100 + "x": 187, + "y": 348 }, - "width": 100, + "width": 197, "height": 66, "opacity": 1, "strokeDash": 0, @@ -168,19 +168,19 @@ "level": 2 }, { - "id": "b.2.x", - "type": "page", + "id": "b.1.x", + "type": "rectangle", "pos": { - "x": 198, - "y": 306 + "x": 62, + "y": 62 }, - "width": 52, - "height": 66, + "width": 302, + "height": 166, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "N7", + "fill": "B4", "stroke": "B1", "shadow": false, "3d": false, @@ -204,138 +204,16 @@ "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, - "level": 3 - }, - { - "id": "b.2.y", - "type": "page", - "pos": { - "x": 197, - "y": 442 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "y", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, - "level": 3 - }, - { - "id": "b.2.z", - "type": "page", - "pos": { - "x": 198, - "y": 578 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, - "level": 3 - }, - { - "id": "b.1.x", - "type": "rectangle", - "pos": { - "x": 68, - "y": 704 - }, - "width": 12, - "height": 358, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "zIndex": 2, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, "level": 3 }, { "id": "b.1.x.u", - "type": "page", + "type": "rectangle", "pos": { - "x": 48, - "y": 714 + "x": 112, + "y": 112 }, "width": 52, "height": 66, @@ -368,15 +246,15 @@ "labelWidth": 7, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 4 }, { "id": "b.1.x.v", - "type": "page", + "type": "rectangle", "pos": { - "x": 47, - "y": 850 + "x": 184, + "y": 112 }, "width": 53, "height": 66, @@ -409,15 +287,15 @@ "labelWidth": 8, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 4 }, { "id": "b.1.x.w", - "type": "page", + "type": "rectangle", "pos": { - "x": 45, - "y": 986 + "x": 257, + "y": 112 }, "width": 57, "height": 66, @@ -450,15 +328,15 @@ "labelWidth": 12, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 4 }, { "id": "b.1.y", - "type": "page", + "type": "rectangle", "pos": { - "x": 47, - "y": 1122 + "x": 384, + "y": 112 }, "width": 53, "height": 66, @@ -491,15 +369,15 @@ "labelWidth": 8, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, "level": 3 }, { "id": "b.1.z", - "type": "page", + "type": "rectangle", "pos": { - "x": 48, - "y": 1258 + "x": 457, + "y": 112 }, "width": 52, "height": 66, @@ -532,18 +410,141 @@ "labelWidth": 7, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 5, + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.x", + "type": "rectangle", + "pos": { + "x": 187, + "y": 348 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.y", + "type": "rectangle", + "pos": { + "x": 259, + "y": 348 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.z", + "type": "rectangle", + "pos": { + "x": 332, + "y": 348 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, "level": 3 }, { "id": "a", "type": "rectangle", "pos": { - "x": 379, - "y": -506 + "x": 652, + "y": -406 }, - "width": 345, - "height": 498, + "width": 245, + "height": 398, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -580,10 +581,10 @@ "id": "a.1", "type": "rectangle", "pos": { - "x": 439, - "y": -446 + "x": 712, + "y": -346 }, - "width": 225, + "width": 125, "height": 66, "opacity": 1, "strokeDash": 0, @@ -621,10 +622,10 @@ "id": "a.2", "type": "rectangle", "pos": { - "x": 439, - "y": -340 + "x": 712, + "y": -240 }, - "width": 225, + "width": 125, "height": 66, "opacity": 1, "strokeDash": 0, @@ -662,11 +663,11 @@ "id": "a.3", "type": "sequence_diagram", "pos": { - "x": 439, - "y": -234 + "x": 712, + "y": -134 }, - "width": 225, - "height": 166, + "width": 125, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 0, @@ -695,7 +696,7 @@ "underline": false, "labelWidth": 11, "labelHeight": 31, - "labelPosition": "INSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, @@ -703,8 +704,8 @@ "id": "a.3.x", "type": "rectangle", "pos": { - "x": 489, - "y": -184 + "x": 712, + "y": -134 }, "width": 52, "height": 66, @@ -744,8 +745,8 @@ "id": "a.3.y", "type": "rectangle", "pos": { - "x": 561, - "y": -184 + "x": 784, + "y": -134 }, "width": 53, "height": 66, @@ -808,94 +809,18 @@ "labelPercentage": 0, "route": [ { - "x": 74, - "y": 236 + "x": 285.5, + "y": 278 }, { - "x": 224, - "y": 236 + "x": 285.5, + "y": 348 } ], "animated": false, "tooltip": "", "icon": null, - "zIndex": 4 - }, - { - "id": "(b.1 -- )[0]", - "src": "b.1", - "srcArrow": "none", - "dst": "1-lifeline-end-1719232319", - "dstArrow": "none", - "opacity": 1, - "strokeDash": 6, - "strokeWidth": 2, - "stroke": "B2", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 74, - "y": 166 - }, - { - "x": 74, - "y": 1394 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 1 - }, - { - "id": "(b.2 -- )[0]", - "src": "b.2", - "srcArrow": "none", - "dst": "2-lifeline-end-1739547740", - "dstArrow": "none", - "opacity": 1, - "strokeDash": 6, - "strokeWidth": 2, - "stroke": "B2", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 224, - "y": 166 - }, - { - "x": 224, - "y": 1394 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 1 + "zIndex": 0 } ], "root": { diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg index 7979d68d6..0bc4e994d 100644 --- a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -bca12123xy xyzyzuvw - - - - - - - - - - - - - - - - - - - + .d2-1680302338 .fill-N1{fill:#0A0F25;} + .d2-1680302338 .fill-N2{fill:#676C7E;} + .d2-1680302338 .fill-N3{fill:#9499AB;} + .d2-1680302338 .fill-N4{fill:#CFD2DD;} + .d2-1680302338 .fill-N5{fill:#DEE1EB;} + .d2-1680302338 .fill-N6{fill:#EEF1F8;} + .d2-1680302338 .fill-N7{fill:#FFFFFF;} + .d2-1680302338 .fill-B1{fill:#0D32B2;} + .d2-1680302338 .fill-B2{fill:#0D32B2;} + .d2-1680302338 .fill-B3{fill:#E3E9FD;} + .d2-1680302338 .fill-B4{fill:#E3E9FD;} + .d2-1680302338 .fill-B5{fill:#EDF0FD;} + .d2-1680302338 .fill-B6{fill:#F7F8FE;} + .d2-1680302338 .fill-AA2{fill:#4A6FF3;} + .d2-1680302338 .fill-AA4{fill:#EDF0FD;} + .d2-1680302338 .fill-AA5{fill:#F7F8FE;} + .d2-1680302338 .fill-AB4{fill:#EDF0FD;} + .d2-1680302338 .fill-AB5{fill:#F7F8FE;} + .d2-1680302338 .stroke-N1{stroke:#0A0F25;} + .d2-1680302338 .stroke-N2{stroke:#676C7E;} + .d2-1680302338 .stroke-N3{stroke:#9499AB;} + .d2-1680302338 .stroke-N4{stroke:#CFD2DD;} + .d2-1680302338 .stroke-N5{stroke:#DEE1EB;} + .d2-1680302338 .stroke-N6{stroke:#EEF1F8;} + .d2-1680302338 .stroke-N7{stroke:#FFFFFF;} + .d2-1680302338 .stroke-B1{stroke:#0D32B2;} + .d2-1680302338 .stroke-B2{stroke:#0D32B2;} + .d2-1680302338 .stroke-B3{stroke:#E3E9FD;} + .d2-1680302338 .stroke-B4{stroke:#E3E9FD;} + .d2-1680302338 .stroke-B5{stroke:#EDF0FD;} + .d2-1680302338 .stroke-B6{stroke:#F7F8FE;} + .d2-1680302338 .stroke-AA2{stroke:#4A6FF3;} + .d2-1680302338 .stroke-AA4{stroke:#EDF0FD;} + .d2-1680302338 .stroke-AA5{stroke:#F7F8FE;} + .d2-1680302338 .stroke-AB4{stroke:#EDF0FD;} + .d2-1680302338 .stroke-AB5{stroke:#F7F8FE;} + .d2-1680302338 .background-color-N1{background-color:#0A0F25;} + .d2-1680302338 .background-color-N2{background-color:#676C7E;} + .d2-1680302338 .background-color-N3{background-color:#9499AB;} + .d2-1680302338 .background-color-N4{background-color:#CFD2DD;} + .d2-1680302338 .background-color-N5{background-color:#DEE1EB;} + .d2-1680302338 .background-color-N6{background-color:#EEF1F8;} + .d2-1680302338 .background-color-N7{background-color:#FFFFFF;} + .d2-1680302338 .background-color-B1{background-color:#0D32B2;} + .d2-1680302338 .background-color-B2{background-color:#0D32B2;} + .d2-1680302338 .background-color-B3{background-color:#E3E9FD;} + .d2-1680302338 .background-color-B4{background-color:#E3E9FD;} + .d2-1680302338 .background-color-B5{background-color:#EDF0FD;} + .d2-1680302338 .background-color-B6{background-color:#F7F8FE;} + .d2-1680302338 .background-color-AA2{background-color:#4A6FF3;} + .d2-1680302338 .background-color-AA4{background-color:#EDF0FD;} + .d2-1680302338 .background-color-AA5{background-color:#F7F8FE;} + .d2-1680302338 .background-color-AB4{background-color:#EDF0FD;} + .d2-1680302338 .background-color-AB5{background-color:#F7F8FE;} + .d2-1680302338 .color-N1{color:#0A0F25;} + .d2-1680302338 .color-N2{color:#676C7E;} + .d2-1680302338 .color-N3{color:#9499AB;} + .d2-1680302338 .color-N4{color:#CFD2DD;} + .d2-1680302338 .color-N5{color:#DEE1EB;} + .d2-1680302338 .color-N6{color:#EEF1F8;} + .d2-1680302338 .color-N7{color:#FFFFFF;} + .d2-1680302338 .color-B1{color:#0D32B2;} + .d2-1680302338 .color-B2{color:#0D32B2;} + .d2-1680302338 .color-B3{color:#E3E9FD;} + .d2-1680302338 .color-B4{color:#E3E9FD;} + .d2-1680302338 .color-B5{color:#EDF0FD;} + .d2-1680302338 .color-B6{color:#F7F8FE;} + .d2-1680302338 .color-AA2{color:#4A6FF3;} + .d2-1680302338 .color-AA4{color:#EDF0FD;} + .d2-1680302338 .color-AA5{color:#F7F8FE;} + .d2-1680302338 .color-AB4{color:#EDF0FD;} + .d2-1680302338 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>bca12123xyzxyzxyuvw + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 37351436a44b02ebb1689a36b896628fe48711a8 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 18 Sep 2023 16:41:46 -0700 Subject: [PATCH 10/35] wip --- d2layouts/d2layouts.go | 3 +- .../testdata/files/nested_diagram_types.d2 | 67 ++++++++++--------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index a3001cf4f..8ef99f12e 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -171,7 +171,7 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { func ExtractSelf(container *d2graph.Object) *d2graph.Graph { nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) - 1 - // nestedGraph.Root.Box = &geo.Box{} + nestedGraph.Root.Box = &geo.Box{} // separate out nested edges g := container.Graph @@ -217,6 +217,7 @@ func ExtractSelf(container *d2graph.Object) *d2graph.Graph { func ExtractDescendants(container *d2graph.Object) *d2graph.Graph { nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) + nestedGraph.Root.Attributes = container.Attributes nestedGraph.Root.Box = &geo.Box{} // separate out nested edges diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 index 701a8ff53..3333025ff 100644 --- a/e2etests/testdata/files/nested_diagram_types.d2 +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -1,47 +1,48 @@ a -b -c +# b +# c a: { grid-rows: 3 1 2 - 3: { - shape: sequence_diagram - x - y - # TODO x -> y - } + 3 + # 3: { + # shape: sequence_diagram + # x + # y + # # TODO x -> y + # } near: top-right } -b: { - shape: sequence_diagram - 1 -> 2 +# b: { +# shape: sequence_diagram +# 1 -> 2 - # TODO This should work - near: bottom-right - # +# # TODO This should work +# near: bottom-right +# # - 2: { - # TODO compile error grid on sequence actor - # grid-rows: 3 - x - y - z - } +# 2: { +# # TODO compile error grid on sequence actor +# # grid-rows: 3 +# x +# y +# z +# } - 1: { - x: { - # TODO compile error grid in sequence (anywhere) - # grid-rows: 3 - u - v - w - } - y - z - } -} +# 1: { +# x: { +# # TODO compile error grid in sequence (anywhere) +# # grid-rows: 3 +# u +# v +# w +# } +# y +# z +# } +# } From e253ab80bb248dcaff39c3e7adc7223d7b1960d3 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 18 Sep 2023 17:20:59 -0700 Subject: [PATCH 11/35] wip --- d2layouts/d2grid/layout.go | 1 - d2layouts/d2layouts.go | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 853a691e7..e85811f10 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -201,7 +201,6 @@ func Layout2(ctx context.Context, g *d2graph.Graph) error { obj.TopLeft.X+float64(horizontalPadding), obj.TopLeft.Y+float64(verticalPadding), ) - gd.cleanup(obj, g) return nil } diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 8ef99f12e..be9f281f7 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -72,8 +72,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co if gi.IsConstantNear { nearGraph = ExtractSelf(child) child.TopLeft = geo.NewPoint(0, 0) - child.Width = nestedGraph.Root.Width - child.Width = nestedGraph.Root.Height } // if gi.IsConstantNear { @@ -282,7 +280,7 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { } func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { - // _, _ := boundingBox(nestedGraph) + // tl, _ := boundingBox(nestedGraph) // Note: assumes nestedGraph's layout has contents positioned relative to 0,0 dx := container.TopLeft.X //- tl.X dy := container.TopLeft.Y //- tl.Y From 96254b56ed663899ed3f064c2b07c8081fc08dc7 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 18 Sep 2023 19:59:13 -0700 Subject: [PATCH 12/35] fix --- d2layouts/d2layouts.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index be9f281f7..f96e234c0 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -274,9 +274,10 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { g.Objects = append(g.Objects, nestedGraph.Objects...) g.Edges = append(g.Edges, nestedGraph.Edges...) - if g.Root.LabelPosition != nil { - container.LabelPosition = g.Root.LabelPosition + if nestedGraph.Root.LabelPosition != nil { + container.LabelPosition = nestedGraph.Root.LabelPosition } + container.Attributes = nestedGraph.Root.Attributes } func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { From bff1e0b06626db4977835691e95f6529de9d8af2 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 18 Sep 2023 20:12:50 -0700 Subject: [PATCH 13/35] cleanup --- d2layouts/d2layouts.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index f96e234c0..09dd0dde4 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -44,14 +44,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // Iterate top-down from Root so all nested diagrams can process their own contents queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) - if graphInfo.IsConstantNear { - near := g.Root.ChildrenArray[0] - if len(near.Children) > 0 { - queue = append(queue, near.ChildrenArray...) - } - } else { - queue = append(queue, g.Root.ChildrenArray...) - } + queue = append(queue, g.Root.ChildrenArray...) for _, child := range queue { if gi := NestedGraphInfo(child); !gi.isDefault() { From 6600a97f671a5e6573d4d87696b284c943083a61 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 18 Sep 2023 20:14:12 -0700 Subject: [PATCH 14/35] save test --- .../testdata/files/nested_diagram_types.d2 | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 index 3333025ff..7435a7776 100644 --- a/e2etests/testdata/files/nested_diagram_types.d2 +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -1,48 +1,50 @@ a -# b -# c +b +c a: { - grid-rows: 3 + grid-columns: 3 1 2 3 - # 3: { - # shape: sequence_diagram - # x - # y - # # TODO x -> y - # } + 3: { + shape: sequence_diagram + x + y + # TODO x -> y + } - near: top-right + 1 -> 2 -> 3 + + near: center-right } -# b: { -# shape: sequence_diagram -# 1 -> 2 +b: { + shape: sequence_diagram + 1 -> 2 -# # TODO This should work -# near: bottom-right -# # + # # TODO This should work + # near: bottom-right + # # -# 2: { -# # TODO compile error grid on sequence actor -# # grid-rows: 3 -# x -# y -# z -# } + # 2: { + # # TODO compile error grid on sequence actor + # # grid-rows: 3 + # x + # y + # z + # } -# 1: { -# x: { -# # TODO compile error grid in sequence (anywhere) -# # grid-rows: 3 -# u -# v -# w -# } -# y -# z -# } -# } + # 1: { + # x: { + # # TODO compile error grid in sequence (anywhere) + # # grid-rows: 3 + # u + # v + # w + # } + # y + # z + # } +} From cbf81c23f382638040f058bc904eb721b06f805c Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 13:24:12 -0700 Subject: [PATCH 15/35] update test --- .../testdata/files/nested_diagram_types.d2 | 40 +- .../nested_diagram_types/dagre/board.exp.json | 1138 ++++++++++------- .../nested_diagram_types/dagre/sketch.exp.svg | 197 ++- .../nested_diagram_types/elk/board.exp.json | 1129 +++++++++------- .../nested_diagram_types/elk/sketch.exp.svg | 197 ++- 5 files changed, 1571 insertions(+), 1130 deletions(-) diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 index 7435a7776..61dbfcdf9 100644 --- a/e2etests/testdata/files/nested_diagram_types.d2 +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -24,27 +24,25 @@ b: { shape: sequence_diagram 1 -> 2 - # # TODO This should work - # near: bottom-right - # # + near: bottom-right - # 2: { - # # TODO compile error grid on sequence actor - # # grid-rows: 3 - # x - # y - # z - # } + 2: { + # TODO compile error grid on sequence actor? + grid-columns: 3 + x + y + z + } - # 1: { - # x: { - # # TODO compile error grid in sequence (anywhere) - # # grid-rows: 3 - # u - # v - # w - # } - # y - # z - # } + 1: { + x: { + # TODO compile error grid in sequence (group) + grid-columns: 3 + u + v + w + } + y + z + } } diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json index 678409ed9..01a2851cd 100644 --- a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json @@ -3,53 +3,12 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "b", - "type": "sequence_diagram", - "pos": { - "x": 0, - "y": 0 - }, - "width": 699, - "height": 393, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 0, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "c", "type": "rectangle", "pos": { - "x": 759, - "y": 164 + "x": 0, + "y": 0 }, "width": 53, "height": 66, @@ -86,14 +45,96 @@ "level": 1 }, { - "id": "b.1", + "id": "a", "type": "rectangle", "pos": { - "x": 0, - "y": 0 + "x": 73, + "y": -142 }, - "width": 617, - "height": 187, + "width": 579, + "height": 351, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "sequence_diagram", + "pos": { + "x": 73, + "y": 228 + }, + "width": 521, + "height": 1106, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.1", + "type": "rectangle", + "pos": { + "x": 133, + "y": -82 + }, + "width": 52, + "height": 231, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -118,23 +159,23 @@ "language": "", "color": "N1", "italic": false, - "bold": false, + "bold": true, "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "OUTSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, { - "id": "b.2", + "id": "a.2", "type": "rectangle", "pos": { - "x": 422, - "y": 327 + "x": 225, + "y": -82 }, - "width": 277, - "height": 66, + "width": 53, + "height": 231, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -159,7 +200,7 @@ "language": "", "color": "N1", "italic": false, - "bold": false, + "bold": true, "underline": false, "labelWidth": 8, "labelHeight": 21, @@ -168,19 +209,60 @@ "level": 2 }, { - "id": "b.1.x", + "id": "a.3", + "type": "sequence_diagram", + "pos": { + "x": 318, + "y": -82 + }, + "width": 274, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "3", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3.x", "type": "rectangle", "pos": { - "x": 30, - "y": 31 + "x": 330, + "y": 0 }, - "width": 342, - "height": 126, + "width": 100, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B4", + "fill": "N7", "stroke": "B1", "shadow": false, "3d": false, @@ -204,141 +286,18 @@ "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "OUTSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 3 }, { - "id": "b.1.x.u", + "id": "a.3.y", "type": "rectangle", "pos": { - "x": 60, - "y": 61 + "x": 480, + "y": 0 }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "u", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - }, - { - "id": "b.1.x.v", - "type": "rectangle", - "pos": { - "x": 172, - "y": 61 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "v", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - }, - { - "id": "b.1.x.w", - "type": "rectangle", - "pos": { - "x": 285, - "y": 61 - }, - "width": 57, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "w", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - }, - { - "id": "b.1.y", - "type": "rectangle", - "pos": { - "x": 534, - "y": 61 - }, - "width": 53, + "width": 100, "height": 66, "opacity": 1, "strokeDash": 0, @@ -373,11 +332,297 @@ "level": 3 }, { - "id": "b.1.z", + "id": "b.1", "type": "rectangle", "pos": { - "x": 422, - "y": 61 + "x": 85, + "y": 436 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2", + "type": "rectangle", + "pos": { + "x": 225, + "y": 316 + }, + "width": 357, + "height": 186, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.1.x", + "type": "rectangle", + "pos": { + "x": 129, + "y": 632 + }, + "width": 12, + "height": 358, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "zIndex": 2, + "level": 3 + }, + { + "id": "b.1.x.u", + "type": "page", + "pos": { + "x": 109, + "y": 642 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.v", + "type": "page", + "pos": { + "x": 108, + "y": 778 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "v", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.w", + "type": "page", + "pos": { + "x": 106, + "y": 914 + }, + "width": 57, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "w", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.y", + "type": "page", + "pos": { + "x": 108, + "y": 1050 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.z", + "type": "page", + "pos": { + "x": 109, + "y": 1186 }, "width": 52, "height": 66, @@ -410,15 +655,15 @@ "labelWidth": 7, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, + "zIndex": 5, "level": 3 }, { "id": "b.2.x", "type": "rectangle", "pos": { - "x": 422, - "y": 327 + "x": 285, + "y": 376 }, "width": 52, "height": 66, @@ -458,8 +703,8 @@ "id": "b.2.y", "type": "rectangle", "pos": { - "x": 534, - "y": 327 + "x": 377, + "y": 376 }, "width": 53, "height": 66, @@ -499,8 +744,8 @@ "id": "b.2.z", "type": "rectangle", "pos": { - "x": 647, - "y": 327 + "x": 470, + "y": 376 }, "width": 52, "height": 66, @@ -535,255 +780,161 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 3 - }, - { - "id": "a", - "type": "rectangle", - "pos": { - "x": 832, - "y": -444 - }, - "width": 285, - "height": 398, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.1", - "type": "rectangle", - "pos": { - "x": 892, - "y": -384 - }, - "width": 165, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "1", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.2", - "type": "rectangle", - "pos": { - "x": 892, - "y": -278 - }, - "width": 165, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "2", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.3", - "type": "sequence_diagram", - "pos": { - "x": 892, - "y": -172 - }, - "width": 165, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 0, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "3", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 11, - "labelHeight": 31, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.3.x", - "type": "rectangle", - "pos": { - "x": 892, - "y": -172 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "x", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "a.3.y", - "type": "rectangle", - "pos": { - "x": 1004, - "y": -172 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "y", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 } ], "connections": [ + { + "id": "a.(1 -> 2)[0]", + "src": "a.1", + "srcArrow": "none", + "dst": "a.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 184.5, + "y": 33 + }, + { + "x": 225.5, + "y": 33 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(2 -> 3)[0]", + "src": "a.2", + "srcArrow": "none", + "dst": "a.3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 278, + "y": 33 + }, + { + "x": 318, + "y": 33 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a.3.x -- )[0]", + "src": "a.3.x", + "srcArrow": "none", + "dst": "x-lifeline-end-1678191278", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 380, + "y": 66.5 + }, + { + "x": 380, + "y": 136.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(a.3.y -- )[0]", + "src": "a.3.y", + "srcArrow": "none", + "dst": "y-lifeline-end-35261543", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 530, + "y": 66.5 + }, + { + "x": 530, + "y": 136.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, { "id": "b.(1 -> 2)[0]", "src": "b.1", @@ -809,27 +960,94 @@ "labelPercentage": 0, "route": [ { - "x": 560.5, - "y": 187 + "x": 135, + "y": 572.5 }, { - "x": 560.5, - "y": 259 - }, - { - "x": 560.5, - "y": 287 - }, - { - "x": 560.5, - "y": 327 + "x": 403.5, + "y": 572.5 } ], - "isCurve": true, "animated": false, "tooltip": "", "icon": null, - "zIndex": 0 + "zIndex": 4 + }, + { + "id": "(b.1 -- )[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "1-lifeline-end-1719232319", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 135, + "y": 502.5 + }, + { + "x": 135, + "y": 1322.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.2 -- )[0]", + "src": "b.2", + "srcArrow": "none", + "dst": "2-lifeline-end-1739547740", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 403.5, + "y": 502.5 + }, + { + "x": 403.5, + "y": 1322.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 } ], "root": { diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg index 10abb5e04..145aa8194 100644 --- a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -bca12123xyzxyzxyuvw - - - - - - - - - - - - - - - - - - - - + .d2-3076621705 .fill-N1{fill:#0A0F25;} + .d2-3076621705 .fill-N2{fill:#676C7E;} + .d2-3076621705 .fill-N3{fill:#9499AB;} + .d2-3076621705 .fill-N4{fill:#CFD2DD;} + .d2-3076621705 .fill-N5{fill:#DEE1EB;} + .d2-3076621705 .fill-N6{fill:#EEF1F8;} + .d2-3076621705 .fill-N7{fill:#FFFFFF;} + .d2-3076621705 .fill-B1{fill:#0D32B2;} + .d2-3076621705 .fill-B2{fill:#0D32B2;} + .d2-3076621705 .fill-B3{fill:#E3E9FD;} + .d2-3076621705 .fill-B4{fill:#E3E9FD;} + .d2-3076621705 .fill-B5{fill:#EDF0FD;} + .d2-3076621705 .fill-B6{fill:#F7F8FE;} + .d2-3076621705 .fill-AA2{fill:#4A6FF3;} + .d2-3076621705 .fill-AA4{fill:#EDF0FD;} + .d2-3076621705 .fill-AA5{fill:#F7F8FE;} + .d2-3076621705 .fill-AB4{fill:#EDF0FD;} + .d2-3076621705 .fill-AB5{fill:#F7F8FE;} + .d2-3076621705 .stroke-N1{stroke:#0A0F25;} + .d2-3076621705 .stroke-N2{stroke:#676C7E;} + .d2-3076621705 .stroke-N3{stroke:#9499AB;} + .d2-3076621705 .stroke-N4{stroke:#CFD2DD;} + .d2-3076621705 .stroke-N5{stroke:#DEE1EB;} + .d2-3076621705 .stroke-N6{stroke:#EEF1F8;} + .d2-3076621705 .stroke-N7{stroke:#FFFFFF;} + .d2-3076621705 .stroke-B1{stroke:#0D32B2;} + .d2-3076621705 .stroke-B2{stroke:#0D32B2;} + .d2-3076621705 .stroke-B3{stroke:#E3E9FD;} + .d2-3076621705 .stroke-B4{stroke:#E3E9FD;} + .d2-3076621705 .stroke-B5{stroke:#EDF0FD;} + .d2-3076621705 .stroke-B6{stroke:#F7F8FE;} + .d2-3076621705 .stroke-AA2{stroke:#4A6FF3;} + .d2-3076621705 .stroke-AA4{stroke:#EDF0FD;} + .d2-3076621705 .stroke-AA5{stroke:#F7F8FE;} + .d2-3076621705 .stroke-AB4{stroke:#EDF0FD;} + .d2-3076621705 .stroke-AB5{stroke:#F7F8FE;} + .d2-3076621705 .background-color-N1{background-color:#0A0F25;} + .d2-3076621705 .background-color-N2{background-color:#676C7E;} + .d2-3076621705 .background-color-N3{background-color:#9499AB;} + .d2-3076621705 .background-color-N4{background-color:#CFD2DD;} + .d2-3076621705 .background-color-N5{background-color:#DEE1EB;} + .d2-3076621705 .background-color-N6{background-color:#EEF1F8;} + .d2-3076621705 .background-color-N7{background-color:#FFFFFF;} + .d2-3076621705 .background-color-B1{background-color:#0D32B2;} + .d2-3076621705 .background-color-B2{background-color:#0D32B2;} + .d2-3076621705 .background-color-B3{background-color:#E3E9FD;} + .d2-3076621705 .background-color-B4{background-color:#E3E9FD;} + .d2-3076621705 .background-color-B5{background-color:#EDF0FD;} + .d2-3076621705 .background-color-B6{background-color:#F7F8FE;} + .d2-3076621705 .background-color-AA2{background-color:#4A6FF3;} + .d2-3076621705 .background-color-AA4{background-color:#EDF0FD;} + .d2-3076621705 .background-color-AA5{background-color:#F7F8FE;} + .d2-3076621705 .background-color-AB4{background-color:#EDF0FD;} + .d2-3076621705 .background-color-AB5{background-color:#F7F8FE;} + .d2-3076621705 .color-N1{color:#0A0F25;} + .d2-3076621705 .color-N2{color:#676C7E;} + .d2-3076621705 .color-N3{color:#9499AB;} + .d2-3076621705 .color-N4{color:#CFD2DD;} + .d2-3076621705 .color-N5{color:#DEE1EB;} + .d2-3076621705 .color-N6{color:#EEF1F8;} + .d2-3076621705 .color-N7{color:#FFFFFF;} + .d2-3076621705 .color-B1{color:#0D32B2;} + .d2-3076621705 .color-B2{color:#0D32B2;} + .d2-3076621705 .color-B3{color:#E3E9FD;} + .d2-3076621705 .color-B4{color:#E3E9FD;} + .d2-3076621705 .color-B5{color:#EDF0FD;} + .d2-3076621705 .color-B6{color:#F7F8FE;} + .d2-3076621705 .color-AA2{color:#4A6FF3;} + .d2-3076621705 .color-AA4{color:#EDF0FD;} + .d2-3076621705 .color-AA5{color:#F7F8FE;} + .d2-3076621705 .color-AB4{color:#EDF0FD;} + .d2-3076621705 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>cab12312xyxyz yzuvw + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json index 8f5124b95..723443863 100644 --- a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json +++ b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json @@ -3,53 +3,12 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "b", - "type": "sequence_diagram", - "pos": { - "x": 12, - "y": 12 - }, - "width": 547, - "height": 402, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 0, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "c", "type": "rectangle", "pos": { - "x": 579, - "y": 180 + "x": 12, + "y": 12 }, "width": 53, "height": 66, @@ -86,14 +45,96 @@ "level": 1 }, { - "id": "b.1", + "id": "a", "type": "rectangle", "pos": { - "x": 12, - "y": 12 + "x": 85, + "y": -130 }, - "width": 547, - "height": 266, + "width": 579, + "height": 351, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "sequence_diagram", + "pos": { + "x": 85, + "y": 240 + }, + "width": 521, + "height": 1106, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.1", + "type": "rectangle", + "pos": { + "x": 145, + "y": -70 + }, + "width": 52, + "height": 231, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -118,23 +159,23 @@ "language": "", "color": "N1", "italic": false, - "bold": false, + "bold": true, "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "INSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, { - "id": "b.2", + "id": "a.2", "type": "rectangle", "pos": { - "x": 187, - "y": 348 + "x": 237, + "y": -70 }, - "width": 197, - "height": 66, + "width": 53, + "height": 231, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -159,7 +200,7 @@ "language": "", "color": "N1", "italic": false, - "bold": false, + "bold": true, "underline": false, "labelWidth": 8, "labelHeight": 21, @@ -168,19 +209,60 @@ "level": 2 }, { - "id": "b.1.x", + "id": "a.3", + "type": "sequence_diagram", + "pos": { + "x": 330, + "y": -70 + }, + "width": 274, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "3", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3.x", "type": "rectangle", "pos": { - "x": 62, - "y": 62 + "x": 342, + "y": 12 }, - "width": 302, - "height": 166, + "width": 100, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B4", + "fill": "N7", "stroke": "B1", "shadow": false, "3d": false, @@ -204,141 +286,18 @@ "underline": false, "labelWidth": 7, "labelHeight": 21, - "labelPosition": "INSIDE_TOP_CENTER", + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 3 }, { - "id": "b.1.x.u", + "id": "a.3.y", "type": "rectangle", "pos": { - "x": 112, - "y": 112 + "x": 492, + "y": 12 }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "u", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - }, - { - "id": "b.1.x.v", - "type": "rectangle", - "pos": { - "x": 184, - "y": 112 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "v", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - }, - { - "id": "b.1.x.w", - "type": "rectangle", - "pos": { - "x": 257, - "y": 112 - }, - "width": 57, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "w", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - }, - { - "id": "b.1.y", - "type": "rectangle", - "pos": { - "x": 384, - "y": 112 - }, - "width": 53, + "width": 100, "height": 66, "opacity": 1, "strokeDash": 0, @@ -373,11 +332,297 @@ "level": 3 }, { - "id": "b.1.z", + "id": "b.1", "type": "rectangle", "pos": { - "x": 457, - "y": 112 + "x": 97, + "y": 448 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2", + "type": "rectangle", + "pos": { + "x": 237, + "y": 328 + }, + "width": 357, + "height": 186, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.1.x", + "type": "rectangle", + "pos": { + "x": 141, + "y": 644 + }, + "width": 12, + "height": 358, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "zIndex": 2, + "level": 3 + }, + { + "id": "b.1.x.u", + "type": "page", + "pos": { + "x": 121, + "y": 654 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.v", + "type": "page", + "pos": { + "x": 120, + "y": 790 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "v", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.w", + "type": "page", + "pos": { + "x": 118, + "y": 926 + }, + "width": 57, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "w", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.y", + "type": "page", + "pos": { + "x": 120, + "y": 1062 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.z", + "type": "page", + "pos": { + "x": 121, + "y": 1198 }, "width": 52, "height": 66, @@ -410,15 +655,15 @@ "labelWidth": 7, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, + "zIndex": 5, "level": 3 }, { "id": "b.2.x", "type": "rectangle", "pos": { - "x": 187, - "y": 348 + "x": 297, + "y": 388 }, "width": 52, "height": 66, @@ -458,8 +703,8 @@ "id": "b.2.y", "type": "rectangle", "pos": { - "x": 259, - "y": 348 + "x": 389, + "y": 388 }, "width": 53, "height": 66, @@ -499,8 +744,8 @@ "id": "b.2.z", "type": "rectangle", "pos": { - "x": 332, - "y": 348 + "x": 482, + "y": 388 }, "width": 52, "height": 66, @@ -535,255 +780,161 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 3 - }, - { - "id": "a", - "type": "rectangle", - "pos": { - "x": 652, - "y": -406 - }, - "width": 245, - "height": 398, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.1", - "type": "rectangle", - "pos": { - "x": 712, - "y": -346 - }, - "width": 125, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "1", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.2", - "type": "rectangle", - "pos": { - "x": 712, - "y": -240 - }, - "width": 125, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "2", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.3", - "type": "sequence_diagram", - "pos": { - "x": 712, - "y": -134 - }, - "width": 125, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 0, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "3", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 11, - "labelHeight": 31, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.3.x", - "type": "rectangle", - "pos": { - "x": 712, - "y": -134 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "x", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "a.3.y", - "type": "rectangle", - "pos": { - "x": 784, - "y": -134 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "y", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 } ], "connections": [ + { + "id": "a.(1 -> 2)[0]", + "src": "a.1", + "srcArrow": "none", + "dst": "a.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 196.5, + "y": 45 + }, + { + "x": 237.5, + "y": 45 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(2 -> 3)[0]", + "src": "a.2", + "srcArrow": "none", + "dst": "a.3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 290, + "y": 45 + }, + { + "x": 330, + "y": 45 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a.3.x -- )[0]", + "src": "a.3.x", + "srcArrow": "none", + "dst": "x-lifeline-end-1678191278", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 392, + "y": 78.5 + }, + { + "x": 392, + "y": 148.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(a.3.y -- )[0]", + "src": "a.3.y", + "srcArrow": "none", + "dst": "y-lifeline-end-35261543", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 542, + "y": 78.5 + }, + { + "x": 542, + "y": 148.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, { "id": "b.(1 -> 2)[0]", "src": "b.1", @@ -809,18 +960,94 @@ "labelPercentage": 0, "route": [ { - "x": 285.5, - "y": 278 + "x": 147, + "y": 584.5 }, { - "x": 285.5, - "y": 348 + "x": 415.5, + "y": 584.5 } ], "animated": false, "tooltip": "", "icon": null, - "zIndex": 0 + "zIndex": 4 + }, + { + "id": "(b.1 -- )[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "1-lifeline-end-1719232319", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 147, + "y": 514.5 + }, + { + "x": 147, + "y": 1334.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.2 -- )[0]", + "src": "b.2", + "srcArrow": "none", + "dst": "2-lifeline-end-1739547740", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 415.5, + "y": 514.5 + }, + { + "x": 415.5, + "y": 1334.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 } ], "root": { diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg index 0bc4e994d..93df04694 100644 --- a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -bca12123xyzxyzxyuvw - - - - - - - - - - - - - - - - - - - - + .d2-1319705341 .fill-N1{fill:#0A0F25;} + .d2-1319705341 .fill-N2{fill:#676C7E;} + .d2-1319705341 .fill-N3{fill:#9499AB;} + .d2-1319705341 .fill-N4{fill:#CFD2DD;} + .d2-1319705341 .fill-N5{fill:#DEE1EB;} + .d2-1319705341 .fill-N6{fill:#EEF1F8;} + .d2-1319705341 .fill-N7{fill:#FFFFFF;} + .d2-1319705341 .fill-B1{fill:#0D32B2;} + .d2-1319705341 .fill-B2{fill:#0D32B2;} + .d2-1319705341 .fill-B3{fill:#E3E9FD;} + .d2-1319705341 .fill-B4{fill:#E3E9FD;} + .d2-1319705341 .fill-B5{fill:#EDF0FD;} + .d2-1319705341 .fill-B6{fill:#F7F8FE;} + .d2-1319705341 .fill-AA2{fill:#4A6FF3;} + .d2-1319705341 .fill-AA4{fill:#EDF0FD;} + .d2-1319705341 .fill-AA5{fill:#F7F8FE;} + .d2-1319705341 .fill-AB4{fill:#EDF0FD;} + .d2-1319705341 .fill-AB5{fill:#F7F8FE;} + .d2-1319705341 .stroke-N1{stroke:#0A0F25;} + .d2-1319705341 .stroke-N2{stroke:#676C7E;} + .d2-1319705341 .stroke-N3{stroke:#9499AB;} + .d2-1319705341 .stroke-N4{stroke:#CFD2DD;} + .d2-1319705341 .stroke-N5{stroke:#DEE1EB;} + .d2-1319705341 .stroke-N6{stroke:#EEF1F8;} + .d2-1319705341 .stroke-N7{stroke:#FFFFFF;} + .d2-1319705341 .stroke-B1{stroke:#0D32B2;} + .d2-1319705341 .stroke-B2{stroke:#0D32B2;} + .d2-1319705341 .stroke-B3{stroke:#E3E9FD;} + .d2-1319705341 .stroke-B4{stroke:#E3E9FD;} + .d2-1319705341 .stroke-B5{stroke:#EDF0FD;} + .d2-1319705341 .stroke-B6{stroke:#F7F8FE;} + .d2-1319705341 .stroke-AA2{stroke:#4A6FF3;} + .d2-1319705341 .stroke-AA4{stroke:#EDF0FD;} + .d2-1319705341 .stroke-AA5{stroke:#F7F8FE;} + .d2-1319705341 .stroke-AB4{stroke:#EDF0FD;} + .d2-1319705341 .stroke-AB5{stroke:#F7F8FE;} + .d2-1319705341 .background-color-N1{background-color:#0A0F25;} + .d2-1319705341 .background-color-N2{background-color:#676C7E;} + .d2-1319705341 .background-color-N3{background-color:#9499AB;} + .d2-1319705341 .background-color-N4{background-color:#CFD2DD;} + .d2-1319705341 .background-color-N5{background-color:#DEE1EB;} + .d2-1319705341 .background-color-N6{background-color:#EEF1F8;} + .d2-1319705341 .background-color-N7{background-color:#FFFFFF;} + .d2-1319705341 .background-color-B1{background-color:#0D32B2;} + .d2-1319705341 .background-color-B2{background-color:#0D32B2;} + .d2-1319705341 .background-color-B3{background-color:#E3E9FD;} + .d2-1319705341 .background-color-B4{background-color:#E3E9FD;} + .d2-1319705341 .background-color-B5{background-color:#EDF0FD;} + .d2-1319705341 .background-color-B6{background-color:#F7F8FE;} + .d2-1319705341 .background-color-AA2{background-color:#4A6FF3;} + .d2-1319705341 .background-color-AA4{background-color:#EDF0FD;} + .d2-1319705341 .background-color-AA5{background-color:#F7F8FE;} + .d2-1319705341 .background-color-AB4{background-color:#EDF0FD;} + .d2-1319705341 .background-color-AB5{background-color:#F7F8FE;} + .d2-1319705341 .color-N1{color:#0A0F25;} + .d2-1319705341 .color-N2{color:#676C7E;} + .d2-1319705341 .color-N3{color:#9499AB;} + .d2-1319705341 .color-N4{color:#CFD2DD;} + .d2-1319705341 .color-N5{color:#DEE1EB;} + .d2-1319705341 .color-N6{color:#EEF1F8;} + .d2-1319705341 .color-N7{color:#FFFFFF;} + .d2-1319705341 .color-B1{color:#0D32B2;} + .d2-1319705341 .color-B2{color:#0D32B2;} + .d2-1319705341 .color-B3{color:#E3E9FD;} + .d2-1319705341 .color-B4{color:#E3E9FD;} + .d2-1319705341 .color-B5{color:#EDF0FD;} + .d2-1319705341 .color-B6{color:#F7F8FE;} + .d2-1319705341 .color-AA2{color:#4A6FF3;} + .d2-1319705341 .color-AA4{color:#EDF0FD;} + .d2-1319705341 .color-AA5{color:#F7F8FE;} + .d2-1319705341 .color-AB4{color:#EDF0FD;} + .d2-1319705341 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>cab12312xyxyz yzuvw + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 2cb2b406e68bf967f4bfcb29b2e5835b778b8df1 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 13:54:41 -0700 Subject: [PATCH 16/35] cleanup --- d2layouts/d2layouts.go | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 09dd0dde4..a1508fdc9 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -34,6 +34,7 @@ func (gi GraphInfo) isDefault() bool { } func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { + g.Root.Box = &geo.Box{} log.Warn(ctx, "ln info", slog.F("gi", graphInfo)) // Before we can layout these nodes, we need to handle all nested diagrams first. @@ -49,7 +50,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co for _, child := range queue { if gi := NestedGraphInfo(child); !gi.isDefault() { extractedInfo[child] = gi - // log.Warn(ctx, "nested", slog.F("child", child.AbsID()), slog.F("gi", gi)) // There is a nested diagram here, so extract its contents and process in the same way nestedGraph := ExtractDescendants(child) @@ -61,24 +61,15 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // Fit child to size of nested layout FitToGraph(child, nestedGraph, spacing) - var nearGraph *d2graph.Graph + // for constant nears, we also extract the child after extracting descendants + // main layout is run, then near positions child, then descendants are injected with all others if gi.IsConstantNear { - nearGraph = ExtractSelf(child) + nearGraph := ExtractSelf(child) child.TopLeft = geo.NewPoint(0, 0) - } - - // if gi.IsConstantNear { - // // FitToGraph(child, nestedGraph, spacing) - // if nestedGraph.Root.Box != nil { - // child.Width = nestedGraph.Root.Width - // child.Height = nestedGraph.Root.Height - // } - // } - - // We will restore the contents after running layout with child as the placeholder - if gi.IsConstantNear { constantNears = append(constantNears, nearGraph) } + + // We will restore the contents after running layout with child as the placeholder extracted[child] = nestedGraph } else if len(child.Children) > 0 { queue = append(queue, child.ChildrenArray...) @@ -90,13 +81,9 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co LayoutDiagram := func(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { spacing := geo.Spacing{} var err error - // TODO - switch graphInfo.DiagramType { case GridDiagram: log.Warn(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) - // layoutWithGrids := d2grid.Layout2(ctx, g, coreLayout) - // layoutWithGrids(ctx, g) if err = d2grid.Layout2(ctx, g); err != nil { panic(err) } @@ -118,7 +105,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } spacing := LayoutDiagram(ctx, g, graphInfo, coreLayout) - // if there are if len(constantNears) > 0 { err := d2near.Layout(ctx, g, constantNears) if err != nil { @@ -128,10 +114,8 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // With the layout set, inject all the extracted graphs for n, nestedGraph := range extracted { - // if !extractedInfo[n].IsConstantNear { InjectNested(n, nestedGraph) PositionNested(n, nestedGraph) - // } } log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel)) From 4385e63eddd1b78c8b28888b8cb36cd81fa81f14 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 14:16:07 -0700 Subject: [PATCH 17/35] fix containers in grid layout --- d2layouts/d2layouts.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index a1508fdc9..92eb3c4de 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -48,14 +48,18 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co queue = append(queue, g.Root.ChildrenArray...) for _, child := range queue { - if gi := NestedGraphInfo(child); !gi.isDefault() { + isGridCellContainer := (graphInfo.DiagramType == GridDiagram && child.IsContainer()) + gi := NestedGraphInfo(child) + // if we are in a grid diagram, and our children have descendants + // we need to run layout on them first, even if they are not special diagram types + if isGridCellContainer || !gi.isDefault() { extractedInfo[child] = gi // There is a nested diagram here, so extract its contents and process in the same way nestedGraph := ExtractDescendants(child) // Layout of nestedGraph is completed - // log.Error(ctx, "recurse", slog.F("child", child.AbsID()), slog.F("level", child.Level())) + log.Info(ctx, "layout nested", slog.F("level", child.Level()), slog.F("child", child.AbsID())) spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout) log.Warn(ctx, "fitting child", slog.F("child", child.AbsID())) // Fit child to size of nested layout @@ -65,9 +69,9 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // main layout is run, then near positions child, then descendants are injected with all others if gi.IsConstantNear { nearGraph := ExtractSelf(child) - child.TopLeft = geo.NewPoint(0, 0) constantNears = append(constantNears, nearGraph) } + child.TopLeft = geo.NewPoint(0, 0) // We will restore the contents after running layout with child as the placeholder extracted[child] = nestedGraph From 1c8df051b993df5f525fb5a17d16b681b76148a2 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 15:22:47 -0700 Subject: [PATCH 18/35] refactor, fix --- d2layouts/d2layouts.go | 160 +++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 78 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 92eb3c4de..5c7fbd242 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -47,38 +47,62 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) queue = append(queue, g.Root.ChildrenArray...) - for _, child := range queue { - isGridCellContainer := (graphInfo.DiagramType == GridDiagram && child.IsContainer()) - gi := NestedGraphInfo(child) + for _, curr := range queue { + isGridCellContainer := graphInfo.DiagramType == GridDiagram && + curr.IsContainer() && curr.Parent == g.Root + gi := NestedGraphInfo(curr) // if we are in a grid diagram, and our children have descendants // we need to run layout on them first, even if they are not special diagram types - if isGridCellContainer || !gi.isDefault() { - extractedInfo[child] = gi + + // !! + // when we have a constant near or a grid cell that is a container, + // we want to extract it as nested graph, not just its descendants, + // run layout, then re-inject it + // !! + + if isGridCellContainer { + nestedGraph := ExtractSubgraph(curr, true) + LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) + InjectNested(g.Root, nestedGraph, false) + dx := -curr.TopLeft.X + dy := -curr.TopLeft.Y + for _, o := range nestedGraph.Objects { + o.TopLeft.X += dx + o.TopLeft.Y += dy + } + for _, e := range nestedGraph.Edges { + e.Move(dx, dy) + } + + } else if !gi.isDefault() { + extractedInfo[curr] = gi // There is a nested diagram here, so extract its contents and process in the same way - nestedGraph := ExtractDescendants(child) + log.Warn(ctx, "extract descendants", slog.F("child", curr.AbsID())) + nestedGraph := ExtractSubgraph(curr, false) // Layout of nestedGraph is completed - log.Info(ctx, "layout nested", slog.F("level", child.Level()), slog.F("child", child.AbsID())) + log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID())) spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout) - log.Warn(ctx, "fitting child", slog.F("child", child.AbsID())) + log.Warn(ctx, "fitting child", slog.F("child", curr.AbsID())) // Fit child to size of nested layout - FitToGraph(child, nestedGraph, spacing) + FitToGraph(curr, nestedGraph, spacing) // for constant nears, we also extract the child after extracting descendants // main layout is run, then near positions child, then descendants are injected with all others if gi.IsConstantNear { - nearGraph := ExtractSelf(child) + nearGraph := ExtractSubgraph(curr, true) constantNears = append(constantNears, nearGraph) } - child.TopLeft = geo.NewPoint(0, 0) + curr.TopLeft = geo.NewPoint(0, 0) // We will restore the contents after running layout with child as the placeholder - extracted[child] = nestedGraph - } else if len(child.Children) > 0 { - queue = append(queue, child.ChildrenArray...) + extracted[curr] = nestedGraph + } else if len(curr.Children) > 0 { + queue = append(queue, curr.ChildrenArray...) } } + log.Warn(ctx, "finished descendants", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) // We can now run layout with accurate sizes of nested layout containers // Layout according to the type of diagram @@ -118,7 +142,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // With the layout set, inject all the extracted graphs for n, nestedGraph := range extracted { - InjectNested(n, nestedGraph) + InjectNested(n, nestedGraph, true) PositionNested(n, nestedGraph) } @@ -147,63 +171,27 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { return gi } -func ExtractSelf(container *d2graph.Object) *d2graph.Graph { - nestedGraph := d2graph.NewGraph() - nestedGraph.RootLevel = int(container.Level()) - 1 - nestedGraph.Root.Box = &geo.Box{} - - // separate out nested edges - g := container.Graph - remainingEdges := make([]*d2graph.Edge, 0, len(g.Edges)) - for _, edge := range g.Edges { - if edge.Src.IsDescendantOf(container) && edge.Dst.IsDescendantOf(container) { - nestedGraph.Edges = append(nestedGraph.Edges, edge) - } else { - remainingEdges = append(remainingEdges, edge) - } - } - g.Edges = remainingEdges - - // separate out nested objects - remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) - for _, obj := range g.Objects { - if obj.IsDescendantOf(container) { - nestedGraph.Objects = append(nestedGraph.Objects, obj) - } else { - remainingObjects = append(remainingObjects, obj) - } - } - g.Objects = remainingObjects - - // update object and new root references - for _, o := range nestedGraph.Objects { - o.Graph = nestedGraph - } - - // remove container parent's references - if container.Parent != nil { - container.Parent.RemoveChild(container) - } - - // set root references - nestedGraph.Root.ChildrenArray = []*d2graph.Object{container} - container.Parent = nestedGraph.Root - nestedGraph.Root.Children[strings.ToLower(container.ID)] = container - - return nestedGraph -} - -func ExtractDescendants(container *d2graph.Object) *d2graph.Graph { +func ExtractSubgraph(container *d2graph.Object, includeSelf bool) *d2graph.Graph { nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) + if includeSelf { + nestedGraph.RootLevel-- + } nestedGraph.Root.Attributes = container.Attributes nestedGraph.Root.Box = &geo.Box{} + isNestedObject := func(obj *d2graph.Object) bool { + if includeSelf { + return obj.IsDescendantOf(container) + } + return obj.Parent.IsDescendantOf(container) + } + // separate out nested edges g := container.Graph remainingEdges := make([]*d2graph.Edge, 0, len(g.Edges)) for _, edge := range g.Edges { - if edge.Src.Parent.IsDescendantOf(container) && edge.Dst.Parent.IsDescendantOf(container) { + if isNestedObject(edge.Src) && isNestedObject(edge.Dst) { nestedGraph.Edges = append(nestedGraph.Edges, edge) } else { remainingEdges = append(remainingEdges, edge) @@ -214,7 +202,7 @@ func ExtractDescendants(container *d2graph.Object) *d2graph.Graph { // separate out nested objects remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) for _, obj := range g.Objects { - if obj.Parent.IsDescendantOf(container) { + if isNestedObject(obj) { nestedGraph.Objects = append(nestedGraph.Objects, obj) } else { remainingObjects = append(remainingObjects, obj) @@ -226,23 +214,37 @@ func ExtractDescendants(container *d2graph.Object) *d2graph.Graph { for _, o := range nestedGraph.Objects { o.Graph = nestedGraph } - // set root references - nestedGraph.Root.ChildrenArray = append(nestedGraph.Root.ChildrenArray, container.ChildrenArray...) - for _, child := range container.ChildrenArray { - child.Parent = nestedGraph.Root - nestedGraph.Root.Children[strings.ToLower(child.ID)] = child - } - // remove container's references - for k := range container.Children { - delete(container.Children, k) + if includeSelf { + // remove container parent's references + if container.Parent != nil { + container.Parent.RemoveChild(container) + } + + // set root references + nestedGraph.Root.ChildrenArray = []*d2graph.Object{container} + container.Parent = nestedGraph.Root + nestedGraph.Root.Children[strings.ToLower(container.ID)] = container + } else { + // set root references + nestedGraph.Root.ChildrenArray = append(nestedGraph.Root.ChildrenArray, container.ChildrenArray...) + for _, child := range container.ChildrenArray { + child.Parent = nestedGraph.Root + nestedGraph.Root.Children[strings.ToLower(child.ID)] = child + } + + // remove container's references + for k := range container.Children { + delete(container.Children, k) + } + container.ChildrenArray = nil } - container.ChildrenArray = nil return nestedGraph } -func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { +func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph, isRoot bool) { + // TODO restore order of objects g := container.Graph for _, obj := range nestedGraph.Root.ChildrenArray { obj.Parent = container @@ -255,10 +257,12 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { g.Objects = append(g.Objects, nestedGraph.Objects...) g.Edges = append(g.Edges, nestedGraph.Edges...) - if nestedGraph.Root.LabelPosition != nil { - container.LabelPosition = nestedGraph.Root.LabelPosition + if isRoot { + if nestedGraph.Root.LabelPosition != nil { + container.LabelPosition = nestedGraph.Root.LabelPosition + } + container.Attributes = nestedGraph.Root.Attributes } - container.Attributes = nestedGraph.Root.Attributes } func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { From 0fbc921248cec6541274d1d463dc83b3a69fa4fa Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 16:18:39 -0700 Subject: [PATCH 19/35] fix extracting near subgraphs --- d2layouts/d2layouts.go | 56 +++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 5c7fbd242..b9ede64ad 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -36,7 +36,7 @@ func (gi GraphInfo) isDefault() bool { func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { g.Root.Box = &geo.Box{} - log.Warn(ctx, "ln info", slog.F("gi", graphInfo)) + log.Warn(ctx, "ln info", slog.F("gi", graphInfo), slog.F("root level", g.RootLevel)) // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) extractedInfo := make(map[*d2graph.Object]GraphInfo) @@ -54,12 +54,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // if we are in a grid diagram, and our children have descendants // we need to run layout on them first, even if they are not special diagram types - // !! - // when we have a constant near or a grid cell that is a container, - // we want to extract it as nested graph, not just its descendants, - // run layout, then re-inject it - // !! - if isGridCellContainer { nestedGraph := ExtractSubgraph(curr, true) LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) @@ -78,26 +72,33 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co extractedInfo[curr] = gi // There is a nested diagram here, so extract its contents and process in the same way - log.Warn(ctx, "extract descendants", slog.F("child", curr.AbsID())) - nestedGraph := ExtractSubgraph(curr, false) + nestedGraph := ExtractSubgraph(curr, gi.IsConstantNear) - // Layout of nestedGraph is completed log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID())) - spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout) - log.Warn(ctx, "fitting child", slog.F("child", curr.AbsID())) - // Fit child to size of nested layout - FitToGraph(curr, nestedGraph, spacing) - - // for constant nears, we also extract the child after extracting descendants - // main layout is run, then near positions child, then descendants are injected with all others + nestedInfo := gi + nearKey := curr.NearKey if gi.IsConstantNear { - nearGraph := ExtractSubgraph(curr, true) - constantNears = append(constantNears, nearGraph) + // layout nested as a non-near + nestedInfo = GraphInfo{} + curr.NearKey = nil } - curr.TopLeft = geo.NewPoint(0, 0) - // We will restore the contents after running layout with child as the placeholder - extracted[curr] = nestedGraph + spacing := LayoutNested(ctx, nestedGraph, nestedInfo, coreLayout) + + if gi.IsConstantNear { + curr.NearKey = nearKey + } else { + FitToGraph(curr, nestedGraph, spacing) + curr.TopLeft = geo.NewPoint(0, 0) + } + + if gi.IsConstantNear { + // near layout will inject these nestedGraphs + constantNears = append(constantNears, nestedGraph) + } else { + // We will restore the contents after running layout with child as the placeholder + extracted[curr] = nestedGraph + } } else if len(curr.Children) > 0 { queue = append(queue, curr.ChildrenArray...) } @@ -150,19 +151,10 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co return spacing } -// TODO multiple types at same (e.g. constant nears with grid at root level) -// e.g. constant nears with sequence diagram at root level func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { if obj.Graph.RootLevel == 0 && obj.IsConstantNear() { gi.IsConstantNear = true } - // if obj.Graph.RootLevel == -1 { - // for _, obj := range obj.Graph.Root.ChildrenArray { - // if obj.IsConstantNear() { - // return ConstantNearGraph - // } - // } - // } if obj.IsSequenceDiagram() { gi.DiagramType = SequenceDiagram } else if obj.IsGridDiagram() { @@ -172,6 +164,8 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { } func ExtractSubgraph(container *d2graph.Object, includeSelf bool) *d2graph.Graph { + // includeSelf: when we have a constant near or a grid cell that is a container, + // we want to include itself in the nested graph, not just its descendants, nestedGraph := d2graph.NewGraph() nestedGraph.RootLevel = int(container.Level()) if includeSelf { From 538d6920c804071e61a65f043fbecbefd6059552 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 16:20:25 -0700 Subject: [PATCH 20/35] icon position --- d2layouts/d2layouts.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index b9ede64ad..6b2d1fc7a 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -255,6 +255,9 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph, isRoot if nestedGraph.Root.LabelPosition != nil { container.LabelPosition = nestedGraph.Root.LabelPosition } + if nestedGraph.Root.IconPosition != nil { + container.IconPosition = nestedGraph.Root.IconPosition + } container.Attributes = nestedGraph.Root.Attributes } } From 6d39f96a7354859e07b611550ef849ff8cab54d1 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 16:33:32 -0700 Subject: [PATCH 21/35] fix empty grid --- d2layouts/d2layouts.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 6b2d1fc7a..8385d83db 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -67,8 +67,12 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co for _, e := range nestedGraph.Edges { e.Move(dx, dy) } - } else if !gi.isDefault() { + // empty grid can have 0 objects.. + if gi.DiagramType == GridDiagram && !gi.IsConstantNear && len(curr.Children) == 0 { + continue + } + extractedInfo[curr] = gi // There is a nested diagram here, so extract its contents and process in the same way From 596cd5ed065d71cd0ce8e2c5c614bb1c1a9fa14e Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 17:19:43 -0700 Subject: [PATCH 22/35] maintain order --- d2layouts/d2layouts.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 8385d83db..4cfa19018 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -3,6 +3,7 @@ package d2layouts import ( "context" "math" + "sort" "strings" "cdr.dev/slog" @@ -33,6 +34,39 @@ func (gi GraphInfo) isDefault() bool { return !gi.IsConstantNear && gi.DiagramType == DefaultGraphType } +func SaveChildrenOrder(container *d2graph.Object) (restoreOrder func()) { + objectOrder := make(map[string]int, len(container.ChildrenArray)) + for i, obj := range container.ChildrenArray { + objectOrder[obj.AbsID()] = i + } + return func() { + sort.SliceStable(container.ChildrenArray, func(i, j int) bool { + return objectOrder[container.ChildrenArray[i].AbsID()] < objectOrder[container.ChildrenArray[j].AbsID()] + }) + } +} + +func SaveOrder(g *d2graph.Graph) (restoreOrder func()) { + objectOrder := make(map[string]int, len(g.Objects)) + for i, obj := range g.Objects { + objectOrder[obj.AbsID()] = i + } + edgeOrder := make(map[string]int, len(g.Edges)) + for i, edge := range g.Edges { + edgeOrder[edge.AbsID()] = i + } + restoreRootOrder := SaveChildrenOrder(g.Root) + return func() { + sort.SliceStable(g.Objects, func(i, j int) bool { + return objectOrder[g.Objects[i].AbsID()] < objectOrder[g.Objects[j].AbsID()] + }) + sort.SliceStable(g.Edges, func(i, j int) bool { + return edgeOrder[g.Edges[i].AbsID()] < edgeOrder[g.Edges[j].AbsID()] + }) + restoreRootOrder() + } +} + func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { g.Root.Box = &geo.Box{} @@ -42,6 +76,8 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co extractedInfo := make(map[*d2graph.Object]GraphInfo) var constantNears []*d2graph.Graph + restoreOrder := SaveOrder(g) + defer restoreOrder() // Iterate top-down from Root so all nested diagrams can process their own contents queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) @@ -58,6 +94,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co nestedGraph := ExtractSubgraph(curr, true) LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) InjectNested(g.Root, nestedGraph, false) + restoreOrder() dx := -curr.TopLeft.X dy := -curr.TopLeft.Y for _, o := range nestedGraph.Objects { From a5dec20dd4294d5df066df411ea215b1746c212a Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 17:27:22 -0700 Subject: [PATCH 23/35] fix queue --- d2layouts/d2layouts.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 4cfa19018..3ad59b8db 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -7,6 +7,7 @@ import ( "strings" "cdr.dev/slog" + "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2grid" "oss.terrastruct.com/d2/d2layouts/d2near" @@ -83,7 +84,10 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) queue = append(queue, g.Root.ChildrenArray...) - for _, curr := range queue { + for len(queue) > 0 { + curr := queue[0] + queue = queue[1:] + isGridCellContainer := graphInfo.DiagramType == GridDiagram && curr.IsContainer() && curr.Parent == g.Root gi := NestedGraphInfo(curr) @@ -140,11 +144,10 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // We will restore the contents after running layout with child as the placeholder extracted[curr] = nestedGraph } - } else if len(curr.Children) > 0 { + } else if len(curr.ChildrenArray) > 0 { queue = append(queue, curr.ChildrenArray...) } } - log.Warn(ctx, "finished descendants", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) // We can now run layout with accurate sizes of nested layout containers // Layout according to the type of diagram From 593bea69824e78eefebba2cc1437ff25084d6bc0 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 17:45:52 -0700 Subject: [PATCH 24/35] fix root grid shift --- d2layouts/d2grid/layout.go | 26 ++++++++++++++------------ d2layouts/d2layouts.go | 5 ++++- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index e85811f10..565f3b15c 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -188,19 +188,21 @@ func Layout2(ctx context.Context, g *d2graph.Graph) error { obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING - if obj.GridGap != nil || obj.HorizontalGap != nil { - horizontalPadding = gd.horizontalGap - } - if obj.GridGap != nil || obj.VerticalGap != nil { - verticalPadding = gd.verticalGap - } + if g.RootLevel > 0 { + horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING + if obj.GridGap != nil || obj.HorizontalGap != nil { + horizontalPadding = gd.horizontalGap + } + if obj.GridGap != nil || obj.VerticalGap != nil { + verticalPadding = gd.verticalGap + } - // shift the grid from (0, 0) - gd.shift( - obj.TopLeft.X+float64(horizontalPadding), - obj.TopLeft.Y+float64(verticalPadding), - ) + // shift the grid from (0, 0) + gd.shift( + obj.TopLeft.X+float64(horizontalPadding), + obj.TopLeft.Y+float64(verticalPadding), + ) + } return nil } diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 3ad59b8db..fba3187b1 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -108,7 +108,10 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co for _, e := range nestedGraph.Edges { e.Move(dx, dy) } - } else if !gi.isDefault() { + continue + } + + if !gi.isDefault() { // empty grid can have 0 objects.. if gi.DiagramType == GridDiagram && !gi.IsConstantNear && len(curr.Children) == 0 { continue From 8bb1e3c4737f2bddbd5104b62de80e3c9d2b8fc9 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 17:58:55 -0700 Subject: [PATCH 25/35] error handling --- d2layouts/d2layouts.go | 29 +++++++++++++++++------------ d2lib/d2.go | 5 ++++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index fba3187b1..9887dff81 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -68,7 +68,7 @@ func SaveOrder(g *d2graph.Graph) (restoreOrder func()) { } } -func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { +func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) error { g.Root.Box = &geo.Box{} log.Warn(ctx, "ln info", slog.F("gi", graphInfo), slog.F("root level", g.RootLevel)) @@ -96,7 +96,10 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co if isGridCellContainer { nestedGraph := ExtractSubgraph(curr, true) - LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) + err := LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) + if err != nil { + return err + } InjectNested(g.Root, nestedGraph, false) restoreOrder() dx := -curr.TopLeft.X @@ -131,12 +134,15 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co curr.NearKey = nil } - spacing := LayoutNested(ctx, nestedGraph, nestedInfo, coreLayout) + err := LayoutNested(ctx, nestedGraph, nestedInfo, coreLayout) + if err != nil { + return err + } if gi.IsConstantNear { curr.NearKey = nearKey } else { - FitToGraph(curr, nestedGraph, spacing) + FitToGraph(curr, nestedGraph, geo.Spacing{}) curr.TopLeft = geo.NewPoint(0, 0) } @@ -154,32 +160,31 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // We can now run layout with accurate sizes of nested layout containers // Layout according to the type of diagram - LayoutDiagram := func(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { - spacing := geo.Spacing{} + LayoutDiagram := func(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) error { var err error switch graphInfo.DiagramType { case GridDiagram: log.Warn(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) if err = d2grid.Layout2(ctx, g); err != nil { - panic(err) + return err } case SequenceDiagram: log.Warn(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) err = d2sequence.Layout2(ctx, g, coreLayout) if err != nil { - panic(err) + return err } default: log.Warn(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) err := coreLayout(ctx, g) if err != nil { - panic(err) + return err } } - return spacing + return nil } - spacing := LayoutDiagram(ctx, g, graphInfo, coreLayout) + err := LayoutDiagram(ctx, g, graphInfo, coreLayout) if len(constantNears) > 0 { err := d2near.Layout(ctx, g, constantNears) @@ -195,7 +200,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel)) - return spacing + return err } func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { diff --git a/d2lib/d2.go b/d2lib/d2.go index 88fcd643e..f08538f61 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -86,7 +86,10 @@ func compile(ctx context.Context, g *d2graph.Graph, compileOpts *CompileOptions, } graphInfo := d2layouts.NestedGraphInfo(g.Root) - d2layouts.LayoutNested(ctx, g, graphInfo, coreLayout) + err = d2layouts.LayoutNested(ctx, g, graphInfo, coreLayout) + if err != nil { + return nil, err + } if false { constantNearGraphs := d2near.WithoutConstantNears(ctx, g) From 8ea2d968214de4f1758bf6af6c8fdc5b61b83433 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 18:10:51 -0700 Subject: [PATCH 26/35] fix order of added sequence edges --- d2layouts/d2layouts.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 9887dff81..3f08756a1 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -62,7 +62,12 @@ func SaveOrder(g *d2graph.Graph) (restoreOrder func()) { return objectOrder[g.Objects[i].AbsID()] < objectOrder[g.Objects[j].AbsID()] }) sort.SliceStable(g.Edges, func(i, j int) bool { - return edgeOrder[g.Edges[i].AbsID()] < edgeOrder[g.Edges[j].AbsID()] + iIndex, iHas := edgeOrder[g.Edges[i].AbsID()] + jIndex, jHas := edgeOrder[g.Edges[j].AbsID()] + if iHas && jHas { + return iIndex < jIndex + } + return iHas }) restoreRootOrder() } From d6a543219c965eedb623aef73292f5aa82fe803f Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 18:22:19 -0700 Subject: [PATCH 27/35] empty sequence --- d2layouts/d2layouts.go | 44 ++---------------------------------------- 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 3f08756a1..a5783cf0e 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -120,8 +120,8 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } if !gi.isDefault() { - // empty grid can have 0 objects.. - if gi.DiagramType == GridDiagram && !gi.IsConstantNear && len(curr.Children) == 0 { + // empty grid or sequence can have 0 objects.. + if !gi.IsConstantNear && len(curr.Children) == 0 { continue } @@ -355,7 +355,6 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding geo.Spacing) { var width, height float64 - // if nestedGraph.Root.Box != nil { width = nestedGraph.Root.Width height = nestedGraph.Root.Height if width == 0 || height == 0 { @@ -366,42 +365,3 @@ func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding g container.Width = padding.Left + width + padding.Right container.Height = padding.Top + height + padding.Bottom } - -// func LayoutDiagram(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing { -// spacing := geo.Spacing{} -// var err error -// // TODO - -// // Need subgraphs? - -// // if graphInfo.IsConstantNear -// // case ConstantNearGraph: -// // // constantNearGraphs := d2near.WithoutConstantNears(ctx, g) -// // constantNearGraphs := d2near.WithoutConstantNears(ctx, g) - -// // err = d2near.Layout(ctx, g, constantNearGraphs) -// // if err != nil { -// // panic(err) -// // } - -// switch graphInfo.DiagramType { -// case GridDiagram: -// layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) -// if err = layoutWithGrids(ctx, g); err != nil { -// panic(err) -// } - -// case SequenceDiagram: -// err = d2sequence.Layout(ctx, g, coreLayout) -// if err != nil { -// panic(err) -// } -// default: -// err := coreLayout(ctx, g) -// if err != nil { -// panic(err) -// } -// } - -// return spacing -// } From 1baac617117772d5eee63d2b6b2171ec45e4102b Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 18:37:47 -0700 Subject: [PATCH 28/35] fix multiple sequence diagram inject order --- d2layouts/d2layouts.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index a5783cf0e..cfdea0ce2 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -79,7 +79,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co log.Warn(ctx, "ln info", slog.F("gi", graphInfo), slog.F("root level", g.RootLevel)) // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) - extractedInfo := make(map[*d2graph.Object]GraphInfo) + var extractedOrder []*d2graph.Object var constantNears []*d2graph.Graph restoreOrder := SaveOrder(g) @@ -125,8 +125,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co continue } - extractedInfo[curr] = gi - // There is a nested diagram here, so extract its contents and process in the same way nestedGraph := ExtractSubgraph(curr, gi.IsConstantNear) @@ -157,6 +155,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } else { // We will restore the contents after running layout with child as the placeholder extracted[curr] = nestedGraph + extractedOrder = append(extractedOrder, curr) } } else if len(curr.ChildrenArray) > 0 { queue = append(queue, curr.ChildrenArray...) @@ -199,7 +198,8 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co } // With the layout set, inject all the extracted graphs - for n, nestedGraph := range extracted { + for _, n := range extractedOrder { + nestedGraph := extracted[n] InjectNested(n, nestedGraph, true) PositionNested(n, nestedGraph) } From d1700e4e6fe74ae06e130b565abd9da7f51aab5a Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 20:07:19 -0700 Subject: [PATCH 29/35] fixed constant nears order --- .../testdata/root-fill/sketch.exp.svg | 558 ++++++------ .../testdata/TestCLI_E2E/animation.exp.svg | 186 ++-- .../TestCLI_E2E/vars-animation.exp.svg | 186 ++-- .../dagre/board.exp.json | 164 ++-- .../dagre/sketch.exp.svg | 160 ++-- .../elk/board.exp.json | 164 ++-- .../elk/sketch.exp.svg | 160 ++-- .../unconnected/dagre/board.exp.json | 80 +- .../unconnected/dagre/sketch.exp.svg | 558 ++++++------ .../regression/unconnected/elk/board.exp.json | 80 +- .../regression/unconnected/elk/sketch.exp.svg | 558 ++++++------ .../constant_near_stress/dagre/board.exp.json | 80 +- .../constant_near_stress/dagre/sketch.exp.svg | 558 ++++++------ .../constant_near_stress/elk/board.exp.json | 80 +- .../constant_near_stress/elk/sketch.exp.svg | 558 ++++++------ .../constant_near_title/dagre/board.exp.json | 80 +- .../constant_near_title/dagre/sketch.exp.svg | 558 ++++++------ .../constant_near_title/elk/board.exp.json | 80 +- .../constant_near_title/elk/sketch.exp.svg | 558 ++++++------ .../dagre/board.exp.json | 844 +++++++++--------- .../dagre/sketch.exp.svg | 172 ++-- .../elk/board.exp.json | 808 ++++++++--------- .../elk/sketch.exp.svg | 172 ++-- 23 files changed, 3701 insertions(+), 3701 deletions(-) diff --git a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg index 477f27ce8..8b87d6a30 100644 --- a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg @@ -1,20 +1,20 @@ - @@ -844,20 +844,20 @@ -OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseFlow-I (Warehousing, Installation)MasterRegional-1Regional-2Regional-N

company Warehouse

+Flow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseMasterRegional-1Regional-2Regional-N

company Warehouse

  • Asset Tagging
  • Inventory
  • Staging
  • Dispatch to Site
-
+
+ - diff --git a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg index f6216f287..4b287519e 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg @@ -1,16 +1,16 @@ Chicken's plan +}]]>Chicken's plan -Approach roadChicken's plan +Chicken's planApproach road - -Approach roadCross roadChicken's plan + +Chicken's planApproach roadCross road + - -Approach roadCross roadMake you wonder whyChicken's plan +Chicken's planApproach roadCross roadMake you wonder why + - \ No newline at end of file diff --git a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg index 8ec9e5a88..a38d833e5 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg @@ -1,16 +1,16 @@ CHICKEN'S PLAN +}]]>CHICKEN'S PLAN -APPROACH ROADCHICKEN'S PLAN +CHICKEN'S PLANAPPROACH ROAD - -APPROACH ROADCROSS ROADCHICKEN'S PLAN + +CHICKEN'S PLANAPPROACH ROADCROSS ROAD + - -APPROACH ROADCROSS ROADMAKE YOU WONDER WHYCHICKEN'S PLAN +CHICKEN'S PLANAPPROACH ROADCROSS ROADMAKE YOU WONDER WHY + - \ No newline at end of file diff --git a/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json b/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json index d20cfdc39..d6231ed4b 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json +++ b/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json @@ -3,47 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 0, - "y": 0 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "a", "type": "rectangle", @@ -85,6 +44,88 @@ "zIndex": 0, "level": 1 }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 73, + "y": 318 + }, + "width": 139, + "height": 292, + "opacity": 0.5, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "green", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "a.1", "type": "rectangle", @@ -208,47 +249,6 @@ "zIndex": 0, "level": 2 }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 73, - "y": 318 - }, - "width": 139, - "height": 292, - "opacity": 0.5, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "green", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "b.1111", "type": "rectangle", diff --git a/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg b/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg index 310f04aac..59453e7ae 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -cab12311112222 + .d2-114303792 .fill-N1{fill:#0A0F25;} + .d2-114303792 .fill-N2{fill:#676C7E;} + .d2-114303792 .fill-N3{fill:#9499AB;} + .d2-114303792 .fill-N4{fill:#CFD2DD;} + .d2-114303792 .fill-N5{fill:#DEE1EB;} + .d2-114303792 .fill-N6{fill:#EEF1F8;} + .d2-114303792 .fill-N7{fill:#FFFFFF;} + .d2-114303792 .fill-B1{fill:#0D32B2;} + .d2-114303792 .fill-B2{fill:#0D32B2;} + .d2-114303792 .fill-B3{fill:#E3E9FD;} + .d2-114303792 .fill-B4{fill:#E3E9FD;} + .d2-114303792 .fill-B5{fill:#EDF0FD;} + .d2-114303792 .fill-B6{fill:#F7F8FE;} + .d2-114303792 .fill-AA2{fill:#4A6FF3;} + .d2-114303792 .fill-AA4{fill:#EDF0FD;} + .d2-114303792 .fill-AA5{fill:#F7F8FE;} + .d2-114303792 .fill-AB4{fill:#EDF0FD;} + .d2-114303792 .fill-AB5{fill:#F7F8FE;} + .d2-114303792 .stroke-N1{stroke:#0A0F25;} + .d2-114303792 .stroke-N2{stroke:#676C7E;} + .d2-114303792 .stroke-N3{stroke:#9499AB;} + .d2-114303792 .stroke-N4{stroke:#CFD2DD;} + .d2-114303792 .stroke-N5{stroke:#DEE1EB;} + .d2-114303792 .stroke-N6{stroke:#EEF1F8;} + .d2-114303792 .stroke-N7{stroke:#FFFFFF;} + .d2-114303792 .stroke-B1{stroke:#0D32B2;} + .d2-114303792 .stroke-B2{stroke:#0D32B2;} + .d2-114303792 .stroke-B3{stroke:#E3E9FD;} + .d2-114303792 .stroke-B4{stroke:#E3E9FD;} + .d2-114303792 .stroke-B5{stroke:#EDF0FD;} + .d2-114303792 .stroke-B6{stroke:#F7F8FE;} + .d2-114303792 .stroke-AA2{stroke:#4A6FF3;} + .d2-114303792 .stroke-AA4{stroke:#EDF0FD;} + .d2-114303792 .stroke-AA5{stroke:#F7F8FE;} + .d2-114303792 .stroke-AB4{stroke:#EDF0FD;} + .d2-114303792 .stroke-AB5{stroke:#F7F8FE;} + .d2-114303792 .background-color-N1{background-color:#0A0F25;} + .d2-114303792 .background-color-N2{background-color:#676C7E;} + .d2-114303792 .background-color-N3{background-color:#9499AB;} + .d2-114303792 .background-color-N4{background-color:#CFD2DD;} + .d2-114303792 .background-color-N5{background-color:#DEE1EB;} + .d2-114303792 .background-color-N6{background-color:#EEF1F8;} + .d2-114303792 .background-color-N7{background-color:#FFFFFF;} + .d2-114303792 .background-color-B1{background-color:#0D32B2;} + .d2-114303792 .background-color-B2{background-color:#0D32B2;} + .d2-114303792 .background-color-B3{background-color:#E3E9FD;} + .d2-114303792 .background-color-B4{background-color:#E3E9FD;} + .d2-114303792 .background-color-B5{background-color:#EDF0FD;} + .d2-114303792 .background-color-B6{background-color:#F7F8FE;} + .d2-114303792 .background-color-AA2{background-color:#4A6FF3;} + .d2-114303792 .background-color-AA4{background-color:#EDF0FD;} + .d2-114303792 .background-color-AA5{background-color:#F7F8FE;} + .d2-114303792 .background-color-AB4{background-color:#EDF0FD;} + .d2-114303792 .background-color-AB5{background-color:#F7F8FE;} + .d2-114303792 .color-N1{color:#0A0F25;} + .d2-114303792 .color-N2{color:#676C7E;} + .d2-114303792 .color-N3{color:#9499AB;} + .d2-114303792 .color-N4{color:#CFD2DD;} + .d2-114303792 .color-N5{color:#DEE1EB;} + .d2-114303792 .color-N6{color:#EEF1F8;} + .d2-114303792 .color-N7{color:#FFFFFF;} + .d2-114303792 .color-B1{color:#0D32B2;} + .d2-114303792 .color-B2{color:#0D32B2;} + .d2-114303792 .color-B3{color:#E3E9FD;} + .d2-114303792 .color-B4{color:#E3E9FD;} + .d2-114303792 .color-B5{color:#EDF0FD;} + .d2-114303792 .color-B6{color:#F7F8FE;} + .d2-114303792 .color-AA2{color:#4A6FF3;} + .d2-114303792 .color-AA4{color:#EDF0FD;} + .d2-114303792 .color-AA5{color:#F7F8FE;} + .d2-114303792 .color-AB4{color:#EDF0FD;} + .d2-114303792 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>abc12311112222 - + diff --git a/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json b/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json index d80cd5430..2ce891239 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json +++ b/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json @@ -3,47 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 12, - "y": 12 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "a", "type": "rectangle", @@ -85,6 +44,88 @@ "zIndex": 0, "level": 1 }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 85, + "y": 284 + }, + "width": 179, + "height": 302, + "opacity": 0.5, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "green", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "a.1", "type": "rectangle", @@ -208,47 +249,6 @@ "zIndex": 0, "level": 2 }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 85, - "y": 284 - }, - "width": 179, - "height": 302, - "opacity": 0.5, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "green", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "b.1111", "type": "rectangle", diff --git a/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg b/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg index fa774803d..9f669ad5d 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -cab12311112222 + .d2-1840765879 .fill-N1{fill:#0A0F25;} + .d2-1840765879 .fill-N2{fill:#676C7E;} + .d2-1840765879 .fill-N3{fill:#9499AB;} + .d2-1840765879 .fill-N4{fill:#CFD2DD;} + .d2-1840765879 .fill-N5{fill:#DEE1EB;} + .d2-1840765879 .fill-N6{fill:#EEF1F8;} + .d2-1840765879 .fill-N7{fill:#FFFFFF;} + .d2-1840765879 .fill-B1{fill:#0D32B2;} + .d2-1840765879 .fill-B2{fill:#0D32B2;} + .d2-1840765879 .fill-B3{fill:#E3E9FD;} + .d2-1840765879 .fill-B4{fill:#E3E9FD;} + .d2-1840765879 .fill-B5{fill:#EDF0FD;} + .d2-1840765879 .fill-B6{fill:#F7F8FE;} + .d2-1840765879 .fill-AA2{fill:#4A6FF3;} + .d2-1840765879 .fill-AA4{fill:#EDF0FD;} + .d2-1840765879 .fill-AA5{fill:#F7F8FE;} + .d2-1840765879 .fill-AB4{fill:#EDF0FD;} + .d2-1840765879 .fill-AB5{fill:#F7F8FE;} + .d2-1840765879 .stroke-N1{stroke:#0A0F25;} + .d2-1840765879 .stroke-N2{stroke:#676C7E;} + .d2-1840765879 .stroke-N3{stroke:#9499AB;} + .d2-1840765879 .stroke-N4{stroke:#CFD2DD;} + .d2-1840765879 .stroke-N5{stroke:#DEE1EB;} + .d2-1840765879 .stroke-N6{stroke:#EEF1F8;} + .d2-1840765879 .stroke-N7{stroke:#FFFFFF;} + .d2-1840765879 .stroke-B1{stroke:#0D32B2;} + .d2-1840765879 .stroke-B2{stroke:#0D32B2;} + .d2-1840765879 .stroke-B3{stroke:#E3E9FD;} + .d2-1840765879 .stroke-B4{stroke:#E3E9FD;} + .d2-1840765879 .stroke-B5{stroke:#EDF0FD;} + .d2-1840765879 .stroke-B6{stroke:#F7F8FE;} + .d2-1840765879 .stroke-AA2{stroke:#4A6FF3;} + .d2-1840765879 .stroke-AA4{stroke:#EDF0FD;} + .d2-1840765879 .stroke-AA5{stroke:#F7F8FE;} + .d2-1840765879 .stroke-AB4{stroke:#EDF0FD;} + .d2-1840765879 .stroke-AB5{stroke:#F7F8FE;} + .d2-1840765879 .background-color-N1{background-color:#0A0F25;} + .d2-1840765879 .background-color-N2{background-color:#676C7E;} + .d2-1840765879 .background-color-N3{background-color:#9499AB;} + .d2-1840765879 .background-color-N4{background-color:#CFD2DD;} + .d2-1840765879 .background-color-N5{background-color:#DEE1EB;} + .d2-1840765879 .background-color-N6{background-color:#EEF1F8;} + .d2-1840765879 .background-color-N7{background-color:#FFFFFF;} + .d2-1840765879 .background-color-B1{background-color:#0D32B2;} + .d2-1840765879 .background-color-B2{background-color:#0D32B2;} + .d2-1840765879 .background-color-B3{background-color:#E3E9FD;} + .d2-1840765879 .background-color-B4{background-color:#E3E9FD;} + .d2-1840765879 .background-color-B5{background-color:#EDF0FD;} + .d2-1840765879 .background-color-B6{background-color:#F7F8FE;} + .d2-1840765879 .background-color-AA2{background-color:#4A6FF3;} + .d2-1840765879 .background-color-AA4{background-color:#EDF0FD;} + .d2-1840765879 .background-color-AA5{background-color:#F7F8FE;} + .d2-1840765879 .background-color-AB4{background-color:#EDF0FD;} + .d2-1840765879 .background-color-AB5{background-color:#F7F8FE;} + .d2-1840765879 .color-N1{color:#0A0F25;} + .d2-1840765879 .color-N2{color:#676C7E;} + .d2-1840765879 .color-N3{color:#9499AB;} + .d2-1840765879 .color-N4{color:#CFD2DD;} + .d2-1840765879 .color-N5{color:#DEE1EB;} + .d2-1840765879 .color-N6{color:#EEF1F8;} + .d2-1840765879 .color-N7{color:#FFFFFF;} + .d2-1840765879 .color-B1{color:#0D32B2;} + .d2-1840765879 .color-B2{color:#0D32B2;} + .d2-1840765879 .color-B3{color:#E3E9FD;} + .d2-1840765879 .color-B4{color:#E3E9FD;} + .d2-1840765879 .color-B5{color:#EDF0FD;} + .d2-1840765879 .color-B6{color:#F7F8FE;} + .d2-1840765879 .color-AA2{color:#4A6FF3;} + .d2-1840765879 .color-AA4{color:#EDF0FD;} + .d2-1840765879 .color-AA5{color:#F7F8FE;} + .d2-1840765879 .color-AB4{color:#EDF0FD;} + .d2-1840765879 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>abc12311112222 - + diff --git a/e2etests/testdata/regression/unconnected/dagre/board.exp.json b/e2etests/testdata/regression/unconnected/dagre/board.exp.json index c247f0d23..1ab1067fa 100644 --- a/e2etests/testdata/regression/unconnected/dagre/board.exp.json +++ b/e2etests/testdata/regression/unconnected/dagre/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 438, + "y": -56 + }, + "width": 639, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Workflow-I (Warehousing, Installation)", + "fontSize": 40, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 639, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "OEM Factory", "type": "rectangle", @@ -493,46 +533,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 438, - "y": -56 - }, - "width": 639, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "Workflow-I (Warehousing, Installation)", - "fontSize": 40, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 639, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg index 33754aad7..c861d0812 100644 --- a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteWorkflow-I (Warehousing, Installation)MasterRegional-1Regional-2Regional-N
    +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
    • Asset Tagging
    • Inventory
    • Staging
    • Dispatch to Site
    -
    InstallationSupport +
InstallationSupport + - diff --git a/e2etests/testdata/regression/unconnected/elk/board.exp.json b/e2etests/testdata/regression/unconnected/elk/board.exp.json index a30837f37..d45f7a548 100644 --- a/e2etests/testdata/regression/unconnected/elk/board.exp.json +++ b/e2etests/testdata/regression/unconnected/elk/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 482, + "y": -59 + }, + "width": 639, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Workflow-I (Warehousing, Installation)", + "fontSize": 40, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 639, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "OEM Factory", "type": "rectangle", @@ -493,46 +533,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 482, - "y": -59 - }, - "width": 639, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "Workflow-I (Warehousing, Installation)", - "fontSize": 40, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 639, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg index 17ae95cfa..a1101fced 100644 --- a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteWorkflow-I (Warehousing, Installation)MasterRegional-1Regional-2Regional-N
    +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
    • Asset Tagging
    • Inventory
    • Staging
    • Dispatch to Site
    -
    InstallationSupport +
InstallationSupport + - diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json b/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json index b81735f0e..b550af1dd 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json +++ b/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json @@ -125,46 +125,6 @@ "zIndex": 0, "level": 1 }, - { - "id": "bottom", - "type": "text", - "pos": { - "x": -431, - "y": 252 - }, - "width": 917, - "height": 131, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 917, - "labelHeight": 131, - "zIndex": 0, - "level": 1 - }, { "id": "Joe", "type": "person", @@ -247,6 +207,46 @@ "zIndex": 0, "level": 1 }, + { + "id": "bottom", + "type": "text", + "pos": { + "x": -431, + "y": 252 + }, + "width": 917, + "height": 131, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 917, + "labelHeight": 131, + "zIndex": 0, + "level": 1 + }, { "id": "i am top left", "type": "text", diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg index 78134855a..b7b35a9ba 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

+xyThe top of the mountainJoeDonald

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right +
i am top lefti am top righti am bottom lefti am bottom right - + diff --git a/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json b/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json index d393d9216..603b35fc4 100644 --- a/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json +++ b/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json @@ -125,46 +125,6 @@ "zIndex": 0, "level": 1 }, - { - "id": "bottom", - "type": "text", - "pos": { - "x": -419, - "y": 234 - }, - "width": 917, - "height": 131, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 917, - "labelHeight": 131, - "zIndex": 0, - "level": 1 - }, { "id": "Joe", "type": "person", @@ -247,6 +207,46 @@ "zIndex": 0, "level": 1 }, + { + "id": "bottom", + "type": "text", + "pos": { + "x": -419, + "y": 234 + }, + "width": 917, + "height": 131, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 917, + "labelHeight": 131, + "zIndex": 0, + "level": 1 + }, { "id": "i am top left", "type": "text", diff --git a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg index d85bffe5b..40fe40ab2 100644 --- a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

+xyThe top of the mountainJoeDonald

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right +
i am top lefti am top righti am bottom lefti am bottom right - + diff --git a/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json b/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json index ac0d6e0df..62e89f006 100644 --- a/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json +++ b/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 37, + "y": -71 + }, + "width": 257, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# A winning strategy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 257, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "poll the people", "type": "rectangle", @@ -207,46 +247,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 1 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 37, - "y": -71 - }, - "width": 257, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# A winning strategy", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 257, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg index 91cd0cab6..b3955e1c1 100644 --- a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -poll the peopleresultsunfavorablefavorablewill of the people

A winning strategy

-
+

A winning strategy

+
poll the peopleresultsunfavorablefavorablewill of the people + -
\ No newline at end of file diff --git a/e2etests/testdata/stable/constant_near_title/elk/board.exp.json b/e2etests/testdata/stable/constant_near_title/elk/board.exp.json index 56d22f7ee..1eb62f0b7 100644 --- a/e2etests/testdata/stable/constant_near_title/elk/board.exp.json +++ b/e2etests/testdata/stable/constant_near_title/elk/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 29, + "y": -59 + }, + "width": 257, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# A winning strategy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 257, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "poll the people", "type": "rectangle", @@ -207,46 +247,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 1 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 29, - "y": -59 - }, - "width": 257, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# A winning strategy", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 257, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg index 8d6e6ec78..275c532b1 100644 --- a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -poll the peopleresultsunfavorablefavorablewill of the people

A winning strategy

-
+

A winning strategy

+
poll the peopleresultsunfavorablefavorablewill of the people + -
\ No newline at end of file diff --git a/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json b/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json index 0b3b174cd..f0d9f8c63 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json +++ b/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json @@ -3,334 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "z", - "type": "rectangle", - "pos": { - "x": -113, - "y": 56 - }, - "width": 227, - "height": 292, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "z.a", - "type": "rectangle", - "pos": { - "x": -83, - "y": 86 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.b", - "type": "rectangle", - "pos": { - "x": -83, - "y": 252 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.c", - "type": "rectangle", - "pos": { - "x": 30, - "y": 86 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.d", - "type": "rectangle", - "pos": { - "x": 29, - "y": 252 - }, - "width": 54, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "d", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 9, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a", - "type": "rectangle", - "pos": { - "x": -86, - "y": -217 - }, - "width": 173, - "height": 197, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.b", - "type": "rectangle", - "pos": { - "x": -56, - "y": -176 - }, - "width": 113, - "height": 126, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 31, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.b.c", - "type": "rectangle", - "pos": { - "x": -26, - "y": -146 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, { "id": "x", "type": "rectangle", @@ -741,6 +413,334 @@ "zIndex": 0, "level": 2 }, + { + "id": "z", + "type": "rectangle", + "pos": { + "x": -113, + "y": 56 + }, + "width": 227, + "height": 292, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "z.a", + "type": "rectangle", + "pos": { + "x": -83, + "y": 86 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.b", + "type": "rectangle", + "pos": { + "x": -83, + "y": 252 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.c", + "type": "rectangle", + "pos": { + "x": 30, + "y": 86 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.d", + "type": "rectangle", + "pos": { + "x": 29, + "y": 252 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": -86, + "y": -217 + }, + "width": 173, + "height": 197, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": -56, + "y": -176 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.b.c", + "type": "rectangle", + "pos": { + "x": -26, + "y": -146 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, { "id": "b", "type": "rectangle", @@ -907,100 +907,6 @@ } ], "connections": [ - { - "id": "z.(a -> b)[0]", - "src": "z.a", - "srcArrow": "none", - "dst": "z.b", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": -57, - "y": 152 - }, - { - "x": -57, - "y": 192 - }, - { - "x": -57, - "y": 212 - }, - { - "x": -57, - "y": 252 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "z.(c -> d)[0]", - "src": "z.c", - "srcArrow": "none", - "dst": "z.d", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 56.5, - "y": 152 - }, - { - "x": 56.5, - "y": 192 - }, - { - "x": 56.5, - "y": 212 - }, - { - "x": 56.5, - "y": 252 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, { "id": "x.(a -> b)[0]", "src": "x.a", @@ -1188,6 +1094,100 @@ "tooltip": "", "icon": null, "zIndex": 0 + }, + { + "id": "z.(a -> b)[0]", + "src": "z.a", + "srcArrow": "none", + "dst": "z.b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": -57, + "y": 152 + }, + { + "x": -57, + "y": 192 + }, + { + "x": -57, + "y": 212 + }, + { + "x": -57, + "y": 252 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "z.(c -> d)[0]", + "src": "z.c", + "srcArrow": "none", + "dst": "z.d", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 56.5, + "y": 152 + }, + { + "x": 56.5, + "y": 192 + }, + { + "x": 56.5, + "y": 212 + }, + { + "x": 56.5, + "y": 252 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], "root": { diff --git a/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg index 006077180..332b06d69 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -zaxybabcdbabcdabcdaccd + .d2-4283156917 .fill-N1{fill:#0A0F25;} + .d2-4283156917 .fill-N2{fill:#676C7E;} + .d2-4283156917 .fill-N3{fill:#9499AB;} + .d2-4283156917 .fill-N4{fill:#CFD2DD;} + .d2-4283156917 .fill-N5{fill:#DEE1EB;} + .d2-4283156917 .fill-N6{fill:#EEF1F8;} + .d2-4283156917 .fill-N7{fill:#FFFFFF;} + .d2-4283156917 .fill-B1{fill:#0D32B2;} + .d2-4283156917 .fill-B2{fill:#0D32B2;} + .d2-4283156917 .fill-B3{fill:#E3E9FD;} + .d2-4283156917 .fill-B4{fill:#E3E9FD;} + .d2-4283156917 .fill-B5{fill:#EDF0FD;} + .d2-4283156917 .fill-B6{fill:#F7F8FE;} + .d2-4283156917 .fill-AA2{fill:#4A6FF3;} + .d2-4283156917 .fill-AA4{fill:#EDF0FD;} + .d2-4283156917 .fill-AA5{fill:#F7F8FE;} + .d2-4283156917 .fill-AB4{fill:#EDF0FD;} + .d2-4283156917 .fill-AB5{fill:#F7F8FE;} + .d2-4283156917 .stroke-N1{stroke:#0A0F25;} + .d2-4283156917 .stroke-N2{stroke:#676C7E;} + .d2-4283156917 .stroke-N3{stroke:#9499AB;} + .d2-4283156917 .stroke-N4{stroke:#CFD2DD;} + .d2-4283156917 .stroke-N5{stroke:#DEE1EB;} + .d2-4283156917 .stroke-N6{stroke:#EEF1F8;} + .d2-4283156917 .stroke-N7{stroke:#FFFFFF;} + .d2-4283156917 .stroke-B1{stroke:#0D32B2;} + .d2-4283156917 .stroke-B2{stroke:#0D32B2;} + .d2-4283156917 .stroke-B3{stroke:#E3E9FD;} + .d2-4283156917 .stroke-B4{stroke:#E3E9FD;} + .d2-4283156917 .stroke-B5{stroke:#EDF0FD;} + .d2-4283156917 .stroke-B6{stroke:#F7F8FE;} + .d2-4283156917 .stroke-AA2{stroke:#4A6FF3;} + .d2-4283156917 .stroke-AA4{stroke:#EDF0FD;} + .d2-4283156917 .stroke-AA5{stroke:#F7F8FE;} + .d2-4283156917 .stroke-AB4{stroke:#EDF0FD;} + .d2-4283156917 .stroke-AB5{stroke:#F7F8FE;} + .d2-4283156917 .background-color-N1{background-color:#0A0F25;} + .d2-4283156917 .background-color-N2{background-color:#676C7E;} + .d2-4283156917 .background-color-N3{background-color:#9499AB;} + .d2-4283156917 .background-color-N4{background-color:#CFD2DD;} + .d2-4283156917 .background-color-N5{background-color:#DEE1EB;} + .d2-4283156917 .background-color-N6{background-color:#EEF1F8;} + .d2-4283156917 .background-color-N7{background-color:#FFFFFF;} + .d2-4283156917 .background-color-B1{background-color:#0D32B2;} + .d2-4283156917 .background-color-B2{background-color:#0D32B2;} + .d2-4283156917 .background-color-B3{background-color:#E3E9FD;} + .d2-4283156917 .background-color-B4{background-color:#E3E9FD;} + .d2-4283156917 .background-color-B5{background-color:#EDF0FD;} + .d2-4283156917 .background-color-B6{background-color:#F7F8FE;} + .d2-4283156917 .background-color-AA2{background-color:#4A6FF3;} + .d2-4283156917 .background-color-AA4{background-color:#EDF0FD;} + .d2-4283156917 .background-color-AA5{background-color:#F7F8FE;} + .d2-4283156917 .background-color-AB4{background-color:#EDF0FD;} + .d2-4283156917 .background-color-AB5{background-color:#F7F8FE;} + .d2-4283156917 .color-N1{color:#0A0F25;} + .d2-4283156917 .color-N2{color:#676C7E;} + .d2-4283156917 .color-N3{color:#9499AB;} + .d2-4283156917 .color-N4{color:#CFD2DD;} + .d2-4283156917 .color-N5{color:#DEE1EB;} + .d2-4283156917 .color-N6{color:#EEF1F8;} + .d2-4283156917 .color-N7{color:#FFFFFF;} + .d2-4283156917 .color-B1{color:#0D32B2;} + .d2-4283156917 .color-B2{color:#0D32B2;} + .d2-4283156917 .color-B3{color:#E3E9FD;} + .d2-4283156917 .color-B4{color:#E3E9FD;} + .d2-4283156917 .color-B5{color:#EDF0FD;} + .d2-4283156917 .color-B6{color:#F7F8FE;} + .d2-4283156917 .color-AA2{color:#4A6FF3;} + .d2-4283156917 .color-AA4{color:#EDF0FD;} + .d2-4283156917 .color-AA5{color:#F7F8FE;} + .d2-4283156917 .color-AB4{color:#EDF0FD;} + .d2-4283156917 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>xyzababcdabcdabcdbaccd - - + + - - - - - @@ -116,6 +111,11 @@ + + + + + diff --git a/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json b/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json index c216a61ab..461bd39c7 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json +++ b/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json @@ -3,334 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "z", - "type": "rectangle", - "pos": { - "x": -113, - "y": 20 - }, - "width": 227, - "height": 302, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "z.a", - "type": "rectangle", - "pos": { - "x": -63, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.b", - "type": "rectangle", - "pos": { - "x": -63, - "y": 206 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.c", - "type": "rectangle", - "pos": { - "x": 10, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.d", - "type": "rectangle", - "pos": { - "x": 9, - "y": 206 - }, - "width": 54, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "d", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 9, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a", - "type": "rectangle", - "pos": { - "x": -126, - "y": -286 - }, - "width": 253, - "height": 266, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "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": -76, - "y": -236 - }, - "width": 153, - "height": 166, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "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": -26, - "y": -186 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, { "id": "x", "type": "rectangle", @@ -741,6 +413,334 @@ "zIndex": 0, "level": 2 }, + { + "id": "z", + "type": "rectangle", + "pos": { + "x": -113, + "y": 20 + }, + "width": 227, + "height": 302, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "z.a", + "type": "rectangle", + "pos": { + "x": -63, + "y": 70 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.b", + "type": "rectangle", + "pos": { + "x": -63, + "y": 206 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.c", + "type": "rectangle", + "pos": { + "x": 10, + "y": 70 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.d", + "type": "rectangle", + "pos": { + "x": 9, + "y": 206 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": -126, + "y": -286 + }, + "width": 253, + "height": 266, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "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": -76, + "y": -236 + }, + "width": 153, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "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": -26, + "y": -186 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, { "id": "b", "type": "rectangle", @@ -907,82 +907,6 @@ } ], "connections": [ - { - "id": "z.(a -> b)[0]", - "src": "z.a", - "srcArrow": "none", - "dst": "z.b", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": -37, - "y": 136 - }, - { - "x": -37, - "y": 206 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "z.(c -> d)[0]", - "src": "z.c", - "srcArrow": "none", - "dst": "z.d", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 36.5, - "y": 136 - }, - { - "x": 36.5, - "y": 206 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, { "id": "x.(a -> b)[0]", "src": "x.a", @@ -1134,6 +1058,82 @@ "tooltip": "", "icon": null, "zIndex": 0 + }, + { + "id": "z.(a -> b)[0]", + "src": "z.a", + "srcArrow": "none", + "dst": "z.b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": -37, + "y": 136 + }, + { + "x": -37, + "y": 206 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "z.(c -> d)[0]", + "src": "z.c", + "srcArrow": "none", + "dst": "z.d", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 36.5, + "y": 136 + }, + { + "x": 36.5, + "y": 206 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], "root": { diff --git a/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg index 535aecf9d..d7853b97f 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -zaxybabcdbabcdabcdaccd + .d2-355368884 .fill-N1{fill:#0A0F25;} + .d2-355368884 .fill-N2{fill:#676C7E;} + .d2-355368884 .fill-N3{fill:#9499AB;} + .d2-355368884 .fill-N4{fill:#CFD2DD;} + .d2-355368884 .fill-N5{fill:#DEE1EB;} + .d2-355368884 .fill-N6{fill:#EEF1F8;} + .d2-355368884 .fill-N7{fill:#FFFFFF;} + .d2-355368884 .fill-B1{fill:#0D32B2;} + .d2-355368884 .fill-B2{fill:#0D32B2;} + .d2-355368884 .fill-B3{fill:#E3E9FD;} + .d2-355368884 .fill-B4{fill:#E3E9FD;} + .d2-355368884 .fill-B5{fill:#EDF0FD;} + .d2-355368884 .fill-B6{fill:#F7F8FE;} + .d2-355368884 .fill-AA2{fill:#4A6FF3;} + .d2-355368884 .fill-AA4{fill:#EDF0FD;} + .d2-355368884 .fill-AA5{fill:#F7F8FE;} + .d2-355368884 .fill-AB4{fill:#EDF0FD;} + .d2-355368884 .fill-AB5{fill:#F7F8FE;} + .d2-355368884 .stroke-N1{stroke:#0A0F25;} + .d2-355368884 .stroke-N2{stroke:#676C7E;} + .d2-355368884 .stroke-N3{stroke:#9499AB;} + .d2-355368884 .stroke-N4{stroke:#CFD2DD;} + .d2-355368884 .stroke-N5{stroke:#DEE1EB;} + .d2-355368884 .stroke-N6{stroke:#EEF1F8;} + .d2-355368884 .stroke-N7{stroke:#FFFFFF;} + .d2-355368884 .stroke-B1{stroke:#0D32B2;} + .d2-355368884 .stroke-B2{stroke:#0D32B2;} + .d2-355368884 .stroke-B3{stroke:#E3E9FD;} + .d2-355368884 .stroke-B4{stroke:#E3E9FD;} + .d2-355368884 .stroke-B5{stroke:#EDF0FD;} + .d2-355368884 .stroke-B6{stroke:#F7F8FE;} + .d2-355368884 .stroke-AA2{stroke:#4A6FF3;} + .d2-355368884 .stroke-AA4{stroke:#EDF0FD;} + .d2-355368884 .stroke-AA5{stroke:#F7F8FE;} + .d2-355368884 .stroke-AB4{stroke:#EDF0FD;} + .d2-355368884 .stroke-AB5{stroke:#F7F8FE;} + .d2-355368884 .background-color-N1{background-color:#0A0F25;} + .d2-355368884 .background-color-N2{background-color:#676C7E;} + .d2-355368884 .background-color-N3{background-color:#9499AB;} + .d2-355368884 .background-color-N4{background-color:#CFD2DD;} + .d2-355368884 .background-color-N5{background-color:#DEE1EB;} + .d2-355368884 .background-color-N6{background-color:#EEF1F8;} + .d2-355368884 .background-color-N7{background-color:#FFFFFF;} + .d2-355368884 .background-color-B1{background-color:#0D32B2;} + .d2-355368884 .background-color-B2{background-color:#0D32B2;} + .d2-355368884 .background-color-B3{background-color:#E3E9FD;} + .d2-355368884 .background-color-B4{background-color:#E3E9FD;} + .d2-355368884 .background-color-B5{background-color:#EDF0FD;} + .d2-355368884 .background-color-B6{background-color:#F7F8FE;} + .d2-355368884 .background-color-AA2{background-color:#4A6FF3;} + .d2-355368884 .background-color-AA4{background-color:#EDF0FD;} + .d2-355368884 .background-color-AA5{background-color:#F7F8FE;} + .d2-355368884 .background-color-AB4{background-color:#EDF0FD;} + .d2-355368884 .background-color-AB5{background-color:#F7F8FE;} + .d2-355368884 .color-N1{color:#0A0F25;} + .d2-355368884 .color-N2{color:#676C7E;} + .d2-355368884 .color-N3{color:#9499AB;} + .d2-355368884 .color-N4{color:#CFD2DD;} + .d2-355368884 .color-N5{color:#DEE1EB;} + .d2-355368884 .color-N6{color:#EEF1F8;} + .d2-355368884 .color-N7{color:#FFFFFF;} + .d2-355368884 .color-B1{color:#0D32B2;} + .d2-355368884 .color-B2{color:#0D32B2;} + .d2-355368884 .color-B3{color:#E3E9FD;} + .d2-355368884 .color-B4{color:#E3E9FD;} + .d2-355368884 .color-B5{color:#EDF0FD;} + .d2-355368884 .color-B6{color:#F7F8FE;} + .d2-355368884 .color-AA2{color:#4A6FF3;} + .d2-355368884 .color-AA4{color:#EDF0FD;} + .d2-355368884 .color-AA5{color:#F7F8FE;} + .d2-355368884 .color-AB4{color:#EDF0FD;} + .d2-355368884 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>xyzababcdabcdabcdbaccd - - + + - - - - - @@ -116,6 +111,11 @@ + + + + + From 7cf4579a0f5b1f4a41ed6b5ff375af416ad8cefe Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 20:18:53 -0700 Subject: [PATCH 30/35] save --- e2etests/testdata/files/nested_diagram_types.d2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 index 61dbfcdf9..a63eacd7d 100644 --- a/e2etests/testdata/files/nested_diagram_types.d2 +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -37,7 +37,7 @@ b: { 1: { x: { # TODO compile error grid in sequence (group) - grid-columns: 3 + # grid-columns: 3 u v w From 0129ec4497f44954061f67c516b1f34c32007533 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 20:34:47 -0700 Subject: [PATCH 31/35] fix sequence in grid cell --- d2layouts/d2layouts.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index cfdea0ce2..b73c8ff60 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -96,10 +96,10 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co isGridCellContainer := graphInfo.DiagramType == GridDiagram && curr.IsContainer() && curr.Parent == g.Root gi := NestedGraphInfo(curr) - // if we are in a grid diagram, and our children have descendants - // we need to run layout on them first, even if they are not special diagram types - if isGridCellContainer { + if isGridCellContainer && gi.isDefault() { + // if we are in a grid diagram, and our children have descendants + // we need to run layout on them first, even if they are not special diagram types nestedGraph := ExtractSubgraph(curr, true) err := LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) if err != nil { @@ -204,7 +204,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co PositionNested(n, nestedGraph) } - log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel)) + log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) return err } From 1f243c405400c10be75f7b60a7933d841836b4f2 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 20:37:54 -0700 Subject: [PATCH 32/35] update test --- .../nested_diagram_types/dagre/board.exp.json | 404 +++++++++--------- .../nested_diagram_types/dagre/sketch.exp.svg | 160 +++---- .../nested_diagram_types/elk/board.exp.json | 404 +++++++++--------- .../nested_diagram_types/elk/sketch.exp.svg | 160 +++---- 4 files changed, 564 insertions(+), 564 deletions(-) diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json index 01a2851cd..84d833a62 100644 --- a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json @@ -3,47 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 0, - "y": 0 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "a", "type": "rectangle", @@ -126,6 +85,47 @@ "zIndex": 0, "level": 1 }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "a.1", "type": "rectangle", @@ -413,6 +413,129 @@ "zIndex": 0, "level": 2 }, + { + "id": "b.2.x", + "type": "rectangle", + "pos": { + "x": 285, + "y": 376 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.y", + "type": "rectangle", + "pos": { + "x": 377, + "y": 376 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.z", + "type": "rectangle", + "pos": { + "x": 470, + "y": 376 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, { "id": "b.1.x", "type": "rectangle", @@ -657,129 +780,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 5, "level": 3 - }, - { - "id": "b.2.x", - "type": "rectangle", - "pos": { - "x": 285, - "y": 376 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "x", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "b.2.y", - "type": "rectangle", - "pos": { - "x": 377, - "y": 376 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "y", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "b.2.z", - "type": "rectangle", - "pos": { - "x": 470, - "y": 376 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 } ], "connections": [ @@ -859,6 +859,44 @@ "icon": null, "zIndex": 0 }, + { + "id": "b.(1 -> 2)[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "b.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 135, + "y": 572.5 + }, + { + "x": 403.5, + "y": 572.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, { "id": "(a.3.x -- )[0]", "src": "a.3.x", @@ -935,44 +973,6 @@ "icon": null, "zIndex": 1 }, - { - "id": "b.(1 -> 2)[0]", - "src": "b.1", - "srcArrow": "none", - "dst": "b.2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 135, - "y": 572.5 - }, - { - "x": 403.5, - "y": 572.5 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 4 - }, { "id": "(b.1 -- )[0]", "src": "b.1", diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg index 145aa8194..393da2b08 100644 --- a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -cab12312xyxyz yzuvw + .d2-1081163781 .fill-N1{fill:#0A0F25;} + .d2-1081163781 .fill-N2{fill:#676C7E;} + .d2-1081163781 .fill-N3{fill:#9499AB;} + .d2-1081163781 .fill-N4{fill:#CFD2DD;} + .d2-1081163781 .fill-N5{fill:#DEE1EB;} + .d2-1081163781 .fill-N6{fill:#EEF1F8;} + .d2-1081163781 .fill-N7{fill:#FFFFFF;} + .d2-1081163781 .fill-B1{fill:#0D32B2;} + .d2-1081163781 .fill-B2{fill:#0D32B2;} + .d2-1081163781 .fill-B3{fill:#E3E9FD;} + .d2-1081163781 .fill-B4{fill:#E3E9FD;} + .d2-1081163781 .fill-B5{fill:#EDF0FD;} + .d2-1081163781 .fill-B6{fill:#F7F8FE;} + .d2-1081163781 .fill-AA2{fill:#4A6FF3;} + .d2-1081163781 .fill-AA4{fill:#EDF0FD;} + .d2-1081163781 .fill-AA5{fill:#F7F8FE;} + .d2-1081163781 .fill-AB4{fill:#EDF0FD;} + .d2-1081163781 .fill-AB5{fill:#F7F8FE;} + .d2-1081163781 .stroke-N1{stroke:#0A0F25;} + .d2-1081163781 .stroke-N2{stroke:#676C7E;} + .d2-1081163781 .stroke-N3{stroke:#9499AB;} + .d2-1081163781 .stroke-N4{stroke:#CFD2DD;} + .d2-1081163781 .stroke-N5{stroke:#DEE1EB;} + .d2-1081163781 .stroke-N6{stroke:#EEF1F8;} + .d2-1081163781 .stroke-N7{stroke:#FFFFFF;} + .d2-1081163781 .stroke-B1{stroke:#0D32B2;} + .d2-1081163781 .stroke-B2{stroke:#0D32B2;} + .d2-1081163781 .stroke-B3{stroke:#E3E9FD;} + .d2-1081163781 .stroke-B4{stroke:#E3E9FD;} + .d2-1081163781 .stroke-B5{stroke:#EDF0FD;} + .d2-1081163781 .stroke-B6{stroke:#F7F8FE;} + .d2-1081163781 .stroke-AA2{stroke:#4A6FF3;} + .d2-1081163781 .stroke-AA4{stroke:#EDF0FD;} + .d2-1081163781 .stroke-AA5{stroke:#F7F8FE;} + .d2-1081163781 .stroke-AB4{stroke:#EDF0FD;} + .d2-1081163781 .stroke-AB5{stroke:#F7F8FE;} + .d2-1081163781 .background-color-N1{background-color:#0A0F25;} + .d2-1081163781 .background-color-N2{background-color:#676C7E;} + .d2-1081163781 .background-color-N3{background-color:#9499AB;} + .d2-1081163781 .background-color-N4{background-color:#CFD2DD;} + .d2-1081163781 .background-color-N5{background-color:#DEE1EB;} + .d2-1081163781 .background-color-N6{background-color:#EEF1F8;} + .d2-1081163781 .background-color-N7{background-color:#FFFFFF;} + .d2-1081163781 .background-color-B1{background-color:#0D32B2;} + .d2-1081163781 .background-color-B2{background-color:#0D32B2;} + .d2-1081163781 .background-color-B3{background-color:#E3E9FD;} + .d2-1081163781 .background-color-B4{background-color:#E3E9FD;} + .d2-1081163781 .background-color-B5{background-color:#EDF0FD;} + .d2-1081163781 .background-color-B6{background-color:#F7F8FE;} + .d2-1081163781 .background-color-AA2{background-color:#4A6FF3;} + .d2-1081163781 .background-color-AA4{background-color:#EDF0FD;} + .d2-1081163781 .background-color-AA5{background-color:#F7F8FE;} + .d2-1081163781 .background-color-AB4{background-color:#EDF0FD;} + .d2-1081163781 .background-color-AB5{background-color:#F7F8FE;} + .d2-1081163781 .color-N1{color:#0A0F25;} + .d2-1081163781 .color-N2{color:#676C7E;} + .d2-1081163781 .color-N3{color:#9499AB;} + .d2-1081163781 .color-N4{color:#CFD2DD;} + .d2-1081163781 .color-N5{color:#DEE1EB;} + .d2-1081163781 .color-N6{color:#EEF1F8;} + .d2-1081163781 .color-N7{color:#FFFFFF;} + .d2-1081163781 .color-B1{color:#0D32B2;} + .d2-1081163781 .color-B2{color:#0D32B2;} + .d2-1081163781 .color-B3{color:#E3E9FD;} + .d2-1081163781 .color-B4{color:#E3E9FD;} + .d2-1081163781 .color-B5{color:#EDF0FD;} + .d2-1081163781 .color-B6{color:#F7F8FE;} + .d2-1081163781 .color-AA2{color:#4A6FF3;} + .d2-1081163781 .color-AA4{color:#EDF0FD;} + .d2-1081163781 .color-AA5{color:#F7F8FE;} + .d2-1081163781 .color-AB4{color:#EDF0FD;} + .d2-1081163781 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>abc12312xyxyz yzuvw - + diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json index 723443863..2c26323ff 100644 --- a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json +++ b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json @@ -3,47 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 12, - "y": 12 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "a", "type": "rectangle", @@ -126,6 +85,47 @@ "zIndex": 0, "level": 1 }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "a.1", "type": "rectangle", @@ -413,6 +413,129 @@ "zIndex": 0, "level": 2 }, + { + "id": "b.2.x", + "type": "rectangle", + "pos": { + "x": 297, + "y": 388 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.y", + "type": "rectangle", + "pos": { + "x": 389, + "y": 388 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.z", + "type": "rectangle", + "pos": { + "x": 482, + "y": 388 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, { "id": "b.1.x", "type": "rectangle", @@ -657,129 +780,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 5, "level": 3 - }, - { - "id": "b.2.x", - "type": "rectangle", - "pos": { - "x": 297, - "y": 388 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "x", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "b.2.y", - "type": "rectangle", - "pos": { - "x": 389, - "y": 388 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "y", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "b.2.z", - "type": "rectangle", - "pos": { - "x": 482, - "y": 388 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "N7", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 7, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 } ], "connections": [ @@ -859,6 +859,44 @@ "icon": null, "zIndex": 0 }, + { + "id": "b.(1 -> 2)[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "b.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 147, + "y": 584.5 + }, + { + "x": 415.5, + "y": 584.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, { "id": "(a.3.x -- )[0]", "src": "a.3.x", @@ -935,44 +973,6 @@ "icon": null, "zIndex": 1 }, - { - "id": "b.(1 -> 2)[0]", - "src": "b.1", - "srcArrow": "none", - "dst": "b.2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 147, - "y": 584.5 - }, - { - "x": 415.5, - "y": 584.5 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 4 - }, { "id": "(b.1 -- )[0]", "src": "b.1", diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg index 93df04694..562f706b3 100644 --- a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -cab12312xyxyz yzuvw + .d2-678101793 .fill-N1{fill:#0A0F25;} + .d2-678101793 .fill-N2{fill:#676C7E;} + .d2-678101793 .fill-N3{fill:#9499AB;} + .d2-678101793 .fill-N4{fill:#CFD2DD;} + .d2-678101793 .fill-N5{fill:#DEE1EB;} + .d2-678101793 .fill-N6{fill:#EEF1F8;} + .d2-678101793 .fill-N7{fill:#FFFFFF;} + .d2-678101793 .fill-B1{fill:#0D32B2;} + .d2-678101793 .fill-B2{fill:#0D32B2;} + .d2-678101793 .fill-B3{fill:#E3E9FD;} + .d2-678101793 .fill-B4{fill:#E3E9FD;} + .d2-678101793 .fill-B5{fill:#EDF0FD;} + .d2-678101793 .fill-B6{fill:#F7F8FE;} + .d2-678101793 .fill-AA2{fill:#4A6FF3;} + .d2-678101793 .fill-AA4{fill:#EDF0FD;} + .d2-678101793 .fill-AA5{fill:#F7F8FE;} + .d2-678101793 .fill-AB4{fill:#EDF0FD;} + .d2-678101793 .fill-AB5{fill:#F7F8FE;} + .d2-678101793 .stroke-N1{stroke:#0A0F25;} + .d2-678101793 .stroke-N2{stroke:#676C7E;} + .d2-678101793 .stroke-N3{stroke:#9499AB;} + .d2-678101793 .stroke-N4{stroke:#CFD2DD;} + .d2-678101793 .stroke-N5{stroke:#DEE1EB;} + .d2-678101793 .stroke-N6{stroke:#EEF1F8;} + .d2-678101793 .stroke-N7{stroke:#FFFFFF;} + .d2-678101793 .stroke-B1{stroke:#0D32B2;} + .d2-678101793 .stroke-B2{stroke:#0D32B2;} + .d2-678101793 .stroke-B3{stroke:#E3E9FD;} + .d2-678101793 .stroke-B4{stroke:#E3E9FD;} + .d2-678101793 .stroke-B5{stroke:#EDF0FD;} + .d2-678101793 .stroke-B6{stroke:#F7F8FE;} + .d2-678101793 .stroke-AA2{stroke:#4A6FF3;} + .d2-678101793 .stroke-AA4{stroke:#EDF0FD;} + .d2-678101793 .stroke-AA5{stroke:#F7F8FE;} + .d2-678101793 .stroke-AB4{stroke:#EDF0FD;} + .d2-678101793 .stroke-AB5{stroke:#F7F8FE;} + .d2-678101793 .background-color-N1{background-color:#0A0F25;} + .d2-678101793 .background-color-N2{background-color:#676C7E;} + .d2-678101793 .background-color-N3{background-color:#9499AB;} + .d2-678101793 .background-color-N4{background-color:#CFD2DD;} + .d2-678101793 .background-color-N5{background-color:#DEE1EB;} + .d2-678101793 .background-color-N6{background-color:#EEF1F8;} + .d2-678101793 .background-color-N7{background-color:#FFFFFF;} + .d2-678101793 .background-color-B1{background-color:#0D32B2;} + .d2-678101793 .background-color-B2{background-color:#0D32B2;} + .d2-678101793 .background-color-B3{background-color:#E3E9FD;} + .d2-678101793 .background-color-B4{background-color:#E3E9FD;} + .d2-678101793 .background-color-B5{background-color:#EDF0FD;} + .d2-678101793 .background-color-B6{background-color:#F7F8FE;} + .d2-678101793 .background-color-AA2{background-color:#4A6FF3;} + .d2-678101793 .background-color-AA4{background-color:#EDF0FD;} + .d2-678101793 .background-color-AA5{background-color:#F7F8FE;} + .d2-678101793 .background-color-AB4{background-color:#EDF0FD;} + .d2-678101793 .background-color-AB5{background-color:#F7F8FE;} + .d2-678101793 .color-N1{color:#0A0F25;} + .d2-678101793 .color-N2{color:#676C7E;} + .d2-678101793 .color-N3{color:#9499AB;} + .d2-678101793 .color-N4{color:#CFD2DD;} + .d2-678101793 .color-N5{color:#DEE1EB;} + .d2-678101793 .color-N6{color:#EEF1F8;} + .d2-678101793 .color-N7{color:#FFFFFF;} + .d2-678101793 .color-B1{color:#0D32B2;} + .d2-678101793 .color-B2{color:#0D32B2;} + .d2-678101793 .color-B3{color:#E3E9FD;} + .d2-678101793 .color-B4{color:#E3E9FD;} + .d2-678101793 .color-B5{color:#EDF0FD;} + .d2-678101793 .color-B6{color:#F7F8FE;} + .d2-678101793 .color-AA2{color:#4A6FF3;} + .d2-678101793 .color-AA4{color:#EDF0FD;} + .d2-678101793 .color-AA5{color:#F7F8FE;} + .d2-678101793 .color-AB4{color:#EDF0FD;} + .d2-678101793 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>abc12312xyxyz yzuvw - + From 9ecbc61945b103b0f5be5d29f516973d74683a52 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 20:41:06 -0700 Subject: [PATCH 33/35] cleanup --- d2layouts/d2layouts.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index b73c8ff60..021385edb 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -76,7 +76,6 @@ func SaveOrder(g *d2graph.Graph) (restoreOrder func()) { func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) error { g.Root.Box = &geo.Box{} - log.Warn(ctx, "ln info", slog.F("gi", graphInfo), slog.F("root level", g.RootLevel)) // Before we can layout these nodes, we need to handle all nested diagrams first. extracted := make(map[*d2graph.Object]*d2graph.Graph) var extractedOrder []*d2graph.Object @@ -128,7 +127,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // There is a nested diagram here, so extract its contents and process in the same way nestedGraph := ExtractSubgraph(curr, gi.IsConstantNear) - log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID())) + log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID()), slog.F("gi", gi)) nestedInfo := gi nearKey := curr.NearKey if gi.IsConstantNear { @@ -168,19 +167,19 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co var err error switch graphInfo.DiagramType { case GridDiagram: - log.Warn(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + log.Debug(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) if err = d2grid.Layout2(ctx, g); err != nil { return err } case SequenceDiagram: - log.Warn(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + log.Debug(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) err = d2sequence.Layout2(ctx, g, coreLayout) if err != nil { return err } default: - log.Warn(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + log.Debug(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) err := coreLayout(ctx, g) if err != nil { return err @@ -204,7 +203,7 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co PositionNested(n, nestedGraph) } - log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + log.Debug(ctx, "done", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) return err } From cee6a92722b83ad735e1507457f4f4c648b0dcf6 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 21 Sep 2023 21:00:02 -0700 Subject: [PATCH 34/35] cleanup --- d2exporter/export_test.go | 6 +- d2layouts/d2grid/layout.go | 317 +-------------------------------- d2layouts/d2layouts.go | 4 +- d2layouts/d2near/layout.go | 26 --- d2layouts/d2sequence/layout.go | 178 +----------------- d2lib/d2.go | 26 --- e2etests/e2e_test.go | 6 - 7 files changed, 10 insertions(+), 553 deletions(-) diff --git a/d2exporter/export_test.go b/d2exporter/export_test.go index 4eb1974c9..4aa862bdd 100644 --- a/d2exporter/export_test.go +++ b/d2exporter/export_test.go @@ -17,9 +17,8 @@ import ( "oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" - "oss.terrastruct.com/d2/d2layouts/d2grid" - "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/lib/geo" @@ -235,7 +234,8 @@ func run(t *testing.T, tc testCase) { err = g.SetDimensions(nil, ruler, nil) assert.JSON(t, nil, err) - err = d2sequence.Layout(ctx, g, d2grid.Layout(ctx, g, d2dagrelayout.DefaultLayout)) + graphInfo := d2layouts.NestedGraphInfo(g.Root) + err = d2layouts.LayoutNested(ctx, g, graphInfo, d2dagrelayout.DefaultLayout) if err != nil { t.Fatal(err) } diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 565f3b15c..f2b01e183 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "math" - "sort" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2target" @@ -21,42 +20,15 @@ const ( // Layout runs the grid layout on containers with rows/columns // Note: children are not allowed edges or descendants -// -// 1. Traverse graph from root, skip objects with no rows/columns -// 2. Construct a grid with the container children -// 3. Remove the children from the main graph -// 4. Run grid layout -// 5. Set the resulting dimensions to the main graph shape -// 6. Run core layouts (without grid children) -// 7. Put grid children back in correct location -func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d2graph.LayoutGraph { - return func(ctx context.Context, g *d2graph.Graph) error { - gridDiagrams, objectOrder, edgeOrder, err := withoutGridDiagrams(ctx, g, layout) - if err != nil { - return err - } - - if g.Root.IsGridDiagram() && len(g.Root.ChildrenArray) != 0 { - g.Root.TopLeft = geo.NewPoint(0, 0) - } else if err := layout(ctx, g); err != nil { - return err - } - - cleanup(g, gridDiagrams, objectOrder, edgeOrder) - return nil - } -} - -func Layout2(ctx context.Context, g *d2graph.Graph) error { - +// 1. Run grid layout on the graph root +// 2. Set the resulting dimensions to the graph root +func Layout(ctx context.Context, g *d2graph.Graph) error { obj := g.Root gd, err := layoutGrid(g, obj) if err != nil { return err } - // obj.Children = make(map[string]*d2graph.Object) - // obj.ChildrenArray = nil if obj.Box != nil { // CONTAINER_PADDING is default, but use gap value if set @@ -163,13 +135,11 @@ func Layout2(ctx context.Context, g *d2graph.Graph) error { // simple straight line edge routing between grid objects for _, e := range g.Edges { - // edgeOrder[e.AbsID()] = i if !e.Src.Parent.IsDescendantOf(obj) && !e.Dst.Parent.IsDescendantOf(obj) { continue } // if edge is within grid, remove it from outer layout gd.edges = append(gd.edges, e) - // edgeToRemove[e] = struct{}{} if e.Src.Parent != obj || e.Dst.Parent != obj { continue @@ -206,233 +176,6 @@ func Layout2(ctx context.Context, g *d2graph.Graph) error { return nil } -func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder, edgeOrder map[string]int, err error) { - toRemove := make(map[*d2graph.Object]struct{}) - edgeToRemove := make(map[*d2graph.Edge]struct{}) - gridDiagrams = make(map[string]*gridDiagram) - - objectOrder = make(map[string]int) - for i, obj := range g.Objects { - objectOrder[obj.AbsID()] = i - } - edgeOrder = make(map[string]int) - for i, edge := range g.Edges { - edgeOrder[edge.AbsID()] = i - } - - var processGrid func(obj *d2graph.Object) error - processGrid = func(obj *d2graph.Object) error { - for _, child := range obj.ChildrenArray { - if len(child.ChildrenArray) == 0 { - continue - } - if child.IsGridDiagram() { - if err := processGrid(child); err != nil { - return err - } - } else { - tempGraph := g.ExtractAsNestedGraph(child) - if err := layout(ctx, tempGraph); err != nil { - return err - } - g.InjectNestedGraph(tempGraph, obj) - - sort.SliceStable(g.Objects, func(i, j int) bool { - return objectOrder[g.Objects[i].AbsID()] < objectOrder[g.Objects[j].AbsID()] - }) - sort.SliceStable(child.ChildrenArray, func(i, j int) bool { - return objectOrder[child.ChildrenArray[i].AbsID()] < objectOrder[child.ChildrenArray[j].AbsID()] - }) - sort.SliceStable(obj.ChildrenArray, func(i, j int) bool { - return objectOrder[obj.ChildrenArray[i].AbsID()] < objectOrder[obj.ChildrenArray[j].AbsID()] - }) - sort.SliceStable(g.Edges, func(i, j int) bool { - return edgeOrder[g.Edges[i].AbsID()] < edgeOrder[g.Edges[j].AbsID()] - }) - - for _, o := range tempGraph.Objects { - toRemove[o] = struct{}{} - } - } - } - - gd, err := layoutGrid(g, obj) - if err != nil { - return err - } - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = nil - - if obj.Box != nil { - // CONTAINER_PADDING is default, but use gap value if set - horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING - if obj.GridGap != nil || obj.HorizontalGap != nil { - horizontalPadding = gd.horizontalGap - } - if obj.GridGap != nil || obj.VerticalGap != nil { - verticalPadding = gd.verticalGap - } - - // size shape according to grid - obj.SizeToContent(gd.width, gd.height, float64(2*horizontalPadding), float64(2*verticalPadding)) - - // compute where the grid should be placed inside shape - s := obj.ToShape() - innerBox := s.GetInnerBox() - if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 { - gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y) - } - - // compute how much space the label and icon occupy - var occupiedWidth, occupiedHeight float64 - if obj.Icon != nil { - iconSpace := float64(d2target.MAX_ICON_SIZE + 2*label.PADDING) - occupiedWidth = iconSpace - occupiedHeight = iconSpace - } - - var dx, dy float64 - if obj.LabelDimensions.Height != 0 { - occupiedHeight = math.Max( - occupiedHeight, - float64(obj.LabelDimensions.Height)+2*label.PADDING, - ) - } - if obj.LabelDimensions.Width != 0 { - // . ├────┤───────├────┤ - // . icon label icon - // with an icon in top left we need 2x the space to fit the label in the center - occupiedWidth *= 2 - occupiedWidth += float64(obj.LabelDimensions.Width) + 2*label.PADDING - if occupiedWidth > obj.Width { - dx = (occupiedWidth - obj.Width) / 2 - obj.Width = occupiedWidth - } - } - - // also check for grid cells with outside top labels or icons - // the first grid object is at the top (and always exists) - topY := gd.objects[0].TopLeft.Y - highestOutside := topY - for _, o := range gd.objects { - // we only want to compute label positions for objects at the top of the grid - if o.TopLeft.Y > topY { - if gd.rowDirected { - // if the grid is rowDirected (row1, row2, etc) we can stop after finishing the first row - break - } else { - // otherwise we continue until the next column - continue - } - } - if o.LabelPosition != nil { - labelPosition := label.Position(*o.LabelPosition) - if labelPosition.IsOutside() { - labelTL := o.GetLabelTopLeft() - if labelTL.Y < highestOutside { - highestOutside = labelTL.Y - } - } - } - if o.IconPosition != nil { - switch label.Position(*o.IconPosition) { - case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight: - iconSpace := float64(d2target.MAX_ICON_SIZE + label.PADDING) - if topY-iconSpace < highestOutside { - highestOutside = topY - iconSpace - } - } - } - } - if highestOutside < topY { - occupiedHeight += topY - highestOutside + 2*label.PADDING - } - if occupiedHeight > float64(verticalPadding) { - // if the label doesn't fit within the padding, we need to add more - dy = occupiedHeight - float64(verticalPadding) - obj.Height += dy - } - - // we need to center children if we have to expand to fit the container label - if dx != 0 || dy != 0 { - gd.shift(dx, dy) - } - } - - if obj.HasLabel() { - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - } - if obj.Icon != nil { - obj.IconPosition = go2.Pointer(string(label.InsideTopLeft)) - } - gridDiagrams[obj.AbsID()] = gd - - for _, o := range gd.objects { - toRemove[o] = struct{}{} - } - - // simple straight line edge routing between grid objects - for i, e := range g.Edges { - edgeOrder[e.AbsID()] = i - if !e.Src.Parent.IsDescendantOf(obj) && !e.Dst.Parent.IsDescendantOf(obj) { - continue - } - // if edge is within grid, remove it from outer layout - gd.edges = append(gd.edges, e) - edgeToRemove[e] = struct{}{} - - if e.Src.Parent != obj || e.Dst.Parent != obj { - continue - } - // if edge is grid child, use simple routing - e.Route = []*geo.Point{e.Src.Center(), e.Dst.Center()} - e.TraceToShape(e.Route, 0, 1) - if e.Label.Value != "" { - e.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) - } - } - - return nil - } - - if len(g.Objects) > 0 { - queue := make([]*d2graph.Object, 1, len(g.Objects)) - queue[0] = g.Root - for len(queue) > 0 { - obj := queue[0] - queue = queue[1:] - if len(obj.ChildrenArray) == 0 { - continue - } - if !obj.IsGridDiagram() { - queue = append(queue, obj.ChildrenArray...) - continue - } - - if err := processGrid(obj); err != nil { - return nil, nil, nil, err - } - } - } - - layoutObjects := make([]*d2graph.Object, 0, len(toRemove)) - for _, obj := range g.Objects { - if _, exists := toRemove[obj]; !exists { - layoutObjects = append(layoutObjects, obj) - } - } - g.Objects = layoutObjects - layoutEdges := make([]*d2graph.Edge, 0, len(edgeToRemove)) - for _, e := range g.Edges { - if _, exists := edgeToRemove[e]; !exists { - layoutEdges = append(layoutEdges, e) - } - } - g.Edges = layoutEdges - - return gridDiagrams, objectOrder, edgeOrder, nil -} - func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) { gd := newGridDiagram(obj) @@ -1128,57 +871,3 @@ func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, horizontalG } return totalDelta } - -// cleanup restores the graph after the core layout engine finishes -// - translating the grid to its position placed by the core layout engine -// - restore the children of the grid -// - sorts objects to their original graph order -func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objectsOrder, edgeOrder map[string]int) { - defer func() { - sort.SliceStable(graph.Objects, func(i, j int) bool { - return objectsOrder[graph.Objects[i].AbsID()] < objectsOrder[graph.Objects[j].AbsID()] - }) - sort.SliceStable(graph.Edges, func(i, j int) bool { - return edgeOrder[graph.Edges[i].AbsID()] < edgeOrder[graph.Edges[j].AbsID()] - }) - }() - - var restore func(obj *d2graph.Object) - restore = func(obj *d2graph.Object) { - gd, exists := gridDiagrams[obj.AbsID()] - if !exists { - return - } - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - - horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING - if obj.GridGap != nil || obj.HorizontalGap != nil { - horizontalPadding = gd.horizontalGap - } - if obj.GridGap != nil || obj.VerticalGap != nil { - verticalPadding = gd.verticalGap - } - - // shift the grid from (0, 0) - gd.shift( - obj.TopLeft.X+float64(horizontalPadding), - obj.TopLeft.Y+float64(verticalPadding), - ) - gd.cleanup(obj, graph) - - for _, child := range obj.ChildrenArray { - restore(child) - } - } - - if graph.Root.IsGridDiagram() { - gd, exists := gridDiagrams[graph.Root.AbsID()] - if exists { - gd.cleanup(graph.Root, graph) - } - } - - for _, obj := range graph.Objects { - restore(obj) - } -} diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 021385edb..2aa15ea3e 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -168,13 +168,13 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co switch graphInfo.DiagramType { case GridDiagram: log.Debug(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) - if err = d2grid.Layout2(ctx, g); err != nil { + if err = d2grid.Layout(ctx, g); err != nil { return err } case SequenceDiagram: log.Debug(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) - err = d2sequence.Layout2(ctx, g, coreLayout) + err = d2sequence.Layout(ctx, g, coreLayout) if err != nil { return err } diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index cb8301e0a..a3baaee65 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -91,10 +91,6 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNearGraphs []*d2graph return nil } -func Place(obj *d2graph.Object) (float64, float64) { - return place(obj) -} - // place returns the position of obj, taking into consideration its near value and the diagram func place(obj *d2graph.Object) (float64, float64) { tl, br := boundingBox(obj.Graph) @@ -149,28 +145,6 @@ func place(obj *d2graph.Object) (float64, float64) { return x, y } -// WithoutConstantNears plucks out the graph objects which have "near" set to a constant value -// This is to be called before layout engines so they don't take part in regular positioning -func WithoutConstantNears(ctx context.Context, g *d2graph.Graph) (constantNearGraphs []*d2graph.Graph) { - for i := 0; i < len(g.Objects); i++ { - obj := g.Objects[i] - if obj.NearKey == nil { - continue - } - _, isKey := g.Root.HasChild(d2graph.Key(obj.NearKey)) - if isKey { - continue - } - _, isConst := d2graph.NearConstants[d2graph.Key(obj.NearKey)[0]] - if isConst { - tempGraph := g.ExtractAsNestedGraph(obj) - constantNearGraphs = append(constantNearGraphs, tempGraph) - i-- - } - } - return constantNearGraphs -} - // boundingBox gets the center of the graph as defined by shapes // The bounds taking into consideration only shapes gives more of a feeling of true center // It differs from d2target.BoundingBox which needs to include every visible thing diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index cdf204606..ccbe9df2e 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -2,7 +2,6 @@ package d2sequence import ( "context" - "sort" "strings" "oss.terrastruct.com/util-go/go2" @@ -15,32 +14,9 @@ import ( // Layout runs the sequence diagram layout engine on objects of shape sequence_diagram // -// 1. Traverse graph from root, skip objects with shape not `sequence_diagram` -// 2. Construct a sequence diagram from all descendant objects and edges -// 3. Remove those objects and edges from the main graph -// 4. Run layout on sequence diagrams -// 5. Set the resulting dimensions to the main graph shape -// 6. Run core layouts (still without sequence diagram innards) -// 7. Put back sequence diagram innards in correct location +// 1. Run layout on sequence diagrams +// 2. Set the resulting dimensions to the main graph shape func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) error { - sequenceDiagrams, objectOrder, edgeOrder, err := WithoutSequenceDiagrams(ctx, g) - if err != nil { - return err - } - - if g.Root.IsSequenceDiagram() { - // the sequence diagram is the only layout engine if the whole diagram is - // shape: sequence_diagram - g.Root.TopLeft = geo.NewPoint(0, 0) - } else if err := layout(ctx, g); err != nil { - return err - } - - cleanup(g, sequenceDiagrams, objectOrder, edgeOrder) - return nil -} - -func Layout2(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) error { // used in layout code g.Root.Shape.Value = d2target.ShapeSequenceDiagram @@ -84,62 +60,6 @@ func Layout2(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) return nil } -func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]*sequenceDiagram, map[string]int, map[string]int, error) { - objectsToRemove := make(map[*d2graph.Object]struct{}) - edgesToRemove := make(map[*d2graph.Edge]struct{}) - sequenceDiagrams := make(map[string]*sequenceDiagram) - - if len(g.Objects) > 0 { - queue := make([]*d2graph.Object, 1, len(g.Objects)) - queue[0] = g.Root - for len(queue) > 0 { - obj := queue[0] - queue = queue[1:] - if len(obj.ChildrenArray) == 0 { - continue - } - if obj.Shape.Value != d2target.ShapeSequenceDiagram { - queue = append(queue, obj.ChildrenArray...) - continue - } - - sd, err := layoutSequenceDiagram(g, obj) - if err != nil { - return nil, nil, nil, err - } - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = nil - obj.Box = geo.NewBox(nil, sd.getWidth()+GROUP_CONTAINER_PADDING*2, sd.getHeight()+GROUP_CONTAINER_PADDING*2) - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - sequenceDiagrams[obj.AbsID()] = sd - - for _, edge := range sd.messages { - edgesToRemove[edge] = struct{}{} - } - for _, obj := range sd.actors { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.notes { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.groups { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.spans { - objectsToRemove[obj] = struct{}{} - } - } - } - - layoutEdges, edgeOrder := getLayoutEdges(g, edgesToRemove) - g.Edges = layoutEdges - layoutObjects, objectOrder := getLayoutObjects(g, objectsToRemove) - // TODO this isn't a proper deletion because the objects still appear as children of the object - g.Objects = layoutObjects - - return sequenceDiagrams, objectOrder, edgeOrder, nil -} - // layoutSequenceDiagram finds the edges inside the sequence diagram and performs the layout on the object descendants func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) (*sequenceDiagram, error) { var edges []*d2graph.Edge @@ -157,97 +77,3 @@ func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) (*sequenceDiag err = sd.layout() return sd, err } - -func getLayoutEdges(g *d2graph.Graph, toRemove map[*d2graph.Edge]struct{}) ([]*d2graph.Edge, map[string]int) { - edgeOrder := make(map[string]int) - layoutEdges := make([]*d2graph.Edge, 0, len(g.Edges)-len(toRemove)) - - for i, edge := range g.Edges { - edgeOrder[edge.AbsID()] = i - if _, exists := toRemove[edge]; !exists { - layoutEdges = append(layoutEdges, edge) - } - } - return layoutEdges, edgeOrder -} - -func getLayoutObjects(g *d2graph.Graph, toRemove map[*d2graph.Object]struct{}) ([]*d2graph.Object, map[string]int) { - objectOrder := make(map[string]int) - layoutObjects := make([]*d2graph.Object, 0, len(toRemove)) - for i, obj := range g.Objects { - objectOrder[obj.AbsID()] = i - if _, exists := toRemove[obj]; !exists { - layoutObjects = append(layoutObjects, obj) - } - } - return layoutObjects, objectOrder -} - -// cleanup restores the graph after the core layout engine finishes -// - translating the sequence diagram to its position placed by the core layout engine -// - restore the children of the sequence diagram graph object -// - adds the sequence diagram edges (messages) back to the graph -// - adds the sequence diagram lifelines to the graph edges -// - adds the sequence diagram descendants back to the graph objects -// - sorts edges and objects to their original graph order -func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, objectsOrder, edgesOrder map[string]int) { - var objects []*d2graph.Object - if g.Root.IsSequenceDiagram() { - objects = []*d2graph.Object{g.Root} - } else { - objects = g.Objects - } - for _, obj := range objects { - sd, exists := sequenceDiagrams[obj.AbsID()] - if !exists { - continue - } - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - - // shift the sequence diagrams as they are always placed at (0, 0) with some padding - sd.shift( - geo.NewPoint( - obj.TopLeft.X+GROUP_CONTAINER_PADDING, - obj.TopLeft.Y+GROUP_CONTAINER_PADDING, - ), - ) - - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = make([]*d2graph.Object, 0) - for _, child := range sd.actors { - obj.Children[strings.ToLower(child.ID)] = child - obj.ChildrenArray = append(obj.ChildrenArray, child) - } - for _, child := range sd.groups { - if child.Parent.AbsID() == obj.AbsID() { - obj.Children[strings.ToLower(child.ID)] = child - obj.ChildrenArray = append(obj.ChildrenArray, child) - } - } - - g.Edges = append(g.Edges, sd.messages...) - g.Edges = append(g.Edges, sd.lifelines...) - g.Objects = append(g.Objects, sd.actors...) - g.Objects = append(g.Objects, sd.notes...) - g.Objects = append(g.Objects, sd.groups...) - g.Objects = append(g.Objects, sd.spans...) - } - - // no new objects, so just keep the same position - sort.SliceStable(g.Objects, func(i, j int) bool { - return objectsOrder[g.Objects[i].AbsID()] < objectsOrder[g.Objects[j].AbsID()] - }) - - // sequence diagrams add lifelines, and they must be the last ones in this slice - sort.SliceStable(g.Edges, func(i, j int) bool { - iOrder, iExists := edgesOrder[g.Edges[i].AbsID()] - jOrder, jExists := edgesOrder[g.Edges[j].AbsID()] - if iExists && jExists { - return iOrder < jOrder - } else if iExists && !jExists { - return true - } - // either both don't exist or i doesn't exist and j exists - return false - }) -} diff --git a/d2lib/d2.go b/d2lib/d2.go index f08538f61..7115a7ffd 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -12,9 +12,6 @@ import ( "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" - "oss.terrastruct.com/d2/d2layouts/d2grid" - "oss.terrastruct.com/d2/d2layouts/d2near" - "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/d2renderers/d2svg" "oss.terrastruct.com/d2/d2target" @@ -90,29 +87,6 @@ func compile(ctx context.Context, g *d2graph.Graph, compileOpts *CompileOptions, if err != nil { return nil, err } - - if false { - constantNearGraphs := d2near.WithoutConstantNears(ctx, g) - - layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) - - // run core layout for constantNears - for _, tempGraph := range constantNearGraphs { - if err = layoutWithGrids(ctx, tempGraph); err != nil { - return nil, err - } - } - - err = d2sequence.Layout(ctx, g, layoutWithGrids) - if err != nil { - return nil, err - } - - err = d2near.Layout(ctx, g, constantNearGraphs) - if err != nil { - return nil, err - } - } } d, err := d2exporter.Export(ctx, g, compileOpts.FontFamily) diff --git a/e2etests/e2e_test.go b/e2etests/e2e_test.go index 2eaa799af..7d8a45c5d 100644 --- a/e2etests/e2e_test.go +++ b/e2etests/e2e_test.go @@ -21,8 +21,6 @@ import ( "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2layouts/d2elklayout" - "oss.terrastruct.com/d2/d2layouts/d2near" - "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2plugin" "oss.terrastruct.com/d2/d2renderers/d2animate" @@ -108,8 +106,6 @@ func runa(t *testing.T, tcs []testCase) { // serde exercises serializing and deserializing the graph // We want to run all the steps leading up to serialization in the course of regular layout func serde(t *testing.T, tc testCase, ruler *textmeasure.Ruler) { - ctx := context.Background() - ctx = log.WithTB(ctx, t, nil) g, _, err := d2compiler.Compile("", strings.NewReader(tc.script), &d2compiler.CompileOptions{ UTF16Pos: false, }) @@ -117,8 +113,6 @@ func serde(t *testing.T, tc testCase, ruler *textmeasure.Ruler) { if len(g.Objects) > 0 { err = g.SetDimensions(nil, ruler, nil) trequire.Nil(t, err) - d2near.WithoutConstantNears(ctx, g) - d2sequence.WithoutSequenceDiagrams(ctx, g) } b, err := d2graph.SerializeGraph(g) trequire.Nil(t, err) From 31252e6752327dde5c9d7dd2396bdd596f647159 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 22 Sep 2023 20:12:20 -0700 Subject: [PATCH 35/35] cleanup --- d2layouts/d2layouts.go | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go index 2aa15ea3e..ff00222dc 100644 --- a/d2layouts/d2layouts.go +++ b/d2layouts/d2layouts.go @@ -163,31 +163,27 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co // We can now run layout with accurate sizes of nested layout containers // Layout according to the type of diagram - LayoutDiagram := func(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) error { - var err error - switch graphInfo.DiagramType { - case GridDiagram: - log.Debug(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) - if err = d2grid.Layout(ctx, g); err != nil { - return err - } - - case SequenceDiagram: - log.Debug(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) - err = d2sequence.Layout(ctx, g, coreLayout) - if err != nil { - return err - } - default: - log.Debug(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) - err := coreLayout(ctx, g) - if err != nil { - return err - } + var err error + switch graphInfo.DiagramType { + case GridDiagram: + log.Debug(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + if err = d2grid.Layout(ctx, g); err != nil { + return err + } + + case SequenceDiagram: + log.Debug(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + err = d2sequence.Layout(ctx, g, coreLayout) + if err != nil { + return err + } + default: + log.Debug(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + err := coreLayout(ctx, g) + if err != nil { + return err } - return nil } - err := LayoutDiagram(ctx, g, graphInfo, coreLayout) if len(constantNears) > 0 { err := d2near.Layout(ctx, g, constantNears)