From 5b22382cfd480dd15692e9468afa27bebbf3ffe1 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 31 Mar 2023 18:13:12 -0700 Subject: [PATCH 01/33] add teleport_grid test --- e2etests/stable_test.go | 1 + e2etests/testdata/files/teleport_grid.d2 | 72 + .../stable/teleport_grid/dagre/board.exp.json | 1888 +++++++++++++++++ .../stable/teleport_grid/dagre/sketch.exp.svg | 853 ++++++++ .../stable/teleport_grid/elk/board.exp.json | 1858 ++++++++++++++++ .../stable/teleport_grid/elk/sketch.exp.svg | 853 ++++++++ 6 files changed, 5525 insertions(+) create mode 100644 e2etests/testdata/files/teleport_grid.d2 create mode 100644 e2etests/testdata/stable/teleport_grid/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/teleport_grid/elk/board.exp.json create mode 100644 e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 521d4c5e4..1fae58d41 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2465,6 +2465,7 @@ scenarios: { }`, }, loadFromFile(t, "arrowhead_scaling"), + loadFromFile(t, "teleport_grid"), } runa(t, tcs) diff --git a/e2etests/testdata/files/teleport_grid.d2 b/e2etests/testdata/files/teleport_grid.d2 new file mode 100644 index 000000000..fc8e6476e --- /dev/null +++ b/e2etests/testdata/files/teleport_grid.d2 @@ -0,0 +1,72 @@ +direction: right + +users -- via -- teleport + +teleport -> jita: "all connections audited and logged" +teleport -> infra + +teleport -> identity provider +teleport <- identity provider + +users: "" { + rows: 2 + + Engineers: { + shape: circle + icon: https://icons.terrastruct.com/essentials%2F365-user.svg + } + Machines: { + shape: circle + icon: https://icons.terrastruct.com/aws%2FCompute%2FCompute.svg + } +} + +via: "" { + columns: 1 + + https: "HTTPS://" + kubectl: "> kubectl" + tsh: "> tsh" + api: "> api" + db clients: "DB Clients" +} + +teleport: "" { + rows: 2 + columns: 2 + + t: |md + # Teleport + | + inp: |md + # Identity Native Proxy + | + + Audit Log.icon: https://icons.terrastruct.com/tech%2Flaptop.svg + Cert Authority.icon: https://icons.terrastruct.com/azure%2FWeb%20Service%20Color%2FApp%20Service%20Certificates.svg +} + +jita: "Just-in-time Access via" { + rows: 1 + + Slack.icon: https://icons.terrastruct.com/dev%2Fslack.svg + Mattermost + Jira + Pagerduty + Email.icon: https://icons.terrastruct.com/aws%2F_General%2FAWS-Email_light-bg.svg +} + +infra: Infrastructure { + rows: 2 + + ssh.icon: https://icons.terrastruct.com/essentials%2F112-server.svg + Kubernetes.icon: https://icons.terrastruct.com/azure%2F_Companies%2FKubernetes.svg + My SQL.icon: https://icons.terrastruct.com/dev%2Fmysql.svg + MongoDB.icon: https://icons.terrastruct.com/dev%2Fmongodb.svg + PSQL.icon: https://icons.terrastruct.com/dev%2Fpostgresql.svg + Windows.icon: https://icons.terrastruct.com/dev%2Fwindows.svg +} + +identity provider: Indentity Provider { + icon: https://icons.terrastruct.com/azure%2FIdentity%20Service%20Color%2FIdentity%20governance.svg +} diff --git a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json new file mode 100644 index 000000000..66435abc2 --- /dev/null +++ b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json @@ -0,0 +1,1888 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "users", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 423, + "height": 540, + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "via", + "type": "rectangle", + "pos": { + "x": 694, + "y": 290 + }, + "width": 472, + "height": 625, + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "teleport", + "type": "rectangle", + "pos": { + "x": 1437, + "y": 564 + }, + "width": 573, + "height": 1231, + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "jita", + "type": "rectangle", + "pos": { + "x": 2512, + "y": 844 + }, + "width": 423, + "height": 688, + "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": "Just-in-time Access via", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 266, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "infra", + "type": "rectangle", + "pos": { + "x": 2512, + "y": 1634 + }, + "width": 423, + "height": 982, + "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": "Infrastructure", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 160, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "identity provider", + "type": "rectangle", + "pos": { + "x": 830, + "y": 1261 + }, + "width": 201, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/azure/Identity Service Color/Identity governance.svg", + "RawPath": "/azure%2FIdentity%20Service%20Color%2FIdentity%20governance.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Indentity Provider", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 130, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "users.rows", + "type": "rectangle", + "pos": { + "x": 185, + "y": 41 + }, + "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": "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": "users.Engineers", + "type": "oval", + "pos": { + "x": 136, + "y": 127 + }, + "width": 152, + "height": 178, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/essentials/365-user.svg", + "RawPath": "/essentials%2F365-user.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Engineers", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 69, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "users.Machines", + "type": "oval", + "pos": { + "x": 137, + "y": 325 + }, + "width": 149, + "height": 175, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/aws/Compute/Compute.svg", + "RawPath": "/aws%2FCompute%2FCompute.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Machines", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 66, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.columns", + "type": "rectangle", + "pos": { + "x": 904, + "y": 379 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "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": "via.https", + "type": "rectangle", + "pos": { + "x": 877, + "y": 465 + }, + "width": 107, + "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": "HTTPS://", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.kubectl", + "type": "rectangle", + "pos": { + "x": 875, + "y": 551 + }, + "width": 111, + "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": "> kubectl", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 66, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.tsh", + "type": "rectangle", + "pos": { + "x": 891, + "y": 637 + }, + "width": 79, + "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": "> tsh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 34, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.api", + "type": "rectangle", + "pos": { + "x": 891, + "y": 723 + }, + "width": 79, + "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": "> api", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 34, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.db clients", + "type": "rectangle", + "pos": { + "x": 872, + "y": 809 + }, + "width": 116, + "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": "DB Clients", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 71, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.rows", + "type": "rectangle", + "pos": { + "x": 1697, + "y": 809 + }, + "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": "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": "teleport.columns", + "type": "rectangle", + "pos": { + "x": 1697, + "y": 895 + }, + "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": "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": "teleport.t", + "type": "text", + "pos": { + "x": 1663, + "y": 981 + }, + "width": 122, + "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": "# Teleport", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 122, + "labelHeight": 51, + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.inp", + "type": "text", + "pos": { + "x": 1573, + "y": 1052 + }, + "width": 302, + "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": "# Identity Native Proxy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 302, + "labelHeight": 51, + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.Audit Log", + "type": "rectangle", + "pos": { + "x": 1654, + "y": 1123 + }, + "width": 140, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/tech/laptop.svg", + "RawPath": "/tech%2Flaptop.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Audit Log", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 69, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.Cert Authority", + "type": "rectangle", + "pos": { + "x": 1637, + "y": 1261 + }, + "width": 173, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/azure/Web Service Color/App Service Certificates.svg", + "RawPath": "/azure%2FWeb%20Service%20Color%2FApp%20Service%20Certificates.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Cert Authority", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 102, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.rows", + "type": "rectangle", + "pos": { + "x": 2698, + "y": 912 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "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": "jita.Slack", + "type": "rectangle", + "pos": { + "x": 2669, + "y": 998 + }, + "width": 110, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/slack.svg", + "RawPath": "/dev%2Fslack.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Slack", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 39, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Mattermost", + "type": "rectangle", + "pos": { + "x": 2660, + "y": 1136 + }, + "width": 128, + "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": "Mattermost", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 83, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Jira", + "type": "rectangle", + "pos": { + "x": 2688, + "y": 1222 + }, + "width": 72, + "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": "Jira", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 27, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Pagerduty", + "type": "rectangle", + "pos": { + "x": 2664, + "y": 1308 + }, + "width": 119, + "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": "Pagerduty", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 74, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Email", + "type": "rectangle", + "pos": { + "x": 2668, + "y": 1394 + }, + "width": 111, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/aws/_General/AWS-Email_light-bg.svg", + "RawPath": "/aws%2F_General%2FAWS-Email_light-bg.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Email", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 40, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.rows", + "type": "rectangle", + "pos": { + "x": 2697, + "y": 1702 + }, + "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": "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": "infra.ssh", + "type": "rectangle", + "pos": { + "x": 2676, + "y": 1788 + }, + "width": 95, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/essentials/112-server.svg", + "RawPath": "/essentials%2F112-server.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ssh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 24, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.Kubernetes", + "type": "rectangle", + "pos": { + "x": 2648, + "y": 1926 + }, + "width": 152, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/azure/_Companies/Kubernetes.svg", + "RawPath": "/azure%2F_Companies%2FKubernetes.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Kubernetes", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 81, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.My SQL", + "type": "rectangle", + "pos": { + "x": 2663, + "y": 2064 + }, + "width": 122, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/mysql.svg", + "RawPath": "/dev%2Fmysql.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "My SQL", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.MongoDB", + "type": "rectangle", + "pos": { + "x": 2655, + "y": 2202 + }, + "width": 138, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/mongodb.svg", + "RawPath": "/dev%2Fmongodb.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "MongoDB", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 67, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.PSQL", + "type": "rectangle", + "pos": { + "x": 2670, + "y": 2340 + }, + "width": 108, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/postgresql.svg", + "RawPath": "/dev%2Fpostgresql.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "PSQL", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 37, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.Windows", + "type": "rectangle", + "pos": { + "x": 2656, + "y": 2478 + }, + "width": 136, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/windows.svg", + "RawPath": "/dev%2Fwindows.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Windows", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 65, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "(users -- via)[0]", + "src": "users", + "srcArrow": "none", + "srcLabel": "", + "dst": "via", + "dstArrow": "none", + "dstLabel": "", + "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": 423, + "y": 412 + }, + { + "x": 531.4, + "y": 412 + }, + { + "x": 585.7, + "y": 412 + }, + { + "x": 694.5, + "y": 412 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(via -- teleport)[0]", + "src": "via", + "srcArrow": "none", + "srcLabel": "", + "dst": "teleport", + "dstArrow": "none", + "dstLabel": "", + "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": 1166, + "y": 842 + }, + { + "x": 1274.4, + "y": 842 + }, + { + "x": 1328.7, + "y": 842 + }, + { + "x": 1437.5, + "y": 842 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport -> jita)[0]", + "src": "teleport", + "srcArrow": "none", + "srcLabel": "", + "dst": "jita", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "all connections audited and logged", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 231, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 2010, + "y": 924.75 + }, + { + "x": 2210.8, + "y": 924.75 + }, + { + "x": 2311.2, + "y": 924.75 + }, + { + "x": 2512, + "y": 924.75 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport -> infra)[0]", + "src": "teleport", + "srcArrow": "none", + "srcLabel": "", + "dst": "infra", + "dstArrow": "triangle", + "dstLabel": "", + "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": 2010, + "y": 1715.25 + }, + { + "x": 2210.8, + "y": 1715.25 + }, + { + "x": 2311.2, + "y": 1715.25 + }, + { + "x": 2512, + "y": 1715.25 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport -> identity provider)[0]", + "src": "teleport", + "srcArrow": "none", + "srcLabel": "", + "dst": "identity provider", + "dstArrow": "triangle", + "dstLabel": "", + "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": 1437, + "y": 1715.25 + }, + { + "x": 1328.6, + "y": 1715.25 + }, + { + "x": 1125.8, + "y": 1648.05 + }, + { + "x": 965, + "y": 1379.25 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport <- identity provider)[0]", + "src": "teleport", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "identity provider", + "dstArrow": "none", + "dstLabel": "", + "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": 1437, + "y": 1148.25 + }, + { + "x": 1328.6, + "y": 1148.25 + }, + { + "x": 1135, + "y": 1170.85 + }, + { + "x": 1011, + "y": 1261.25 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "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/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg new file mode 100644 index 000000000..5bc6ca42e --- /dev/null +++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg @@ -0,0 +1,853 @@ +Just-in-time Access viaInfrastructureIndentity Provider2EngineersMachines1HTTPS://> kubectl> tsh> apiDB Clients22

Teleport

+

Identity Native Proxy

+
Audit LogCert Authority1SlackMattermostJiraPagerdutyEmail2sshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + + +
\ No newline at end of file diff --git a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json new file mode 100644 index 000000000..d9d10a15d --- /dev/null +++ b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json @@ -0,0 +1,1858 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "users", + "type": "rectangle", + "pos": { + "x": 12, + "y": 842 + }, + "width": 252, + "height": 559, + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "via", + "type": "rectangle", + "pos": { + "x": 334, + "y": 823 + }, + "width": 216, + "height": 596, + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "teleport", + "type": "rectangle", + "pos": { + "x": 620, + "y": 786 + }, + "width": 402, + "height": 670, + "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": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "jita", + "type": "rectangle", + "pos": { + "x": 1474, + "y": 12 + }, + "width": 311, + "height": 700, + "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": "Just-in-time Access via", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 266, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "infra", + "type": "rectangle", + "pos": { + "x": 1152, + "y": 394 + }, + "width": 252, + "height": 994, + "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": "Infrastructure", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 160, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "identity provider", + "type": "rectangle", + "pos": { + "x": 1152, + "y": 1408 + }, + "width": 201, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/azure/Identity Service Color/Identity governance.svg", + "RawPath": "/azure%2FIdentity%20Service%20Color%2FIdentity%20governance.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Indentity Provider", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 130, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "users.rows", + "type": "rectangle", + "pos": { + "x": 111, + "y": 892 + }, + "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": "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": "users.Engineers", + "type": "oval", + "pos": { + "x": 62, + "y": 978 + }, + "width": 152, + "height": 178, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/essentials/365-user.svg", + "RawPath": "/essentials%2F365-user.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Engineers", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 69, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "users.Machines", + "type": "oval", + "pos": { + "x": 63, + "y": 1176 + }, + "width": 149, + "height": 175, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/aws/Compute/Compute.svg", + "RawPath": "/aws%2FCompute%2FCompute.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Machines", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 66, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.columns", + "type": "rectangle", + "pos": { + "x": 416, + "y": 873 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "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": "via.https", + "type": "rectangle", + "pos": { + "x": 388, + "y": 959 + }, + "width": 107, + "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": "HTTPS://", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.kubectl", + "type": "rectangle", + "pos": { + "x": 386, + "y": 1045 + }, + "width": 111, + "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": "> kubectl", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 66, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.tsh", + "type": "rectangle", + "pos": { + "x": 402, + "y": 1131 + }, + "width": 79, + "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": "> tsh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 34, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.api", + "type": "rectangle", + "pos": { + "x": 402, + "y": 1217 + }, + "width": 79, + "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": "> api", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 34, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "via.db clients", + "type": "rectangle", + "pos": { + "x": 384, + "y": 1303 + }, + "width": 116, + "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": "DB Clients", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 71, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.rows", + "type": "rectangle", + "pos": { + "x": 794, + "y": 836 + }, + "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": "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": "teleport.columns", + "type": "rectangle", + "pos": { + "x": 794, + "y": 922 + }, + "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": "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": "teleport.t", + "type": "text", + "pos": { + "x": 760, + "y": 1008 + }, + "width": 122, + "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": "# Teleport", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 122, + "labelHeight": 51, + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.inp", + "type": "text", + "pos": { + "x": 670, + "y": 1079 + }, + "width": 302, + "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": "# Identity Native Proxy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 302, + "labelHeight": 51, + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.Audit Log", + "type": "rectangle", + "pos": { + "x": 751, + "y": 1150 + }, + "width": 140, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/tech/laptop.svg", + "RawPath": "/tech%2Flaptop.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Audit Log", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 69, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "teleport.Cert Authority", + "type": "rectangle", + "pos": { + "x": 734, + "y": 1288 + }, + "width": 173, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/azure/Web Service Color/App Service Certificates.svg", + "RawPath": "/azure%2FWeb%20Service%20Color%2FApp%20Service%20Certificates.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Cert Authority", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 102, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.rows", + "type": "rectangle", + "pos": { + "x": 1603, + "y": 62 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "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": "jita.Slack", + "type": "rectangle", + "pos": { + "x": 1574, + "y": 148 + }, + "width": 110, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/slack.svg", + "RawPath": "/dev%2Fslack.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Slack", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 39, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Mattermost", + "type": "rectangle", + "pos": { + "x": 1565, + "y": 286 + }, + "width": 128, + "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": "Mattermost", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 83, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Jira", + "type": "rectangle", + "pos": { + "x": 1593, + "y": 372 + }, + "width": 72, + "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": "Jira", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 27, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Pagerduty", + "type": "rectangle", + "pos": { + "x": 1570, + "y": 458 + }, + "width": 119, + "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": "Pagerduty", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 74, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "jita.Email", + "type": "rectangle", + "pos": { + "x": 1574, + "y": 544 + }, + "width": 111, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/aws/_General/AWS-Email_light-bg.svg", + "RawPath": "/aws%2F_General%2FAWS-Email_light-bg.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Email", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 40, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.rows", + "type": "rectangle", + "pos": { + "x": 1251, + "y": 444 + }, + "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": "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": "infra.ssh", + "type": "rectangle", + "pos": { + "x": 1230, + "y": 530 + }, + "width": 95, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/essentials/112-server.svg", + "RawPath": "/essentials%2F112-server.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ssh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 24, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.Kubernetes", + "type": "rectangle", + "pos": { + "x": 1202, + "y": 668 + }, + "width": 152, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/azure/_Companies/Kubernetes.svg", + "RawPath": "/azure%2F_Companies%2FKubernetes.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Kubernetes", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 81, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.My SQL", + "type": "rectangle", + "pos": { + "x": 1217, + "y": 806 + }, + "width": 122, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/mysql.svg", + "RawPath": "/dev%2Fmysql.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "My SQL", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.MongoDB", + "type": "rectangle", + "pos": { + "x": 1209, + "y": 944 + }, + "width": 138, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/mongodb.svg", + "RawPath": "/dev%2Fmongodb.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "MongoDB", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 67, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.PSQL", + "type": "rectangle", + "pos": { + "x": 1224, + "y": 1082 + }, + "width": 108, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/postgresql.svg", + "RawPath": "/dev%2Fpostgresql.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "PSQL", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 37, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "infra.Windows", + "type": "rectangle", + "pos": { + "x": 1210, + "y": 1220 + }, + "width": 136, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/windows.svg", + "RawPath": "/dev%2Fwindows.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Windows", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 65, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "(users -- via)[0]", + "src": "users", + "srcArrow": "none", + "srcLabel": "", + "dst": "via", + "dstArrow": "none", + "dstLabel": "", + "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": 264, + "y": 1121.8333333333333 + }, + { + "x": 334, + "y": 1121.8333333333333 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(via -- teleport)[0]", + "src": "via", + "srcArrow": "none", + "srcLabel": "", + "dst": "teleport", + "dstArrow": "none", + "dstLabel": "", + "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": 550, + "y": 1121.8333333333333 + }, + { + "x": 620, + "y": 1121.8333333333333 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport -> jita)[0]", + "src": "teleport", + "srcArrow": "none", + "srcLabel": "", + "dst": "jita", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "all connections audited and logged", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 231, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 1022, + "y": 920.8333333333333 + }, + { + "x": 1062, + "y": 920.8333333333333 + }, + { + "x": 1062, + "y": 362 + }, + { + "x": 1474, + "y": 362 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport -> infra)[0]", + "src": "teleport", + "srcArrow": "none", + "srcLabel": "", + "dst": "infra", + "dstArrow": "triangle", + "dstLabel": "", + "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": 1022, + "y": 1054.8333333333333 + }, + { + "x": 1152, + "y": 1054.8333333333333 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport -> identity provider)[0]", + "src": "teleport", + "srcArrow": "none", + "srcLabel": "", + "dst": "identity provider", + "dstArrow": "triangle", + "dstLabel": "", + "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": 1022, + "y": 1188.8333333333333 + }, + { + "x": 1112, + "y": 1188.8333333333333 + }, + { + "x": 1112, + "y": 1447.3333333333333 + }, + { + "x": 1152, + "y": 1447.3333333333333 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(teleport <- identity provider)[0]", + "src": "teleport", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "identity provider", + "dstArrow": "none", + "dstLabel": "", + "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": 1022, + "y": 1322.8333333333333 + }, + { + "x": 1062, + "y": 1322.8333333333333 + }, + { + "x": 1062, + "y": 1486.6666666666667 + }, + { + "x": 1152, + "y": 1486.6666666666667 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "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/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg new file mode 100644 index 000000000..d0f70137b --- /dev/null +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -0,0 +1,853 @@ +Just-in-time Access viaInfrastructureIndentity Provider2EngineersMachines1HTTPS://> kubectl> tsh> apiDB Clients22

Teleport

+

Identity Native Proxy

+
Audit LogCert Authority1SlackMattermostJiraPagerdutyEmail2sshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + + +
\ No newline at end of file From d139eeadadeadaa9d72cf97cfa5f3a5cf895e4d7 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 31 Mar 2023 17:18:17 -0700 Subject: [PATCH 02/33] layout with grids --- d2compiler/compile.go | 26 ++ d2compiler/compile_test.go | 20 ++ d2exporter/export_test.go | 3 +- d2graph/d2graph.go | 8 + d2graph/grid.go | 6 + d2layouts/d2grid/layout.go | 223 ++++++++++++++++++ d2layouts/d2sequence/layout.go | 2 +- d2lib/d2.go | 7 +- d2oracle/edit.go | 10 + testdata/d2compiler/TestCompile/grid.exp.json | 180 ++++++++++++++ .../TestCompile/grid_negative.exp.json | 12 + 11 files changed, 493 insertions(+), 4 deletions(-) create mode 100644 d2graph/grid.go create mode 100644 d2layouts/d2grid/layout.go create mode 100644 testdata/d2compiler/TestCompile/grid.exp.json create mode 100644 testdata/d2compiler/TestCompile/grid_negative.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 28288795d..4dd2badbb 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -362,6 +362,32 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { } attrs.Constraint.Value = scalar.ScalarString() attrs.Constraint.MapKey = f.LastPrimaryKey() + case "rows": + v, err := strconv.Atoi(scalar.ScalarString()) + if err != nil { + c.errorf(scalar, "non-integer rows %#v: %s", scalar.ScalarString(), err) + return + } + if v < 0 { + c.errorf(scalar, "rows must be a non-negative integer: %#v", scalar.ScalarString()) + return + } + attrs.Rows = &d2graph.Scalar{} + attrs.Rows.Value = scalar.ScalarString() + attrs.Rows.MapKey = f.LastPrimaryKey() + case "columns": + v, err := strconv.Atoi(scalar.ScalarString()) + if err != nil { + c.errorf(scalar, "non-integer columns %#v: %s", scalar.ScalarString(), err) + return + } + if v < 0 { + c.errorf(scalar, "columns must be a non-negative integer: %#v", scalar.ScalarString()) + return + } + attrs.Columns = &d2graph.Scalar{} + attrs.Columns.Value = scalar.ScalarString() + attrs.Columns.MapKey = f.LastPrimaryKey() } if attrs.Link != nil && attrs.Tooltip != nil { diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 53e33e22f..7dc218cae 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2268,6 +2268,26 @@ obj { `, expErr: `d2/testdata/d2compiler/TestCompile/near_near_const.d2:7:8: near keys cannot be set to an object with a constant near key`, }, + { + name: "grid", + text: `hey: { + rows: 200 + columns: 230 +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + tassert.Equal(t, "200", g.Objects[0].Attributes.Rows.Value) + }, + }, + { + name: "grid_negative", + text: `hey: { + rows: 200 + columns: -200 +} +`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a non-negative integer: "-200"`, + }, } for _, tc := range testCases { diff --git a/d2exporter/export_test.go b/d2exporter/export_test.go index effcc07a8..bc6f47010 100644 --- a/d2exporter/export_test.go +++ b/d2exporter/export_test.go @@ -16,6 +16,7 @@ import ( "oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" + "oss.terrastruct.com/d2/d2layouts/d2grid" "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/lib/geo" @@ -231,7 +232,7 @@ func run(t *testing.T, tc testCase) { err = g.SetDimensions(nil, ruler, nil) assert.JSON(t, nil, err) - err = d2sequence.Layout(ctx, g, d2dagrelayout.DefaultLayout) + err = d2sequence.Layout(ctx, g, d2grid.Layout(ctx, g, d2dagrelayout.DefaultLayout)) if err != nil { t.Fatal(err) } diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index a9c370620..42f42977a 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1,6 +1,7 @@ package d2graph import ( + "context" "errors" "fmt" "math" @@ -67,6 +68,8 @@ func (g *Graph) RootBoard() *Graph { return g } +type LayoutGraph func(context.Context, *Graph) error + // TODO consider having different Scalar types // Right now we'll hold any types in Value and just convert, e.g. floats type Scalar struct { @@ -129,6 +132,9 @@ type Attributes struct { Direction Scalar `json:"direction"` Constraint Scalar `json:"constraint"` + + Rows *Scalar `json:"rows,omitempty"` + Columns *Scalar `json:"columns,omitempty"` } // TODO references at the root scope should have their Scope set to root graph AST @@ -1534,6 +1540,8 @@ var SimpleReservedKeywords = map[string]struct{}{ "direction": {}, "top": {}, "left": {}, + "rows": {}, + "columns": {}, } // ReservedKeywordHolders are reserved keywords that are meaningless on its own and exist solely to hold a set of reserved keywords diff --git a/d2graph/grid.go b/d2graph/grid.go new file mode 100644 index 000000000..b746f11a3 --- /dev/null +++ b/d2graph/grid.go @@ -0,0 +1,6 @@ +package d2graph + +func (obj *Object) IsGrid() bool { + return obj != nil && obj.Attributes != nil && len(obj.ChildrenArray) != 0 && + (obj.Attributes.Rows != nil || obj.Attributes.Columns != nil) +} diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go new file mode 100644 index 000000000..05f4176f2 --- /dev/null +++ b/d2layouts/d2grid/layout.go @@ -0,0 +1,223 @@ +package d2grid + +import ( + "context" + "math" + "sort" + "strconv" + + "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/lib/geo" + "oss.terrastruct.com/d2/lib/label" + "oss.terrastruct.com/util-go/go2" +) + +const CONTAINER_PADDING = 60. +const HORIZONTAL_PAD = 40. +const VERTICAL_PAD = 40. + +type grid struct { + root *d2graph.Object + nodes []*d2graph.Object + rows int + columns int + + width float64 + height float64 +} + +func newGrid(root *d2graph.Object) *grid { + g := grid{root: root, nodes: root.ChildrenArray} + if root.Attributes.Rows != nil { + g.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) + } + if root.Attributes.Columns != nil { + g.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) + } + + // compute exact row/column count based on values entered + // TODO consider making this based on node dimensions + if g.rows == 0 { + // set rows based on number of columns + if g.columns == 0 { + // 0,0: put everything in one row + g.rows = 1 + g.columns = len(g.nodes) + } else { + g.rows = len(g.nodes) / g.columns + if len(g.nodes)%g.columns != 0 { + g.rows++ + } + } + } else if g.columns == 0 { + // set columns based on number of rows + g.columns = len(g.nodes) / g.rows + if len(g.nodes)%g.rows != 0 { + g.columns++ + } + } else { + // rows and columns specified (add more rows if needed) + capacity := g.rows * g.columns + for capacity < len(g.nodes) { + g.rows++ + capacity += g.columns + } + } + + return &g +} + +func (g *grid) shift(dx, dy float64) { + for _, obj := range g.nodes { + obj.TopLeft.X += dx + obj.TopLeft.Y += dy + } +} + +// 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 { + grids, objectOrder, err := withoutGrids(ctx, g) + if err != nil { + return err + } + + if g.Root.IsGrid() { + g.Root.TopLeft = geo.NewPoint(0, 0) + } else if err := layout(ctx, g); err != nil { + return err + } + + cleanup(g, grids, objectOrder) + return nil + } +} + +func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { + grid := newGrid(obj) + + // position nodes + cursor := geo.NewPoint(0, 0) + maxWidth := 0. + for i := 0; i < grid.rows; i++ { + maxHeight := 0. + for j := 0; j < grid.columns; j++ { + n := grid.nodes[i*grid.columns+j] + n.TopLeft = cursor.Copy() + cursor.X += n.Width + HORIZONTAL_PAD + maxHeight = math.Max(maxHeight, n.Height) + } + maxWidth = math.Max(maxWidth, cursor.X-HORIZONTAL_PAD) + cursor.X = 0 + cursor.Y += float64(maxHeight) + VERTICAL_PAD + } + grid.width = maxWidth + grid.height = cursor.Y - VERTICAL_PAD + + // position labels and icons + for _, n := range grid.nodes { + if n.Attributes.Icon != nil { + n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } else { + n.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } + } + + return grid, nil +} + +func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*grid, objectOrder map[string]int, err error) { + toRemove := make(map[*d2graph.Object]struct{}) + grids := make(map[string]*grid) + + 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.IsGrid() { + queue = append(queue, obj.ChildrenArray...) + continue + } + + grid, err := layoutGrid(g, obj) + if err != nil { + return nil, nil, err + } + obj.Children = make(map[string]*d2graph.Object) + obj.ChildrenArray = nil + obj.Box = geo.NewBox(nil, grid.width+CONTAINER_PADDING*2, grid.height+CONTAINER_PADDING*2) + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + grids[obj.AbsID()] = grid + + for _, node := range grid.nodes { + toRemove[node] = struct{}{} + } + } + } + + 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) + } + } + g.Objects = layoutObjects + + return grids, objectOrder, nil +} + +// 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(g *d2graph.Graph, grids map[string]*grid, objectsOrder map[string]int) { + var objects []*d2graph.Object + if g.Root.IsGrid() { + objects = []*d2graph.Object{g.Root} + } else { + objects = g.Objects + } + for _, obj := range objects { + if _, exists := grids[obj.AbsID()]; !exists { + continue + } + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + sd := grids[obj.AbsID()] + + // shift the grid from (0, 0) + sd.shift( + obj.TopLeft.X+CONTAINER_PADDING, + obj.TopLeft.Y+CONTAINER_PADDING, + ) + + obj.Children = make(map[string]*d2graph.Object) + obj.ChildrenArray = make([]*d2graph.Object, 0) + for _, child := range sd.nodes { + obj.Children[child.ID] = child + obj.ChildrenArray = append(obj.ChildrenArray, child) + } + + g.Objects = append(g.Objects, grids[obj.AbsID()].nodes...) + } + + sort.SliceStable(g.Objects, func(i, j int) bool { + return objectsOrder[g.Objects[i].AbsID()] < objectsOrder[g.Objects[j].AbsID()] + }) +} diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index 28755f3e0..cfae446c4 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -78,7 +78,7 @@ func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string] // 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 -func Layout(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Context, g *d2graph.Graph) error) error { +func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) error { sequenceDiagrams, objectOrder, edgeOrder, err := WithoutSequenceDiagrams(ctx, g) if err != nil { return err diff --git a/d2lib/d2.go b/d2lib/d2.go index 060204ea9..11638833a 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -10,6 +10,7 @@ import ( "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2graph" "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" @@ -70,7 +71,9 @@ func compile(ctx context.Context, g *d2graph.Graph, opts *CompileOptions) (*d2ta constantNears := d2near.WithoutConstantNears(ctx, g) - err = d2sequence.Layout(ctx, g, coreLayout) + layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) + + err = d2sequence.Layout(ctx, g, layoutWithGrids) if err != nil { return nil, err } @@ -110,7 +113,7 @@ func compile(ctx context.Context, g *d2graph.Graph, opts *CompileOptions) (*d2ta return d, nil } -func getLayout(opts *CompileOptions) (func(context.Context, *d2graph.Graph) error, error) { +func getLayout(opts *CompileOptions) (d2graph.LayoutGraph, error) { if opts.Layout != nil { return opts.Layout, nil } else if os.Getenv("D2_LAYOUT") == "dagre" { diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 668b6d4a0..376634e22 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -314,6 +314,16 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Left.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } + case "rows": + if attrs.Rows != nil && attrs.Rows.MapKey != nil { + attrs.Rows.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "columns": + if attrs.Columns != nil && attrs.Columns.MapKey != nil { + attrs.Columns.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } case "source-arrowhead", "target-arrowhead": if reservedKey == "source-arrowhead" { attrs = edge.SrcArrowhead diff --git a/testdata/d2compiler/TestCompile/grid.exp.json b/testdata/d2compiler/TestCompile/grid.exp.json new file mode 100644 index 000000000..8cad38d75 --- /dev/null +++ b/testdata/d2compiler/TestCompile/grid.exp.json @@ -0,0 +1,180 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-4:0:34", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-3:1:33", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3", + "value": [ + { + "string": "hey", + "raw_string": "hey" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:5:5-3:0:32", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:10:17", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:5:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:5:12", + "value": [ + { + "string": "rows", + "raw_string": "rows" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:7:14-1:10:17", + "raw": "200", + "value": "200" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:19-2:13:31", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:19-2:8:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:19-2:8:26", + "value": [ + { + "string": "columns", + "raw_string": "columns" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:10:28-2:13:31", + "raw": "230", + "value": "230" + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "hey", + "id_val": "hey", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3", + "value": [ + { + "string": "hey", + "raw_string": "hey" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "hey" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + }, + "rows": { + "value": "200" + }, + "columns": { + "value": "230" + } + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/grid_negative.exp.json b/testdata/d2compiler/TestCompile/grid_negative.exp.json new file mode 100644 index 000000000..ff17efc56 --- /dev/null +++ b/testdata/d2compiler/TestCompile/grid_negative.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/grid_negative.d2,2:10:28-2:14:32", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a non-negative integer: \"-200\"" + } + ] + } +} From 67ca089a4b74cde48764c53d9eae2917d302019b Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Fri, 31 Mar 2023 18:49:15 -0700 Subject: [PATCH 03/33] update test --- .../stable/teleport_grid/dagre/board.exp.json | 505 +++++------------- .../stable/teleport_grid/dagre/sketch.exp.svg | 190 +++---- .../stable/teleport_grid/elk/board.exp.json | 475 ++++------------ .../stable/teleport_grid/elk/sketch.exp.svg | 190 +++---- 4 files changed, 439 insertions(+), 921 deletions(-) diff --git a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json index 66435abc2..3877af04c 100644 --- a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 0, - "y": 0 + "y": 204 }, - "width": 423, - "height": 540, + "width": 272, + "height": 461, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -40,6 +40,7 @@ "underline": false, "labelWidth": 0, "labelHeight": 0, + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -47,11 +48,11 @@ "id": "via", "type": "rectangle", "pos": { - "x": 694, - "y": 290 + "x": 543, + "y": 130 }, - "width": 472, - "height": 625, + "width": 236, + "height": 610, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -80,6 +81,7 @@ "underline": false, "labelWidth": 0, "labelHeight": 0, + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -87,11 +89,11 @@ "id": "teleport", "type": "rectangle", "pos": { - "x": 1437, - "y": 564 + "x": 1050, + "y": 283 }, - "width": 573, - "height": 1231, + "width": 584, + "height": 303, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -120,6 +122,7 @@ "underline": false, "labelWidth": 0, "labelHeight": 0, + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -127,11 +130,11 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 2512, - "y": 844 + "x": 2136, + "y": 0 }, - "width": 423, - "height": 688, + "width": 820, + "height": 212, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -160,7 +163,7 @@ "underline": false, "labelWidth": 266, "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -168,11 +171,11 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 2512, - "y": 1634 + "x": 2255, + "y": 232 }, - "width": 423, - "height": 982, + "width": 582, + "height": 344, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -201,7 +204,7 @@ "underline": false, "labelWidth": 160, "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -209,8 +212,8 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 830, - "y": 1261 + "x": 2446, + "y": 596 }, "width": 201, "height": 118, @@ -258,56 +261,15 @@ "zIndex": 0, "level": 1 }, - { - "id": "users.rows", - "type": "rectangle", - "pos": { - "x": 185, - "y": 41 - }, - "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": "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": "users.Engineers", "type": "oval", "pos": { - "x": 136, - "y": 127 + "x": 60, + "y": 264 }, "width": 152, - "height": 178, + "height": 152, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -356,11 +318,11 @@ "id": "users.Machines", "type": "oval", "pos": { - "x": 137, - "y": 325 + "x": 60, + "y": 456 }, "width": 149, - "height": 175, + "height": 149, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -405,53 +367,12 @@ "zIndex": 0, "level": 2 }, - { - "id": "via.columns", - "type": "rectangle", - "pos": { - "x": 904, - "y": 379 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "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": "via.https", "type": "rectangle", "pos": { - "x": 877, - "y": 465 + "x": 603, + "y": 190 }, "width": 107, "height": 66, @@ -491,8 +412,8 @@ "id": "via.kubectl", "type": "rectangle", "pos": { - "x": 875, - "y": 551 + "x": 603, + "y": 296 }, "width": 111, "height": 66, @@ -532,8 +453,8 @@ "id": "via.tsh", "type": "rectangle", "pos": { - "x": 891, - "y": 637 + "x": 603, + "y": 402 }, "width": 79, "height": 66, @@ -573,8 +494,8 @@ "id": "via.api", "type": "rectangle", "pos": { - "x": 891, - "y": 723 + "x": 603, + "y": 508 }, "width": 79, "height": 66, @@ -614,8 +535,8 @@ "id": "via.db clients", "type": "rectangle", "pos": { - "x": 872, - "y": 809 + "x": 603, + "y": 614 }, "width": 116, "height": 66, @@ -651,94 +572,12 @@ "zIndex": 0, "level": 2 }, - { - "id": "teleport.rows", - "type": "rectangle", - "pos": { - "x": 1697, - "y": 809 - }, - "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": "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": "teleport.columns", - "type": "rectangle", - "pos": { - "x": 1697, - "y": 895 - }, - "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": "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": "teleport.t", "type": "text", "pos": { - "x": 1663, - "y": 981 + "x": 1110, + "y": 343 }, "width": 122, "height": 51, @@ -770,6 +609,7 @@ "underline": false, "labelWidth": 122, "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, @@ -777,8 +617,8 @@ "id": "teleport.inp", "type": "text", "pos": { - "x": 1573, - "y": 1052 + "x": 1272, + "y": 343 }, "width": 302, "height": 51, @@ -810,6 +650,7 @@ "underline": false, "labelWidth": 302, "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, @@ -817,11 +658,11 @@ "id": "teleport.Audit Log", "type": "rectangle", "pos": { - "x": 1654, - "y": 1123 + "x": 1110, + "y": 434 }, "width": 140, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -870,11 +711,11 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 1637, - "y": 1261 + "x": 1290, + "y": 434 }, "width": 173, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -919,56 +760,15 @@ "zIndex": 0, "level": 2 }, - { - "id": "jita.rows", - "type": "rectangle", - "pos": { - "x": 2698, - "y": 912 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "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": "jita.Slack", "type": "rectangle", "pos": { - "x": 2669, - "y": 998 + "x": 2196, + "y": 60 }, "width": 110, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1017,8 +817,8 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 2660, - "y": 1136 + "x": 2346, + "y": 60 }, "width": 128, "height": 66, @@ -1058,8 +858,8 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 2688, - "y": 1222 + "x": 2514, + "y": 60 }, "width": 72, "height": 66, @@ -1099,8 +899,8 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 2664, - "y": 1308 + "x": 2626, + "y": 60 }, "width": 119, "height": 66, @@ -1140,11 +940,11 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 2668, - "y": 1394 + "x": 2785, + "y": 60 }, "width": 111, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1189,56 +989,15 @@ "zIndex": 0, "level": 2 }, - { - "id": "infra.rows", - "type": "rectangle", - "pos": { - "x": 2697, - "y": 1702 - }, - "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": "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": "infra.ssh", "type": "rectangle", "pos": { - "x": 2676, - "y": 1788 + "x": 2315, + "y": 292 }, "width": 95, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1287,11 +1046,11 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 2648, - "y": 1926 + "x": 2450, + "y": 292 }, "width": 152, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1340,11 +1099,11 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 2663, - "y": 2064 + "x": 2642, + "y": 292 }, "width": 122, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1393,11 +1152,11 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 2655, - "y": 2202 + "x": 2315, + "y": 424 }, "width": 138, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1446,11 +1205,11 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 2670, - "y": 2340 + "x": 2493, + "y": 424 }, "width": 108, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1499,11 +1258,11 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 2656, - "y": 2478 + "x": 2641, + "y": 424 }, "width": 136, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1577,20 +1336,20 @@ "labelPercentage": 0, "route": [ { - "x": 423, - "y": 412 + "x": 272, + "y": 434.5 }, { - "x": 531.4, - "y": 412 + "x": 380.4, + "y": 434.5 }, { - "x": 585.7, - "y": 412 + "x": 434.7, + "y": 434.5 }, { - "x": 694.5, - "y": 412 + "x": 543.5, + "y": 434.5 } ], "isCurve": true, @@ -1626,20 +1385,20 @@ "labelPercentage": 0, "route": [ { - "x": 1166, - "y": 842 + "x": 779, + "y": 434.5 }, { - "x": 1274.4, - "y": 842 + "x": 887.4, + "y": 434.5 }, { - "x": 1328.7, - "y": 842 + "x": 941.7, + "y": 434.5 }, { - "x": 1437.5, - "y": 842 + "x": 1050.5, + "y": 434.5 } ], "isCurve": true, @@ -1675,20 +1434,20 @@ "labelPercentage": 0, "route": [ { - "x": 2010, - "y": 924.75 + "x": 1592.4246575342465, + "y": 283 }, { - "x": 2210.8, - "y": 924.75 + "x": 1826.4849315068493, + "y": 141.4 }, { - "x": 2311.2, - "y": 924.75 + "x": 1935.2, + "y": 106 }, { - "x": 2512, - "y": 924.75 + "x": 2136, + "y": 106 } ], "isCurve": true, @@ -1724,20 +1483,20 @@ "labelPercentage": 0, "route": [ { - "x": 2010, - "y": 1715.25 + "x": 1634, + "y": 418.0985267034991 }, { - "x": 2210.8, - "y": 1715.25 + "x": 1834.8, + "y": 406.81970534069984 }, { - "x": 2311.2, - "y": 1715.25 + "x": 1959, + "y": 404 }, { - "x": 2512, - "y": 1715.25 + "x": 2255, + "y": 404 } ], "isCurve": true, @@ -1773,20 +1532,20 @@ "labelPercentage": 0, "route": [ { - "x": 1437, - "y": 1715.25 + "x": 1634, + "y": 501.98802946593 }, { - "x": 1328.6, - "y": 1715.25 + "x": 1834.8, + "y": 548.397605893186 }, { - "x": 1125.8, - "y": 1648.05 + "x": 1997.1, + "y": 576.1111951588503 }, { - "x": 965, - "y": 1379.25 + "x": 2445.5, + "y": 640.5559757942511 } ], "isCurve": true, @@ -1822,20 +1581,20 @@ "labelPercentage": 0, "route": [ { - "x": 1437, - "y": 1148.25 + "x": 1634, + "y": 569.47605893186 }, { - "x": 1328.6, - "y": 1148.25 + "x": 1834.8, + "y": 662.295211786372 }, { - "x": 1135, - "y": 1170.85 + "x": 1997.1, + "y": 680.3274583963691 }, { - "x": 1011, - "y": 1261.25 + "x": 2445.5, + "y": 659.6372919818457 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg index 5bc6ca42e..6269083ef 100644 --- a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg @@ -1,24 +1,24 @@ -Just-in-time Access viaInfrastructureIndentity Provider2EngineersMachines1HTTPS://> kubectl> tsh> apiDB Clients22

Teleport

-

Identity Native Proxy

-
Audit LogCert Authority1SlackMattermostJiraPagerdutyEmail2sshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

+

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file diff --git a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json index d9d10a15d..0fad16a9e 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 12, - "y": 842 + "y": 196 }, - "width": 252, - "height": 559, + "width": 272, + "height": 461, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -40,6 +40,7 @@ "underline": false, "labelWidth": 0, "labelHeight": 0, + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -47,11 +48,11 @@ "id": "via", "type": "rectangle", "pos": { - "x": 334, - "y": 823 + "x": 354, + "y": 122 }, - "width": 216, - "height": 596, + "width": 236, + "height": 610, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -80,6 +81,7 @@ "underline": false, "labelWidth": 0, "labelHeight": 0, + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -87,11 +89,11 @@ "id": "teleport", "type": "rectangle", "pos": { - "x": 620, - "y": 786 + "x": 660, + "y": 275 }, - "width": 402, - "height": 670, + "width": 584, + "height": 303, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -120,6 +122,7 @@ "underline": false, "labelWidth": 0, "labelHeight": 0, + "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, @@ -127,11 +130,11 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 1474, + "x": 2026, "y": 12 }, - "width": 311, - "height": 700, + "width": 820, + "height": 212, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -168,11 +171,11 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 1152, - "y": 394 + "x": 1374, + "y": 150 }, - "width": 252, - "height": 994, + "width": 582, + "height": 344, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -209,8 +212,8 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 1152, - "y": 1408 + "x": 1374, + "y": 514 }, "width": 201, "height": 118, @@ -258,56 +261,15 @@ "zIndex": 0, "level": 1 }, - { - "id": "users.rows", - "type": "rectangle", - "pos": { - "x": 111, - "y": 892 - }, - "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": "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": "users.Engineers", "type": "oval", "pos": { - "x": 62, - "y": 978 + "x": 72, + "y": 256 }, "width": 152, - "height": 178, + "height": 152, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -356,11 +318,11 @@ "id": "users.Machines", "type": "oval", "pos": { - "x": 63, - "y": 1176 + "x": 72, + "y": 448 }, "width": 149, - "height": 175, + "height": 149, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -405,53 +367,12 @@ "zIndex": 0, "level": 2 }, - { - "id": "via.columns", - "type": "rectangle", - "pos": { - "x": 416, - "y": 873 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "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": "via.https", "type": "rectangle", "pos": { - "x": 388, - "y": 959 + "x": 414, + "y": 182 }, "width": 107, "height": 66, @@ -491,8 +412,8 @@ "id": "via.kubectl", "type": "rectangle", "pos": { - "x": 386, - "y": 1045 + "x": 414, + "y": 288 }, "width": 111, "height": 66, @@ -532,8 +453,8 @@ "id": "via.tsh", "type": "rectangle", "pos": { - "x": 402, - "y": 1131 + "x": 414, + "y": 394 }, "width": 79, "height": 66, @@ -573,8 +494,8 @@ "id": "via.api", "type": "rectangle", "pos": { - "x": 402, - "y": 1217 + "x": 414, + "y": 500 }, "width": 79, "height": 66, @@ -614,8 +535,8 @@ "id": "via.db clients", "type": "rectangle", "pos": { - "x": 384, - "y": 1303 + "x": 414, + "y": 606 }, "width": 116, "height": 66, @@ -651,94 +572,12 @@ "zIndex": 0, "level": 2 }, - { - "id": "teleport.rows", - "type": "rectangle", - "pos": { - "x": 794, - "y": 836 - }, - "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": "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": "teleport.columns", - "type": "rectangle", - "pos": { - "x": 794, - "y": 922 - }, - "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": "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": "teleport.t", "type": "text", "pos": { - "x": 760, - "y": 1008 + "x": 720, + "y": 335 }, "width": 122, "height": 51, @@ -770,6 +609,7 @@ "underline": false, "labelWidth": 122, "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, @@ -777,8 +617,8 @@ "id": "teleport.inp", "type": "text", "pos": { - "x": 670, - "y": 1079 + "x": 882, + "y": 335 }, "width": 302, "height": 51, @@ -810,6 +650,7 @@ "underline": false, "labelWidth": 302, "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 }, @@ -817,11 +658,11 @@ "id": "teleport.Audit Log", "type": "rectangle", "pos": { - "x": 751, - "y": 1150 + "x": 720, + "y": 426 }, "width": 140, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -870,11 +711,11 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 734, - "y": 1288 + "x": 900, + "y": 426 }, "width": 173, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -919,56 +760,15 @@ "zIndex": 0, "level": 2 }, - { - "id": "jita.rows", - "type": "rectangle", - "pos": { - "x": 1603, - "y": 62 - }, - "width": 52, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "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": "jita.Slack", "type": "rectangle", "pos": { - "x": 1574, - "y": 148 + "x": 2086, + "y": 72 }, "width": 110, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1017,8 +817,8 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 1565, - "y": 286 + "x": 2236, + "y": 72 }, "width": 128, "height": 66, @@ -1058,8 +858,8 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 1593, - "y": 372 + "x": 2404, + "y": 72 }, "width": 72, "height": 66, @@ -1099,8 +899,8 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 1570, - "y": 458 + "x": 2516, + "y": 72 }, "width": 119, "height": 66, @@ -1140,11 +940,11 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 1574, - "y": 544 + "x": 2675, + "y": 72 }, "width": 111, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1189,56 +989,15 @@ "zIndex": 0, "level": 2 }, - { - "id": "infra.rows", - "type": "rectangle", - "pos": { - "x": 1251, - "y": 444 - }, - "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": "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": "infra.ssh", "type": "rectangle", "pos": { - "x": 1230, - "y": 530 + "x": 1434, + "y": 210 }, "width": 95, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1287,11 +1046,11 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 1202, - "y": 668 + "x": 1569, + "y": 210 }, "width": 152, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1340,11 +1099,11 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 1217, - "y": 806 + "x": 1761, + "y": 210 }, "width": 122, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1393,11 +1152,11 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 1209, - "y": 944 + "x": 1434, + "y": 342 }, "width": 138, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1446,11 +1205,11 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 1224, - "y": 1082 + "x": 1612, + "y": 342 }, "width": 108, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1499,11 +1258,11 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 1210, - "y": 1220 + "x": 1760, + "y": 342 }, "width": 136, - "height": 118, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1577,12 +1336,12 @@ "labelPercentage": 0, "route": [ { - "x": 264, - "y": 1121.8333333333333 + "x": 284, + "y": 427.0333333333333 }, { - "x": 334, - "y": 1121.8333333333333 + "x": 354, + "y": 427.0333333333333 } ], "animated": false, @@ -1617,12 +1376,12 @@ "labelPercentage": 0, "route": [ { - "x": 550, - "y": 1121.8333333333333 + "x": 590, + "y": 427.0333333333333 }, { - "x": 620, - "y": 1121.8333333333333 + "x": 660, + "y": 427.0333333333333 } ], "animated": false, @@ -1657,20 +1416,20 @@ "labelPercentage": 0, "route": [ { - "x": 1022, - "y": 920.8333333333333 + "x": 1244, + "y": 336.1333333333333 }, { - "x": 1062, - "y": 920.8333333333333 + "x": 1284, + "y": 336.1333333333333 }, { - "x": 1062, - "y": 362 + "x": 1284, + "y": 118 }, { - "x": 1474, - "y": 362 + "x": 2026, + "y": 118 } ], "animated": false, @@ -1705,12 +1464,12 @@ "labelPercentage": 0, "route": [ { - "x": 1022, - "y": 1054.8333333333333 + "x": 1244, + "y": 396.7333333333333 }, { - "x": 1152, - "y": 1054.8333333333333 + "x": 1374, + "y": 396.7333333333333 } ], "animated": false, @@ -1745,20 +1504,20 @@ "labelPercentage": 0, "route": [ { - "x": 1022, - "y": 1188.8333333333333 + "x": 1244, + "y": 457.3333333333333 }, { - "x": 1112, - "y": 1188.8333333333333 + "x": 1334, + "y": 457.3333333333333 }, { - "x": 1112, - "y": 1447.3333333333333 + "x": 1334, + "y": 553.3333333333333 }, { - "x": 1152, - "y": 1447.3333333333333 + "x": 1374, + "y": 553.3333333333333 } ], "animated": false, @@ -1793,20 +1552,20 @@ "labelPercentage": 0, "route": [ { - "x": 1022, - "y": 1322.8333333333333 + "x": 1244, + "y": 517.9333333333333 }, { - "x": 1062, - "y": 1322.8333333333333 + "x": 1284, + "y": 517.9333333333333 }, { - "x": 1062, - "y": 1486.6666666666667 + "x": 1284, + "y": 592.6666666666666 }, { - "x": 1152, - "y": 1486.6666666666667 + "x": 1374, + "y": 592.6666666666666 } ], "animated": false, diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg index d0f70137b..a12a64bbf 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -1,24 +1,24 @@ -Just-in-time Access viaInfrastructureIndentity Provider2EngineersMachines1HTTPS://> kubectl> tsh> apiDB Clients22

Teleport

-

Identity Native Proxy

-
Audit LogCert Authority1SlackMattermostJiraPagerdutyEmail2sshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

+

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file From f8617d1560af55c8de2ebe30b6abcf34e498083b Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 11:36:01 -0700 Subject: [PATCH 04/33] refactor --- d2layouts/d2grid/grid.go | 65 +++++++++++++++++ d2layouts/d2grid/layout.go | 145 +++++++++++-------------------------- 2 files changed, 109 insertions(+), 101 deletions(-) create mode 100644 d2layouts/d2grid/grid.go diff --git a/d2layouts/d2grid/grid.go b/d2layouts/d2grid/grid.go new file mode 100644 index 000000000..29853fc8a --- /dev/null +++ b/d2layouts/d2grid/grid.go @@ -0,0 +1,65 @@ +package d2grid + +import ( + "strconv" + + "oss.terrastruct.com/d2/d2graph" +) + +type grid struct { + root *d2graph.Object + nodes []*d2graph.Object + rows int + columns int + + width float64 + height float64 +} + +func newGrid(root *d2graph.Object) *grid { + g := grid{root: root, nodes: root.ChildrenArray} + if root.Attributes.Rows != nil { + g.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) + } + if root.Attributes.Columns != nil { + g.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) + } + + // compute exact row/column count based on values entered + // TODO consider making this based on node dimensions + if g.rows == 0 { + // set rows based on number of columns + if g.columns == 0 { + // 0,0: put everything in one row + g.rows = 1 + g.columns = len(g.nodes) + } else { + g.rows = len(g.nodes) / g.columns + if len(g.nodes)%g.columns != 0 { + g.rows++ + } + } + } else if g.columns == 0 { + // set columns based on number of rows + g.columns = len(g.nodes) / g.rows + if len(g.nodes)%g.rows != 0 { + g.columns++ + } + } else { + // rows and columns specified (add more rows if needed) + capacity := g.rows * g.columns + for capacity < len(g.nodes) { + g.rows++ + capacity += g.columns + } + } + + return &g +} + +func (g *grid) shift(dx, dy float64) { + for _, obj := range g.nodes { + obj.TopLeft.X += dx + obj.TopLeft.Y += dy + } +} diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 05f4176f2..45966e3a2 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -4,7 +4,6 @@ import ( "context" "math" "sort" - "strconv" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/lib/geo" @@ -12,67 +11,11 @@ import ( "oss.terrastruct.com/util-go/go2" ) -const CONTAINER_PADDING = 60. -const HORIZONTAL_PAD = 40. -const VERTICAL_PAD = 40. - -type grid struct { - root *d2graph.Object - nodes []*d2graph.Object - rows int - columns int - - width float64 - height float64 -} - -func newGrid(root *d2graph.Object) *grid { - g := grid{root: root, nodes: root.ChildrenArray} - if root.Attributes.Rows != nil { - g.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) - } - if root.Attributes.Columns != nil { - g.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) - } - - // compute exact row/column count based on values entered - // TODO consider making this based on node dimensions - if g.rows == 0 { - // set rows based on number of columns - if g.columns == 0 { - // 0,0: put everything in one row - g.rows = 1 - g.columns = len(g.nodes) - } else { - g.rows = len(g.nodes) / g.columns - if len(g.nodes)%g.columns != 0 { - g.rows++ - } - } - } else if g.columns == 0 { - // set columns based on number of rows - g.columns = len(g.nodes) / g.rows - if len(g.nodes)%g.rows != 0 { - g.columns++ - } - } else { - // rows and columns specified (add more rows if needed) - capacity := g.rows * g.columns - for capacity < len(g.nodes) { - g.rows++ - capacity += g.columns - } - } - - return &g -} - -func (g *grid) shift(dx, dy float64) { - for _, obj := range g.nodes { - obj.TopLeft.X += dx - obj.TopLeft.Y += dy - } -} +const ( + CONTAINER_PADDING = 60 + HORIZONTAL_PAD = 40. + VERTICAL_PAD = 40. +) // Layout runs the grid layout on containers with rows/columns // Note: children are not allowed edges or descendants @@ -102,40 +45,6 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d } } -func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { - grid := newGrid(obj) - - // position nodes - cursor := geo.NewPoint(0, 0) - maxWidth := 0. - for i := 0; i < grid.rows; i++ { - maxHeight := 0. - for j := 0; j < grid.columns; j++ { - n := grid.nodes[i*grid.columns+j] - n.TopLeft = cursor.Copy() - cursor.X += n.Width + HORIZONTAL_PAD - maxHeight = math.Max(maxHeight, n.Height) - } - maxWidth = math.Max(maxWidth, cursor.X-HORIZONTAL_PAD) - cursor.X = 0 - cursor.Y += float64(maxHeight) + VERTICAL_PAD - } - grid.width = maxWidth - grid.height = cursor.Y - VERTICAL_PAD - - // position labels and icons - for _, n := range grid.nodes { - if n.Attributes.Icon != nil { - n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) - } else { - n.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) - } - } - - return grid, nil -} - func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*grid, objectOrder map[string]int, err error) { toRemove := make(map[*d2graph.Object]struct{}) grids := make(map[string]*grid) @@ -183,6 +92,40 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g return grids, objectOrder, nil } +func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { + grid := newGrid(obj) + + // position nodes + cursor := geo.NewPoint(0, 0) + maxWidth := 0. + for i := 0; i < grid.rows; i++ { + maxHeight := 0. + for j := 0; j < grid.columns; j++ { + n := grid.nodes[i*grid.columns+j] + n.TopLeft = cursor.Copy() + cursor.X += n.Width + HORIZONTAL_PAD + maxHeight = math.Max(maxHeight, n.Height) + } + maxWidth = math.Max(maxWidth, cursor.X-HORIZONTAL_PAD) + cursor.X = 0 + cursor.Y += float64(maxHeight) + VERTICAL_PAD + } + grid.width = maxWidth + grid.height = cursor.Y - VERTICAL_PAD + + // position labels and icons + for _, n := range grid.nodes { + if n.Attributes.Icon != nil { + n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } else { + n.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } + } + + return grid, nil +} + // 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 @@ -195,26 +138,26 @@ func cleanup(g *d2graph.Graph, grids map[string]*grid, objectsOrder map[string]i objects = g.Objects } for _, obj := range objects { - if _, exists := grids[obj.AbsID()]; !exists { + grid, exists := grids[obj.AbsID()] + if !exists { continue } obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - sd := grids[obj.AbsID()] // shift the grid from (0, 0) - sd.shift( + grid.shift( obj.TopLeft.X+CONTAINER_PADDING, obj.TopLeft.Y+CONTAINER_PADDING, ) obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = make([]*d2graph.Object, 0) - for _, child := range sd.nodes { + for _, child := range grid.nodes { obj.Children[child.ID] = child obj.ChildrenArray = append(obj.ChildrenArray, child) } - g.Objects = append(g.Objects, grids[obj.AbsID()].nodes...) + g.Objects = append(g.Objects, grid.nodes...) } sort.SliceStable(g.Objects, func(i, j int) bool { From abe27cdc26a39eee1b45d6e831653a2eb9c15ace Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 11:45:45 -0700 Subject: [PATCH 05/33] cleanup --- d2layouts/d2sequence/layout.go | 70 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index cfae446c4..a2c7df0a5 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -13,6 +13,33 @@ import ( "oss.terrastruct.com/d2/lib/label" ) +// 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 +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 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{}) @@ -69,33 +96,6 @@ func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string] return sequenceDiagrams, objectOrder, edgeOrder, nil } -// 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 -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 -} - // 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 @@ -154,11 +154,11 @@ func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, obj objects = g.Objects } for _, obj := range objects { - if _, exists := sequenceDiagrams[obj.AbsID()]; !exists { + sd, exists := sequenceDiagrams[obj.AbsID()] + if !exists { continue } obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - sd := sequenceDiagrams[obj.AbsID()] // shift the sequence diagrams as they are always placed at (0, 0) with some padding sd.shift( @@ -181,12 +181,12 @@ func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, obj } } - g.Edges = append(g.Edges, sequenceDiagrams[obj.AbsID()].messages...) - g.Edges = append(g.Edges, sequenceDiagrams[obj.AbsID()].lifelines...) - g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].actors...) - g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].notes...) - g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].groups...) - g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].spans...) + 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 From 06fb313d3e65a0b76f4ea927323a0e82fee8b7bf Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 11:52:12 -0700 Subject: [PATCH 06/33] values must be positive --- d2compiler/compile.go | 8 ++++---- d2compiler/compile_test.go | 2 +- d2layouts/d2grid/grid.go | 12 +++--------- .../d2compiler/TestCompile/grid_negative.exp.json | 2 +- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 4dd2badbb..66940ce56 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -368,8 +368,8 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { c.errorf(scalar, "non-integer rows %#v: %s", scalar.ScalarString(), err) return } - if v < 0 { - c.errorf(scalar, "rows must be a non-negative integer: %#v", scalar.ScalarString()) + if v <= 0 { + c.errorf(scalar, "rows must be a positive integer: %#v", scalar.ScalarString()) return } attrs.Rows = &d2graph.Scalar{} @@ -381,8 +381,8 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { c.errorf(scalar, "non-integer columns %#v: %s", scalar.ScalarString(), err) return } - if v < 0 { - c.errorf(scalar, "columns must be a non-negative integer: %#v", scalar.ScalarString()) + if v <= 0 { + c.errorf(scalar, "columns must be a positive integer: %#v", scalar.ScalarString()) return } attrs.Columns = &d2graph.Scalar{} diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 7dc218cae..2d6e63a95 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2286,7 +2286,7 @@ obj { columns: -200 } `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a non-negative integer: "-200"`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a positive integer: "-200"`, }, } diff --git a/d2layouts/d2grid/grid.go b/d2layouts/d2grid/grid.go index 29853fc8a..cd5e4ec8f 100644 --- a/d2layouts/d2grid/grid.go +++ b/d2layouts/d2grid/grid.go @@ -29,15 +29,9 @@ func newGrid(root *d2graph.Object) *grid { // TODO consider making this based on node dimensions if g.rows == 0 { // set rows based on number of columns - if g.columns == 0 { - // 0,0: put everything in one row - g.rows = 1 - g.columns = len(g.nodes) - } else { - g.rows = len(g.nodes) / g.columns - if len(g.nodes)%g.columns != 0 { - g.rows++ - } + g.rows = len(g.nodes) / g.columns + if len(g.nodes)%g.columns != 0 { + g.rows++ } } else if g.columns == 0 { // set columns based on number of rows diff --git a/testdata/d2compiler/TestCompile/grid_negative.exp.json b/testdata/d2compiler/TestCompile/grid_negative.exp.json index ff17efc56..5551871da 100644 --- a/testdata/d2compiler/TestCompile/grid_negative.exp.json +++ b/testdata/d2compiler/TestCompile/grid_negative.exp.json @@ -5,7 +5,7 @@ "errs": [ { "range": "d2/testdata/d2compiler/TestCompile/grid_negative.d2,2:10:28-2:14:32", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a non-negative integer: \"-200\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a positive integer: \"-200\"" } ] } From acd0638325fa77c8460c41c46c429092a4454808 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 12:59:54 -0700 Subject: [PATCH 07/33] evenly size grid nodes --- d2layouts/d2grid/grid.go | 45 +++++++++++++++++++++++++++++++++++--- d2layouts/d2grid/layout.go | 15 +++++-------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/d2layouts/d2grid/grid.go b/d2layouts/d2grid/grid.go index cd5e4ec8f..4a743c60f 100644 --- a/d2layouts/d2grid/grid.go +++ b/d2layouts/d2grid/grid.go @@ -1,6 +1,7 @@ package d2grid import ( + "math" "strconv" "oss.terrastruct.com/d2/d2graph" @@ -12,8 +13,10 @@ type grid struct { rows int columns int - width float64 - height float64 + cellWidth float64 + cellHeight float64 + width float64 + height float64 } func newGrid(root *d2graph.Object) *grid { @@ -26,7 +29,6 @@ func newGrid(root *d2graph.Object) *grid { } // compute exact row/column count based on values entered - // TODO consider making this based on node dimensions if g.rows == 0 { // set rows based on number of columns g.rows = len(g.nodes) / g.columns @@ -48,6 +50,43 @@ func newGrid(root *d2graph.Object) *grid { } } + // if we have the following nodes for a 2 row, 3 column grid + // . ┌A──────────────────┐ ┌B─────┐ ┌C────────────┐ ┌D───────────┐ ┌E───────────────────┐ + // . │ │ │ │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ │ │ │ + // . └───────────────────┘ │ │ │ │ │ │ │ │ + // . │ │ └─────────────┘ │ │ │ │ + // . │ │ │ │ └────────────────────┘ + // . └──────┘ │ │ + // . └────────────┘ + // Then we must get the max width and max height to determine the grid cell size + // . maxWidth├────────────────────┤ + // . ┌A───────────────────┐ ┌B───────────────────┐ ┌C───────────────────┐ ┬maxHeight + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . └────────────────────┘ └────────────────────┘ └────────────────────┘ ┴ + // . ┌D───────────────────┐ ┌E───────────────────┐ + // . │ │ │ │ + // . │ │ │ │ + // . │ │ │ │ + // . │ │ │ │ + // . │ │ │ │ + // . │ │ │ │ + // . └────────────────────┘ └────────────────────┘ + var maxWidth, maxHeight float64 + for _, n := range g.nodes { + maxWidth = math.Max(maxWidth, n.Width) + maxHeight = math.Max(maxHeight, n.Height) + } + g.cellWidth = maxWidth + g.cellHeight = maxHeight + g.width = maxWidth + (float64(g.columns)-1)*(maxWidth+HORIZONTAL_PAD) + g.height = maxHeight + (float64(g.rows)-1)*(maxHeight+VERTICAL_PAD) + return &g } diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 45966e3a2..e9d68bccd 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -2,7 +2,6 @@ package d2grid import ( "context" - "math" "sort" "oss.terrastruct.com/d2/d2graph" @@ -69,7 +68,7 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g } obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = nil - obj.Box = geo.NewBox(nil, grid.width+CONTAINER_PADDING*2, grid.height+CONTAINER_PADDING*2) + obj.Box = geo.NewBox(nil, grid.width+2*CONTAINER_PADDING, grid.height+2*CONTAINER_PADDING) obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) grids[obj.AbsID()] = grid @@ -97,21 +96,17 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { // position nodes cursor := geo.NewPoint(0, 0) - maxWidth := 0. for i := 0; i < grid.rows; i++ { - maxHeight := 0. for j := 0; j < grid.columns; j++ { n := grid.nodes[i*grid.columns+j] + n.Width = grid.cellWidth + n.Height = grid.cellHeight n.TopLeft = cursor.Copy() - cursor.X += n.Width + HORIZONTAL_PAD - maxHeight = math.Max(maxHeight, n.Height) + cursor.X += grid.cellWidth + HORIZONTAL_PAD } - maxWidth = math.Max(maxWidth, cursor.X-HORIZONTAL_PAD) cursor.X = 0 - cursor.Y += float64(maxHeight) + VERTICAL_PAD + cursor.Y += float64(grid.cellHeight) + VERTICAL_PAD } - grid.width = maxWidth - grid.height = cursor.Y - VERTICAL_PAD // position labels and icons for _, n := range grid.nodes { From 13a8ca0e9fb9d459b27e4f738b46aebfcbf830b7 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 13:01:08 -0700 Subject: [PATCH 08/33] update test --- .../stable/teleport_grid/dagre/board.exp.json | 160 +++++++-------- .../stable/teleport_grid/dagre/sketch.exp.svg | 184 +++++++++--------- .../stable/teleport_grid/elk/board.exp.json | 168 ++++++++-------- .../stable/teleport_grid/elk/sketch.exp.svg | 184 +++++++++--------- 4 files changed, 348 insertions(+), 348 deletions(-) diff --git a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json index 3877af04c..d1ba12de3 100644 --- a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 0, - "y": 204 + "y": 203 }, "width": 272, - "height": 461, + "height": 464, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -90,10 +90,10 @@ "type": "rectangle", "pos": { "x": 1050, - "y": 283 + "y": 263 }, - "width": 584, - "height": 303, + "width": 764, + "height": 344, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -130,10 +130,10 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 2136, + "x": 2316, "y": 0 }, - "width": 820, + "width": 920, "height": 212, "opacity": 1, "strokeDash": 0, @@ -171,10 +171,10 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 2255, + "x": 2448, "y": 232 }, - "width": 582, + "width": 656, "height": 344, "opacity": 1, "strokeDash": 0, @@ -212,7 +212,7 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 2446, + "x": 2676, "y": 596 }, "width": 201, @@ -266,7 +266,7 @@ "type": "oval", "pos": { "x": 60, - "y": 264 + "y": 263 }, "width": 152, "height": 152, @@ -319,10 +319,10 @@ "type": "oval", "pos": { "x": 60, - "y": 456 + "y": 455 }, - "width": 149, - "height": 149, + "width": 152, + "height": 152, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -374,7 +374,7 @@ "x": 603, "y": 190 }, - "width": 107, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -415,7 +415,7 @@ "x": 603, "y": 296 }, - "width": 111, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -456,7 +456,7 @@ "x": 603, "y": 402 }, - "width": 79, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -497,7 +497,7 @@ "x": 603, "y": 508 }, - "width": 79, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -577,10 +577,10 @@ "type": "text", "pos": { "x": 1110, - "y": 343 + "y": 323 }, - "width": 122, - "height": 51, + "width": 302, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -617,11 +617,11 @@ "id": "teleport.inp", "type": "text", "pos": { - "x": 1272, - "y": 343 + "x": 1452, + "y": 323 }, "width": 302, - "height": 51, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -659,9 +659,9 @@ "type": "rectangle", "pos": { "x": 1110, - "y": 434 + "y": 455 }, - "width": 140, + "width": 302, "height": 92, "opacity": 1, "strokeDash": 0, @@ -711,10 +711,10 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 1290, - "y": 434 + "x": 1452, + "y": 455 }, - "width": 173, + "width": 302, "height": 92, "opacity": 1, "strokeDash": 0, @@ -764,10 +764,10 @@ "id": "jita.Slack", "type": "rectangle", "pos": { - "x": 2196, + "x": 2376, "y": 60 }, - "width": 110, + "width": 128, "height": 92, "opacity": 1, "strokeDash": 0, @@ -817,11 +817,11 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 2346, + "x": 2544, "y": 60 }, "width": 128, - "height": 66, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -858,11 +858,11 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 2514, + "x": 2712, "y": 60 }, - "width": 72, - "height": 66, + "width": 128, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -899,11 +899,11 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 2626, + "x": 2880, "y": 60 }, - "width": 119, - "height": 66, + "width": 128, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -940,10 +940,10 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 2785, + "x": 3048, "y": 60 }, - "width": 111, + "width": 128, "height": 92, "opacity": 1, "strokeDash": 0, @@ -993,10 +993,10 @@ "id": "infra.ssh", "type": "rectangle", "pos": { - "x": 2315, + "x": 2508, "y": 292 }, - "width": 95, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1046,7 +1046,7 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 2450, + "x": 2700, "y": 292 }, "width": 152, @@ -1099,10 +1099,10 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 2642, + "x": 2892, "y": 292 }, - "width": 122, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1152,10 +1152,10 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 2315, + "x": 2508, "y": 424 }, - "width": 138, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1205,10 +1205,10 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 2493, + "x": 2700, "y": 424 }, - "width": 108, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1258,10 +1258,10 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 2641, + "x": 2892, "y": 424 }, - "width": 136, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1434,19 +1434,19 @@ "labelPercentage": 0, "route": [ { - "x": 1592.4246575342465, - "y": 283 + "x": 1763.433789954338, + "y": 262.5 }, { - "x": 1826.4849315068493, - "y": 141.4 + "x": 2004.6867579908676, + "y": 137.3 }, { - "x": 1935.2, + "x": 2115.2, "y": 106 }, { - "x": 2136, + "x": 2316, "y": 106 } ], @@ -1483,19 +1483,19 @@ "labelPercentage": 0, "route": [ { - "x": 1634, - "y": 418.0985267034991 + "x": 1814, + "y": 416.09399684044234 }, { - "x": 1834.8, - "y": 406.81970534069984 + "x": 2014.8, + "y": 406.41879936808846 }, { - "x": 1959, + "x": 2141.6, "y": 404 }, { - "x": 2255, + "x": 2448, "y": 404 } ], @@ -1532,20 +1532,20 @@ "labelPercentage": 0, "route": [ { - "x": 1634, - "y": 501.98802946593 + "x": 1814, + "y": 510.2361769352291 }, { - "x": 1834.8, - "y": 548.397605893186 + "x": 2014.8, + "y": 550.0472353870458 }, { - "x": 1997.1, - "y": 576.1111951588503 + "x": 2187.1, + "y": 576.3143459915611 }, { - "x": 2445.5, - "y": 640.5559757942511 + "x": 2675.5, + "y": 641.5717299578059 } ], "isCurve": true, @@ -1581,20 +1581,20 @@ "labelPercentage": 0, "route": [ { - "x": 1634, - "y": 569.47605893186 + "x": 1814, + "y": 585.9723538704582 }, { - "x": 1834.8, - "y": 662.295211786372 + "x": 2014.8, + "y": 665.5944707740916 }, { - "x": 1997.1, - "y": 680.3274583963691 + "x": 2187.1, + "y": 680.2622362869198 }, { - "x": 2445.5, - "y": 659.6372919818457 + "x": 2675.5, + "y": 659.3111814345991 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg index 6269083ef..f6a003864 100644 --- a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg @@ -1,23 +1,23 @@ -Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

-

Identity Native Proxy

-
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

+

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file diff --git a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json index 0fad16a9e..791027e81 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 12, - "y": 196 + "y": 190 }, "width": 272, - "height": 461, + "height": 464, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -49,7 +49,7 @@ "type": "rectangle", "pos": { "x": 354, - "y": 122 + "y": 117 }, "width": 236, "height": 610, @@ -90,10 +90,10 @@ "type": "rectangle", "pos": { "x": 660, - "y": 275 + "y": 250 }, - "width": 584, - "height": 303, + "width": 764, + "height": 344, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -130,10 +130,10 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 2026, + "x": 2280, "y": 12 }, - "width": 820, + "width": 920, "height": 212, "opacity": 1, "strokeDash": 0, @@ -171,10 +171,10 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 1374, + "x": 1554, "y": 150 }, - "width": 582, + "width": 656, "height": 344, "opacity": 1, "strokeDash": 0, @@ -212,7 +212,7 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 1374, + "x": 1554, "y": 514 }, "width": 201, @@ -266,7 +266,7 @@ "type": "oval", "pos": { "x": 72, - "y": 256 + "y": 250 }, "width": 152, "height": 152, @@ -319,10 +319,10 @@ "type": "oval", "pos": { "x": 72, - "y": 448 + "y": 442 }, - "width": 149, - "height": 149, + "width": 152, + "height": 152, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -372,9 +372,9 @@ "type": "rectangle", "pos": { "x": 414, - "y": 182 + "y": 177 }, - "width": 107, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -413,9 +413,9 @@ "type": "rectangle", "pos": { "x": 414, - "y": 288 + "y": 283 }, - "width": 111, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -454,9 +454,9 @@ "type": "rectangle", "pos": { "x": 414, - "y": 394 + "y": 389 }, - "width": 79, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -495,9 +495,9 @@ "type": "rectangle", "pos": { "x": 414, - "y": 500 + "y": 495 }, - "width": 79, + "width": 116, "height": 66, "opacity": 1, "strokeDash": 0, @@ -536,7 +536,7 @@ "type": "rectangle", "pos": { "x": 414, - "y": 606 + "y": 601 }, "width": 116, "height": 66, @@ -577,10 +577,10 @@ "type": "text", "pos": { "x": 720, - "y": 335 + "y": 310 }, - "width": 122, - "height": 51, + "width": 302, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -617,11 +617,11 @@ "id": "teleport.inp", "type": "text", "pos": { - "x": 882, - "y": 335 + "x": 1062, + "y": 310 }, "width": 302, - "height": 51, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -659,9 +659,9 @@ "type": "rectangle", "pos": { "x": 720, - "y": 426 + "y": 442 }, - "width": 140, + "width": 302, "height": 92, "opacity": 1, "strokeDash": 0, @@ -711,10 +711,10 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 900, - "y": 426 + "x": 1062, + "y": 442 }, - "width": 173, + "width": 302, "height": 92, "opacity": 1, "strokeDash": 0, @@ -764,10 +764,10 @@ "id": "jita.Slack", "type": "rectangle", "pos": { - "x": 2086, + "x": 2340, "y": 72 }, - "width": 110, + "width": 128, "height": 92, "opacity": 1, "strokeDash": 0, @@ -817,11 +817,11 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 2236, + "x": 2508, "y": 72 }, "width": 128, - "height": 66, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -858,11 +858,11 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 2404, + "x": 2676, "y": 72 }, - "width": 72, - "height": 66, + "width": 128, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -899,11 +899,11 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 2516, + "x": 2844, "y": 72 }, - "width": 119, - "height": 66, + "width": 128, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -940,10 +940,10 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 2675, + "x": 3012, "y": 72 }, - "width": 111, + "width": 128, "height": 92, "opacity": 1, "strokeDash": 0, @@ -993,10 +993,10 @@ "id": "infra.ssh", "type": "rectangle", "pos": { - "x": 1434, + "x": 1614, "y": 210 }, - "width": 95, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1046,7 +1046,7 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 1569, + "x": 1806, "y": 210 }, "width": 152, @@ -1099,10 +1099,10 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 1761, + "x": 1998, "y": 210 }, - "width": 122, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1152,10 +1152,10 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 1434, + "x": 1614, "y": 342 }, - "width": 138, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1205,10 +1205,10 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 1612, + "x": 1806, "y": 342 }, - "width": 108, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1258,10 +1258,10 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 1760, + "x": 1998, "y": 342 }, - "width": 136, + "width": 152, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1337,11 +1337,11 @@ "route": [ { "x": 284, - "y": 427.0333333333333 + "y": 422.93333333333334 }, { "x": 354, - "y": 427.0333333333333 + "y": 422.93333333333334 } ], "animated": false, @@ -1377,11 +1377,11 @@ "route": [ { "x": 590, - "y": 427.0333333333333 + "y": 422.93333333333334 }, { "x": 660, - "y": 427.0333333333333 + "y": 422.93333333333334 } ], "animated": false, @@ -1416,19 +1416,19 @@ "labelPercentage": 0, "route": [ { - "x": 1244, - "y": 336.1333333333333 + "x": 1424, + "y": 319.73333333333335 }, { - "x": 1284, - "y": 336.1333333333333 + "x": 1464, + "y": 319.73333333333335 }, { - "x": 1284, + "x": 1464, "y": 118 }, { - "x": 2026, + "x": 2280, "y": 118 } ], @@ -1464,12 +1464,12 @@ "labelPercentage": 0, "route": [ { - "x": 1244, - "y": 396.7333333333333 + "x": 1424, + "y": 388.53333333333336 }, { - "x": 1374, - "y": 396.7333333333333 + "x": 1554, + "y": 388.53333333333336 } ], "animated": false, @@ -1504,19 +1504,19 @@ "labelPercentage": 0, "route": [ { - "x": 1244, + "x": 1424, "y": 457.3333333333333 }, { - "x": 1334, + "x": 1514, "y": 457.3333333333333 }, { - "x": 1334, + "x": 1514, "y": 553.3333333333333 }, { - "x": 1374, + "x": 1554, "y": 553.3333333333333 } ], @@ -1552,20 +1552,20 @@ "labelPercentage": 0, "route": [ { - "x": 1244, - "y": 517.9333333333333 + "x": 1424, + "y": 526.1333333333333 }, { - "x": 1284, - "y": 517.9333333333333 + "x": 1464, + "y": 526.1333333333333 }, { - "x": 1284, - "y": 592.6666666666666 + "x": 1464, + "y": 592.6666666666667 }, { - "x": 1374, - "y": 592.6666666666666 + "x": 1554, + "y": 592.6666666666667 } ], "animated": false, diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg index a12a64bbf..1d5730d9b 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -1,23 +1,23 @@ -Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

-

Identity Native Proxy

-
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

+

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file From 0ed4bfe244746314eb040180c71bf2b641df0021 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 18:58:07 -0700 Subject: [PATCH 09/33] add dagger_grid test --- e2etests/stable_test.go | 1 + e2etests/testdata/files/dagger_grid.d2 | 25 ++ .../stable/dagger_grid/dagre/board.exp.json | 417 ++++++++++++++++++ .../stable/dagger_grid/dagre/sketch.exp.svg | 102 +++++ .../stable/dagger_grid/elk/board.exp.json | 417 ++++++++++++++++++ .../stable/dagger_grid/elk/sketch.exp.svg | 102 +++++ 6 files changed, 1064 insertions(+) create mode 100644 e2etests/testdata/files/dagger_grid.d2 create mode 100644 e2etests/testdata/stable/dagger_grid/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/dagger_grid/elk/board.exp.json create mode 100644 e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 1fae58d41..4499dafca 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2466,6 +2466,7 @@ scenarios: { }, loadFromFile(t, "arrowhead_scaling"), loadFromFile(t, "teleport_grid"), + loadFromFile(t, "dagger_grid"), } runa(t, tcs) diff --git a/e2etests/testdata/files/dagger_grid.d2 b/e2etests/testdata/files/dagger_grid.d2 new file mode 100644 index 000000000..66ea0432f --- /dev/null +++ b/e2etests/testdata/files/dagger_grid.d2 @@ -0,0 +1,25 @@ +todo root level grid: { + rows: 4 + + flow: { + width: 800 + height: 200 + } + + dagger engine: { + width: 800 + } + + any docker compatible runtime: { + width: 800 + } + + any ci: { + width: 800 + } + + windows + linux + macos + kubernetes +} diff --git a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json new file mode 100644 index 000000000..bd49385e0 --- /dev/null +++ b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json @@ -0,0 +1,417 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "todo root level grid", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 1760, + "height": 1040, + "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": "todo root level grid", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 222, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "todo root level grid.flow", + "type": "rectangle", + "pos": { + "x": 60, + "y": 60 + }, + "width": 800, + "height": 200, + "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": "flow", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 32, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.dagger engine", + "type": "rectangle", + "pos": { + "x": 900, + "y": 60 + }, + "width": 800, + "height": 200, + "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": "dagger engine", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 101, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.any docker compatible runtime", + "type": "rectangle", + "pos": { + "x": 60, + "y": 300 + }, + "width": 800, + "height": 200, + "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": "any docker compatible runtime", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 222, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.any ci", + "type": "rectangle", + "pos": { + "x": 900, + "y": 300 + }, + "width": 800, + "height": 200, + "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": "any ci", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 41, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.windows", + "type": "rectangle", + "pos": { + "x": 60, + "y": 540 + }, + "width": 800, + "height": 200, + "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": "windows", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 64, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.linux", + "type": "rectangle", + "pos": { + "x": 900, + "y": 540 + }, + "width": 800, + "height": 200, + "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": "linux", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 35, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.macos", + "type": "rectangle", + "pos": { + "x": 60, + "y": 780 + }, + "width": 800, + "height": 200, + "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": "macos", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 45, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.kubernetes", + "type": "rectangle", + "pos": { + "x": 900, + "y": 780 + }, + "width": 800, + "height": 200, + "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": "kubernetes", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 80, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [], + "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/dagger_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg new file mode 100644 index 000000000..298a9765e --- /dev/null +++ b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg @@ -0,0 +1,102 @@ +todo root level gridflowdagger engineany docker compatible runtimeany ciwindowslinuxmacoskubernetes + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json new file mode 100644 index 000000000..36716f307 --- /dev/null +++ b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json @@ -0,0 +1,417 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "todo root level grid", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 1760, + "height": 1040, + "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": "todo root level grid", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 222, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "todo root level grid.flow", + "type": "rectangle", + "pos": { + "x": 72, + "y": 72 + }, + "width": 800, + "height": 200, + "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": "flow", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 32, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.dagger engine", + "type": "rectangle", + "pos": { + "x": 912, + "y": 72 + }, + "width": 800, + "height": 200, + "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": "dagger engine", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 101, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.any docker compatible runtime", + "type": "rectangle", + "pos": { + "x": 72, + "y": 312 + }, + "width": 800, + "height": 200, + "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": "any docker compatible runtime", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 222, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.any ci", + "type": "rectangle", + "pos": { + "x": 912, + "y": 312 + }, + "width": 800, + "height": 200, + "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": "any ci", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 41, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.windows", + "type": "rectangle", + "pos": { + "x": 72, + "y": 552 + }, + "width": 800, + "height": 200, + "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": "windows", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 64, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.linux", + "type": "rectangle", + "pos": { + "x": 912, + "y": 552 + }, + "width": 800, + "height": 200, + "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": "linux", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 35, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.macos", + "type": "rectangle", + "pos": { + "x": 72, + "y": 792 + }, + "width": 800, + "height": 200, + "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": "macos", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 45, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "todo root level grid.kubernetes", + "type": "rectangle", + "pos": { + "x": 912, + "y": 792 + }, + "width": 800, + "height": 200, + "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": "kubernetes", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 80, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [], + "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/dagger_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg new file mode 100644 index 000000000..8ae60a5db --- /dev/null +++ b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg @@ -0,0 +1,102 @@ +todo root level gridflowdagger engineany docker compatible runtimeany ciwindowslinuxmacoskubernetes + + + \ No newline at end of file From c958269b03f2b9731a788e4b112482836ff89768 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 21:38:08 -0700 Subject: [PATCH 10/33] more dynamic grid sizing according to node sizes --- d2graph/grid.go | 2 +- d2layouts/d2grid/grid.go | 91 ++++---- d2layouts/d2grid/layout.go | 251 ++++++++++++++++++++--- e2etests/testdata/files/dagger_grid.d2 | 80 ++++++-- e2etests/testdata/files/teleport_grid.d2 | 2 +- 5 files changed, 315 insertions(+), 111 deletions(-) diff --git a/d2graph/grid.go b/d2graph/grid.go index b746f11a3..1ff029bba 100644 --- a/d2graph/grid.go +++ b/d2graph/grid.go @@ -1,6 +1,6 @@ package d2graph func (obj *Object) IsGrid() bool { - return obj != nil && obj.Attributes != nil && len(obj.ChildrenArray) != 0 && + return obj != nil && obj.Attributes != nil && (obj.Attributes.Rows != nil || obj.Attributes.Columns != nil) } diff --git a/d2layouts/d2grid/grid.go b/d2layouts/d2grid/grid.go index 4a743c60f..22cc23afd 100644 --- a/d2layouts/d2grid/grid.go +++ b/d2layouts/d2grid/grid.go @@ -1,7 +1,6 @@ package d2grid import ( - "math" "strconv" "oss.terrastruct.com/d2/d2graph" @@ -13,6 +12,8 @@ type grid struct { rows int columns int + rowDominant bool + cellWidth float64 cellHeight float64 width float64 @@ -29,64 +30,38 @@ func newGrid(root *d2graph.Object) *grid { } // compute exact row/column count based on values entered - if g.rows == 0 { - // set rows based on number of columns - g.rows = len(g.nodes) / g.columns - if len(g.nodes)%g.columns != 0 { - g.rows++ - } - } else if g.columns == 0 { - // set columns based on number of rows - g.columns = len(g.nodes) / g.rows - if len(g.nodes)%g.rows != 0 { - g.columns++ - } + if g.columns == 0 { + g.rowDominant = true + } else if g.rows == 0 { + g.rowDominant = false } else { - // rows and columns specified (add more rows if needed) + // if keyword rows is first, rows are primary, columns secondary. + if root.Attributes.Rows.MapKey.Range.Before(root.Attributes.Columns.MapKey.Range) { + g.rowDominant = true + } + + // rows and columns specified, but we want to continue naturally if user enters more nodes + // e.g. 2 rows, 3 columns specified + g node added: │ with 3 columns, 2 rows: + // . original add row add column │ original add row add column + // . ┌───────┐ ┌───────┐ ┌─────────┐ │ ┌───────┐ ┌───────┐ ┌─────────┐ + // . │ a b c │ │ a b c │ │ a b c d │ │ │ a c e │ │ a d g │ │ a c e g │ + // . │ d e f │ │ d e f │ │ e f g │ │ │ b d f │ │ b e │ │ b d f │ + // . └───────┘ │ g │ └─────────┘ │ └───────┘ │ c f │ └─────────┘ + // . └───────┘ ▲ │ └───────┘ ▲ + // . ▲ └─existing nodes modified │ ▲ └─existing nodes preserved + // . └─existing rows preserved │ └─existing rows modified capacity := g.rows * g.columns for capacity < len(g.nodes) { - g.rows++ - capacity += g.columns + if g.rowDominant { + g.rows++ + capacity += g.columns + } else { + g.columns++ + capacity += g.rows + } } } - // if we have the following nodes for a 2 row, 3 column grid - // . ┌A──────────────────┐ ┌B─────┐ ┌C────────────┐ ┌D───────────┐ ┌E───────────────────┐ - // . │ │ │ │ │ │ │ │ │ │ - // . │ │ │ │ │ │ │ │ │ │ - // . └───────────────────┘ │ │ │ │ │ │ │ │ - // . │ │ └─────────────┘ │ │ │ │ - // . │ │ │ │ └────────────────────┘ - // . └──────┘ │ │ - // . └────────────┘ - // Then we must get the max width and max height to determine the grid cell size - // . maxWidth├────────────────────┤ - // . ┌A───────────────────┐ ┌B───────────────────┐ ┌C───────────────────┐ ┬maxHeight - // . │ │ │ │ │ │ │ - // . │ │ │ │ │ │ │ - // . │ │ │ │ │ │ │ - // . │ │ │ │ │ │ │ - // . │ │ │ │ │ │ │ - // . │ │ │ │ │ │ │ - // . └────────────────────┘ └────────────────────┘ └────────────────────┘ ┴ - // . ┌D───────────────────┐ ┌E───────────────────┐ - // . │ │ │ │ - // . │ │ │ │ - // . │ │ │ │ - // . │ │ │ │ - // . │ │ │ │ - // . │ │ │ │ - // . └────────────────────┘ └────────────────────┘ - var maxWidth, maxHeight float64 - for _, n := range g.nodes { - maxWidth = math.Max(maxWidth, n.Width) - maxHeight = math.Max(maxHeight, n.Height) - } - g.cellWidth = maxWidth - g.cellHeight = maxHeight - g.width = maxWidth + (float64(g.columns)-1)*(maxWidth+HORIZONTAL_PAD) - g.height = maxHeight + (float64(g.rows)-1)*(maxHeight+VERTICAL_PAD) - return &g } @@ -96,3 +71,13 @@ func (g *grid) shift(dx, dy float64) { obj.TopLeft.Y += dy } } + +func (g *grid) cleanup(obj *d2graph.Object, graph *d2graph.Graph) { + obj.Children = make(map[string]*d2graph.Object) + obj.ChildrenArray = make([]*d2graph.Object, 0) + for _, child := range g.nodes { + obj.Children[child.ID] = child + obj.ChildrenArray = append(obj.ChildrenArray, child) + } + graph.Objects = append(graph.Objects, g.nodes...) +} diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index e9d68bccd..755146535 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -2,6 +2,7 @@ package d2grid import ( "context" + "math" "sort" "oss.terrastruct.com/d2/d2graph" @@ -33,7 +34,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d return err } - if g.Root.IsGrid() { + if g.Root.IsGrid() && len(g.Root.ChildrenArray) != 0 { g.Root.TopLeft = geo.NewPoint(0, 0) } else if err := layout(ctx, g); err != nil { return err @@ -93,20 +94,207 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { grid := newGrid(obj) + // assume we have the following nodes to layout: + // . ┌A──────────────┐ ┌B──┐ ┌C─────────┐ ┌D────────┐ ┌E────────────────┐ + // . └───────────────┘ │ │ │ │ │ │ │ │ + // . │ │ └──────────┘ │ │ │ │ + // . │ │ │ │ └─────────────────┘ + // . └───┘ │ │ + // . └─────────┘ + // Note: if the grid is row dominant, all nodes should be the same height (same width if column dominant) + // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┌D────────┐ ┌E────────────────┐ + // . ├ ─ ─ ─ ─ ─ ─ ─┤ │ │ │ │ │ │ │ │ + // . │ │ │ │ ├ ─ ─ ─ ─ ─┤ │ │ │ │ + // . │ │ │ │ │ │ │ │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ┤ + // . │ │ ├ ─ ┤ │ │ │ │ │ │ + // . └──────────────┘ └───┘ └──────────┘ └─────────┘ └─────────────────┘ - // position nodes - cursor := geo.NewPoint(0, 0) - for i := 0; i < grid.rows; i++ { - for j := 0; j < grid.columns; j++ { - n := grid.nodes[i*grid.columns+j] - n.Width = grid.cellWidth - n.Height = grid.cellHeight - n.TopLeft = cursor.Copy() - cursor.X += grid.cellWidth + HORIZONTAL_PAD - } - cursor.X = 0 - cursor.Y += float64(grid.cellHeight) + VERTICAL_PAD + // we want to split up the total width across the N rows or columns as evenly as possible + var totalWidth, totalHeight float64 + for _, n := range grid.nodes { + totalWidth += n.Width + totalHeight += n.Height } + totalWidth += HORIZONTAL_PAD * float64(len(grid.nodes)-1) + totalHeight += VERTICAL_PAD * float64(len(grid.nodes)-1) + + layout := [][]int{{}} + if grid.rowDominant { + targetWidth := totalWidth / float64(grid.rows) + rowWidth := 0. + rowIndex := 0 + for i, n := range grid.nodes { + layout[rowIndex] = append(layout[rowIndex], i) + rowWidth += n.Width + HORIZONTAL_PAD + // add a new row if we pass the target width and there are more nodes + if rowWidth > targetWidth && i < len(grid.nodes)-1 { + layout = append(layout, []int{}) + rowIndex++ + rowWidth = 0 + } + } + } else { + targetHeight := totalHeight / float64(grid.columns) + columnHeight := 0. + columnIndex := 0 + for i, n := range grid.nodes { + layout[columnIndex] = append(layout[columnIndex], i) + columnHeight += n.Height + VERTICAL_PAD + if columnHeight > targetHeight && i < len(grid.nodes)-1 { + layout = append(layout, []int{}) + columnIndex++ + columnHeight = 0 + } + } + } + + cursor := geo.NewPoint(0, 0) + var maxY, maxX float64 + if grid.rowDominant { + // if we have 2 rows, then each row's nodes should have the same height + // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) + // . ├ ─ ─ ─ ─ ─ ─ ─┤ │ │ │ │ │ + // . │ │ │ │ ├ ─ ─ ─ ─ ─┤ │ + // . │ │ │ │ │ │ │ + // . └──────────────┘ └───┘ └──────────┘ ┴ + // . ┌D────────┐ ┌E────────────────┐ ┬ maxHeight(D,E) + // . │ │ │ │ │ + // . │ │ │ │ │ + // . │ │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ + // . │ │ │ │ │ + // . └─────────┘ └─────────────────┘ ┴ + rowWidths := []float64{} + for _, row := range layout { + rowHeight := 0. + for _, nodeIndex := range row { + n := grid.nodes[nodeIndex] + n.TopLeft = cursor.Copy() + cursor.X += n.Width + HORIZONTAL_PAD + rowHeight = math.Max(rowHeight, n.Height) + } + rowWidth := cursor.X - HORIZONTAL_PAD + rowWidths = append(rowWidths, rowWidth) + maxX = math.Max(maxX, rowWidth) + + // set all nodes in row to the same height + for _, nodeIndex := range row { + n := grid.nodes[nodeIndex] + n.Height = rowHeight + } + + // new row + cursor.X = 0 + cursor.Y += rowHeight + VERTICAL_PAD + } + maxY = cursor.Y - VERTICAL_PAD + + // then expand thinnest nodes to make each row the same width + // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . │ │ │ │ │ │ │ + // . └──────────────┘ └───┘ └──────────┘ ┴ + // . ┌D────────┬────┐ ┌E────────────────┐ ┬ maxHeight(D,E) + // . │ │ │ │ │ + // . │ │ │ │ │ │ + // . │ │ │ │ │ + // . │ │ │ │ │ │ + // . └─────────┴────┘ └─────────────────┘ ┴ + for i, row := range layout { + rowWidth := rowWidths[i] + if rowWidth == maxX { + continue + } + delta := maxX - rowWidth + nodes := []*d2graph.Object{} + var widest float64 + for _, nodeIndex := range row { + n := grid.nodes[nodeIndex] + widest = math.Max(widest, n.Width) + nodes = append(nodes, n) + } + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].Width < nodes[j].Width + }) + // expand smaller nodes to fill remaining space + for _, n := range nodes { + if n.Width < widest { + var index int + for i, nodeIndex := range row { + if n == grid.nodes[nodeIndex] { + index = i + break + } + } + grow := math.Min(widest-n.Width, delta) + n.Width += grow + // shift following nodes + for i := index + 1; i < len(row); i++ { + grid.nodes[row[i]].TopLeft.X += grow + } + delta -= grow + if delta <= 0 { + break + } + } + } + if delta > 0 { + grow := delta / float64(len(row)) + for i := len(row) - 1; i >= 0; i-- { + n := grid.nodes[row[i]] + n.TopLeft.X += grow * float64(i) + n.Width += grow + delta -= grow + } + } + } + } else { + // if we have 3 columns, then each column's nodes should have the same width + // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ + // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ + // . └──────────────┘ │ │ │ │ + // . ┌B──┬──────────┐ └──────────┘ │ │ + // . │ │ ┌D────────┬┐ └─────────────────┘ + // . │ │ │ │ │ + // . │ │ │ ││ + // . └───┴──────────┘ │ │ + // . │ ││ + // . └─────────┴┘ + for _, column := range layout { + columnWidth := 0. + for _, nodeIndex := range column { + n := grid.nodes[nodeIndex] + n.TopLeft = cursor.Copy() + cursor.Y += n.Height + VERTICAL_PAD + columnWidth = math.Max(columnWidth, n.Width) + } + maxY = math.Max(maxY, cursor.Y-VERTICAL_PAD) + // set all nodes in column to the same width + for _, nodeIndex := range column { + n := grid.nodes[nodeIndex] + n.Width = columnWidth + } + + // new column + cursor.Y = 0 + cursor.X += columnWidth + HORIZONTAL_PAD + } + maxX = cursor.X - HORIZONTAL_PAD + // then expand shortest nodes to make each column the same height + // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ + // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ + // . ├ ─ ─ ─ ─ ─ ─ ┤ │ │ │ │ + // . │ │ └──────────┘ │ │ + // . └──────────────┘ ┌D─────────┐ ├ ─ ─ ─ ─ ─ ─ ─ ─ ┤ + // . ┌B─────────────┐ │ │ │ │ + // . │ │ │ │ │ │ + // . │ │ │ │ │ │ + // . │ │ │ │ │ │ + // . └──────────────┘ └──────────┘ └─────────────────┘ + // TODO see rows + } + grid.width = maxX + grid.height = maxY // position labels and icons for _, n := range grid.nodes { @@ -125,37 +313,32 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { // - 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(g *d2graph.Graph, grids map[string]*grid, objectsOrder map[string]int) { - var objects []*d2graph.Object - if g.Root.IsGrid() { - objects = []*d2graph.Object{g.Root} - } else { - objects = g.Objects +func cleanup(graph *d2graph.Graph, grids map[string]*grid, objectsOrder 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()] + }) + }() + + if graph.Root.IsGrid() { + grid, exists := grids[graph.Root.AbsID()] + if exists { + grid.cleanup(graph.Root, graph) + return + } } - for _, obj := range objects { + + for _, obj := range graph.Objects { grid, exists := grids[obj.AbsID()] if !exists { continue } obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - // shift the grid from (0, 0) grid.shift( obj.TopLeft.X+CONTAINER_PADDING, obj.TopLeft.Y+CONTAINER_PADDING, ) - - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = make([]*d2graph.Object, 0) - for _, child := range grid.nodes { - obj.Children[child.ID] = child - obj.ChildrenArray = append(obj.ChildrenArray, child) - } - - g.Objects = append(g.Objects, grid.nodes...) + grid.cleanup(obj, graph) } - - sort.SliceStable(g.Objects, func(i, j int) bool { - return objectsOrder[g.Objects[i].AbsID()] < objectsOrder[g.Objects[j].AbsID()] - }) } diff --git a/e2etests/testdata/files/dagger_grid.d2 b/e2etests/testdata/files/dagger_grid.d2 index 66ea0432f..b3db8ac9a 100644 --- a/e2etests/testdata/files/dagger_grid.d2 +++ b/e2etests/testdata/files/dagger_grid.d2 @@ -1,25 +1,61 @@ -todo root level grid: { - rows: 4 +rows: 4 +style.fill: black - flow: { - width: 800 - height: 200 +flow: "" { + width: 800 + height: 200 + style: { + fill: cornflowerblue } - - dagger engine: { - width: 800 - } - - any docker compatible runtime: { - width: 800 - } - - any ci: { - width: 800 - } - - windows - linux - macos - kubernetes +} + +DAGGER ENGINE: { + width: 800 + style: { + fill: beige + stroke: darkcyan + font-color: blue + stroke-width: 8 + } +} + +ANY DOCKER COMPATIBLE RUNTIME: { + width: 800 + style: { + fill: lightcyan + stroke: darkcyan + font-color: black + stroke-width: 8 + } + icon: https://icons.terrastruct.com/dev%2Fdocker.svg +} + +ANY CI: { + style: { + fill: gold + stroke: maroon + font-color: maroon + stroke-width: 8 + } +} + +WINDOWS.style: { + font-color: white + fill: darkcyan + stroke: black +} +LINUX.style: { + font-color: white + fill: darkcyan + stroke: black +} +MACOS.style: { + font-color: white + fill: darkcyan + stroke: black +} +KUBERNETES.style: { + font-color: white + fill: darkcyan + stroke: black } diff --git a/e2etests/testdata/files/teleport_grid.d2 b/e2etests/testdata/files/teleport_grid.d2 index fc8e6476e..ca6b0acac 100644 --- a/e2etests/testdata/files/teleport_grid.d2 +++ b/e2etests/testdata/files/teleport_grid.d2 @@ -9,7 +9,7 @@ teleport -> identity provider teleport <- identity provider users: "" { - rows: 2 + columns: 1 Engineers: { shape: circle From bb090becb88489fb9fa03811b57ec22ab533f3ee Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 3 Apr 2023 21:38:31 -0700 Subject: [PATCH 11/33] update tests --- .../stable/dagger_grid/dagre/board.exp.json | 349 ++++++++--------- .../stable/dagger_grid/dagre/sketch.exp.svg | 163 ++++---- .../stable/dagger_grid/elk/board.exp.json | 353 ++++++++---------- .../stable/dagger_grid/elk/sketch.exp.svg | 163 ++++---- .../stable/teleport_grid/dagre/board.exp.json | 144 +++---- .../stable/teleport_grid/dagre/sketch.exp.svg | 184 ++++----- .../stable/teleport_grid/elk/board.exp.json | 152 ++++---- .../stable/teleport_grid/elk/sketch.exp.svg | 184 ++++----- 8 files changed, 810 insertions(+), 882 deletions(-) diff --git a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json index bd49385e0..b438f9716 100644 --- a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json @@ -4,19 +4,19 @@ "fontFamily": "SourceSansPro", "shapes": [ { - "id": "todo root level grid", + "id": "flow", "type": "rectangle", "pos": { "x": 0, "y": 0 }, - "width": 1760, - "height": 1040, + "width": 800, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B4", + "fill": "cornflowerblue", "stroke": "B1", "shadow": false, "3d": false, @@ -30,35 +30,129 @@ "fields": null, "methods": null, "columns": null, - "label": "todo root level grid", - "fontSize": 28, + "label": "", + "fontSize": 16, "fontFamily": "DEFAULT", "language": "", "color": "N1", "italic": false, - "bold": false, + "bold": true, "underline": false, - "labelWidth": 222, - "labelHeight": 36, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "DAGGER ENGINE", + "type": "rectangle", + "pos": { + "x": 0, + "y": 240 + }, + "width": 800, + "height": 61, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "borderRadius": 0, + "fill": "beige", + "stroke": "darkcyan", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "DAGGER ENGINE", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "blue", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 114, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "ANY DOCKER COMPATIBLE RUNTIME", + "type": "rectangle", + "pos": { + "x": 0, + "y": 341 + }, + "width": 800, + "height": 87, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "borderRadius": 0, + "fill": "lightcyan", + "stroke": "darkcyan", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/docker.svg", + "RawPath": "/dev%2Fdocker.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ANY DOCKER COMPATIBLE RUNTIME", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "black", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 255, + "labelHeight": 21, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "todo root level grid.flow", + "id": "ANY CI", "type": "rectangle", "pos": { - "x": 60, - "y": 60 + "x": 0, + "y": 468 }, - "width": 800, - "height": 200, + "width": 139, + "height": 66, "opacity": 1, "strokeDash": 0, - "strokeWidth": 2, + "strokeWidth": 8, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "gold", + "stroke": "maroon", "shadow": false, "3d": false, "multiple": false, @@ -71,35 +165,35 @@ "fields": null, "methods": null, "columns": null, - "label": "flow", + "label": "ANY CI", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "maroon", "italic": false, "bold": true, "underline": false, - "labelWidth": 32, + "labelWidth": 46, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.dagger engine", + "id": "WINDOWS", "type": "rectangle", "pos": { - "x": 900, - "y": 60 + "x": 179, + "y": 468 }, - "width": 800, - "height": 200, + "width": 117, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -112,35 +206,35 @@ "fields": null, "methods": null, "columns": null, - "label": "dagger engine", + "label": "WINDOWS", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 101, + "labelWidth": 72, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.any docker compatible runtime", + "id": "LINUX", "type": "rectangle", "pos": { - "x": 60, - "y": 300 + "x": 336, + "y": 468 }, - "width": 800, - "height": 200, + "width": 139, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -153,35 +247,35 @@ "fields": null, "methods": null, "columns": null, - "label": "any docker compatible runtime", + "label": "LINUX", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 222, + "labelWidth": 43, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.any ci", + "id": "MACOS", "type": "rectangle", "pos": { - "x": 900, - "y": 300 + "x": 515, + "y": 468 }, - "width": 800, - "height": 200, + "width": 106, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -194,35 +288,35 @@ "fields": null, "methods": null, "columns": null, - "label": "any ci", + "label": "MACOS", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 41, + "labelWidth": 50, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.windows", + "id": "KUBERNETES", "type": "rectangle", "pos": { - "x": 60, - "y": 540 + "x": 661, + "y": 468 }, - "width": 800, - "height": 200, + "width": 139, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -235,142 +329,19 @@ "fields": null, "methods": null, "columns": null, - "label": "windows", + "label": "KUBERNETES", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 64, + "labelWidth": 94, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 - }, - { - "id": "todo root level grid.linux", - "type": "rectangle", - "pos": { - "x": 900, - "y": 540 - }, - "width": 800, - "height": 200, - "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": "linux", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 35, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "todo root level grid.macos", - "type": "rectangle", - "pos": { - "x": 60, - "y": 780 - }, - "width": 800, - "height": 200, - "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": "macos", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 45, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "todo root level grid.kubernetes", - "type": "rectangle", - "pos": { - "x": 900, - "y": 780 - }, - "width": 800, - "height": 200, - "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": "kubernetes", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 80, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 + "level": 1 } ], "connections": [], @@ -387,7 +358,7 @@ "strokeDash": 0, "strokeWidth": 0, "borderRadius": 0, - "fill": "N7", + "fill": "black", "stroke": "", "shadow": false, "3d": false, diff --git a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg index 298a9765e..2e9ae781c 100644 --- a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg @@ -1,17 +1,10 @@ -todo root level gridflowdagger engineany docker compatible runtimeany ciwindowslinuxmacoskubernetes - + .d2-1379472985 .fill-N1{fill:#0A0F25;} + .d2-1379472985 .fill-N2{fill:#676C7E;} + .d2-1379472985 .fill-N3{fill:#9499AB;} + .d2-1379472985 .fill-N4{fill:#CFD2DD;} + .d2-1379472985 .fill-N5{fill:#DEE1EB;} + .d2-1379472985 .fill-N6{fill:#EEF1F8;} + .d2-1379472985 .fill-N7{fill:#FFFFFF;} + .d2-1379472985 .fill-B1{fill:#0D32B2;} + .d2-1379472985 .fill-B2{fill:#0D32B2;} + .d2-1379472985 .fill-B3{fill:#E3E9FD;} + .d2-1379472985 .fill-B4{fill:#E3E9FD;} + .d2-1379472985 .fill-B5{fill:#EDF0FD;} + .d2-1379472985 .fill-B6{fill:#F7F8FE;} + .d2-1379472985 .fill-AA2{fill:#4A6FF3;} + .d2-1379472985 .fill-AA4{fill:#EDF0FD;} + .d2-1379472985 .fill-AA5{fill:#F7F8FE;} + .d2-1379472985 .fill-AB4{fill:#EDF0FD;} + .d2-1379472985 .fill-AB5{fill:#F7F8FE;} + .d2-1379472985 .stroke-N1{stroke:#0A0F25;} + .d2-1379472985 .stroke-N2{stroke:#676C7E;} + .d2-1379472985 .stroke-N3{stroke:#9499AB;} + .d2-1379472985 .stroke-N4{stroke:#CFD2DD;} + .d2-1379472985 .stroke-N5{stroke:#DEE1EB;} + .d2-1379472985 .stroke-N6{stroke:#EEF1F8;} + .d2-1379472985 .stroke-N7{stroke:#FFFFFF;} + .d2-1379472985 .stroke-B1{stroke:#0D32B2;} + .d2-1379472985 .stroke-B2{stroke:#0D32B2;} + .d2-1379472985 .stroke-B3{stroke:#E3E9FD;} + .d2-1379472985 .stroke-B4{stroke:#E3E9FD;} + .d2-1379472985 .stroke-B5{stroke:#EDF0FD;} + .d2-1379472985 .stroke-B6{stroke:#F7F8FE;} + .d2-1379472985 .stroke-AA2{stroke:#4A6FF3;} + .d2-1379472985 .stroke-AA4{stroke:#EDF0FD;} + .d2-1379472985 .stroke-AA5{stroke:#F7F8FE;} + .d2-1379472985 .stroke-AB4{stroke:#EDF0FD;} + .d2-1379472985 .stroke-AB5{stroke:#F7F8FE;} + .d2-1379472985 .background-color-N1{background-color:#0A0F25;} + .d2-1379472985 .background-color-N2{background-color:#676C7E;} + .d2-1379472985 .background-color-N3{background-color:#9499AB;} + .d2-1379472985 .background-color-N4{background-color:#CFD2DD;} + .d2-1379472985 .background-color-N5{background-color:#DEE1EB;} + .d2-1379472985 .background-color-N6{background-color:#EEF1F8;} + .d2-1379472985 .background-color-N7{background-color:#FFFFFF;} + .d2-1379472985 .background-color-B1{background-color:#0D32B2;} + .d2-1379472985 .background-color-B2{background-color:#0D32B2;} + .d2-1379472985 .background-color-B3{background-color:#E3E9FD;} + .d2-1379472985 .background-color-B4{background-color:#E3E9FD;} + .d2-1379472985 .background-color-B5{background-color:#EDF0FD;} + .d2-1379472985 .background-color-B6{background-color:#F7F8FE;} + .d2-1379472985 .background-color-AA2{background-color:#4A6FF3;} + .d2-1379472985 .background-color-AA4{background-color:#EDF0FD;} + .d2-1379472985 .background-color-AA5{background-color:#F7F8FE;} + .d2-1379472985 .background-color-AB4{background-color:#EDF0FD;} + .d2-1379472985 .background-color-AB5{background-color:#F7F8FE;} + .d2-1379472985 .color-N1{color:#0A0F25;} + .d2-1379472985 .color-N2{color:#676C7E;} + .d2-1379472985 .color-N3{color:#9499AB;} + .d2-1379472985 .color-N4{color:#CFD2DD;} + .d2-1379472985 .color-N5{color:#DEE1EB;} + .d2-1379472985 .color-N6{color:#EEF1F8;} + .d2-1379472985 .color-N7{color:#FFFFFF;} + .d2-1379472985 .color-B1{color:#0D32B2;} + .d2-1379472985 .color-B2{color:#0D32B2;} + .d2-1379472985 .color-B3{color:#E3E9FD;} + .d2-1379472985 .color-B4{color:#E3E9FD;} + .d2-1379472985 .color-B5{color:#EDF0FD;} + .d2-1379472985 .color-B6{color:#F7F8FE;} + .d2-1379472985 .color-AA2{color:#4A6FF3;} + .d2-1379472985 .color-AA4{color:#EDF0FD;} + .d2-1379472985 .color-AA5{color:#F7F8FE;} + .d2-1379472985 .color-AB4{color:#EDF0FD;} + .d2-1379472985 .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}]]>DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES + \ No newline at end of file diff --git a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json index 36716f307..b438f9716 100644 --- a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json @@ -4,19 +4,19 @@ "fontFamily": "SourceSansPro", "shapes": [ { - "id": "todo root level grid", + "id": "flow", "type": "rectangle", "pos": { - "x": 12, - "y": 12 + "x": 0, + "y": 0 }, - "width": 1760, - "height": 1040, + "width": 800, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B4", + "fill": "cornflowerblue", "stroke": "B1", "shadow": false, "3d": false, @@ -30,35 +30,129 @@ "fields": null, "methods": null, "columns": null, - "label": "todo root level grid", - "fontSize": 28, + "label": "", + "fontSize": 16, "fontFamily": "DEFAULT", "language": "", "color": "N1", "italic": false, - "bold": false, + "bold": true, "underline": false, - "labelWidth": 222, - "labelHeight": 36, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "DAGGER ENGINE", + "type": "rectangle", + "pos": { + "x": 0, + "y": 240 + }, + "width": 800, + "height": 61, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "borderRadius": 0, + "fill": "beige", + "stroke": "darkcyan", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "DAGGER ENGINE", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "blue", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 114, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "ANY DOCKER COMPATIBLE RUNTIME", + "type": "rectangle", + "pos": { + "x": 0, + "y": 341 + }, + "width": 800, + "height": 87, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "borderRadius": 0, + "fill": "lightcyan", + "stroke": "darkcyan", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "icons.terrastruct.com", + "Path": "/dev/docker.svg", + "RawPath": "/dev%2Fdocker.svg", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ANY DOCKER COMPATIBLE RUNTIME", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "black", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 255, + "labelHeight": 21, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "todo root level grid.flow", + "id": "ANY CI", "type": "rectangle", "pos": { - "x": 72, - "y": 72 + "x": 0, + "y": 468 }, - "width": 800, - "height": 200, + "width": 139, + "height": 66, "opacity": 1, "strokeDash": 0, - "strokeWidth": 2, + "strokeWidth": 8, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "gold", + "stroke": "maroon", "shadow": false, "3d": false, "multiple": false, @@ -71,35 +165,35 @@ "fields": null, "methods": null, "columns": null, - "label": "flow", + "label": "ANY CI", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "maroon", "italic": false, "bold": true, "underline": false, - "labelWidth": 32, + "labelWidth": 46, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.dagger engine", + "id": "WINDOWS", "type": "rectangle", "pos": { - "x": 912, - "y": 72 + "x": 179, + "y": 468 }, - "width": 800, - "height": 200, + "width": 117, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -112,35 +206,35 @@ "fields": null, "methods": null, "columns": null, - "label": "dagger engine", + "label": "WINDOWS", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 101, + "labelWidth": 72, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.any docker compatible runtime", + "id": "LINUX", "type": "rectangle", "pos": { - "x": 72, - "y": 312 + "x": 336, + "y": 468 }, - "width": 800, - "height": 200, + "width": 139, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -153,35 +247,35 @@ "fields": null, "methods": null, "columns": null, - "label": "any docker compatible runtime", + "label": "LINUX", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 222, + "labelWidth": 43, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.any ci", + "id": "MACOS", "type": "rectangle", "pos": { - "x": 912, - "y": 312 + "x": 515, + "y": 468 }, - "width": 800, - "height": 200, + "width": 106, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -194,35 +288,35 @@ "fields": null, "methods": null, "columns": null, - "label": "any ci", + "label": "MACOS", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 41, + "labelWidth": 50, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 + "level": 1 }, { - "id": "todo root level grid.windows", + "id": "KUBERNETES", "type": "rectangle", "pos": { - "x": 72, - "y": 552 + "x": 661, + "y": 468 }, - "width": 800, - "height": 200, + "width": 139, + "height": 66, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, - "fill": "B5", - "stroke": "B1", + "fill": "darkcyan", + "stroke": "black", "shadow": false, "3d": false, "multiple": false, @@ -235,142 +329,19 @@ "fields": null, "methods": null, "columns": null, - "label": "windows", + "label": "KUBERNETES", "fontSize": 16, "fontFamily": "DEFAULT", "language": "", - "color": "N1", + "color": "white", "italic": false, "bold": true, "underline": false, - "labelWidth": 64, + "labelWidth": 94, "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, - "level": 2 - }, - { - "id": "todo root level grid.linux", - "type": "rectangle", - "pos": { - "x": 912, - "y": 552 - }, - "width": 800, - "height": 200, - "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": "linux", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 35, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "todo root level grid.macos", - "type": "rectangle", - "pos": { - "x": 72, - "y": 792 - }, - "width": 800, - "height": 200, - "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": "macos", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 45, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "todo root level grid.kubernetes", - "type": "rectangle", - "pos": { - "x": 912, - "y": 792 - }, - "width": 800, - "height": 200, - "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": "kubernetes", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 80, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 + "level": 1 } ], "connections": [], @@ -387,7 +358,7 @@ "strokeDash": 0, "strokeWidth": 0, "borderRadius": 0, - "fill": "N7", + "fill": "black", "stroke": "", "shadow": false, "3d": false, diff --git a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg index 8ae60a5db..2e9ae781c 100644 --- a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg @@ -1,17 +1,10 @@ -todo root level gridflowdagger engineany docker compatible runtimeany ciwindowslinuxmacoskubernetes - + .d2-1379472985 .fill-N1{fill:#0A0F25;} + .d2-1379472985 .fill-N2{fill:#676C7E;} + .d2-1379472985 .fill-N3{fill:#9499AB;} + .d2-1379472985 .fill-N4{fill:#CFD2DD;} + .d2-1379472985 .fill-N5{fill:#DEE1EB;} + .d2-1379472985 .fill-N6{fill:#EEF1F8;} + .d2-1379472985 .fill-N7{fill:#FFFFFF;} + .d2-1379472985 .fill-B1{fill:#0D32B2;} + .d2-1379472985 .fill-B2{fill:#0D32B2;} + .d2-1379472985 .fill-B3{fill:#E3E9FD;} + .d2-1379472985 .fill-B4{fill:#E3E9FD;} + .d2-1379472985 .fill-B5{fill:#EDF0FD;} + .d2-1379472985 .fill-B6{fill:#F7F8FE;} + .d2-1379472985 .fill-AA2{fill:#4A6FF3;} + .d2-1379472985 .fill-AA4{fill:#EDF0FD;} + .d2-1379472985 .fill-AA5{fill:#F7F8FE;} + .d2-1379472985 .fill-AB4{fill:#EDF0FD;} + .d2-1379472985 .fill-AB5{fill:#F7F8FE;} + .d2-1379472985 .stroke-N1{stroke:#0A0F25;} + .d2-1379472985 .stroke-N2{stroke:#676C7E;} + .d2-1379472985 .stroke-N3{stroke:#9499AB;} + .d2-1379472985 .stroke-N4{stroke:#CFD2DD;} + .d2-1379472985 .stroke-N5{stroke:#DEE1EB;} + .d2-1379472985 .stroke-N6{stroke:#EEF1F8;} + .d2-1379472985 .stroke-N7{stroke:#FFFFFF;} + .d2-1379472985 .stroke-B1{stroke:#0D32B2;} + .d2-1379472985 .stroke-B2{stroke:#0D32B2;} + .d2-1379472985 .stroke-B3{stroke:#E3E9FD;} + .d2-1379472985 .stroke-B4{stroke:#E3E9FD;} + .d2-1379472985 .stroke-B5{stroke:#EDF0FD;} + .d2-1379472985 .stroke-B6{stroke:#F7F8FE;} + .d2-1379472985 .stroke-AA2{stroke:#4A6FF3;} + .d2-1379472985 .stroke-AA4{stroke:#EDF0FD;} + .d2-1379472985 .stroke-AA5{stroke:#F7F8FE;} + .d2-1379472985 .stroke-AB4{stroke:#EDF0FD;} + .d2-1379472985 .stroke-AB5{stroke:#F7F8FE;} + .d2-1379472985 .background-color-N1{background-color:#0A0F25;} + .d2-1379472985 .background-color-N2{background-color:#676C7E;} + .d2-1379472985 .background-color-N3{background-color:#9499AB;} + .d2-1379472985 .background-color-N4{background-color:#CFD2DD;} + .d2-1379472985 .background-color-N5{background-color:#DEE1EB;} + .d2-1379472985 .background-color-N6{background-color:#EEF1F8;} + .d2-1379472985 .background-color-N7{background-color:#FFFFFF;} + .d2-1379472985 .background-color-B1{background-color:#0D32B2;} + .d2-1379472985 .background-color-B2{background-color:#0D32B2;} + .d2-1379472985 .background-color-B3{background-color:#E3E9FD;} + .d2-1379472985 .background-color-B4{background-color:#E3E9FD;} + .d2-1379472985 .background-color-B5{background-color:#EDF0FD;} + .d2-1379472985 .background-color-B6{background-color:#F7F8FE;} + .d2-1379472985 .background-color-AA2{background-color:#4A6FF3;} + .d2-1379472985 .background-color-AA4{background-color:#EDF0FD;} + .d2-1379472985 .background-color-AA5{background-color:#F7F8FE;} + .d2-1379472985 .background-color-AB4{background-color:#EDF0FD;} + .d2-1379472985 .background-color-AB5{background-color:#F7F8FE;} + .d2-1379472985 .color-N1{color:#0A0F25;} + .d2-1379472985 .color-N2{color:#676C7E;} + .d2-1379472985 .color-N3{color:#9499AB;} + .d2-1379472985 .color-N4{color:#CFD2DD;} + .d2-1379472985 .color-N5{color:#DEE1EB;} + .d2-1379472985 .color-N6{color:#EEF1F8;} + .d2-1379472985 .color-N7{color:#FFFFFF;} + .d2-1379472985 .color-B1{color:#0D32B2;} + .d2-1379472985 .color-B2{color:#0D32B2;} + .d2-1379472985 .color-B3{color:#E3E9FD;} + .d2-1379472985 .color-B4{color:#E3E9FD;} + .d2-1379472985 .color-B5{color:#EDF0FD;} + .d2-1379472985 .color-B6{color:#F7F8FE;} + .d2-1379472985 .color-AA2{color:#4A6FF3;} + .d2-1379472985 .color-AA4{color:#EDF0FD;} + .d2-1379472985 .color-AA5{color:#F7F8FE;} + .d2-1379472985 .color-AB4{color:#EDF0FD;} + .d2-1379472985 .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}]]>DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES + \ No newline at end of file diff --git a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json index d1ba12de3..b9acb9863 100644 --- a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 0, - "y": 203 + "y": 204 }, "width": 272, - "height": 464, + "height": 461, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -90,10 +90,10 @@ "type": "rectangle", "pos": { "x": 1050, - "y": 263 + "y": 283 }, - "width": 764, - "height": 344, + "width": 584, + "height": 303, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -130,10 +130,10 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 2316, + "x": 2136, "y": 0 }, - "width": 920, + "width": 820, "height": 212, "opacity": 1, "strokeDash": 0, @@ -171,10 +171,10 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 2448, + "x": 2255, "y": 232 }, - "width": 656, + "width": 582, "height": 344, "opacity": 1, "strokeDash": 0, @@ -212,7 +212,7 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 2676, + "x": 2446, "y": 596 }, "width": 201, @@ -266,7 +266,7 @@ "type": "oval", "pos": { "x": 60, - "y": 263 + "y": 264 }, "width": 152, "height": 152, @@ -319,10 +319,10 @@ "type": "oval", "pos": { "x": 60, - "y": 455 + "y": 456 }, "width": 152, - "height": 152, + "height": 149, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -577,10 +577,10 @@ "type": "text", "pos": { "x": 1110, - "y": 323 + "y": 343 }, - "width": 302, - "height": 92, + "width": 122, + "height": 51, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -617,11 +617,11 @@ "id": "teleport.inp", "type": "text", "pos": { - "x": 1452, - "y": 323 + "x": 1272, + "y": 343 }, "width": 302, - "height": 92, + "height": 51, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -659,9 +659,9 @@ "type": "rectangle", "pos": { "x": 1110, - "y": 455 + "y": 434 }, - "width": 302, + "width": 212, "height": 92, "opacity": 1, "strokeDash": 0, @@ -711,10 +711,10 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 1452, - "y": 455 + "x": 1362, + "y": 434 }, - "width": 302, + "width": 212, "height": 92, "opacity": 1, "strokeDash": 0, @@ -764,10 +764,10 @@ "id": "jita.Slack", "type": "rectangle", "pos": { - "x": 2376, + "x": 2196, "y": 60 }, - "width": 128, + "width": 110, "height": 92, "opacity": 1, "strokeDash": 0, @@ -817,7 +817,7 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 2544, + "x": 2346, "y": 60 }, "width": 128, @@ -858,10 +858,10 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 2712, + "x": 2514, "y": 60 }, - "width": 128, + "width": 72, "height": 92, "opacity": 1, "strokeDash": 0, @@ -899,10 +899,10 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 2880, + "x": 2626, "y": 60 }, - "width": 128, + "width": 119, "height": 92, "opacity": 1, "strokeDash": 0, @@ -940,10 +940,10 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 3048, + "x": 2785, "y": 60 }, - "width": 128, + "width": 111, "height": 92, "opacity": 1, "strokeDash": 0, @@ -993,10 +993,10 @@ "id": "infra.ssh", "type": "rectangle", "pos": { - "x": 2508, + "x": 2315, "y": 292 }, - "width": 152, + "width": 108, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1046,7 +1046,7 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 2700, + "x": 2463, "y": 292 }, "width": 152, @@ -1099,10 +1099,10 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 2892, + "x": 2655, "y": 292 }, - "width": 152, + "width": 122, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1152,10 +1152,10 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 2508, + "x": 2315, "y": 424 }, - "width": 152, + "width": 138, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1205,10 +1205,10 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 2700, + "x": 2493, "y": 424 }, - "width": 152, + "width": 108, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1258,10 +1258,10 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 2892, + "x": 2641, "y": 424 }, - "width": 152, + "width": 136, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1434,19 +1434,19 @@ "labelPercentage": 0, "route": [ { - "x": 1763.433789954338, - "y": 262.5 + "x": 1592.4246575342465, + "y": 283 }, { - "x": 2004.6867579908676, - "y": 137.3 + "x": 1826.4849315068493, + "y": 141.4 }, { - "x": 2115.2, + "x": 1935.2, "y": 106 }, { - "x": 2316, + "x": 2136, "y": 106 } ], @@ -1483,19 +1483,19 @@ "labelPercentage": 0, "route": [ { - "x": 1814, - "y": 416.09399684044234 + "x": 1634, + "y": 418.0985267034991 }, { - "x": 2014.8, - "y": 406.41879936808846 + "x": 1834.8, + "y": 406.81970534069984 }, { - "x": 2141.6, + "x": 1959, "y": 404 }, { - "x": 2448, + "x": 2255, "y": 404 } ], @@ -1532,20 +1532,20 @@ "labelPercentage": 0, "route": [ { - "x": 1814, - "y": 510.2361769352291 + "x": 1634, + "y": 501.98802946593 }, { - "x": 2014.8, - "y": 550.0472353870458 + "x": 1834.8, + "y": 548.397605893186 }, { - "x": 2187.1, - "y": 576.3143459915611 + "x": 1997.1, + "y": 576.1111951588503 }, { - "x": 2675.5, - "y": 641.5717299578059 + "x": 2445.5, + "y": 640.5559757942511 } ], "isCurve": true, @@ -1581,20 +1581,20 @@ "labelPercentage": 0, "route": [ { - "x": 1814, - "y": 585.9723538704582 + "x": 1634, + "y": 569.47605893186 }, { - "x": 2014.8, - "y": 665.5944707740916 + "x": 1834.8, + "y": 662.295211786372 }, { - "x": 2187.1, - "y": 680.2622362869198 + "x": 1997.1, + "y": 680.3274583963691 }, { - "x": 2675.5, - "y": 659.3111814345991 + "x": 2445.5, + "y": 659.6372919818457 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg index f6a003864..8490082b2 100644 --- a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg @@ -1,23 +1,23 @@ -Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

-

Identity Native Proxy

-
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

+

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file diff --git a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json index 791027e81..bb00928e2 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 12, - "y": 190 + "y": 196 }, "width": 272, - "height": 464, + "height": 461, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -49,7 +49,7 @@ "type": "rectangle", "pos": { "x": 354, - "y": 117 + "y": 122 }, "width": 236, "height": 610, @@ -90,10 +90,10 @@ "type": "rectangle", "pos": { "x": 660, - "y": 250 + "y": 275 }, - "width": 764, - "height": 344, + "width": 584, + "height": 303, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -130,10 +130,10 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 2280, + "x": 2026, "y": 12 }, - "width": 920, + "width": 820, "height": 212, "opacity": 1, "strokeDash": 0, @@ -171,10 +171,10 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 1554, + "x": 1374, "y": 150 }, - "width": 656, + "width": 582, "height": 344, "opacity": 1, "strokeDash": 0, @@ -212,7 +212,7 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 1554, + "x": 1374, "y": 514 }, "width": 201, @@ -266,7 +266,7 @@ "type": "oval", "pos": { "x": 72, - "y": 250 + "y": 256 }, "width": 152, "height": 152, @@ -319,10 +319,10 @@ "type": "oval", "pos": { "x": 72, - "y": 442 + "y": 448 }, "width": 152, - "height": 152, + "height": 149, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -372,7 +372,7 @@ "type": "rectangle", "pos": { "x": 414, - "y": 177 + "y": 182 }, "width": 116, "height": 66, @@ -413,7 +413,7 @@ "type": "rectangle", "pos": { "x": 414, - "y": 283 + "y": 288 }, "width": 116, "height": 66, @@ -454,7 +454,7 @@ "type": "rectangle", "pos": { "x": 414, - "y": 389 + "y": 394 }, "width": 116, "height": 66, @@ -495,7 +495,7 @@ "type": "rectangle", "pos": { "x": 414, - "y": 495 + "y": 500 }, "width": 116, "height": 66, @@ -536,7 +536,7 @@ "type": "rectangle", "pos": { "x": 414, - "y": 601 + "y": 606 }, "width": 116, "height": 66, @@ -577,10 +577,10 @@ "type": "text", "pos": { "x": 720, - "y": 310 + "y": 335 }, - "width": 302, - "height": 92, + "width": 122, + "height": 51, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -617,11 +617,11 @@ "id": "teleport.inp", "type": "text", "pos": { - "x": 1062, - "y": 310 + "x": 882, + "y": 335 }, "width": 302, - "height": 92, + "height": 51, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -659,9 +659,9 @@ "type": "rectangle", "pos": { "x": 720, - "y": 442 + "y": 426 }, - "width": 302, + "width": 212, "height": 92, "opacity": 1, "strokeDash": 0, @@ -711,10 +711,10 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 1062, - "y": 442 + "x": 972, + "y": 426 }, - "width": 302, + "width": 212, "height": 92, "opacity": 1, "strokeDash": 0, @@ -764,10 +764,10 @@ "id": "jita.Slack", "type": "rectangle", "pos": { - "x": 2340, + "x": 2086, "y": 72 }, - "width": 128, + "width": 110, "height": 92, "opacity": 1, "strokeDash": 0, @@ -817,7 +817,7 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 2508, + "x": 2236, "y": 72 }, "width": 128, @@ -858,10 +858,10 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 2676, + "x": 2404, "y": 72 }, - "width": 128, + "width": 72, "height": 92, "opacity": 1, "strokeDash": 0, @@ -899,10 +899,10 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 2844, + "x": 2516, "y": 72 }, - "width": 128, + "width": 119, "height": 92, "opacity": 1, "strokeDash": 0, @@ -940,10 +940,10 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 3012, + "x": 2675, "y": 72 }, - "width": 128, + "width": 111, "height": 92, "opacity": 1, "strokeDash": 0, @@ -993,10 +993,10 @@ "id": "infra.ssh", "type": "rectangle", "pos": { - "x": 1614, + "x": 1434, "y": 210 }, - "width": 152, + "width": 108, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1046,7 +1046,7 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 1806, + "x": 1582, "y": 210 }, "width": 152, @@ -1099,10 +1099,10 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 1998, + "x": 1774, "y": 210 }, - "width": 152, + "width": 122, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1152,10 +1152,10 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 1614, + "x": 1434, "y": 342 }, - "width": 152, + "width": 138, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1205,10 +1205,10 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 1806, + "x": 1612, "y": 342 }, - "width": 152, + "width": 108, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1258,10 +1258,10 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 1998, + "x": 1760, "y": 342 }, - "width": 152, + "width": 136, "height": 92, "opacity": 1, "strokeDash": 0, @@ -1337,11 +1337,11 @@ "route": [ { "x": 284, - "y": 422.93333333333334 + "y": 427.0333333333333 }, { "x": 354, - "y": 422.93333333333334 + "y": 427.0333333333333 } ], "animated": false, @@ -1377,11 +1377,11 @@ "route": [ { "x": 590, - "y": 422.93333333333334 + "y": 427.0333333333333 }, { "x": 660, - "y": 422.93333333333334 + "y": 427.0333333333333 } ], "animated": false, @@ -1416,19 +1416,19 @@ "labelPercentage": 0, "route": [ { - "x": 1424, - "y": 319.73333333333335 + "x": 1244, + "y": 336.1333333333333 }, { - "x": 1464, - "y": 319.73333333333335 + "x": 1284, + "y": 336.1333333333333 }, { - "x": 1464, + "x": 1284, "y": 118 }, { - "x": 2280, + "x": 2026, "y": 118 } ], @@ -1464,12 +1464,12 @@ "labelPercentage": 0, "route": [ { - "x": 1424, - "y": 388.53333333333336 + "x": 1244, + "y": 396.7333333333333 }, { - "x": 1554, - "y": 388.53333333333336 + "x": 1374, + "y": 396.7333333333333 } ], "animated": false, @@ -1504,19 +1504,19 @@ "labelPercentage": 0, "route": [ { - "x": 1424, + "x": 1244, "y": 457.3333333333333 }, { - "x": 1514, + "x": 1334, "y": 457.3333333333333 }, { - "x": 1514, + "x": 1334, "y": 553.3333333333333 }, { - "x": 1554, + "x": 1374, "y": 553.3333333333333 } ], @@ -1552,20 +1552,20 @@ "labelPercentage": 0, "route": [ { - "x": 1424, - "y": 526.1333333333333 + "x": 1244, + "y": 517.9333333333333 }, { - "x": 1464, - "y": 526.1333333333333 + "x": 1284, + "y": 517.9333333333333 }, { - "x": 1464, - "y": 592.6666666666667 + "x": 1284, + "y": 592.6666666666666 }, { - "x": 1554, - "y": 592.6666666666667 + "x": 1374, + "y": 592.6666666666666 } ], "animated": false, diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg index 1d5730d9b..0f29b7d25 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -1,23 +1,23 @@ -Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

-

Identity Native Proxy

-
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

+

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file From a16924752d57b42f5ad57034809f4b3ac9c4203c Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 11:38:33 -0700 Subject: [PATCH 12/33] finish column logic --- d2layouts/d2grid/layout.go | 76 +++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 755146535..180ae0cf2 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -135,15 +135,15 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { } } else { targetHeight := totalHeight / float64(grid.columns) - columnHeight := 0. - columnIndex := 0 + colHeight := 0. + colIndex := 0 for i, n := range grid.nodes { - layout[columnIndex] = append(layout[columnIndex], i) - columnHeight += n.Height + VERTICAL_PAD - if columnHeight > targetHeight && i < len(grid.nodes)-1 { + layout[colIndex] = append(layout[colIndex], i) + colHeight += n.Height + VERTICAL_PAD + if colHeight > targetHeight && i < len(grid.nodes)-1 { layout = append(layout, []int{}) - columnIndex++ - columnHeight = 0 + colIndex++ + colHeight = 0 } } } @@ -260,24 +260,27 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { // . └───┴──────────┘ │ │ // . │ ││ // . └─────────┴┘ + colHeights := []float64{} for _, column := range layout { - columnWidth := 0. + colWidth := 0. for _, nodeIndex := range column { n := grid.nodes[nodeIndex] n.TopLeft = cursor.Copy() cursor.Y += n.Height + VERTICAL_PAD - columnWidth = math.Max(columnWidth, n.Width) + colWidth = math.Max(colWidth, n.Width) } - maxY = math.Max(maxY, cursor.Y-VERTICAL_PAD) + colHeight := cursor.Y - VERTICAL_PAD + colHeights = append(colHeights, colHeight) + maxY = math.Max(maxY, colHeight) // set all nodes in column to the same width for _, nodeIndex := range column { n := grid.nodes[nodeIndex] - n.Width = columnWidth + n.Width = colWidth } // new column cursor.Y = 0 - cursor.X += columnWidth + HORIZONTAL_PAD + cursor.X += colWidth + HORIZONTAL_PAD } maxX = cursor.X - HORIZONTAL_PAD // then expand shortest nodes to make each column the same height @@ -291,7 +294,54 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { // . │ │ │ │ │ │ // . │ │ │ │ │ │ // . └──────────────┘ └──────────┘ └─────────────────┘ - // TODO see rows + for i, column := range layout { + colHeight := colHeights[i] + if colHeight == maxY { + continue + } + delta := maxY - colHeight + nodes := []*d2graph.Object{} + var tallest float64 + for _, nodeIndex := range column { + n := grid.nodes[nodeIndex] + tallest = math.Max(tallest, n.Height) + nodes = append(nodes, n) + } + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].Height < nodes[j].Height + }) + // expand smaller nodes to fill remaining space + for _, n := range nodes { + if n.Height < tallest { + var index int + for i, nodeIndex := range column { + if n == grid.nodes[nodeIndex] { + index = i + break + } + } + grow := math.Min(tallest-n.Height, delta) + n.Height += grow + // shift following nodes + for i := index + 1; i < len(column); i++ { + grid.nodes[column[i]].TopLeft.Y += grow + } + delta -= grow + if delta <= 0 { + break + } + } + } + if delta > 0 { + grow := delta / float64(len(column)) + for i := len(column) - 1; i >= 0; i-- { + n := grid.nodes[column[i]] + n.TopLeft.Y += grow * float64(i) + n.Height += grow + delta -= grow + } + } + } } grid.width = maxX grid.height = maxY From 7ac72140c7178c723f8e68163d952acee70761ba Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 13:42:25 -0700 Subject: [PATCH 13/33] fixing rows creation --- d2layouts/d2grid/layout.go | 57 +++++++++++++++++++++----- e2etests/testdata/files/dagger_grid.d2 | 46 +++++++++++++++++---- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 180ae0cf2..c16529fe0 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -123,27 +123,62 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { targetWidth := totalWidth / float64(grid.rows) rowWidth := 0. rowIndex := 0 - for i, n := range grid.nodes { + addRow := func() { + layout = append(layout, []int{}) + rowIndex++ + rowWidth = 0 + } + addNode := func(i int, n *d2graph.Object) { layout[rowIndex] = append(layout[rowIndex], i) rowWidth += n.Width + HORIZONTAL_PAD - // add a new row if we pass the target width and there are more nodes - if rowWidth > targetWidth && i < len(grid.nodes)-1 { - layout = append(layout, []int{}) - rowIndex++ - rowWidth = 0 + } + + for i, n := range grid.nodes { + // if the next node will be past the target, start a new row + if rowWidth+n.Width+HORIZONTAL_PAD > targetWidth { + // if the node is mostly past the target, put it on the next row + if rowWidth+n.Width/2 > targetWidth { + addRow() + addNode(i, n) + } else { + addNode(i, n) + if i < len(grid.nodes)-1 { + addRow() + } + } + } else { + addNode(i, n) } } } else { targetHeight := totalHeight / float64(grid.columns) colHeight := 0. colIndex := 0 - for i, n := range grid.nodes { + addCol := func() { + layout = append(layout, []int{}) + colIndex++ + colHeight = 0 + } + addNode := func(i int, n *d2graph.Object) { layout[colIndex] = append(layout[colIndex], i) colHeight += n.Height + VERTICAL_PAD - if colHeight > targetHeight && i < len(grid.nodes)-1 { - layout = append(layout, []int{}) - colIndex++ - colHeight = 0 + } + + for i, n := range grid.nodes { + // if the next node will be past the target, start a new row + if colHeight+n.Height+VERTICAL_PAD > targetHeight { + // if the node is mostly past the target, put it on the next row + if colHeight+n.Height/2 > targetHeight { + addCol() + addNode(i, n) + } else { + addNode(i, n) + if i < len(grid.nodes)-1 { + addCol() + } + } + } else { + addNode(i, n) } } } diff --git a/e2etests/testdata/files/dagger_grid.d2 b/e2etests/testdata/files/dagger_grid.d2 index b3db8ac9a..9bbe12df2 100644 --- a/e2etests/testdata/files/dagger_grid.d2 +++ b/e2etests/testdata/files/dagger_grid.d2 @@ -1,12 +1,44 @@ -rows: 4 +rows: 5 style.fill: black -flow: "" { - width: 800 - height: 200 - style: { - fill: cornflowerblue - } +flow1: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow2: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow3: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow4: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow5: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow6: "" { + width: 240 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow7: "" { + width: 100 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow8: "" { + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow9: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} +} +flow10: "" { + width: 120 + style: {fill: white; stroke: cornflowerblue; stroke-width: 10} } DAGGER ENGINE: { From a9a7d23ffdcca42b20eb9b4c61afcb4bf4abc3b1 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 13:45:16 -0700 Subject: [PATCH 14/33] update test --- .../stable/dagger_grid/dagre/board.exp.json | 409 +++++++++++++++++- .../stable/dagger_grid/dagre/sketch.exp.svg | 154 +++---- .../stable/dagger_grid/elk/board.exp.json | 409 +++++++++++++++++- .../stable/dagger_grid/elk/sketch.exp.svg | 154 +++---- 4 files changed, 932 insertions(+), 194 deletions(-) diff --git a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json index b438f9716..e8cca26bb 100644 --- a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json @@ -4,20 +4,389 @@ "fontFamily": "SourceSansPro", "shapes": [ { - "id": "flow", + "id": "flow1", "type": "rectangle", "pos": { "x": 0, "y": 0 }, - "width": 800, - "height": 200, + "width": 136, + "height": 100, "opacity": 1, "strokeDash": 0, - "strokeWidth": 2, + "strokeWidth": 10, "borderRadius": 0, - "fill": "cornflowerblue", - "stroke": "B1", + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow2", + "type": "rectangle", + "pos": { + "x": 176, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow3", + "type": "rectangle", + "pos": { + "x": 352, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow4", + "type": "rectangle", + "pos": { + "x": 528, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow5", + "type": "rectangle", + "pos": { + "x": 704, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow6", + "type": "rectangle", + "pos": { + "x": 0, + "y": 140 + }, + "width": 240, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow7", + "type": "rectangle", + "pos": { + "x": 280, + "y": 140 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow8", + "type": "rectangle", + "pos": { + "x": 420, + "y": 140 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow9", + "type": "rectangle", + "pos": { + "x": 560, + "y": 140 + }, + "width": 120, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow10", + "type": "rectangle", + "pos": { + "x": 720, + "y": 140 + }, + "width": 120, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", "shadow": false, "3d": false, "multiple": false, @@ -49,9 +418,9 @@ "type": "rectangle", "pos": { "x": 0, - "y": 240 + "y": 280 }, - "width": 800, + "width": 840, "height": 61, "opacity": 1, "strokeDash": 0, @@ -90,9 +459,9 @@ "type": "rectangle", "pos": { "x": 0, - "y": 341 + "y": 381 }, - "width": 800, + "width": 840, "height": 87, "opacity": 1, "strokeDash": 0, @@ -143,7 +512,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 468 + "y": 508 }, "width": 139, "height": 66, @@ -184,9 +553,9 @@ "type": "rectangle", "pos": { "x": 179, - "y": 468 + "y": 508 }, - "width": 117, + "width": 124, "height": 66, "opacity": 1, "strokeDash": 0, @@ -224,8 +593,8 @@ "id": "LINUX", "type": "rectangle", "pos": { - "x": 336, - "y": 468 + "x": 343, + "y": 508 }, "width": 139, "height": 66, @@ -265,10 +634,10 @@ "id": "MACOS", "type": "rectangle", "pos": { - "x": 515, - "y": 468 + "x": 522, + "y": 508 }, - "width": 106, + "width": 139, "height": 66, "opacity": 1, "strokeDash": 0, @@ -306,8 +675,8 @@ "id": "KUBERNETES", "type": "rectangle", "pos": { - "x": 661, - "y": 468 + "x": 701, + "y": 508 }, "width": 139, "height": 66, diff --git a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg index 2e9ae781c..9841e85d6 100644 --- a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES - + .d2-1905618427 .fill-N1{fill:#0A0F25;} + .d2-1905618427 .fill-N2{fill:#676C7E;} + .d2-1905618427 .fill-N3{fill:#9499AB;} + .d2-1905618427 .fill-N4{fill:#CFD2DD;} + .d2-1905618427 .fill-N5{fill:#DEE1EB;} + .d2-1905618427 .fill-N6{fill:#EEF1F8;} + .d2-1905618427 .fill-N7{fill:#FFFFFF;} + .d2-1905618427 .fill-B1{fill:#0D32B2;} + .d2-1905618427 .fill-B2{fill:#0D32B2;} + .d2-1905618427 .fill-B3{fill:#E3E9FD;} + .d2-1905618427 .fill-B4{fill:#E3E9FD;} + .d2-1905618427 .fill-B5{fill:#EDF0FD;} + .d2-1905618427 .fill-B6{fill:#F7F8FE;} + .d2-1905618427 .fill-AA2{fill:#4A6FF3;} + .d2-1905618427 .fill-AA4{fill:#EDF0FD;} + .d2-1905618427 .fill-AA5{fill:#F7F8FE;} + .d2-1905618427 .fill-AB4{fill:#EDF0FD;} + .d2-1905618427 .fill-AB5{fill:#F7F8FE;} + .d2-1905618427 .stroke-N1{stroke:#0A0F25;} + .d2-1905618427 .stroke-N2{stroke:#676C7E;} + .d2-1905618427 .stroke-N3{stroke:#9499AB;} + .d2-1905618427 .stroke-N4{stroke:#CFD2DD;} + .d2-1905618427 .stroke-N5{stroke:#DEE1EB;} + .d2-1905618427 .stroke-N6{stroke:#EEF1F8;} + .d2-1905618427 .stroke-N7{stroke:#FFFFFF;} + .d2-1905618427 .stroke-B1{stroke:#0D32B2;} + .d2-1905618427 .stroke-B2{stroke:#0D32B2;} + .d2-1905618427 .stroke-B3{stroke:#E3E9FD;} + .d2-1905618427 .stroke-B4{stroke:#E3E9FD;} + .d2-1905618427 .stroke-B5{stroke:#EDF0FD;} + .d2-1905618427 .stroke-B6{stroke:#F7F8FE;} + .d2-1905618427 .stroke-AA2{stroke:#4A6FF3;} + .d2-1905618427 .stroke-AA4{stroke:#EDF0FD;} + .d2-1905618427 .stroke-AA5{stroke:#F7F8FE;} + .d2-1905618427 .stroke-AB4{stroke:#EDF0FD;} + .d2-1905618427 .stroke-AB5{stroke:#F7F8FE;} + .d2-1905618427 .background-color-N1{background-color:#0A0F25;} + .d2-1905618427 .background-color-N2{background-color:#676C7E;} + .d2-1905618427 .background-color-N3{background-color:#9499AB;} + .d2-1905618427 .background-color-N4{background-color:#CFD2DD;} + .d2-1905618427 .background-color-N5{background-color:#DEE1EB;} + .d2-1905618427 .background-color-N6{background-color:#EEF1F8;} + .d2-1905618427 .background-color-N7{background-color:#FFFFFF;} + .d2-1905618427 .background-color-B1{background-color:#0D32B2;} + .d2-1905618427 .background-color-B2{background-color:#0D32B2;} + .d2-1905618427 .background-color-B3{background-color:#E3E9FD;} + .d2-1905618427 .background-color-B4{background-color:#E3E9FD;} + .d2-1905618427 .background-color-B5{background-color:#EDF0FD;} + .d2-1905618427 .background-color-B6{background-color:#F7F8FE;} + .d2-1905618427 .background-color-AA2{background-color:#4A6FF3;} + .d2-1905618427 .background-color-AA4{background-color:#EDF0FD;} + .d2-1905618427 .background-color-AA5{background-color:#F7F8FE;} + .d2-1905618427 .background-color-AB4{background-color:#EDF0FD;} + .d2-1905618427 .background-color-AB5{background-color:#F7F8FE;} + .d2-1905618427 .color-N1{color:#0A0F25;} + .d2-1905618427 .color-N2{color:#676C7E;} + .d2-1905618427 .color-N3{color:#9499AB;} + .d2-1905618427 .color-N4{color:#CFD2DD;} + .d2-1905618427 .color-N5{color:#DEE1EB;} + .d2-1905618427 .color-N6{color:#EEF1F8;} + .d2-1905618427 .color-N7{color:#FFFFFF;} + .d2-1905618427 .color-B1{color:#0D32B2;} + .d2-1905618427 .color-B2{color:#0D32B2;} + .d2-1905618427 .color-B3{color:#E3E9FD;} + .d2-1905618427 .color-B4{color:#E3E9FD;} + .d2-1905618427 .color-B5{color:#EDF0FD;} + .d2-1905618427 .color-B6{color:#F7F8FE;} + .d2-1905618427 .color-AA2{color:#4A6FF3;} + .d2-1905618427 .color-AA4{color:#EDF0FD;} + .d2-1905618427 .color-AA5{color:#F7F8FE;} + .d2-1905618427 .color-AB4{color:#EDF0FD;} + .d2-1905618427 .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}]]>DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES + \ No newline at end of file diff --git a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json index b438f9716..e8cca26bb 100644 --- a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json @@ -4,20 +4,389 @@ "fontFamily": "SourceSansPro", "shapes": [ { - "id": "flow", + "id": "flow1", "type": "rectangle", "pos": { "x": 0, "y": 0 }, - "width": 800, - "height": 200, + "width": 136, + "height": 100, "opacity": 1, "strokeDash": 0, - "strokeWidth": 2, + "strokeWidth": 10, "borderRadius": 0, - "fill": "cornflowerblue", - "stroke": "B1", + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow2", + "type": "rectangle", + "pos": { + "x": 176, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow3", + "type": "rectangle", + "pos": { + "x": 352, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow4", + "type": "rectangle", + "pos": { + "x": 528, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow5", + "type": "rectangle", + "pos": { + "x": 704, + "y": 0 + }, + "width": 136, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow6", + "type": "rectangle", + "pos": { + "x": 0, + "y": 140 + }, + "width": 240, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow7", + "type": "rectangle", + "pos": { + "x": 280, + "y": 140 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow8", + "type": "rectangle", + "pos": { + "x": 420, + "y": 140 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow9", + "type": "rectangle", + "pos": { + "x": 560, + "y": 140 + }, + "width": 120, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", + "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": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "flow10", + "type": "rectangle", + "pos": { + "x": 720, + "y": 140 + }, + "width": 120, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 10, + "borderRadius": 0, + "fill": "white", + "stroke": "cornflowerblue", "shadow": false, "3d": false, "multiple": false, @@ -49,9 +418,9 @@ "type": "rectangle", "pos": { "x": 0, - "y": 240 + "y": 280 }, - "width": 800, + "width": 840, "height": 61, "opacity": 1, "strokeDash": 0, @@ -90,9 +459,9 @@ "type": "rectangle", "pos": { "x": 0, - "y": 341 + "y": 381 }, - "width": 800, + "width": 840, "height": 87, "opacity": 1, "strokeDash": 0, @@ -143,7 +512,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 468 + "y": 508 }, "width": 139, "height": 66, @@ -184,9 +553,9 @@ "type": "rectangle", "pos": { "x": 179, - "y": 468 + "y": 508 }, - "width": 117, + "width": 124, "height": 66, "opacity": 1, "strokeDash": 0, @@ -224,8 +593,8 @@ "id": "LINUX", "type": "rectangle", "pos": { - "x": 336, - "y": 468 + "x": 343, + "y": 508 }, "width": 139, "height": 66, @@ -265,10 +634,10 @@ "id": "MACOS", "type": "rectangle", "pos": { - "x": 515, - "y": 468 + "x": 522, + "y": 508 }, - "width": 106, + "width": 139, "height": 66, "opacity": 1, "strokeDash": 0, @@ -306,8 +675,8 @@ "id": "KUBERNETES", "type": "rectangle", "pos": { - "x": 661, - "y": 468 + "x": 701, + "y": 508 }, "width": 139, "height": 66, diff --git a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg index 2e9ae781c..9841e85d6 100644 --- a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES - + .d2-1905618427 .fill-N1{fill:#0A0F25;} + .d2-1905618427 .fill-N2{fill:#676C7E;} + .d2-1905618427 .fill-N3{fill:#9499AB;} + .d2-1905618427 .fill-N4{fill:#CFD2DD;} + .d2-1905618427 .fill-N5{fill:#DEE1EB;} + .d2-1905618427 .fill-N6{fill:#EEF1F8;} + .d2-1905618427 .fill-N7{fill:#FFFFFF;} + .d2-1905618427 .fill-B1{fill:#0D32B2;} + .d2-1905618427 .fill-B2{fill:#0D32B2;} + .d2-1905618427 .fill-B3{fill:#E3E9FD;} + .d2-1905618427 .fill-B4{fill:#E3E9FD;} + .d2-1905618427 .fill-B5{fill:#EDF0FD;} + .d2-1905618427 .fill-B6{fill:#F7F8FE;} + .d2-1905618427 .fill-AA2{fill:#4A6FF3;} + .d2-1905618427 .fill-AA4{fill:#EDF0FD;} + .d2-1905618427 .fill-AA5{fill:#F7F8FE;} + .d2-1905618427 .fill-AB4{fill:#EDF0FD;} + .d2-1905618427 .fill-AB5{fill:#F7F8FE;} + .d2-1905618427 .stroke-N1{stroke:#0A0F25;} + .d2-1905618427 .stroke-N2{stroke:#676C7E;} + .d2-1905618427 .stroke-N3{stroke:#9499AB;} + .d2-1905618427 .stroke-N4{stroke:#CFD2DD;} + .d2-1905618427 .stroke-N5{stroke:#DEE1EB;} + .d2-1905618427 .stroke-N6{stroke:#EEF1F8;} + .d2-1905618427 .stroke-N7{stroke:#FFFFFF;} + .d2-1905618427 .stroke-B1{stroke:#0D32B2;} + .d2-1905618427 .stroke-B2{stroke:#0D32B2;} + .d2-1905618427 .stroke-B3{stroke:#E3E9FD;} + .d2-1905618427 .stroke-B4{stroke:#E3E9FD;} + .d2-1905618427 .stroke-B5{stroke:#EDF0FD;} + .d2-1905618427 .stroke-B6{stroke:#F7F8FE;} + .d2-1905618427 .stroke-AA2{stroke:#4A6FF3;} + .d2-1905618427 .stroke-AA4{stroke:#EDF0FD;} + .d2-1905618427 .stroke-AA5{stroke:#F7F8FE;} + .d2-1905618427 .stroke-AB4{stroke:#EDF0FD;} + .d2-1905618427 .stroke-AB5{stroke:#F7F8FE;} + .d2-1905618427 .background-color-N1{background-color:#0A0F25;} + .d2-1905618427 .background-color-N2{background-color:#676C7E;} + .d2-1905618427 .background-color-N3{background-color:#9499AB;} + .d2-1905618427 .background-color-N4{background-color:#CFD2DD;} + .d2-1905618427 .background-color-N5{background-color:#DEE1EB;} + .d2-1905618427 .background-color-N6{background-color:#EEF1F8;} + .d2-1905618427 .background-color-N7{background-color:#FFFFFF;} + .d2-1905618427 .background-color-B1{background-color:#0D32B2;} + .d2-1905618427 .background-color-B2{background-color:#0D32B2;} + .d2-1905618427 .background-color-B3{background-color:#E3E9FD;} + .d2-1905618427 .background-color-B4{background-color:#E3E9FD;} + .d2-1905618427 .background-color-B5{background-color:#EDF0FD;} + .d2-1905618427 .background-color-B6{background-color:#F7F8FE;} + .d2-1905618427 .background-color-AA2{background-color:#4A6FF3;} + .d2-1905618427 .background-color-AA4{background-color:#EDF0FD;} + .d2-1905618427 .background-color-AA5{background-color:#F7F8FE;} + .d2-1905618427 .background-color-AB4{background-color:#EDF0FD;} + .d2-1905618427 .background-color-AB5{background-color:#F7F8FE;} + .d2-1905618427 .color-N1{color:#0A0F25;} + .d2-1905618427 .color-N2{color:#676C7E;} + .d2-1905618427 .color-N3{color:#9499AB;} + .d2-1905618427 .color-N4{color:#CFD2DD;} + .d2-1905618427 .color-N5{color:#DEE1EB;} + .d2-1905618427 .color-N6{color:#EEF1F8;} + .d2-1905618427 .color-N7{color:#FFFFFF;} + .d2-1905618427 .color-B1{color:#0D32B2;} + .d2-1905618427 .color-B2{color:#0D32B2;} + .d2-1905618427 .color-B3{color:#E3E9FD;} + .d2-1905618427 .color-B4{color:#E3E9FD;} + .d2-1905618427 .color-B5{color:#EDF0FD;} + .d2-1905618427 .color-B6{color:#F7F8FE;} + .d2-1905618427 .color-AA2{color:#4A6FF3;} + .d2-1905618427 .color-AA4{color:#EDF0FD;} + .d2-1905618427 .color-AA5{color:#F7F8FE;} + .d2-1905618427 .color-AB4{color:#EDF0FD;} + .d2-1905618427 .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}]]>DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES + \ No newline at end of file From bcc4ce1e923adaac0390f9f3162a287b38380633 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 13:47:51 -0700 Subject: [PATCH 15/33] update test --- e2etests/testdata/files/dagger_grid.d2 | 9 +- .../stable/dagger_grid/dagre/board.exp.json | 83 +++------- .../stable/dagger_grid/dagre/sketch.exp.svg | 154 +++++++++--------- .../stable/dagger_grid/elk/board.exp.json | 83 +++------- .../stable/dagger_grid/elk/sketch.exp.svg | 154 +++++++++--------- 5 files changed, 199 insertions(+), 284 deletions(-) diff --git a/e2etests/testdata/files/dagger_grid.d2 b/e2etests/testdata/files/dagger_grid.d2 index 9bbe12df2..dc9d8debe 100644 --- a/e2etests/testdata/files/dagger_grid.d2 +++ b/e2etests/testdata/files/dagger_grid.d2 @@ -26,18 +26,15 @@ flow6: "" { style: {fill: white; stroke: cornflowerblue; stroke-width: 10} } flow7: "" { - width: 100 + width: 80 style: {fill: white; stroke: cornflowerblue; stroke-width: 10} } flow8: "" { + width: 160 style: {fill: white; stroke: cornflowerblue; stroke-width: 10} } flow9: "" { - width: 120 - style: {fill: white; stroke: cornflowerblue; stroke-width: 10} -} -flow10: "" { - width: 120 + width: 160 style: {fill: white; stroke: cornflowerblue; stroke-width: 10} } diff --git a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json index e8cca26bb..b94be0069 100644 --- a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -48,10 +48,10 @@ "id": "flow2", "type": "rectangle", "pos": { - "x": 176, + "x": 168, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -89,10 +89,10 @@ "id": "flow3", "type": "rectangle", "pos": { - "x": 352, + "x": 336, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -130,10 +130,10 @@ "id": "flow4", "type": "rectangle", "pos": { - "x": 528, + "x": 504, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -171,10 +171,10 @@ "id": "flow5", "type": "rectangle", "pos": { - "x": 704, + "x": 672, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -256,7 +256,7 @@ "x": 280, "y": 140 }, - "width": 100, + "width": 120, "height": 100, "opacity": 1, "strokeDash": 0, @@ -294,10 +294,10 @@ "id": "flow8", "type": "rectangle", "pos": { - "x": 420, + "x": 440, "y": 140 }, - "width": 100, + "width": 160, "height": 100, "opacity": 1, "strokeDash": 0, @@ -335,51 +335,10 @@ "id": "flow9", "type": "rectangle", "pos": { - "x": 560, + "x": 640, "y": 140 }, - "width": 120, - "height": 100, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 10, - "borderRadius": 0, - "fill": "white", - "stroke": "cornflowerblue", - "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": true, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "flow10", - "type": "rectangle", - "pos": { - "x": 720, - "y": 140 - }, - "width": 120, + "width": 160, "height": 100, "opacity": 1, "strokeDash": 0, @@ -420,7 +379,7 @@ "x": 0, "y": 280 }, - "width": 840, + "width": 800, "height": 61, "opacity": 1, "strokeDash": 0, @@ -461,7 +420,7 @@ "x": 0, "y": 381 }, - "width": 840, + "width": 800, "height": 87, "opacity": 1, "strokeDash": 0, @@ -555,7 +514,7 @@ "x": 179, "y": 508 }, - "width": 124, + "width": 117, "height": 66, "opacity": 1, "strokeDash": 0, @@ -593,7 +552,7 @@ "id": "LINUX", "type": "rectangle", "pos": { - "x": 343, + "x": 336, "y": 508 }, "width": 139, @@ -634,10 +593,10 @@ "id": "MACOS", "type": "rectangle", "pos": { - "x": 522, + "x": 515, "y": 508 }, - "width": 139, + "width": 106, "height": 66, "opacity": 1, "strokeDash": 0, @@ -675,7 +634,7 @@ "id": "KUBERNETES", "type": "rectangle", "pos": { - "x": 701, + "x": 661, "y": 508 }, "width": 139, diff --git a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg index 9841e85d6..cc62b273b 100644 --- a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES - + .d2-1659554808 .fill-N1{fill:#0A0F25;} + .d2-1659554808 .fill-N2{fill:#676C7E;} + .d2-1659554808 .fill-N3{fill:#9499AB;} + .d2-1659554808 .fill-N4{fill:#CFD2DD;} + .d2-1659554808 .fill-N5{fill:#DEE1EB;} + .d2-1659554808 .fill-N6{fill:#EEF1F8;} + .d2-1659554808 .fill-N7{fill:#FFFFFF;} + .d2-1659554808 .fill-B1{fill:#0D32B2;} + .d2-1659554808 .fill-B2{fill:#0D32B2;} + .d2-1659554808 .fill-B3{fill:#E3E9FD;} + .d2-1659554808 .fill-B4{fill:#E3E9FD;} + .d2-1659554808 .fill-B5{fill:#EDF0FD;} + .d2-1659554808 .fill-B6{fill:#F7F8FE;} + .d2-1659554808 .fill-AA2{fill:#4A6FF3;} + .d2-1659554808 .fill-AA4{fill:#EDF0FD;} + .d2-1659554808 .fill-AA5{fill:#F7F8FE;} + .d2-1659554808 .fill-AB4{fill:#EDF0FD;} + .d2-1659554808 .fill-AB5{fill:#F7F8FE;} + .d2-1659554808 .stroke-N1{stroke:#0A0F25;} + .d2-1659554808 .stroke-N2{stroke:#676C7E;} + .d2-1659554808 .stroke-N3{stroke:#9499AB;} + .d2-1659554808 .stroke-N4{stroke:#CFD2DD;} + .d2-1659554808 .stroke-N5{stroke:#DEE1EB;} + .d2-1659554808 .stroke-N6{stroke:#EEF1F8;} + .d2-1659554808 .stroke-N7{stroke:#FFFFFF;} + .d2-1659554808 .stroke-B1{stroke:#0D32B2;} + .d2-1659554808 .stroke-B2{stroke:#0D32B2;} + .d2-1659554808 .stroke-B3{stroke:#E3E9FD;} + .d2-1659554808 .stroke-B4{stroke:#E3E9FD;} + .d2-1659554808 .stroke-B5{stroke:#EDF0FD;} + .d2-1659554808 .stroke-B6{stroke:#F7F8FE;} + .d2-1659554808 .stroke-AA2{stroke:#4A6FF3;} + .d2-1659554808 .stroke-AA4{stroke:#EDF0FD;} + .d2-1659554808 .stroke-AA5{stroke:#F7F8FE;} + .d2-1659554808 .stroke-AB4{stroke:#EDF0FD;} + .d2-1659554808 .stroke-AB5{stroke:#F7F8FE;} + .d2-1659554808 .background-color-N1{background-color:#0A0F25;} + .d2-1659554808 .background-color-N2{background-color:#676C7E;} + .d2-1659554808 .background-color-N3{background-color:#9499AB;} + .d2-1659554808 .background-color-N4{background-color:#CFD2DD;} + .d2-1659554808 .background-color-N5{background-color:#DEE1EB;} + .d2-1659554808 .background-color-N6{background-color:#EEF1F8;} + .d2-1659554808 .background-color-N7{background-color:#FFFFFF;} + .d2-1659554808 .background-color-B1{background-color:#0D32B2;} + .d2-1659554808 .background-color-B2{background-color:#0D32B2;} + .d2-1659554808 .background-color-B3{background-color:#E3E9FD;} + .d2-1659554808 .background-color-B4{background-color:#E3E9FD;} + .d2-1659554808 .background-color-B5{background-color:#EDF0FD;} + .d2-1659554808 .background-color-B6{background-color:#F7F8FE;} + .d2-1659554808 .background-color-AA2{background-color:#4A6FF3;} + .d2-1659554808 .background-color-AA4{background-color:#EDF0FD;} + .d2-1659554808 .background-color-AA5{background-color:#F7F8FE;} + .d2-1659554808 .background-color-AB4{background-color:#EDF0FD;} + .d2-1659554808 .background-color-AB5{background-color:#F7F8FE;} + .d2-1659554808 .color-N1{color:#0A0F25;} + .d2-1659554808 .color-N2{color:#676C7E;} + .d2-1659554808 .color-N3{color:#9499AB;} + .d2-1659554808 .color-N4{color:#CFD2DD;} + .d2-1659554808 .color-N5{color:#DEE1EB;} + .d2-1659554808 .color-N6{color:#EEF1F8;} + .d2-1659554808 .color-N7{color:#FFFFFF;} + .d2-1659554808 .color-B1{color:#0D32B2;} + .d2-1659554808 .color-B2{color:#0D32B2;} + .d2-1659554808 .color-B3{color:#E3E9FD;} + .d2-1659554808 .color-B4{color:#E3E9FD;} + .d2-1659554808 .color-B5{color:#EDF0FD;} + .d2-1659554808 .color-B6{color:#F7F8FE;} + .d2-1659554808 .color-AA2{color:#4A6FF3;} + .d2-1659554808 .color-AA4{color:#EDF0FD;} + .d2-1659554808 .color-AA5{color:#F7F8FE;} + .d2-1659554808 .color-AB4{color:#EDF0FD;} + .d2-1659554808 .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}]]>DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES + \ No newline at end of file diff --git a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json index e8cca26bb..b94be0069 100644 --- a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -48,10 +48,10 @@ "id": "flow2", "type": "rectangle", "pos": { - "x": 176, + "x": 168, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -89,10 +89,10 @@ "id": "flow3", "type": "rectangle", "pos": { - "x": 352, + "x": 336, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -130,10 +130,10 @@ "id": "flow4", "type": "rectangle", "pos": { - "x": 528, + "x": 504, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -171,10 +171,10 @@ "id": "flow5", "type": "rectangle", "pos": { - "x": 704, + "x": 672, "y": 0 }, - "width": 136, + "width": 128, "height": 100, "opacity": 1, "strokeDash": 0, @@ -256,7 +256,7 @@ "x": 280, "y": 140 }, - "width": 100, + "width": 120, "height": 100, "opacity": 1, "strokeDash": 0, @@ -294,10 +294,10 @@ "id": "flow8", "type": "rectangle", "pos": { - "x": 420, + "x": 440, "y": 140 }, - "width": 100, + "width": 160, "height": 100, "opacity": 1, "strokeDash": 0, @@ -335,51 +335,10 @@ "id": "flow9", "type": "rectangle", "pos": { - "x": 560, + "x": 640, "y": 140 }, - "width": 120, - "height": 100, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 10, - "borderRadius": 0, - "fill": "white", - "stroke": "cornflowerblue", - "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": true, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "flow10", - "type": "rectangle", - "pos": { - "x": 720, - "y": 140 - }, - "width": 120, + "width": 160, "height": 100, "opacity": 1, "strokeDash": 0, @@ -420,7 +379,7 @@ "x": 0, "y": 280 }, - "width": 840, + "width": 800, "height": 61, "opacity": 1, "strokeDash": 0, @@ -461,7 +420,7 @@ "x": 0, "y": 381 }, - "width": 840, + "width": 800, "height": 87, "opacity": 1, "strokeDash": 0, @@ -555,7 +514,7 @@ "x": 179, "y": 508 }, - "width": 124, + "width": 117, "height": 66, "opacity": 1, "strokeDash": 0, @@ -593,7 +552,7 @@ "id": "LINUX", "type": "rectangle", "pos": { - "x": 343, + "x": 336, "y": 508 }, "width": 139, @@ -634,10 +593,10 @@ "id": "MACOS", "type": "rectangle", "pos": { - "x": 522, + "x": 515, "y": 508 }, - "width": 139, + "width": 106, "height": 66, "opacity": 1, "strokeDash": 0, @@ -675,7 +634,7 @@ "id": "KUBERNETES", "type": "rectangle", "pos": { - "x": 701, + "x": 661, "y": 508 }, "width": 139, diff --git a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg index 9841e85d6..cc62b273b 100644 --- a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES - + .d2-1659554808 .fill-N1{fill:#0A0F25;} + .d2-1659554808 .fill-N2{fill:#676C7E;} + .d2-1659554808 .fill-N3{fill:#9499AB;} + .d2-1659554808 .fill-N4{fill:#CFD2DD;} + .d2-1659554808 .fill-N5{fill:#DEE1EB;} + .d2-1659554808 .fill-N6{fill:#EEF1F8;} + .d2-1659554808 .fill-N7{fill:#FFFFFF;} + .d2-1659554808 .fill-B1{fill:#0D32B2;} + .d2-1659554808 .fill-B2{fill:#0D32B2;} + .d2-1659554808 .fill-B3{fill:#E3E9FD;} + .d2-1659554808 .fill-B4{fill:#E3E9FD;} + .d2-1659554808 .fill-B5{fill:#EDF0FD;} + .d2-1659554808 .fill-B6{fill:#F7F8FE;} + .d2-1659554808 .fill-AA2{fill:#4A6FF3;} + .d2-1659554808 .fill-AA4{fill:#EDF0FD;} + .d2-1659554808 .fill-AA5{fill:#F7F8FE;} + .d2-1659554808 .fill-AB4{fill:#EDF0FD;} + .d2-1659554808 .fill-AB5{fill:#F7F8FE;} + .d2-1659554808 .stroke-N1{stroke:#0A0F25;} + .d2-1659554808 .stroke-N2{stroke:#676C7E;} + .d2-1659554808 .stroke-N3{stroke:#9499AB;} + .d2-1659554808 .stroke-N4{stroke:#CFD2DD;} + .d2-1659554808 .stroke-N5{stroke:#DEE1EB;} + .d2-1659554808 .stroke-N6{stroke:#EEF1F8;} + .d2-1659554808 .stroke-N7{stroke:#FFFFFF;} + .d2-1659554808 .stroke-B1{stroke:#0D32B2;} + .d2-1659554808 .stroke-B2{stroke:#0D32B2;} + .d2-1659554808 .stroke-B3{stroke:#E3E9FD;} + .d2-1659554808 .stroke-B4{stroke:#E3E9FD;} + .d2-1659554808 .stroke-B5{stroke:#EDF0FD;} + .d2-1659554808 .stroke-B6{stroke:#F7F8FE;} + .d2-1659554808 .stroke-AA2{stroke:#4A6FF3;} + .d2-1659554808 .stroke-AA4{stroke:#EDF0FD;} + .d2-1659554808 .stroke-AA5{stroke:#F7F8FE;} + .d2-1659554808 .stroke-AB4{stroke:#EDF0FD;} + .d2-1659554808 .stroke-AB5{stroke:#F7F8FE;} + .d2-1659554808 .background-color-N1{background-color:#0A0F25;} + .d2-1659554808 .background-color-N2{background-color:#676C7E;} + .d2-1659554808 .background-color-N3{background-color:#9499AB;} + .d2-1659554808 .background-color-N4{background-color:#CFD2DD;} + .d2-1659554808 .background-color-N5{background-color:#DEE1EB;} + .d2-1659554808 .background-color-N6{background-color:#EEF1F8;} + .d2-1659554808 .background-color-N7{background-color:#FFFFFF;} + .d2-1659554808 .background-color-B1{background-color:#0D32B2;} + .d2-1659554808 .background-color-B2{background-color:#0D32B2;} + .d2-1659554808 .background-color-B3{background-color:#E3E9FD;} + .d2-1659554808 .background-color-B4{background-color:#E3E9FD;} + .d2-1659554808 .background-color-B5{background-color:#EDF0FD;} + .d2-1659554808 .background-color-B6{background-color:#F7F8FE;} + .d2-1659554808 .background-color-AA2{background-color:#4A6FF3;} + .d2-1659554808 .background-color-AA4{background-color:#EDF0FD;} + .d2-1659554808 .background-color-AA5{background-color:#F7F8FE;} + .d2-1659554808 .background-color-AB4{background-color:#EDF0FD;} + .d2-1659554808 .background-color-AB5{background-color:#F7F8FE;} + .d2-1659554808 .color-N1{color:#0A0F25;} + .d2-1659554808 .color-N2{color:#676C7E;} + .d2-1659554808 .color-N3{color:#9499AB;} + .d2-1659554808 .color-N4{color:#CFD2DD;} + .d2-1659554808 .color-N5{color:#DEE1EB;} + .d2-1659554808 .color-N6{color:#EEF1F8;} + .d2-1659554808 .color-N7{color:#FFFFFF;} + .d2-1659554808 .color-B1{color:#0D32B2;} + .d2-1659554808 .color-B2{color:#0D32B2;} + .d2-1659554808 .color-B3{color:#E3E9FD;} + .d2-1659554808 .color-B4{color:#E3E9FD;} + .d2-1659554808 .color-B5{color:#EDF0FD;} + .d2-1659554808 .color-B6{color:#F7F8FE;} + .d2-1659554808 .color-AA2{color:#4A6FF3;} + .d2-1659554808 .color-AA4{color:#EDF0FD;} + .d2-1659554808 .color-AA5{color:#F7F8FE;} + .d2-1659554808 .color-AB4{color:#EDF0FD;} + .d2-1659554808 .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}]]>DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES + \ No newline at end of file From cadaaeb21f89b165717f18079ee8616736be7501 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 4 Apr 2023 12:54:59 -0700 Subject: [PATCH 16/33] add padding between dagre labels --- ci/release/changelogs/next.md | 2 + d2layouts/d2dagrelayout/layout.go | 82 +++-- .../testdata/dots-real/sketch.exp.svg | 168 ++++----- .../testdata/paper-real/sketch.exp.svg | 168 ++++----- .../d2sketch/testdata/terminal/sketch.exp.svg | 176 +++++----- .../TestCLI_E2E/internal_linked_pdf.exp.pdf | Bin 79806 -> 79882 bytes e2etests/stable_test.go | 6 + .../patterns/real-lines/dagre/board.exp.json | 44 +-- .../patterns/real-lines/dagre/sketch.exp.svg | 174 +++++----- .../patterns/real/dagre/board.exp.json | 32 +- .../patterns/real/dagre/sketch.exp.svg | 168 ++++----- .../dagre/board.exp.json | 42 +-- .../dagre/sketch.exp.svg | 174 +++++----- .../stable/chaos2/dagre/board.exp.json | 136 ++++---- .../stable/chaos2/dagre/sketch.exp.svg | 194 +++++------ .../edge-label-overflow/dagre/board.exp.json | 319 +++++++++++++++++ .../edge-label-overflow/dagre/sketch.exp.svg | 104 ++++++ .../edge-label-overflow/elk/board.exp.json | 324 ++++++++++++++++++ .../edge-label-overflow/elk/sketch.exp.svg | 104 ++++++ .../stable/elk_shim/dagre/board.exp.json | 96 +++--- .../stable/elk_shim/dagre/sketch.exp.svg | 182 +++++----- .../stable/mono-font/dagre/board.exp.json | 28 +- .../stable/mono-font/dagre/sketch.exp.svg | 166 ++++----- .../self-referencing/dagre/board.exp.json | 132 +++---- .../self-referencing/dagre/sketch.exp.svg | 162 ++++----- .../themes/origami/dagre/board.exp.json | 96 +++--- .../themes/origami/dagre/sketch.exp.svg | 184 +++++----- .../themes/terminal/dagre/board.exp.json | 128 +++---- .../themes/terminal/dagre/sketch.exp.svg | 206 +++++------ .../terminal_grayscale/dagre/board.exp.json | 108 +++--- .../terminal_grayscale/dagre/sketch.exp.svg | 176 +++++----- 31 files changed, 2484 insertions(+), 1597 deletions(-) create mode 100644 e2etests/testdata/stable/edge-label-overflow/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/edge-label-overflow/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/edge-label-overflow/elk/board.exp.json create mode 100644 e2etests/testdata/stable/edge-label-overflow/elk/sketch.exp.svg diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index fdef15d98..4c987851e 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -4,6 +4,8 @@ #### Improvements 🧹 +- Labels on parallel `dagre` connections include a gap between them [#1134](https://github.com/terrastruct/d2/pull/1134) + #### Bugfixes ⛑️ - Fix a bug in 32bit builds [#1115](https://github.com/terrastruct/d2/issues/1115) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index dec8c164e..afa676dc0 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -33,6 +33,7 @@ var dagreJS string const ( MIN_SEGMENT_LEN = 10 MIN_RANK_SEP = 60 + EDGE_LABEL_GAP = 20 ) type ConfigurableOpts struct { @@ -173,37 +174,30 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } for _, edge := range g.Edges { - // dagre doesn't work with edges to containers so we connect container edges to their first child instead (going all the way down) - // we will chop the edge where it intersects the container border so it only shows the edge from the container - src := edge.Src - for len(src.Children) > 0 && src.Class == nil && src.SQLTable == nil { - // We want to get the bottom node of sources, setting its rank higher than all children - src = getLongestEdgeChainTail(g, src) - } - dst := edge.Dst - for len(dst.Children) > 0 && dst.Class == nil && dst.SQLTable == nil { - dst = dst.ChildrenArray[0] + src, dst := getEdgeEndpoints(g, edge) - // We want to get the top node of destinations - for _, child := range dst.ChildrenArray { - isHead := true - for _, e := range g.Edges { - if inContainer(e.Src, child) != nil && inContainer(e.Dst, dst) != nil { - isHead = false - break - } - } - if isHead { - dst = child - break - } + width := edge.LabelDimensions.Width + height := edge.LabelDimensions.Height + + numEdges := 0 + for _, e := range g.Edges { + otherSrc, otherDst := getEdgeEndpoints(g, e) + if (otherSrc == src && otherDst == dst) || (otherSrc == dst && otherDst == src) { + numEdges++ } } - if edge.SrcArrow && !edge.DstArrow { - // for `b <- a`, edge.Edge is `a -> b` and we expect this routing result - src, dst = dst, src + + // We want to leave some gap between multiple edges + if numEdges > 1 { + switch g.Root.Attributes.Direction.Value { + case "down", "up", "": + width += EDGE_LABEL_GAP + case "left", "right": + height += EDGE_LABEL_GAP + } } - loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID(), edge.LabelDimensions.Width, edge.LabelDimensions.Height) + + loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID(), width, height) } if debugJS { @@ -528,6 +522,40 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err return nil } +func getEdgeEndpoints(g *d2graph.Graph, edge *d2graph.Edge) (*d2graph.Object, *d2graph.Object) { + // dagre doesn't work with edges to containers so we connect container edges to their first child instead (going all the way down) + // we will chop the edge where it intersects the container border so it only shows the edge from the container + src := edge.Src + for len(src.Children) > 0 && src.Class == nil && src.SQLTable == nil { + // We want to get the bottom node of sources, setting its rank higher than all children + src = getLongestEdgeChainTail(g, src) + } + dst := edge.Dst + for len(dst.Children) > 0 && dst.Class == nil && dst.SQLTable == nil { + dst = dst.ChildrenArray[0] + + // We want to get the top node of destinations + for _, child := range dst.ChildrenArray { + isHead := true + for _, e := range g.Edges { + if inContainer(e.Src, child) != nil && inContainer(e.Dst, dst) != nil { + isHead = false + break + } + } + if isHead { + dst = child + break + } + } + } + if edge.SrcArrow && !edge.DstArrow { + // for `b <- a`, edge.Edge is `a -> b` and we expect this routing result + src, dst = dst, src + } + return src, dst +} + func setGraphAttrs(attrs dagreOpts) string { return fmt.Sprintf(`g.setGraph({ ranksep: %d, diff --git a/d2renderers/d2sketch/testdata/dots-real/sketch.exp.svg b/d2renderers/d2sketch/testdata/dots-real/sketch.exp.svg index c75d9d004..2433dad67 100644 --- a/d2renderers/d2sketch/testdata/dots-real/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/dots-real/sketch.exp.svg @@ -1,16 +1,16 @@ - + .d2-1107823994 .fill-N1{fill:#0A0F25;} + .d2-1107823994 .fill-N2{fill:#676C7E;} + .d2-1107823994 .fill-N3{fill:#9499AB;} + .d2-1107823994 .fill-N4{fill:#CFD2DD;} + .d2-1107823994 .fill-N5{fill:#DEE1EB;} + .d2-1107823994 .fill-N6{fill:#EEF1F8;} + .d2-1107823994 .fill-N7{fill:#FFFFFF;} + .d2-1107823994 .fill-B1{fill:#0D32B2;} + .d2-1107823994 .fill-B2{fill:#0D32B2;} + .d2-1107823994 .fill-B3{fill:#E3E9FD;} + .d2-1107823994 .fill-B4{fill:#E3E9FD;} + .d2-1107823994 .fill-B5{fill:#EDF0FD;} + .d2-1107823994 .fill-B6{fill:#F7F8FE;} + .d2-1107823994 .fill-AA2{fill:#4A6FF3;} + .d2-1107823994 .fill-AA4{fill:#EDF0FD;} + .d2-1107823994 .fill-AA5{fill:#F7F8FE;} + .d2-1107823994 .fill-AB4{fill:#EDF0FD;} + .d2-1107823994 .fill-AB5{fill:#F7F8FE;} + .d2-1107823994 .stroke-N1{stroke:#0A0F25;} + .d2-1107823994 .stroke-N2{stroke:#676C7E;} + .d2-1107823994 .stroke-N3{stroke:#9499AB;} + .d2-1107823994 .stroke-N4{stroke:#CFD2DD;} + .d2-1107823994 .stroke-N5{stroke:#DEE1EB;} + .d2-1107823994 .stroke-N6{stroke:#EEF1F8;} + .d2-1107823994 .stroke-N7{stroke:#FFFFFF;} + .d2-1107823994 .stroke-B1{stroke:#0D32B2;} + .d2-1107823994 .stroke-B2{stroke:#0D32B2;} + .d2-1107823994 .stroke-B3{stroke:#E3E9FD;} + .d2-1107823994 .stroke-B4{stroke:#E3E9FD;} + .d2-1107823994 .stroke-B5{stroke:#EDF0FD;} + .d2-1107823994 .stroke-B6{stroke:#F7F8FE;} + .d2-1107823994 .stroke-AA2{stroke:#4A6FF3;} + .d2-1107823994 .stroke-AA4{stroke:#EDF0FD;} + .d2-1107823994 .stroke-AA5{stroke:#F7F8FE;} + .d2-1107823994 .stroke-AB4{stroke:#EDF0FD;} + .d2-1107823994 .stroke-AB5{stroke:#F7F8FE;} + .d2-1107823994 .background-color-N1{background-color:#0A0F25;} + .d2-1107823994 .background-color-N2{background-color:#676C7E;} + .d2-1107823994 .background-color-N3{background-color:#9499AB;} + .d2-1107823994 .background-color-N4{background-color:#CFD2DD;} + .d2-1107823994 .background-color-N5{background-color:#DEE1EB;} + .d2-1107823994 .background-color-N6{background-color:#EEF1F8;} + .d2-1107823994 .background-color-N7{background-color:#FFFFFF;} + .d2-1107823994 .background-color-B1{background-color:#0D32B2;} + .d2-1107823994 .background-color-B2{background-color:#0D32B2;} + .d2-1107823994 .background-color-B3{background-color:#E3E9FD;} + .d2-1107823994 .background-color-B4{background-color:#E3E9FD;} + .d2-1107823994 .background-color-B5{background-color:#EDF0FD;} + .d2-1107823994 .background-color-B6{background-color:#F7F8FE;} + .d2-1107823994 .background-color-AA2{background-color:#4A6FF3;} + .d2-1107823994 .background-color-AA4{background-color:#EDF0FD;} + .d2-1107823994 .background-color-AA5{background-color:#F7F8FE;} + .d2-1107823994 .background-color-AB4{background-color:#EDF0FD;} + .d2-1107823994 .background-color-AB5{background-color:#F7F8FE;} + .d2-1107823994 .color-N1{color:#0A0F25;} + .d2-1107823994 .color-N2{color:#676C7E;} + .d2-1107823994 .color-N3{color:#9499AB;} + .d2-1107823994 .color-N4{color:#CFD2DD;} + .d2-1107823994 .color-N5{color:#DEE1EB;} + .d2-1107823994 .color-N6{color:#EEF1F8;} + .d2-1107823994 .color-N7{color:#FFFFFF;} + .d2-1107823994 .color-B1{color:#0D32B2;} + .d2-1107823994 .color-B2{color:#0D32B2;} + .d2-1107823994 .color-B3{color:#E3E9FD;} + .d2-1107823994 .color-B4{color:#E3E9FD;} + .d2-1107823994 .color-B5{color:#EDF0FD;} + .d2-1107823994 .color-B6{color:#F7F8FE;} + .d2-1107823994 .color-AA2{color:#4A6FF3;} + .d2-1107823994 .color-AA4{color:#EDF0FD;} + .d2-1107823994 .color-AA5{color:#F7F8FE;} + .d2-1107823994 .color-AB4{color:#EDF0FD;} + .d2-1107823994 .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}]]> @@ -159,9 +159,9 @@ -NETWORKD2 Parser+readerio.RuneReader+readerPosd2ast.Position-lookahead[]rune#peekn(n int)(s string, eof bool)+peek()(r rune, eof bool)+rewind()void+commit()voidCELL TOWERSATELLITESTRANSMITTER SEND SEND SEND - - - - +NETWORKD2 Parser+readerio.RuneReader+readerPosd2ast.Position-lookahead[]rune#peekn(n int)(s string, eof bool)+peek()(r rune, eof bool)+rewind()void+commit()voidCELL TOWERSATELLITESTRANSMITTER SEND SEND SEND + + + + \ No newline at end of file diff --git a/d2renderers/d2sketch/testdata/paper-real/sketch.exp.svg b/d2renderers/d2sketch/testdata/paper-real/sketch.exp.svg index c61df223a..b213a3400 100644 --- a/d2renderers/d2sketch/testdata/paper-real/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/paper-real/sketch.exp.svg @@ -1,16 +1,16 @@ - + .d2-3084549463 .fill-N1{fill:#0A0F25;} + .d2-3084549463 .fill-N2{fill:#676C7E;} + .d2-3084549463 .fill-N3{fill:#9499AB;} + .d2-3084549463 .fill-N4{fill:#CFD2DD;} + .d2-3084549463 .fill-N5{fill:#DEE1EB;} + .d2-3084549463 .fill-N6{fill:#EEF1F8;} + .d2-3084549463 .fill-N7{fill:#FFFFFF;} + .d2-3084549463 .fill-B1{fill:#0D32B2;} + .d2-3084549463 .fill-B2{fill:#0D32B2;} + .d2-3084549463 .fill-B3{fill:#E3E9FD;} + .d2-3084549463 .fill-B4{fill:#E3E9FD;} + .d2-3084549463 .fill-B5{fill:#EDF0FD;} + .d2-3084549463 .fill-B6{fill:#F7F8FE;} + .d2-3084549463 .fill-AA2{fill:#4A6FF3;} + .d2-3084549463 .fill-AA4{fill:#EDF0FD;} + .d2-3084549463 .fill-AA5{fill:#F7F8FE;} + .d2-3084549463 .fill-AB4{fill:#EDF0FD;} + .d2-3084549463 .fill-AB5{fill:#F7F8FE;} + .d2-3084549463 .stroke-N1{stroke:#0A0F25;} + .d2-3084549463 .stroke-N2{stroke:#676C7E;} + .d2-3084549463 .stroke-N3{stroke:#9499AB;} + .d2-3084549463 .stroke-N4{stroke:#CFD2DD;} + .d2-3084549463 .stroke-N5{stroke:#DEE1EB;} + .d2-3084549463 .stroke-N6{stroke:#EEF1F8;} + .d2-3084549463 .stroke-N7{stroke:#FFFFFF;} + .d2-3084549463 .stroke-B1{stroke:#0D32B2;} + .d2-3084549463 .stroke-B2{stroke:#0D32B2;} + .d2-3084549463 .stroke-B3{stroke:#E3E9FD;} + .d2-3084549463 .stroke-B4{stroke:#E3E9FD;} + .d2-3084549463 .stroke-B5{stroke:#EDF0FD;} + .d2-3084549463 .stroke-B6{stroke:#F7F8FE;} + .d2-3084549463 .stroke-AA2{stroke:#4A6FF3;} + .d2-3084549463 .stroke-AA4{stroke:#EDF0FD;} + .d2-3084549463 .stroke-AA5{stroke:#F7F8FE;} + .d2-3084549463 .stroke-AB4{stroke:#EDF0FD;} + .d2-3084549463 .stroke-AB5{stroke:#F7F8FE;} + .d2-3084549463 .background-color-N1{background-color:#0A0F25;} + .d2-3084549463 .background-color-N2{background-color:#676C7E;} + .d2-3084549463 .background-color-N3{background-color:#9499AB;} + .d2-3084549463 .background-color-N4{background-color:#CFD2DD;} + .d2-3084549463 .background-color-N5{background-color:#DEE1EB;} + .d2-3084549463 .background-color-N6{background-color:#EEF1F8;} + .d2-3084549463 .background-color-N7{background-color:#FFFFFF;} + .d2-3084549463 .background-color-B1{background-color:#0D32B2;} + .d2-3084549463 .background-color-B2{background-color:#0D32B2;} + .d2-3084549463 .background-color-B3{background-color:#E3E9FD;} + .d2-3084549463 .background-color-B4{background-color:#E3E9FD;} + .d2-3084549463 .background-color-B5{background-color:#EDF0FD;} + .d2-3084549463 .background-color-B6{background-color:#F7F8FE;} + .d2-3084549463 .background-color-AA2{background-color:#4A6FF3;} + .d2-3084549463 .background-color-AA4{background-color:#EDF0FD;} + .d2-3084549463 .background-color-AA5{background-color:#F7F8FE;} + .d2-3084549463 .background-color-AB4{background-color:#EDF0FD;} + .d2-3084549463 .background-color-AB5{background-color:#F7F8FE;} + .d2-3084549463 .color-N1{color:#0A0F25;} + .d2-3084549463 .color-N2{color:#676C7E;} + .d2-3084549463 .color-N3{color:#9499AB;} + .d2-3084549463 .color-N4{color:#CFD2DD;} + .d2-3084549463 .color-N5{color:#DEE1EB;} + .d2-3084549463 .color-N6{color:#EEF1F8;} + .d2-3084549463 .color-N7{color:#FFFFFF;} + .d2-3084549463 .color-B1{color:#0D32B2;} + .d2-3084549463 .color-B2{color:#0D32B2;} + .d2-3084549463 .color-B3{color:#E3E9FD;} + .d2-3084549463 .color-B4{color:#E3E9FD;} + .d2-3084549463 .color-B5{color:#EDF0FD;} + .d2-3084549463 .color-B6{color:#F7F8FE;} + .d2-3084549463 .color-AA2{color:#4A6FF3;} + .d2-3084549463 .color-AA4{color:#EDF0FD;} + .d2-3084549463 .color-AA5{color:#F7F8FE;} + .d2-3084549463 .color-AB4{color:#EDF0FD;} + .d2-3084549463 .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}]]> @@ -1205,9 +1205,9 @@ -NETWORKCELL TOWERSATELLITESTRANSMITTER SEND SEND SEND - - - - +NETWORKCELL TOWERSATELLITESTRANSMITTER SEND SEND SEND + + + + \ No newline at end of file diff --git a/d2renderers/d2sketch/testdata/terminal/sketch.exp.svg b/d2renderers/d2sketch/testdata/terminal/sketch.exp.svg index 167aac474..4459c8a37 100644 --- a/d2renderers/d2sketch/testdata/terminal/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/terminal/sketch.exp.svg @@ -1,16 +1,16 @@ - + .d2-457017616 .fill-N1{fill:#000410;} + .d2-457017616 .fill-N2{fill:#0000B8;} + .d2-457017616 .fill-N3{fill:#9499AB;} + .d2-457017616 .fill-N4{fill:#CFD2DD;} + .d2-457017616 .fill-N5{fill:#C3DEF3;} + .d2-457017616 .fill-N6{fill:#EEF1F8;} + .d2-457017616 .fill-N7{fill:#FFFFFF;} + .d2-457017616 .fill-B1{fill:#000410;} + .d2-457017616 .fill-B2{fill:#0000E4;} + .d2-457017616 .fill-B3{fill:#5AA4DC;} + .d2-457017616 .fill-B4{fill:#E7E9EE;} + .d2-457017616 .fill-B5{fill:#F5F6F9;} + .d2-457017616 .fill-B6{fill:#FFFFFF;} + .d2-457017616 .fill-AA2{fill:#008566;} + .d2-457017616 .fill-AA4{fill:#45BBA5;} + .d2-457017616 .fill-AA5{fill:#7ACCBD;} + .d2-457017616 .fill-AB4{fill:#F1C759;} + .d2-457017616 .fill-AB5{fill:#F9E088;} + .d2-457017616 .stroke-N1{stroke:#000410;} + .d2-457017616 .stroke-N2{stroke:#0000B8;} + .d2-457017616 .stroke-N3{stroke:#9499AB;} + .d2-457017616 .stroke-N4{stroke:#CFD2DD;} + .d2-457017616 .stroke-N5{stroke:#C3DEF3;} + .d2-457017616 .stroke-N6{stroke:#EEF1F8;} + .d2-457017616 .stroke-N7{stroke:#FFFFFF;} + .d2-457017616 .stroke-B1{stroke:#000410;} + .d2-457017616 .stroke-B2{stroke:#0000E4;} + .d2-457017616 .stroke-B3{stroke:#5AA4DC;} + .d2-457017616 .stroke-B4{stroke:#E7E9EE;} + .d2-457017616 .stroke-B5{stroke:#F5F6F9;} + .d2-457017616 .stroke-B6{stroke:#FFFFFF;} + .d2-457017616 .stroke-AA2{stroke:#008566;} + .d2-457017616 .stroke-AA4{stroke:#45BBA5;} + .d2-457017616 .stroke-AA5{stroke:#7ACCBD;} + .d2-457017616 .stroke-AB4{stroke:#F1C759;} + .d2-457017616 .stroke-AB5{stroke:#F9E088;} + .d2-457017616 .background-color-N1{background-color:#000410;} + .d2-457017616 .background-color-N2{background-color:#0000B8;} + .d2-457017616 .background-color-N3{background-color:#9499AB;} + .d2-457017616 .background-color-N4{background-color:#CFD2DD;} + .d2-457017616 .background-color-N5{background-color:#C3DEF3;} + .d2-457017616 .background-color-N6{background-color:#EEF1F8;} + .d2-457017616 .background-color-N7{background-color:#FFFFFF;} + .d2-457017616 .background-color-B1{background-color:#000410;} + .d2-457017616 .background-color-B2{background-color:#0000E4;} + .d2-457017616 .background-color-B3{background-color:#5AA4DC;} + .d2-457017616 .background-color-B4{background-color:#E7E9EE;} + .d2-457017616 .background-color-B5{background-color:#F5F6F9;} + .d2-457017616 .background-color-B6{background-color:#FFFFFF;} + .d2-457017616 .background-color-AA2{background-color:#008566;} + .d2-457017616 .background-color-AA4{background-color:#45BBA5;} + .d2-457017616 .background-color-AA5{background-color:#7ACCBD;} + .d2-457017616 .background-color-AB4{background-color:#F1C759;} + .d2-457017616 .background-color-AB5{background-color:#F9E088;} + .d2-457017616 .color-N1{color:#000410;} + .d2-457017616 .color-N2{color:#0000B8;} + .d2-457017616 .color-N3{color:#9499AB;} + .d2-457017616 .color-N4{color:#CFD2DD;} + .d2-457017616 .color-N5{color:#C3DEF3;} + .d2-457017616 .color-N6{color:#EEF1F8;} + .d2-457017616 .color-N7{color:#FFFFFF;} + .d2-457017616 .color-B1{color:#000410;} + .d2-457017616 .color-B2{color:#0000E4;} + .d2-457017616 .color-B3{color:#5AA4DC;} + .d2-457017616 .color-B4{color:#E7E9EE;} + .d2-457017616 .color-B5{color:#F5F6F9;} + .d2-457017616 .color-B6{color:#FFFFFF;} + .d2-457017616 .color-AA2{color:#008566;} + .d2-457017616 .color-AA4{color:#45BBA5;} + .d2-457017616 .color-AA5{color:#7ACCBD;} + .d2-457017616 .color-AB4{color:#F1C759;} + .d2-457017616 .color-AB5{color:#F9E088;}.appendix text.text{fill:#000410}.md{--color-fg-default:#000410;--color-fg-muted:#0000B8;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#000410;--color-border-muted:#0000E4;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0000E4;--color-accent-emphasis:#0000E4;--color-attention-subtle:#0000B8;--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-normal);mix-blend-mode:color-burn}.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-normal);mix-blend-mode:color-burn}.sketch-overlay-AA5{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-AB4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-AB5{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-darker);mix-blend-mode:lighten}.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-normal);mix-blend-mode:color-burn}.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}]]> @@ -137,14 +137,14 @@ -NETWORKUSERAPI SERVERLOGSCELL TOWERONLINE PORTALDATA PROCESSORSATELLITESTRANSMITTERUISTORAGE SEND SEND SEND PHONE LOGS MAKE CALL ACCESS DISPLAY PERSIST - - - - - - +NETWORKUSERAPI SERVERLOGSCELL TOWERONLINE PORTALDATA PROCESSORSATELLITESTRANSMITTERUISTORAGE SEND SEND SEND PHONE LOGS MAKE CALL ACCESS DISPLAY PERSIST + + + + + + - - + + \ No newline at end of file diff --git a/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf b/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf index 463c4cc7a850319782fab64d0a0a7e65fab8a7a9..23628020db9dbd4c1b99f85e76f13e62381db091 100644 GIT binary patch delta 20342 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 delta 20244 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%0AK9~P z=^yIfpYX-ee-AayZ;I5t+`Ujj8z=^5!pW~{`Pp+hy6y2?$3-DMc1$p1SRsD3t~!K0 z?JNM2i^u@b;AZ#i>c5qSULT!1BA%4LWD6{=C~JaK9_U!t$H+vY|Ucl`rkm-WHrt2SihuDm44S zobUr*%3!Hq<5ys?$LH!`5l5D@NYu3G{g!qwN={mo1eplZ8)2_ZF{2h)Jd(& zrlO&ZAwNH%WaUJGsM0fL{+F-EK6Q_CW%|%jVo{T~ME4hh4o~*_ zXWRH?654=R^y12F*Vp4jfG0aa>yA}daL*{P^J?{`EgTf0H<~*7XHB141sCFZ5<>dY z#(t}3qScB;#hSLKa#aE+H(~DUPLC;^DLm0a+jpr0;I-toqYXTlGi^PxlYg(6z*ZyG zura;vy2CAH!)gho#Eb5RzT29ILP*{5y$ybiuM$;{)J014<=7?zqTeKIi}w?{8hrk6 zvQJc?ITT-XKV?{WytyUGdUx&p{i?RfPd25+gF;x>oLI6Sp;iNM>j1yGaFI((Qr*$= zE78m5VZ*4n|Kg(}C$Ts3pGT?H3HOj)wiBCsk;y9K@5+8N$fb+$dBOXzv*^l<^;+MGSPUS_y-e(V`N#9^34HzY+I8glMGSW)vYIJ47kq9>nVE%}xP44F>bC}NLRQA28ThQ$P^TU?14sNP_76ZnS#Z8xRMo-2t~N!X;1?W zzMu_9<3XSs5)Ojg$ryLM8wx?exq6_mWLG@W)g6zb;1rRlb&a(q4Si@n7tdTEGfL19 zn|%l*9D&6k4?#6g`cRC>zV3<#jSeH>NE93m|1M)_VjxMfSVj2Sq3Ep$UBAHMw6u_n zZVcoI0kr)O5gd+3p*PkcPXyaY_p!L%?qoA<^(3%p%cP(D8pZh19}g8JTM) zerOS`1;=fKqp@hr#yYSQD8|&9i67t?Exgtba6IA%N3_5gGW4+!8TXBFBn}*%4JJ@v ocs4qsg@NNXn#JPq*o{HJ;^8 api server `, }, + { + name: "edge-label-overflow", + script: `student -> committee chair: Apply for appeal +student <- committee chair: Deny. Need more information +committee chair -> committee: Accept appeal`, + }, { name: "mono-edge", script: `direction: right diff --git a/e2etests/testdata/patterns/real-lines/dagre/board.exp.json b/e2etests/testdata/patterns/real-lines/dagre/board.exp.json index 82f61f9b5..40986c0a6 100644 --- a/e2etests/testdata/patterns/real-lines/dagre/board.exp.json +++ b/e2etests/testdata/patterns/real-lines/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 41 }, - "width": 334, + "width": 360, "height": 640, "opacity": 1, "strokeDash": 0, @@ -52,7 +52,7 @@ "x": 20, "y": 106 }, - "width": 294, + "width": 320, "height": 545, "opacity": 1, "strokeDash": 0, @@ -91,7 +91,7 @@ "id": "NETWORK.CELL TOWER.satellites", "type": "stored_data", "pos": { - "x": 87, + "x": 100, "y": 195 }, "width": 161, @@ -132,7 +132,7 @@ "id": "NETWORK.CELL TOWER.transmitter", "type": "rectangle", "pos": { - "x": 92, + "x": 105, "y": 496 }, "width": 151, @@ -173,7 +173,7 @@ "id": "costumes", "type": "sql_table", "pos": { - "x": 374, + "x": 401, "y": 100 }, "width": 311, @@ -330,7 +330,7 @@ "id": "monsters", "type": "sql_table", "pos": { - "x": 374, + "x": 401, "y": 401 }, "width": 311, @@ -512,19 +512,19 @@ "labelPercentage": 0, "route": [ { - "x": 151, + "x": 163, "y": 262 }, { - "x": 108, + "x": 114.4, "y": 355.6 }, { - "x": 108.05, + "x": 114.45, "y": 402.6 }, { - "x": 151.25, + "x": 163.25, "y": 497 } ], @@ -561,19 +561,19 @@ "labelPercentage": 0, "route": [ { - "x": 167, + "x": 180, "y": 262 }, { - "x": 167, + "x": 180.2, "y": 355.6 }, { - "x": 167, + "x": 180.25, "y": 402.6 }, { - "x": 167, + "x": 180.25, "y": 497 } ], @@ -610,19 +610,19 @@ "labelPercentage": 0, "route": [ { - "x": 183, + "x": 198, "y": 262 }, { - "x": 226, + "x": 246.2, "y": 355.6 }, { - "x": 225.95, + "x": 246.05, "y": 402.6 }, { - "x": 182.75, + "x": 197.25, "y": 497 } ], @@ -659,19 +659,19 @@ "labelPercentage": 0, "route": [ { - "x": 529.5, + "x": 556, "y": 280 }, { - "x": 529.5, + "x": 556, "y": 328.4 }, { - "x": 529.5, + "x": 556, "y": 352.7 }, { - "x": 529.5, + "x": 556, "y": 401.5 } ], diff --git a/e2etests/testdata/patterns/real-lines/dagre/sketch.exp.svg b/e2etests/testdata/patterns/real-lines/dagre/sketch.exp.svg index 6508e7c12..2ca214a94 100644 --- a/e2etests/testdata/patterns/real-lines/dagre/sketch.exp.svg +++ b/e2etests/testdata/patterns/real-lines/dagre/sketch.exp.svg @@ -1,23 +1,23 @@ -Kubernetesopensvck8s-master1k8s-master2k8s-master3k8s-worker1k8s-worker2k8s-worker3VM1VM2 keycloakheptapodharborvault - - - - - + .d2-3464567729 .fill-N1{fill:#0A0F25;} + .d2-3464567729 .fill-N2{fill:#676C7E;} + .d2-3464567729 .fill-N3{fill:#9499AB;} + .d2-3464567729 .fill-N4{fill:#CFD2DD;} + .d2-3464567729 .fill-N5{fill:#DEE1EB;} + .d2-3464567729 .fill-N6{fill:#EEF1F8;} + .d2-3464567729 .fill-N7{fill:#FFFFFF;} + .d2-3464567729 .fill-B1{fill:#0D32B2;} + .d2-3464567729 .fill-B2{fill:#0D32B2;} + .d2-3464567729 .fill-B3{fill:#E3E9FD;} + .d2-3464567729 .fill-B4{fill:#E3E9FD;} + .d2-3464567729 .fill-B5{fill:#EDF0FD;} + .d2-3464567729 .fill-B6{fill:#F7F8FE;} + .d2-3464567729 .fill-AA2{fill:#4A6FF3;} + .d2-3464567729 .fill-AA4{fill:#EDF0FD;} + .d2-3464567729 .fill-AA5{fill:#F7F8FE;} + .d2-3464567729 .fill-AB4{fill:#EDF0FD;} + .d2-3464567729 .fill-AB5{fill:#F7F8FE;} + .d2-3464567729 .stroke-N1{stroke:#0A0F25;} + .d2-3464567729 .stroke-N2{stroke:#676C7E;} + .d2-3464567729 .stroke-N3{stroke:#9499AB;} + .d2-3464567729 .stroke-N4{stroke:#CFD2DD;} + .d2-3464567729 .stroke-N5{stroke:#DEE1EB;} + .d2-3464567729 .stroke-N6{stroke:#EEF1F8;} + .d2-3464567729 .stroke-N7{stroke:#FFFFFF;} + .d2-3464567729 .stroke-B1{stroke:#0D32B2;} + .d2-3464567729 .stroke-B2{stroke:#0D32B2;} + .d2-3464567729 .stroke-B3{stroke:#E3E9FD;} + .d2-3464567729 .stroke-B4{stroke:#E3E9FD;} + .d2-3464567729 .stroke-B5{stroke:#EDF0FD;} + .d2-3464567729 .stroke-B6{stroke:#F7F8FE;} + .d2-3464567729 .stroke-AA2{stroke:#4A6FF3;} + .d2-3464567729 .stroke-AA4{stroke:#EDF0FD;} + .d2-3464567729 .stroke-AA5{stroke:#F7F8FE;} + .d2-3464567729 .stroke-AB4{stroke:#EDF0FD;} + .d2-3464567729 .stroke-AB5{stroke:#F7F8FE;} + .d2-3464567729 .background-color-N1{background-color:#0A0F25;} + .d2-3464567729 .background-color-N2{background-color:#676C7E;} + .d2-3464567729 .background-color-N3{background-color:#9499AB;} + .d2-3464567729 .background-color-N4{background-color:#CFD2DD;} + .d2-3464567729 .background-color-N5{background-color:#DEE1EB;} + .d2-3464567729 .background-color-N6{background-color:#EEF1F8;} + .d2-3464567729 .background-color-N7{background-color:#FFFFFF;} + .d2-3464567729 .background-color-B1{background-color:#0D32B2;} + .d2-3464567729 .background-color-B2{background-color:#0D32B2;} + .d2-3464567729 .background-color-B3{background-color:#E3E9FD;} + .d2-3464567729 .background-color-B4{background-color:#E3E9FD;} + .d2-3464567729 .background-color-B5{background-color:#EDF0FD;} + .d2-3464567729 .background-color-B6{background-color:#F7F8FE;} + .d2-3464567729 .background-color-AA2{background-color:#4A6FF3;} + .d2-3464567729 .background-color-AA4{background-color:#EDF0FD;} + .d2-3464567729 .background-color-AA5{background-color:#F7F8FE;} + .d2-3464567729 .background-color-AB4{background-color:#EDF0FD;} + .d2-3464567729 .background-color-AB5{background-color:#F7F8FE;} + .d2-3464567729 .color-N1{color:#0A0F25;} + .d2-3464567729 .color-N2{color:#676C7E;} + .d2-3464567729 .color-N3{color:#9499AB;} + .d2-3464567729 .color-N4{color:#CFD2DD;} + .d2-3464567729 .color-N5{color:#DEE1EB;} + .d2-3464567729 .color-N6{color:#EEF1F8;} + .d2-3464567729 .color-N7{color:#FFFFFF;} + .d2-3464567729 .color-B1{color:#0D32B2;} + .d2-3464567729 .color-B2{color:#0D32B2;} + .d2-3464567729 .color-B3{color:#E3E9FD;} + .d2-3464567729 .color-B4{color:#E3E9FD;} + .d2-3464567729 .color-B5{color:#EDF0FD;} + .d2-3464567729 .color-B6{color:#F7F8FE;} + .d2-3464567729 .color-AA2{color:#4A6FF3;} + .d2-3464567729 .color-AA4{color:#EDF0FD;} + .d2-3464567729 .color-AA5{color:#F7F8FE;} + .d2-3464567729 .color-AB4{color:#EDF0FD;} + .d2-3464567729 .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}]]>Kubernetesopensvck8s-master1k8s-master2k8s-master3k8s-worker1k8s-worker2k8s-worker3VM1VM2 keycloakheptapodharborvault + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/chaos2/dagre/board.exp.json b/e2etests/testdata/stable/chaos2/dagre/board.exp.json index 1fb61555f..216ed84ab 100644 --- a/e2etests/testdata/stable/chaos2/dagre/board.exp.json +++ b/e2etests/testdata/stable/chaos2/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 41 }, - "width": 806, + "width": 834, "height": 1314, "opacity": 1, "strokeDash": 0, @@ -51,7 +51,7 @@ "x": 20, "y": 106 }, - "width": 567, + "width": 595, "height": 1219, "opacity": 1, "strokeDash": 0, @@ -92,7 +92,7 @@ "x": 40, "y": 721 }, - "width": 393, + "width": 421, "height": 572, "opacity": 1, "strokeDash": 0, @@ -252,7 +252,7 @@ "id": "aa.bb.cc.gg", "type": "text", "pos": { - "x": 190, + "x": 187, "y": 1043 }, "width": 17, @@ -292,7 +292,7 @@ "id": "aa.bb.cc.hh", "type": "rectangle", "pos": { - "x": 324, + "x": 334, "y": 1189 }, "width": 63, @@ -336,7 +336,7 @@ "x": 52, "y": 169 }, - "width": 469, + "width": 496, "height": 161, "opacity": 1, "strokeDash": 0, @@ -374,7 +374,7 @@ "id": "aa.bb.ii.jj", "type": "diamond", "pos": { - "x": 431, + "x": 458, "y": 204 }, "width": 50, @@ -415,7 +415,7 @@ "id": "aa.bb.kk", "type": "oval", "pos": { - "x": 474, + "x": 501, "y": 1169 }, "width": 74, @@ -456,7 +456,7 @@ "id": "aa.ll", "type": "rectangle", "pos": { - "x": 670, + "x": 698, "y": 772 }, "width": 54, @@ -497,7 +497,7 @@ "id": "aa.mm", "type": "cylinder", "pos": { - "x": 662, + "x": 689, "y": 433 }, "width": 71, @@ -538,7 +538,7 @@ "id": "aa.nn", "type": "text", "pos": { - "x": 628, + "x": 655, "y": 1178 }, "width": 16, @@ -578,7 +578,7 @@ "id": "aa.oo", "type": "rectangle", "pos": { - "x": 704, + "x": 731, "y": 1155 }, "width": 63, @@ -652,12 +652,12 @@ "y": 910.3 }, { - "x": 132.35, - "y": 995.1959501557633 + "x": 131.8, + "y": 995.1 }, { - "x": 189.75, - "y": 1045.9797507788162 + "x": 187, + "y": 1045.5 } ], "isCurve": true, @@ -693,20 +693,20 @@ "labelPercentage": 0, "route": [ { - "x": 198.25, + "x": 195.5, "y": 1064 }, { - "x": 198.25, + "x": 195.5, "y": 1112.4 }, { - "x": 223.45, - "y": 1140.1 + "x": 223.3, + "y": 1140.3 }, { - "x": 324.25, - "y": 1202.5 + "x": 334.5, + "y": 1203.5 } ], "isCurve": true, @@ -815,12 +815,12 @@ "labelPercentage": 0, "route": [ { - "x": 670.25, - "y": 811.7993675333802 + "x": 697.5, + "y": 811.4285714285714 }, { - "x": 587.25, - "y": 866.7993675333802 + "x": 614.5, + "y": 865.4285714285714 } ], "animated": false, @@ -855,12 +855,12 @@ "labelPercentage": 0, "route": [ { - "x": 662, - "y": 501 + "x": 689, + "y": 500 }, { - "x": 284.79999999999995, - "y": 589.8 + "x": 290.2, + "y": 589.6 }, { "x": 190.5, @@ -904,31 +904,31 @@ "labelPercentage": 0, "route": [ { - "x": 697, + "x": 725, "y": 552 }, { - "x": 697.2, + "x": 724.6, "y": 600 }, { - "x": 697.25, + "x": 724.5, "y": 624.1 }, { - "x": 697.25, + "x": 724.5, "y": 642.25 }, { - "x": 697.25, + "x": 724.5, "y": 660.4 }, { - "x": 697.25, + "x": 724.5, "y": 732.5 }, { - "x": 697.25, + "x": 724.5, "y": 772.5 } ], @@ -965,12 +965,12 @@ "labelPercentage": 0, "route": [ { - "x": 662, + "x": 689, "y": 505 }, { - "x": 587.75, - "y": 568.4633307868602 + "x": 615, + "y": 566.9955817378498 } ], "animated": false, @@ -1005,19 +1005,19 @@ "labelPercentage": 0, "route": [ { - "x": 670.25, - "y": 811.1842105263158 + "x": 697.5, + "y": 810.8167259786477 }, { - "x": 376.45, - "y": 873.0368421052632 + "x": 381.9, + "y": 872.9633451957295 }, { - "x": 283.8, + "x": 283.2, "y": 968.7 }, { - "x": 207, + "x": 204, "y": 1047.5 } ], @@ -1054,19 +1054,19 @@ "labelPercentage": 0, "route": [ { - "x": 662, + "x": 689, "y": 473 }, { - "x": 517.8, + "x": 545, "y": 393 }, { - "x": 481.8, + "x": 509, "y": 364.6 }, { - "x": 482, + "x": 509, "y": 331 } ], @@ -1103,12 +1103,12 @@ "labelPercentage": 0, "route": [ { - "x": 434, + "x": 461, "y": 896.5 }, { - "x": 670, - "y": 813.5 + "x": 697.5, + "y": 812.9328358208955 } ], "animated": false, @@ -1143,56 +1143,56 @@ "labelPercentage": 0, "route": [ { - "x": 454, + "x": 481, "y": 331 }, { - "x": 453.8, + "x": 481, "y": 364.6 }, { - "x": 453.75, + "x": 481, "y": 396.9 }, { - "x": 453.75, + "x": 481, "y": 432.75 }, { - "x": 453.75, + "x": 481, "y": 468.6 }, { - "x": 453.75, + "x": 481, "y": 516.4 }, { - "x": 453.75, + "x": 481, "y": 552.25 }, { - "x": 453.75, + "x": 481, "y": 588.1 }, { - "x": 453.75, + "x": 481, "y": 624.1 }, { - "x": 453.75, + "x": 481, "y": 642.25 }, { - "x": 453.75, + "x": 481, "y": 660.4 }, { - "x": 496.95, - "y": 737.3 + "x": 524.3, + "y": 737.2593429158111 }, { - "x": 669.75, - "y": 796.5 + "x": 697.5, + "y": 796.2967145790554 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg b/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg index 2580cdbb6..b7776e4c0 100644 --- a/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg @@ -1,23 +1,23 @@ -aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - - - - - - - - - +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/edge-label-overflow/dagre/board.exp.json b/e2etests/testdata/stable/edge-label-overflow/dagre/board.exp.json new file mode 100644 index 000000000..447a27946 --- /dev/null +++ b/e2etests/testdata/stable/edge-label-overflow/dagre/board.exp.json @@ -0,0 +1,319 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "student", + "type": "rectangle", + "pos": { + "x": 110, + "y": 0 + }, + "width": 100, + "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": "student", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 55, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "committee chair", + "type": "rectangle", + "pos": { + "x": 79, + "y": 187 + }, + "width": 162, + "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": "committee chair", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 117, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "committee", + "type": "rectangle", + "pos": { + "x": 99, + "y": 374 + }, + "width": 122, + "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": "committee", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 77, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(student -> committee chair)[0]", + "src": "student", + "srcArrow": "none", + "srcLabel": "", + "dst": "committee chair", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Apply for appeal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 109, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 126.13235294117646, + "y": 66 + }, + { + "x": 76.82647058823528, + "y": 114.4 + }, + { + "x": 76.9, + "y": 138.7 + }, + { + "x": 126.5, + "y": 187.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(student <- committee chair)[0]", + "src": "student", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "committee chair", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Deny. Need more information", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 192, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 193.36764705882354, + "y": 66 + }, + { + "x": 242.67352941176472, + "y": 114.4 + }, + { + "x": 242.6, + "y": 138.7 + }, + { + "x": 193, + "y": 187.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(committee chair -> committee)[0]", + "src": "committee chair", + "srcArrow": "none", + "srcLabel": "", + "dst": "committee", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Accept appeal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 94, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 159.75, + "y": 253 + }, + { + "x": 159.75, + "y": 301.4 + }, + { + "x": 159.75, + "y": 325.7 + }, + { + "x": 159.75, + "y": 374.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "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/edge-label-overflow/dagre/sketch.exp.svg b/e2etests/testdata/stable/edge-label-overflow/dagre/sketch.exp.svg new file mode 100644 index 000000000..efcdc3cce --- /dev/null +++ b/e2etests/testdata/stable/edge-label-overflow/dagre/sketch.exp.svg @@ -0,0 +1,104 @@ +studentcommittee chaircommittee Apply for appeal Deny. Need more informationAccept appeal + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/edge-label-overflow/elk/board.exp.json b/e2etests/testdata/stable/edge-label-overflow/elk/board.exp.json new file mode 100644 index 000000000..f17ddcb63 --- /dev/null +++ b/e2etests/testdata/stable/edge-label-overflow/elk/board.exp.json @@ -0,0 +1,324 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "student", + "type": "rectangle", + "pos": { + "x": 97, + "y": 12 + }, + "width": 100, + "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": "student", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 55, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "committee chair", + "type": "rectangle", + "pos": { + "x": 66, + "y": 259 + }, + "width": 162, + "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": "committee chair", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 117, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "committee", + "type": "rectangle", + "pos": { + "x": 86, + "y": 486 + }, + "width": 122, + "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": "committee", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 77, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(student -> committee chair)[0]", + "src": "student", + "srcArrow": "none", + "srcLabel": "", + "dst": "committee chair", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Apply for appeal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 109, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 130.58333333333331, + "y": 78 + }, + { + "x": 130.58333333333331, + "y": 118 + }, + { + "x": 66.5, + "y": 118 + }, + { + "x": 66.5, + "y": 219 + }, + { + "x": 120.25, + "y": 219 + }, + { + "x": 120.25, + "y": 259 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(student <- committee chair)[0]", + "src": "student", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "committee chair", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Deny. Need more information", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 192, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 163.91666666666666, + "y": 78 + }, + { + "x": 163.91666666666666, + "y": 118 + }, + { + "x": 228, + "y": 118 + }, + { + "x": 228, + "y": 219 + }, + { + "x": 174.25, + "y": 219 + }, + { + "x": 174.25, + "y": 259 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(committee chair -> committee)[0]", + "src": "committee chair", + "srcArrow": "none", + "srcLabel": "", + "dst": "committee", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Accept appeal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 94, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 147.25, + "y": 325 + }, + { + "x": 147.25, + "y": 486 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "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/edge-label-overflow/elk/sketch.exp.svg b/e2etests/testdata/stable/edge-label-overflow/elk/sketch.exp.svg new file mode 100644 index 000000000..fd70eb8b0 --- /dev/null +++ b/e2etests/testdata/stable/edge-label-overflow/elk/sketch.exp.svg @@ -0,0 +1,104 @@ +studentcommittee chaircommittee Apply for appeal Deny. Need more informationAccept appeal + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/elk_shim/dagre/board.exp.json b/e2etests/testdata/stable/elk_shim/dagre/board.exp.json index f839bf8a2..825a9fef0 100644 --- a/e2etests/testdata/stable/elk_shim/dagre/board.exp.json +++ b/e2etests/testdata/stable/elk_shim/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 275 }, - "width": 387, + "width": 417, "height": 1215, "opacity": 1, "strokeDash": 0, @@ -51,7 +51,7 @@ "x": 95, "y": 340 }, - "width": 273, + "width": 302, "height": 307, "opacity": 1, "strokeDash": 0, @@ -89,7 +89,7 @@ "id": "network.cell tower.satellites", "type": "stored_data", "pos": { - "x": 161, + "x": 176, "y": 372 }, "width": 140, @@ -130,7 +130,7 @@ "id": "network.cell tower.transmitter", "type": "rectangle", "pos": { - "x": 161, + "x": 176, "y": 554 }, "width": 140, @@ -253,7 +253,7 @@ "id": "network.data processor", "type": "rectangle", "pos": { - "x": 142, + "x": 157, "y": 804 }, "width": 179, @@ -294,7 +294,7 @@ "id": "network.data processor.storage", "type": "cylinder", "pos": { - "x": 182, + "x": 197, "y": 836 }, "width": 99, @@ -335,7 +335,7 @@ "id": "user", "type": "person", "pos": { - "x": 75, + "x": 80, "y": 0 }, "width": 130, @@ -376,7 +376,7 @@ "id": "api server", "type": "rectangle", "pos": { - "x": 428, + "x": 457, "y": 1066 }, "width": 116, @@ -417,7 +417,7 @@ "id": "logs", "type": "page", "pos": { - "x": 449, + "x": 479, "y": 1303 }, "width": 73, @@ -483,19 +483,19 @@ "labelPercentage": 0, "route": [ { - "x": 210, + "x": 221, "y": 434 }, { - "x": 176.4, + "x": 182.6, "y": 482 }, { - "x": 176.4, + "x": 182.8, "y": 506.2 }, { - "x": 210, + "x": 222, "y": 555 } ], @@ -532,19 +532,19 @@ "labelPercentage": 0, "route": [ { - "x": 231, + "x": 246, "y": 434 }, { - "x": 231.2, + "x": 246, "y": 482 }, { - "x": 231.25, + "x": 246, "y": 506.2 }, { - "x": 231.25, + "x": 246, "y": 555 } ], @@ -581,19 +581,19 @@ "labelPercentage": 0, "route": [ { - "x": 253, + "x": 271, "y": 434 }, { - "x": 286.2, + "x": 309.4, "y": 482 }, { - "x": 286.1, + "x": 309.2, "y": 506.2 }, { - "x": 252.5, + "x": 270, "y": 555 } ], @@ -630,31 +630,31 @@ "labelPercentage": 0, "route": [ { - "x": 231.25, + "x": 246, "y": 615.5 }, { - "x": 231.25, + "x": 246, "y": 641.1 }, { - "x": 231.25, + "x": 246, "y": 659.6 }, { - "x": 231.25, + "x": 246, "y": 677.75 }, { - "x": 231.25, + "x": 246, "y": 695.9 }, { - "x": 231.2, + "x": 246, "y": 782.2 }, { - "x": 231, + "x": 246, "y": 837 } ], @@ -691,19 +691,19 @@ "labelPercentage": 0, "route": [ { - "x": 164, + "x": 171, "y": 87 }, { - "x": 217.8, + "x": 231, "y": 156.2 }, { - "x": 231.25, + "x": 246, "y": 248.2 }, { - "x": 231.25, + "x": 246, "y": 305 } ], @@ -740,11 +740,11 @@ "labelPercentage": 0, "route": [ { - "x": 123, + "x": 126, "y": 87 }, { - "x": 84.4, + "x": 85, "y": 156.2 }, { @@ -945,12 +945,12 @@ "labelPercentage": 0, "route": [ { - "x": 427.75, - "y": 1113.8881262868908 + "x": 457.25, + "y": 1112.7726984126984 }, { - "x": 182.75, - "y": 1176.777625257378 + "x": 188.64999999999998, + "y": 1176.5545396825396 }, { "x": 118.2, @@ -994,19 +994,19 @@ "labelPercentage": 0, "route": [ { - "x": 485.75, + "x": 515.25, "y": 1132 }, { - "x": 485.75, + "x": 515.25, "y": 1180.4 }, { - "x": 485.8, + "x": 515.2, "y": 1263 }, { - "x": 486, + "x": 515, "y": 1303 } ], @@ -1043,20 +1043,20 @@ "labelPercentage": 0, "route": [ { - "x": 231.25, + "x": 246, "y": 986.5 }, { - "x": 231.25, + "x": 246, "y": 1010.1 }, { - "x": 270.55, - "y": 1028.8168958742633 + "x": 288.2, + "y": 1029 }, { - "x": 427.75, - "y": 1080.0844793713163 + "x": 457, + "y": 1081 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/elk_shim/dagre/sketch.exp.svg b/e2etests/testdata/stable/elk_shim/dagre/sketch.exp.svg index 6f5a2477e..b7f521821 100644 --- a/e2etests/testdata/stable/elk_shim/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/elk_shim/dagre/sketch.exp.svg @@ -1,23 +1,23 @@ -networkuserapi serverlogscell towerONLINE PORTALLLLdata processorsatellitestransmitteruistorage sendsendsendphone logsmake call accessdisplaypersist - - - - - - - - - + .d2-49621034 .fill-N1{fill:#0A0F25;} + .d2-49621034 .fill-N2{fill:#676C7E;} + .d2-49621034 .fill-N3{fill:#9499AB;} + .d2-49621034 .fill-N4{fill:#CFD2DD;} + .d2-49621034 .fill-N5{fill:#DEE1EB;} + .d2-49621034 .fill-N6{fill:#EEF1F8;} + .d2-49621034 .fill-N7{fill:#FFFFFF;} + .d2-49621034 .fill-B1{fill:#0D32B2;} + .d2-49621034 .fill-B2{fill:#0D32B2;} + .d2-49621034 .fill-B3{fill:#E3E9FD;} + .d2-49621034 .fill-B4{fill:#E3E9FD;} + .d2-49621034 .fill-B5{fill:#EDF0FD;} + .d2-49621034 .fill-B6{fill:#F7F8FE;} + .d2-49621034 .fill-AA2{fill:#4A6FF3;} + .d2-49621034 .fill-AA4{fill:#EDF0FD;} + .d2-49621034 .fill-AA5{fill:#F7F8FE;} + .d2-49621034 .fill-AB4{fill:#EDF0FD;} + .d2-49621034 .fill-AB5{fill:#F7F8FE;} + .d2-49621034 .stroke-N1{stroke:#0A0F25;} + .d2-49621034 .stroke-N2{stroke:#676C7E;} + .d2-49621034 .stroke-N3{stroke:#9499AB;} + .d2-49621034 .stroke-N4{stroke:#CFD2DD;} + .d2-49621034 .stroke-N5{stroke:#DEE1EB;} + .d2-49621034 .stroke-N6{stroke:#EEF1F8;} + .d2-49621034 .stroke-N7{stroke:#FFFFFF;} + .d2-49621034 .stroke-B1{stroke:#0D32B2;} + .d2-49621034 .stroke-B2{stroke:#0D32B2;} + .d2-49621034 .stroke-B3{stroke:#E3E9FD;} + .d2-49621034 .stroke-B4{stroke:#E3E9FD;} + .d2-49621034 .stroke-B5{stroke:#EDF0FD;} + .d2-49621034 .stroke-B6{stroke:#F7F8FE;} + .d2-49621034 .stroke-AA2{stroke:#4A6FF3;} + .d2-49621034 .stroke-AA4{stroke:#EDF0FD;} + .d2-49621034 .stroke-AA5{stroke:#F7F8FE;} + .d2-49621034 .stroke-AB4{stroke:#EDF0FD;} + .d2-49621034 .stroke-AB5{stroke:#F7F8FE;} + .d2-49621034 .background-color-N1{background-color:#0A0F25;} + .d2-49621034 .background-color-N2{background-color:#676C7E;} + .d2-49621034 .background-color-N3{background-color:#9499AB;} + .d2-49621034 .background-color-N4{background-color:#CFD2DD;} + .d2-49621034 .background-color-N5{background-color:#DEE1EB;} + .d2-49621034 .background-color-N6{background-color:#EEF1F8;} + .d2-49621034 .background-color-N7{background-color:#FFFFFF;} + .d2-49621034 .background-color-B1{background-color:#0D32B2;} + .d2-49621034 .background-color-B2{background-color:#0D32B2;} + .d2-49621034 .background-color-B3{background-color:#E3E9FD;} + .d2-49621034 .background-color-B4{background-color:#E3E9FD;} + .d2-49621034 .background-color-B5{background-color:#EDF0FD;} + .d2-49621034 .background-color-B6{background-color:#F7F8FE;} + .d2-49621034 .background-color-AA2{background-color:#4A6FF3;} + .d2-49621034 .background-color-AA4{background-color:#EDF0FD;} + .d2-49621034 .background-color-AA5{background-color:#F7F8FE;} + .d2-49621034 .background-color-AB4{background-color:#EDF0FD;} + .d2-49621034 .background-color-AB5{background-color:#F7F8FE;} + .d2-49621034 .color-N1{color:#0A0F25;} + .d2-49621034 .color-N2{color:#676C7E;} + .d2-49621034 .color-N3{color:#9499AB;} + .d2-49621034 .color-N4{color:#CFD2DD;} + .d2-49621034 .color-N5{color:#DEE1EB;} + .d2-49621034 .color-N6{color:#EEF1F8;} + .d2-49621034 .color-N7{color:#FFFFFF;} + .d2-49621034 .color-B1{color:#0D32B2;} + .d2-49621034 .color-B2{color:#0D32B2;} + .d2-49621034 .color-B3{color:#E3E9FD;} + .d2-49621034 .color-B4{color:#E3E9FD;} + .d2-49621034 .color-B5{color:#EDF0FD;} + .d2-49621034 .color-B6{color:#F7F8FE;} + .d2-49621034 .color-AA2{color:#4A6FF3;} + .d2-49621034 .color-AA4{color:#EDF0FD;} + .d2-49621034 .color-AA5{color:#F7F8FE;} + .d2-49621034 .color-AB4{color:#EDF0FD;} + .d2-49621034 .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}]]>networkuserapi serverlogscell towerONLINE PORTALLLLdata processorsatellitestransmitteruistorage sendsendsendphone logsmake call accessdisplaypersist + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/mono-font/dagre/board.exp.json b/e2etests/testdata/stable/mono-font/dagre/board.exp.json index 81f339d09..26858d406 100644 --- a/e2etests/testdata/stable/mono-font/dagre/board.exp.json +++ b/e2etests/testdata/stable/mono-font/dagre/board.exp.json @@ -7,7 +7,7 @@ "id": "satellites", "type": "stored_data", "pos": { - "x": 0, + "x": 27, "y": 0 }, "width": 161, @@ -48,7 +48,7 @@ "id": "transmitter", "type": "rectangle", "pos": { - "x": 5, + "x": 32, "y": 187 }, "width": 151, @@ -114,19 +114,19 @@ "labelPercentage": 0, "route": [ { - "x": 60, + "x": 79, "y": 66 }, { - "x": 30, + "x": 39, "y": 114.4 }, { - "x": 30.1, + "x": 39, "y": 138.7 }, { - "x": 60.5, + "x": 79, "y": 187.5 } ], @@ -163,19 +163,19 @@ "labelPercentage": 0, "route": [ { - "x": 80, + "x": 107, "y": 66 }, { - "x": 80.4, + "x": 107, "y": 114.4 }, { - "x": 80.5, + "x": 107, "y": 138.7 }, { - "x": 80.5, + "x": 107, "y": 187.5 } ], @@ -212,19 +212,19 @@ "labelPercentage": 0, "route": [ { - "x": 101, + "x": 135, "y": 66 }, { - "x": 131, + "x": 175, "y": 114.4 }, { - "x": 130.9, + "x": 175, "y": 138.7 }, { - "x": 100.5, + "x": 135, "y": 187.5 } ], diff --git a/e2etests/testdata/stable/mono-font/dagre/sketch.exp.svg b/e2etests/testdata/stable/mono-font/dagre/sketch.exp.svg index ce9247380..3a7b425a7 100644 --- a/e2etests/testdata/stable/mono-font/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/mono-font/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -SATELLITESTRANSMITTER SENDSENDSEND - - - - + .d2-1620692864 .fill-N1{fill:#0A0F25;} + .d2-1620692864 .fill-N2{fill:#676C7E;} + .d2-1620692864 .fill-N3{fill:#9499AB;} + .d2-1620692864 .fill-N4{fill:#CFD2DD;} + .d2-1620692864 .fill-N5{fill:#DEE1EB;} + .d2-1620692864 .fill-N6{fill:#EEF1F8;} + .d2-1620692864 .fill-N7{fill:#FFFFFF;} + .d2-1620692864 .fill-B1{fill:#0D32B2;} + .d2-1620692864 .fill-B2{fill:#0D32B2;} + .d2-1620692864 .fill-B3{fill:#E3E9FD;} + .d2-1620692864 .fill-B4{fill:#E3E9FD;} + .d2-1620692864 .fill-B5{fill:#EDF0FD;} + .d2-1620692864 .fill-B6{fill:#F7F8FE;} + .d2-1620692864 .fill-AA2{fill:#4A6FF3;} + .d2-1620692864 .fill-AA4{fill:#EDF0FD;} + .d2-1620692864 .fill-AA5{fill:#F7F8FE;} + .d2-1620692864 .fill-AB4{fill:#EDF0FD;} + .d2-1620692864 .fill-AB5{fill:#F7F8FE;} + .d2-1620692864 .stroke-N1{stroke:#0A0F25;} + .d2-1620692864 .stroke-N2{stroke:#676C7E;} + .d2-1620692864 .stroke-N3{stroke:#9499AB;} + .d2-1620692864 .stroke-N4{stroke:#CFD2DD;} + .d2-1620692864 .stroke-N5{stroke:#DEE1EB;} + .d2-1620692864 .stroke-N6{stroke:#EEF1F8;} + .d2-1620692864 .stroke-N7{stroke:#FFFFFF;} + .d2-1620692864 .stroke-B1{stroke:#0D32B2;} + .d2-1620692864 .stroke-B2{stroke:#0D32B2;} + .d2-1620692864 .stroke-B3{stroke:#E3E9FD;} + .d2-1620692864 .stroke-B4{stroke:#E3E9FD;} + .d2-1620692864 .stroke-B5{stroke:#EDF0FD;} + .d2-1620692864 .stroke-B6{stroke:#F7F8FE;} + .d2-1620692864 .stroke-AA2{stroke:#4A6FF3;} + .d2-1620692864 .stroke-AA4{stroke:#EDF0FD;} + .d2-1620692864 .stroke-AA5{stroke:#F7F8FE;} + .d2-1620692864 .stroke-AB4{stroke:#EDF0FD;} + .d2-1620692864 .stroke-AB5{stroke:#F7F8FE;} + .d2-1620692864 .background-color-N1{background-color:#0A0F25;} + .d2-1620692864 .background-color-N2{background-color:#676C7E;} + .d2-1620692864 .background-color-N3{background-color:#9499AB;} + .d2-1620692864 .background-color-N4{background-color:#CFD2DD;} + .d2-1620692864 .background-color-N5{background-color:#DEE1EB;} + .d2-1620692864 .background-color-N6{background-color:#EEF1F8;} + .d2-1620692864 .background-color-N7{background-color:#FFFFFF;} + .d2-1620692864 .background-color-B1{background-color:#0D32B2;} + .d2-1620692864 .background-color-B2{background-color:#0D32B2;} + .d2-1620692864 .background-color-B3{background-color:#E3E9FD;} + .d2-1620692864 .background-color-B4{background-color:#E3E9FD;} + .d2-1620692864 .background-color-B5{background-color:#EDF0FD;} + .d2-1620692864 .background-color-B6{background-color:#F7F8FE;} + .d2-1620692864 .background-color-AA2{background-color:#4A6FF3;} + .d2-1620692864 .background-color-AA4{background-color:#EDF0FD;} + .d2-1620692864 .background-color-AA5{background-color:#F7F8FE;} + .d2-1620692864 .background-color-AB4{background-color:#EDF0FD;} + .d2-1620692864 .background-color-AB5{background-color:#F7F8FE;} + .d2-1620692864 .color-N1{color:#0A0F25;} + .d2-1620692864 .color-N2{color:#676C7E;} + .d2-1620692864 .color-N3{color:#9499AB;} + .d2-1620692864 .color-N4{color:#CFD2DD;} + .d2-1620692864 .color-N5{color:#DEE1EB;} + .d2-1620692864 .color-N6{color:#EEF1F8;} + .d2-1620692864 .color-N7{color:#FFFFFF;} + .d2-1620692864 .color-B1{color:#0D32B2;} + .d2-1620692864 .color-B2{color:#0D32B2;} + .d2-1620692864 .color-B3{color:#E3E9FD;} + .d2-1620692864 .color-B4{color:#E3E9FD;} + .d2-1620692864 .color-B5{color:#EDF0FD;} + .d2-1620692864 .color-B6{color:#F7F8FE;} + .d2-1620692864 .color-AA2{color:#4A6FF3;} + .d2-1620692864 .color-AA4{color:#EDF0FD;} + .d2-1620692864 .color-AA5{color:#F7F8FE;} + .d2-1620692864 .color-AB4{color:#EDF0FD;} + .d2-1620692864 .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}]]>SATELLITESTRANSMITTER SENDSENDSEND + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/self-referencing/dagre/board.exp.json b/e2etests/testdata/stable/self-referencing/dagre/board.exp.json index 400eed576..f0bffef02 100644 --- a/e2etests/testdata/stable/self-referencing/dagre/board.exp.json +++ b/e2etests/testdata/stable/self-referencing/dagre/board.exp.json @@ -48,7 +48,7 @@ "id": "y", "type": "rectangle", "pos": { - "x": 76, + "x": 96, "y": 166 }, "width": 54, @@ -89,7 +89,7 @@ "id": "z", "type": "rectangle", "pos": { - "x": 153, + "x": 193, "y": 0 }, "width": 52, @@ -156,55 +156,55 @@ "route": [ { "x": 53, - "y": 16.551724137931032 + "y": 18.38440111420613 }, { - "x": 74.33333333333333, - "y": 3.3103448275862064 + "x": 79.66666666666667, + "y": 3.676880222841225 }, { - "x": 81, + "x": 88, "y": 0 }, { - "x": 83, + "x": 90.5, "y": 0 }, { - "x": 85, + "x": 93, "y": 0 }, { - "x": 87.66666666666667, + "x": 96.33333333333333, "y": 6.6000000000000005 }, { - "x": 89.66666666666667, + "x": 98.83333333333333, "y": 16.5 }, { - "x": 91.66666666666667, + "x": 101.33333333333333, "y": 26.400000000000002 }, { - "x": 91.66666666666667, + "x": 101.33333333333333, "y": 39.6 }, { - "x": 89.66666666666667, + "x": 98.83333333333333, "y": 49.5 }, { - "x": 87.66666666666667, + "x": 96.33333333333333, "y": 59.400000000000006 }, { - "x": 74.33333333333333, - "y": 62.689655172413794 + "x": 79.66666666666667, + "y": 62.32311977715877 }, { "x": 53, - "y": 49.44827586206897 + "y": 47.61559888579387 } ], "isCurve": true, @@ -241,55 +241,55 @@ "route": [ { "x": 53, - "y": 19.849624060150376 - }, - { - "x": 85, - "y": 3.969924812030074 - }, - { - "x": 95, - "y": 0 - }, - { - "x": 98, - "y": 0 + "y": 22.890173410404625 }, { "x": 101, + "y": 4.578034682080926 + }, + { + "x": 116, "y": 0 }, { - "x": 105, + "x": 120.5, + "y": 0 + }, + { + "x": 125, + "y": 0 + }, + { + "x": 131, "y": 6.6000000000000005 }, { - "x": 108, + "x": 135.5, "y": 16.5 }, { - "x": 111, + "x": 140, "y": 26.400000000000002 }, { - "x": 111, + "x": 140, "y": 39.6 }, { - "x": 108, + "x": 135.5, "y": 49.5 }, { - "x": 105, + "x": 131, "y": 59.400000000000006 }, { - "x": 85, - "y": 62.03007518796993 + "x": 101, + "y": 61.421965317919074 }, { "x": 53, - "y": 46.150375939849624 + "y": 43.10982658959537 } ], "isCurve": true, @@ -333,12 +333,12 @@ "y": 106 }, { - "x": 36.35, - "y": 126.72196721311475 + "x": 40.35, + "y": 127.94337662337662 }, { - "x": 75.75, - "y": 169.60983606557377 + "x": 95.75, + "y": 175.7168831168831 } ], "isCurve": true, @@ -374,20 +374,20 @@ "labelPercentage": 0, "route": [ { - "x": 179, + "x": 219, "y": 66 }, { - "x": 179, + "x": 219, "y": 106 }, { - "x": 169.2, - "y": 126.6 + "x": 205.2, + "y": 128 }, { - "x": 130, - "y": 169 + "x": 150, + "y": 176 } ], "isCurve": true, @@ -423,56 +423,56 @@ "labelPercentage": 0, "route": [ { - "x": 205, - "y": 19.523560209424083 + "x": 245, + "y": 19.52356020942409 }, { - "x": 235.13333333333333, - "y": 3.9047120418848156 + "x": 275.1333333333333, + "y": 3.9047120418848174 }, { - "x": 244.54999999999998, + "x": 284.55, "y": 0 }, { - "x": 247.375, + "x": 287.375, "y": 0 }, { - "x": 250.20000000000002, + "x": 290.2, "y": 0 }, { - "x": 253.96666666666667, + "x": 293.96666666666664, "y": 6.6000000000000005 }, { - "x": 256.7916666666667, + "x": 296.79166666666663, "y": 16.5 }, { - "x": 259.6166666666667, + "x": 299.6166666666667, "y": 26.400000000000002 }, { - "x": 259.6166666666667, + "x": 299.6166666666667, "y": 39.6 }, { - "x": 256.7916666666667, + "x": 296.79166666666663, "y": 49.5 }, { - "x": 253.96666666666667, + "x": 293.96666666666664, "y": 59.400000000000006 }, { - "x": 235.13333333333333, - "y": 62.095287958115186 + "x": 275.1333333333333, + "y": 62.09528795811518 }, { - "x": 205, - "y": 46.47643979057592 + "x": 245, + "y": 46.47643979057591 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/self-referencing/dagre/sketch.exp.svg b/e2etests/testdata/stable/self-referencing/dagre/sketch.exp.svg index f20e33297..57476f28f 100644 --- a/e2etests/testdata/stable/self-referencing/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/self-referencing/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -xyz hello - - + .d2-4144856773 .fill-N1{fill:#0A0F25;} + .d2-4144856773 .fill-N2{fill:#676C7E;} + .d2-4144856773 .fill-N3{fill:#9499AB;} + .d2-4144856773 .fill-N4{fill:#CFD2DD;} + .d2-4144856773 .fill-N5{fill:#DEE1EB;} + .d2-4144856773 .fill-N6{fill:#EEF1F8;} + .d2-4144856773 .fill-N7{fill:#FFFFFF;} + .d2-4144856773 .fill-B1{fill:#0D32B2;} + .d2-4144856773 .fill-B2{fill:#0D32B2;} + .d2-4144856773 .fill-B3{fill:#E3E9FD;} + .d2-4144856773 .fill-B4{fill:#E3E9FD;} + .d2-4144856773 .fill-B5{fill:#EDF0FD;} + .d2-4144856773 .fill-B6{fill:#F7F8FE;} + .d2-4144856773 .fill-AA2{fill:#4A6FF3;} + .d2-4144856773 .fill-AA4{fill:#EDF0FD;} + .d2-4144856773 .fill-AA5{fill:#F7F8FE;} + .d2-4144856773 .fill-AB4{fill:#EDF0FD;} + .d2-4144856773 .fill-AB5{fill:#F7F8FE;} + .d2-4144856773 .stroke-N1{stroke:#0A0F25;} + .d2-4144856773 .stroke-N2{stroke:#676C7E;} + .d2-4144856773 .stroke-N3{stroke:#9499AB;} + .d2-4144856773 .stroke-N4{stroke:#CFD2DD;} + .d2-4144856773 .stroke-N5{stroke:#DEE1EB;} + .d2-4144856773 .stroke-N6{stroke:#EEF1F8;} + .d2-4144856773 .stroke-N7{stroke:#FFFFFF;} + .d2-4144856773 .stroke-B1{stroke:#0D32B2;} + .d2-4144856773 .stroke-B2{stroke:#0D32B2;} + .d2-4144856773 .stroke-B3{stroke:#E3E9FD;} + .d2-4144856773 .stroke-B4{stroke:#E3E9FD;} + .d2-4144856773 .stroke-B5{stroke:#EDF0FD;} + .d2-4144856773 .stroke-B6{stroke:#F7F8FE;} + .d2-4144856773 .stroke-AA2{stroke:#4A6FF3;} + .d2-4144856773 .stroke-AA4{stroke:#EDF0FD;} + .d2-4144856773 .stroke-AA5{stroke:#F7F8FE;} + .d2-4144856773 .stroke-AB4{stroke:#EDF0FD;} + .d2-4144856773 .stroke-AB5{stroke:#F7F8FE;} + .d2-4144856773 .background-color-N1{background-color:#0A0F25;} + .d2-4144856773 .background-color-N2{background-color:#676C7E;} + .d2-4144856773 .background-color-N3{background-color:#9499AB;} + .d2-4144856773 .background-color-N4{background-color:#CFD2DD;} + .d2-4144856773 .background-color-N5{background-color:#DEE1EB;} + .d2-4144856773 .background-color-N6{background-color:#EEF1F8;} + .d2-4144856773 .background-color-N7{background-color:#FFFFFF;} + .d2-4144856773 .background-color-B1{background-color:#0D32B2;} + .d2-4144856773 .background-color-B2{background-color:#0D32B2;} + .d2-4144856773 .background-color-B3{background-color:#E3E9FD;} + .d2-4144856773 .background-color-B4{background-color:#E3E9FD;} + .d2-4144856773 .background-color-B5{background-color:#EDF0FD;} + .d2-4144856773 .background-color-B6{background-color:#F7F8FE;} + .d2-4144856773 .background-color-AA2{background-color:#4A6FF3;} + .d2-4144856773 .background-color-AA4{background-color:#EDF0FD;} + .d2-4144856773 .background-color-AA5{background-color:#F7F8FE;} + .d2-4144856773 .background-color-AB4{background-color:#EDF0FD;} + .d2-4144856773 .background-color-AB5{background-color:#F7F8FE;} + .d2-4144856773 .color-N1{color:#0A0F25;} + .d2-4144856773 .color-N2{color:#676C7E;} + .d2-4144856773 .color-N3{color:#9499AB;} + .d2-4144856773 .color-N4{color:#CFD2DD;} + .d2-4144856773 .color-N5{color:#DEE1EB;} + .d2-4144856773 .color-N6{color:#EEF1F8;} + .d2-4144856773 .color-N7{color:#FFFFFF;} + .d2-4144856773 .color-B1{color:#0D32B2;} + .d2-4144856773 .color-B2{color:#0D32B2;} + .d2-4144856773 .color-B3{color:#E3E9FD;} + .d2-4144856773 .color-B4{color:#E3E9FD;} + .d2-4144856773 .color-B5{color:#EDF0FD;} + .d2-4144856773 .color-B6{color:#F7F8FE;} + .d2-4144856773 .color-AA2{color:#4A6FF3;} + .d2-4144856773 .color-AA4{color:#EDF0FD;} + .d2-4144856773 .color-AA5{color:#F7F8FE;} + .d2-4144856773 .color-AB4{color:#EDF0FD;} + .d2-4144856773 .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}]]>xyz hello + + \ No newline at end of file diff --git a/e2etests/testdata/themes/origami/dagre/board.exp.json b/e2etests/testdata/themes/origami/dagre/board.exp.json index d317916d9..a0f45ac09 100644 --- a/e2etests/testdata/themes/origami/dagre/board.exp.json +++ b/e2etests/testdata/themes/origami/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 275 }, - "width": 351, + "width": 399, "height": 1225, "opacity": 1, "strokeDash": 0, @@ -52,7 +52,7 @@ "x": 95, "y": 340 }, - "width": 237, + "width": 284, "height": 317, "opacity": 1, "strokeDash": 0, @@ -91,7 +91,7 @@ "id": "network.cell tower.satellites", "type": "stored_data", "pos": { - "x": 161, + "x": 185, "y": 372 }, "width": 104, @@ -133,7 +133,7 @@ "id": "network.cell tower.transmitter", "type": "rectangle", "pos": { - "x": 161, + "x": 185, "y": 559 }, "width": 104, @@ -259,7 +259,7 @@ "id": "network.data processor", "type": "rectangle", "pos": { - "x": 121, + "x": 145, "y": 814 }, "width": 184, @@ -301,7 +301,7 @@ "id": "network.data processor.storage", "type": "cylinder", "pos": { - "x": 161, + "x": 185, "y": 846 }, "width": 104, @@ -343,7 +343,7 @@ "id": "user", "type": "person", "pos": { - "x": 66, + "x": 80, "y": 0 }, "width": 130, @@ -385,7 +385,7 @@ "id": "api server", "type": "rectangle", "pos": { - "x": 392, + "x": 439, "y": 1076 }, "width": 153, @@ -427,7 +427,7 @@ "id": "logs", "type": "page", "pos": { - "x": 426, + "x": 474, "y": 1313 }, "width": 84, @@ -493,19 +493,19 @@ "labelPercentage": 0, "route": [ { - "x": 194, + "x": 211, "y": 439 }, { - "x": 166, + "x": 173.4, "y": 487 }, { - "x": 166, + "x": 173.4, "y": 511.2 }, { - "x": 194, + "x": 211, "y": 560 } ], @@ -541,19 +541,19 @@ "labelPercentage": 0, "route": [ { - "x": 213, + "x": 237, "y": 439 }, { - "x": 213.2, + "x": 237, "y": 487 }, { - "x": 213.25, + "x": 237, "y": 511.2 }, { - "x": 213.25, + "x": 237, "y": 560 } ], @@ -589,19 +589,19 @@ "labelPercentage": 0, "route": [ { - "x": 233, + "x": 263, "y": 439 }, { - "x": 260.6, + "x": 300.6, "y": 487 }, { - "x": 260.5, + "x": 300.6, "y": 511.2 }, { - "x": 232.5, + "x": 263, "y": 560 } ], @@ -637,31 +637,31 @@ "labelPercentage": 0, "route": [ { - "x": 213.25, + "x": 237, "y": 625.5 }, { - "x": 213.25, + "x": 237, "y": 651.1 }, { - "x": 213.25, + "x": 237, "y": 669.6 }, { - "x": 213.25, + "x": 237, "y": 687.75 }, { - "x": 213.25, + "x": 237, "y": 705.9 }, { - "x": 213.2, + "x": 237, "y": 792.2 }, { - "x": 213, + "x": 237, "y": 847 } ], @@ -697,19 +697,19 @@ "labelPercentage": 0, "route": [ { - "x": 152, + "x": 169, "y": 87 }, { - "x": 201, + "x": 223.4, "y": 156.2 }, { - "x": 213.25, + "x": 237, "y": 248.2 }, { - "x": 213.25, + "x": 237, "y": 305 } ], @@ -745,11 +745,11 @@ "labelPercentage": 0, "route": [ { - "x": 116, + "x": 126, "y": 87 }, { - "x": 83, + "x": 85, "y": 156.2 }, { @@ -949,12 +949,12 @@ "labelPercentage": 0, "route": [ { - "x": 391.75, - "y": 1129.4949856733524 + "x": 439.25, + "y": 1127.0397225725094 }, { - "x": 173.75, - "y": 1187.8989971346705 + "x": 183.25, + "y": 1187.4079445145019 }, { "x": 116, @@ -997,19 +997,19 @@ "labelPercentage": 0, "route": [ { - "x": 468.25, + "x": 515.75, "y": 1142 }, { - "x": 468.25, + "x": 515.75, "y": 1190.4 }, { - "x": 468.2, + "x": 515.8, "y": 1273 }, { - "x": 468, + "x": 516, "y": 1313 } ], @@ -1045,20 +1045,20 @@ "labelPercentage": 0, "route": [ { - "x": 213.25, + "x": 237, "y": 996.5 }, { - "x": 213.25, + "x": 237, "y": 1020.1 }, { - "x": 248.95, - "y": 1037.62 + "x": 277.4, + "y": 1038 }, { - "x": 391.75, - "y": 1084.1 + "x": 439, + "y": 1086 } ], "isCurve": true, diff --git a/e2etests/testdata/themes/origami/dagre/sketch.exp.svg b/e2etests/testdata/themes/origami/dagre/sketch.exp.svg index 56d38cf2e..a580bee19 100644 --- a/e2etests/testdata/themes/origami/dagre/sketch.exp.svg +++ b/e2etests/testdata/themes/origami/dagre/sketch.exp.svg @@ -1,23 +1,23 @@ - \ No newline at end of file diff --git a/e2etests/testdata/themes/terminal_grayscale/dagre/board.exp.json b/e2etests/testdata/themes/terminal_grayscale/dagre/board.exp.json index aaff0b214..6777766c6 100644 --- a/e2etests/testdata/themes/terminal_grayscale/dagre/board.exp.json +++ b/e2etests/testdata/themes/terminal_grayscale/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 275 }, - "width": 410, + "width": 436, "height": 1225, "opacity": 1, "strokeDash": 0, @@ -52,7 +52,7 @@ "x": 96, "y": 340 }, - "width": 294, + "width": 320, "height": 317, "opacity": 1, "strokeDash": 0, @@ -91,7 +91,7 @@ "id": "network.cell tower.satellites", "type": "stored_data", "pos": { - "x": 163, + "x": 176, "y": 372 }, "width": 161, @@ -132,7 +132,7 @@ "id": "network.cell tower.transmitter", "type": "rectangle", "pos": { - "x": 168, + "x": 181, "y": 559 }, "width": 151, @@ -176,7 +176,7 @@ "x": 20, "y": 1319 }, - "width": 157, + "width": 154, "height": 151, "opacity": 1, "strokeDash": 0, @@ -215,7 +215,7 @@ "id": "network.online portal.ui", "type": "hexagon", "pos": { - "x": 71, + "x": 69, "y": 1360 }, "width": 65, @@ -256,7 +256,7 @@ "id": "network.data processor", "type": "rectangle", "pos": { - "x": 147, + "x": 161, "y": 814 }, "width": 192, @@ -298,7 +298,7 @@ "id": "network.data processor.storage", "type": "cylinder", "pos": { - "x": 187, + "x": 201, "y": 846 }, "width": 112, @@ -339,7 +339,7 @@ "id": "user", "type": "person", "pos": { - "x": 82, + "x": 85, "y": 0 }, "width": 130, @@ -380,7 +380,7 @@ "id": "api server", "type": "rectangle", "pos": { - "x": 450, + "x": 477, "y": 1076 }, "width": 142, @@ -421,7 +421,7 @@ "id": "logs", "type": "page", "pos": { - "x": 480, + "x": 507, "y": 1313 }, "width": 82, @@ -486,19 +486,19 @@ "labelPercentage": 0, "route": [ { - "x": 218, + "x": 229, "y": 439 }, { - "x": 182.4, + "x": 188.6, "y": 487 }, { - "x": 182.5, + "x": 188.5, "y": 511.2 }, { - "x": 218.5, + "x": 228.5, "y": 560 } ], @@ -534,19 +534,19 @@ "labelPercentage": 0, "route": [ { - "x": 243, + "x": 256, "y": 439 }, { - "x": 243.2, + "x": 256.4, "y": 487 }, { - "x": 243.25, + "x": 256.5, "y": 511.2 }, { - "x": 243.25, + "x": 256.5, "y": 560 } ], @@ -582,19 +582,19 @@ "labelPercentage": 0, "route": [ { - "x": 268, + "x": 284, "y": 439 }, { - "x": 304, + "x": 324.4, "y": 487 }, { - "x": 304, + "x": 324.5, "y": 511.2 }, { - "x": 268, + "x": 284.5, "y": 560 } ], @@ -630,31 +630,31 @@ "labelPercentage": 0, "route": [ { - "x": 243.25, + "x": 256.5, "y": 625.5 }, { - "x": 243.25, + "x": 256.5, "y": 651.1 }, { - "x": 243.25, + "x": 256.5, "y": 669.6 }, { - "x": 243.25, + "x": 256.5, "y": 687.75 }, { - "x": 243.25, + "x": 256.5, "y": 705.9 }, { - "x": 243.2, + "x": 256.6, "y": 792.2 }, { - "x": 243, + "x": 257, "y": 847 } ], @@ -690,19 +690,19 @@ "labelPercentage": 0, "route": [ { - "x": 172, + "x": 178, "y": 87 }, { - "x": 229, + "x": 240.8, "y": 156.2 }, { - "x": 243.25, + "x": 256.5, "y": 248.2 }, { - "x": 243.25, + "x": 256.5, "y": 305 } ], @@ -738,11 +738,11 @@ "labelPercentage": 0, "route": [ { - "x": 128, + "x": 131, "y": 87 }, { - "x": 86.6, + "x": 87.19999999999999, "y": 156.2 }, { @@ -902,11 +902,11 @@ "y": 1183.8 }, { - "x": 79.6, + "x": 79.4, "y": 1282.6 }, { - "x": 93, + "x": 92, "y": 1361 } ], @@ -942,19 +942,19 @@ "labelPercentage": 0, "route": [ { - "x": 450.25, - "y": 1126 + "x": 476.75, + "y": 1124.9196642685852 }, { - "x": 194.64999999999998, - "y": 1187.2 + "x": 199.95, + "y": 1186.983932853717 }, { - "x": 127.4, + "x": 127, "y": 1282.6 }, { - "x": 114, + "x": 112, "y": 1361 } ], @@ -990,19 +990,19 @@ "labelPercentage": 0, "route": [ { - "x": 521.25, + "x": 547.75, "y": 1142 }, { - "x": 521.25, + "x": 547.75, "y": 1190.4 }, { - "x": 521.2, + "x": 547.8, "y": 1273 }, { - "x": 521, + "x": 548, "y": 1313 } ], @@ -1038,20 +1038,20 @@ "labelPercentage": 0, "route": [ { - "x": 243.25, + "x": 256.5, "y": 996.5 }, { - "x": 243.25, + "x": 256.5, "y": 1020.1 }, { - "x": 284.65, - "y": 1038.4 + "x": 300.55, + "y": 1038.5533047210301 }, { - "x": 450.25, - "y": 1088 + "x": 476.75, + "y": 1088.7665236051503 } ], "isCurve": true, diff --git a/e2etests/testdata/themes/terminal_grayscale/dagre/sketch.exp.svg b/e2etests/testdata/themes/terminal_grayscale/dagre/sketch.exp.svg index 234bf36dc..e76c544c7 100644 --- a/e2etests/testdata/themes/terminal_grayscale/dagre/sketch.exp.svg +++ b/e2etests/testdata/themes/terminal_grayscale/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

-

Identity Native Proxy

-
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file diff --git a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json index bb00928e2..3c2b5f426 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json @@ -92,7 +92,7 @@ "x": 660, "y": 275 }, - "width": 584, + "width": 473, "height": 303, "opacity": 1, "strokeDash": 0, @@ -112,7 +112,7 @@ "fields": null, "methods": null, "columns": null, - "label": "", + "label": "Teleport", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -120,8 +120,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 0, - "labelHeight": 0, + "labelWidth": 101, + "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 @@ -130,7 +130,7 @@ "id": "jita", "type": "rectangle", "pos": { - "x": 2026, + "x": 1915, "y": 12 }, "width": 820, @@ -171,7 +171,7 @@ "id": "infra", "type": "rectangle", "pos": { - "x": 1374, + "x": 1263, "y": 150 }, "width": 582, @@ -212,7 +212,7 @@ "id": "identity provider", "type": "rectangle", "pos": { - "x": 1374, + "x": 1263, "y": 514 }, "width": 201, @@ -573,54 +573,13 @@ "level": 2 }, { - "id": "teleport.t", + "id": "teleport.inp", "type": "text", "pos": { "x": 720, "y": 335 }, - "width": 122, - "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": "# Teleport", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 122, - "labelHeight": 51, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "teleport.inp", - "type": "text", - "pos": { - "x": 882, - "y": 335 - }, - "width": 302, + "width": 353, "height": 51, "opacity": 1, "strokeDash": 0, @@ -661,7 +620,7 @@ "x": 720, "y": 426 }, - "width": 212, + "width": 140, "height": 92, "opacity": 1, "strokeDash": 0, @@ -711,10 +670,10 @@ "id": "teleport.Cert Authority", "type": "rectangle", "pos": { - "x": 972, + "x": 900, "y": 426 }, - "width": 212, + "width": 173, "height": 92, "opacity": 1, "strokeDash": 0, @@ -764,7 +723,7 @@ "id": "jita.Slack", "type": "rectangle", "pos": { - "x": 2086, + "x": 1975, "y": 72 }, "width": 110, @@ -817,7 +776,7 @@ "id": "jita.Mattermost", "type": "rectangle", "pos": { - "x": 2236, + "x": 2125, "y": 72 }, "width": 128, @@ -858,7 +817,7 @@ "id": "jita.Jira", "type": "rectangle", "pos": { - "x": 2404, + "x": 2293, "y": 72 }, "width": 72, @@ -899,7 +858,7 @@ "id": "jita.Pagerduty", "type": "rectangle", "pos": { - "x": 2516, + "x": 2405, "y": 72 }, "width": 119, @@ -940,7 +899,7 @@ "id": "jita.Email", "type": "rectangle", "pos": { - "x": 2675, + "x": 2564, "y": 72 }, "width": 111, @@ -993,7 +952,7 @@ "id": "infra.ssh", "type": "rectangle", "pos": { - "x": 1434, + "x": 1323, "y": 210 }, "width": 108, @@ -1046,7 +1005,7 @@ "id": "infra.Kubernetes", "type": "rectangle", "pos": { - "x": 1582, + "x": 1471, "y": 210 }, "width": 152, @@ -1099,7 +1058,7 @@ "id": "infra.My SQL", "type": "rectangle", "pos": { - "x": 1774, + "x": 1663, "y": 210 }, "width": 122, @@ -1152,7 +1111,7 @@ "id": "infra.MongoDB", "type": "rectangle", "pos": { - "x": 1434, + "x": 1323, "y": 342 }, "width": 138, @@ -1205,7 +1164,7 @@ "id": "infra.PSQL", "type": "rectangle", "pos": { - "x": 1612, + "x": 1501, "y": 342 }, "width": 108, @@ -1258,7 +1217,7 @@ "id": "infra.Windows", "type": "rectangle", "pos": { - "x": 1760, + "x": 1649, "y": 342 }, "width": 136, @@ -1416,19 +1375,19 @@ "labelPercentage": 0, "route": [ { - "x": 1244, + "x": 1133, "y": 336.1333333333333 }, { - "x": 1284, + "x": 1173, "y": 336.1333333333333 }, { - "x": 1284, + "x": 1173, "y": 118 }, { - "x": 2026, + "x": 1915, "y": 118 } ], @@ -1464,11 +1423,11 @@ "labelPercentage": 0, "route": [ { - "x": 1244, + "x": 1133, "y": 396.7333333333333 }, { - "x": 1374, + "x": 1263, "y": 396.7333333333333 } ], @@ -1504,19 +1463,19 @@ "labelPercentage": 0, "route": [ { - "x": 1244, + "x": 1133, "y": 457.3333333333333 }, { - "x": 1334, + "x": 1223, "y": 457.3333333333333 }, { - "x": 1334, + "x": 1223, "y": 553.3333333333333 }, { - "x": 1374, + "x": 1263, "y": 553.3333333333333 } ], @@ -1552,19 +1511,19 @@ "labelPercentage": 0, "route": [ { - "x": 1244, + "x": 1133, "y": 517.9333333333333 }, { - "x": 1284, + "x": 1173, "y": 517.9333333333333 }, { - "x": 1284, + "x": 1173, "y": 592.6666666666666 }, { - "x": 1374, + "x": 1263, "y": 592.6666666666666 } ], diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg index 0f29b7d25..f5b39beb8 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -1,23 +1,23 @@ -Just-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Teleport

-

Identity Native Proxy

-
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged - - +TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

Identity Native Proxy

+
Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged + +
\ No newline at end of file From bce774fd4a9944954b67f77d3991b940d31bf5bf Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 17:44:05 -0700 Subject: [PATCH 18/33] validate edges --- d2compiler/compile.go | 14 +++++++++++++ d2compiler/compile_test.go | 15 ++++++++++++++ d2graph/d2graph.go | 4 ++++ d2graph/grid.go | 10 ++++++++++ .../d2compiler/TestCompile/grid_edge.exp.json | 20 +++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 testdata/d2compiler/TestCompile/grid_edge.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 66940ce56..0236a9ce2 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -73,6 +73,7 @@ func (c *compiler) compileBoard(g *d2graph.Graph, ir *d2ir.Map) *d2graph.Graph { c.validateKeys(g.Root, ir) } c.validateNear(g) + c.validateEdges(g) c.compileBoardsField(g, ir, "layers") c.compileBoardsField(g, ir, "scenarios") @@ -787,6 +788,19 @@ func (c *compiler) validateNear(g *d2graph.Graph) { } } +func (c *compiler) validateEdges(g *d2graph.Graph) { + for _, edge := range g.Edges { + if grid := edge.Src.ClosestGrid(); grid != nil { + c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid %#v", d2format.Format(edge.GetAstEdge()), grid.AbsID()) + continue + } + if grid := edge.Dst.ClosestGrid(); grid != nil { + c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid %#v", d2format.Format(edge.GetAstEdge()), grid.AbsID()) + continue + } + } +} + func (c *compiler) validateBoardLinks(g *d2graph.Graph) { for _, obj := range g.Objects { if obj.Attributes.Link == nil { diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 2d6e63a95..4afc52fbf 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2288,6 +2288,21 @@ obj { `, expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a positive integer: "-200"`, }, + { + name: "grid_edge", + text: `hey: { + rows: 1 + a -> b +} + c -> hey.b + hey.a -> c + + hey -> c: ok +`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge "a -> b" cannot enter grid "hey" +d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge "c -> hey.b" cannot enter grid "hey" +d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot enter grid "hey"`, + }, } for _, tc := range testCases { diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 42f42977a..d9ae9a89d 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1013,6 +1013,10 @@ type EdgeReference struct { ScopeObj *Object `json:"-"` } +func (e *Edge) GetAstEdge() *d2ast.Edge { + return e.References[0].Edge +} + func (e *Edge) GetStroke(dashGapSize interface{}) string { if dashGapSize != 0.0 { return color.B2 diff --git a/d2graph/grid.go b/d2graph/grid.go index 1ff029bba..0315fe60b 100644 --- a/d2graph/grid.go +++ b/d2graph/grid.go @@ -4,3 +4,13 @@ func (obj *Object) IsGrid() bool { return obj != nil && obj.Attributes != nil && (obj.Attributes.Rows != nil || obj.Attributes.Columns != nil) } + +func (obj *Object) ClosestGrid() *Object { + if obj.Parent == nil { + return nil + } + if obj.Parent.IsGrid() { + return obj.Parent + } + return obj.Parent.ClosestGrid() +} diff --git a/testdata/d2compiler/TestCompile/grid_edge.exp.json b/testdata/d2compiler/TestCompile/grid_edge.exp.json new file mode 100644 index 000000000..1d6c84181 --- /dev/null +++ b/testdata/d2compiler/TestCompile/grid_edge.exp.json @@ -0,0 +1,20 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,2:1:17-2:7:23", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge \"a -> b\" cannot enter grid \"hey\"" + }, + { + "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,4:1:27-4:11:37", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge \"c -> hey.b\" cannot enter grid \"hey\"" + }, + { + "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,5:1:39-5:11:49", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge \"hey.a -> c\" cannot enter grid \"hey\"" + } + ] + } +} From ac0845da1c35e50c639d6248f9fa65feddeb6bfa Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 19:07:49 -0700 Subject: [PATCH 19/33] center container if growing to fit label --- d2layouts/d2grid/layout.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index c16529fe0..69050c15d 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -69,7 +69,28 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g } obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = nil - obj.Box = geo.NewBox(nil, grid.width+2*CONTAINER_PADDING, grid.height+2*CONTAINER_PADDING) + + var dx, dy float64 + width := grid.width + 2*CONTAINER_PADDING + labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING + if labelWidth > width { + dx = (labelWidth - width) / 2 + width = labelWidth + } + height := grid.height + 2*CONTAINER_PADDING + labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING + if labelHeight > CONTAINER_PADDING { + // if the label doesn't fit within the padding, we need to add more + grow := labelHeight - CONTAINER_PADDING + dy = grow / 2 + height += grow + } + // we need to center children if we have to expand to fit the container label + if dx != 0 || dy != 0 { + grid.shift(dx, dy) + } + obj.Box = geo.NewBox(nil, width, height) + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) grids[obj.AbsID()] = grid From 108faceb998eaa41e3f7322a0a33a762b6deb073 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 20:02:22 -0700 Subject: [PATCH 20/33] layout evenly with rows and columns --- d2layouts/d2grid/grid.go | 6 +- d2layouts/d2grid/layout.go | 122 +++++++++++++++++++++++++++++++++---- 2 files changed, 112 insertions(+), 16 deletions(-) diff --git a/d2layouts/d2grid/grid.go b/d2layouts/d2grid/grid.go index 22cc23afd..f5d6e7b65 100644 --- a/d2layouts/d2grid/grid.go +++ b/d2layouts/d2grid/grid.go @@ -14,10 +14,8 @@ type grid struct { rowDominant bool - cellWidth float64 - cellHeight float64 - width float64 - height float64 + width float64 + height float64 } func newGrid(root *d2graph.Object) *grid { diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 69050c15d..3bdc0a4be 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -115,6 +115,116 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { grid := newGrid(obj) + + if grid.rows != 0 && grid.columns != 0 { + grid.layoutEvenly(g, obj) + } else { + grid.layoutDynamic(g, obj) + } + + // position labels and icons + for _, n := range grid.nodes { + if n.Attributes.Icon != nil { + n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } else { + n.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) + } + } + + return grid, nil +} + +func (grid *grid) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { + // layout nodes in a grid with these 2 properties: + // all nodes in the same row should have the same height + // all nodes in the same column should have the same width + + getNode := func(rowIndex, columnIndex int) *d2graph.Object { + var index int + if grid.rowDominant { + index = rowIndex*grid.columns + columnIndex + } else { + index = columnIndex*grid.rows + rowIndex + } + if index < len(grid.nodes) { + return grid.nodes[index] + } + return nil + } + + rowHeights := make([]float64, 0, grid.rows) + colWidths := make([]float64, 0, grid.columns) + for i := 0; i < grid.rows; i++ { + rowHeight := 0. + for j := 0; j < grid.columns; j++ { + n := getNode(i, j) + if n == nil { + break + } + rowHeight = math.Max(rowHeight, n.Height) + } + rowHeights = append(rowHeights, rowHeight) + } + for j := 0; j < grid.columns; j++ { + columnWidth := 0. + for i := 0; i < grid.rows; i++ { + n := getNode(i, j) + if n == nil { + break + } + columnWidth = math.Max(columnWidth, n.Width) + } + colWidths = append(colWidths, columnWidth) + } + + cursor := geo.NewPoint(0, 0) + if grid.rowDominant { + for i := 0; i < grid.rows; i++ { + for j := 0; j < grid.columns; j++ { + n := getNode(i, j) + if n == nil { + break + } + n.Width = colWidths[j] + n.Height = rowHeights[i] + n.TopLeft = cursor.Copy() + cursor.X += n.Width + HORIZONTAL_PAD + } + cursor.X = 0 + cursor.Y += rowHeights[i] + VERTICAL_PAD + } + } else { + for j := 0; j < grid.columns; j++ { + for i := 0; i < grid.rows; i++ { + n := getNode(i, j) + if n == nil { + break + } + n.Width = colWidths[j] + n.Height = rowHeights[i] + n.TopLeft = cursor.Copy() + cursor.Y += n.Height + VERTICAL_PAD + } + cursor.X += colWidths[j] + HORIZONTAL_PAD + cursor.Y = 0 + } + } + + var totalWidth, totalHeight float64 + for _, w := range colWidths { + totalWidth += w + HORIZONTAL_PAD + } + for _, h := range rowHeights { + totalHeight += h + VERTICAL_PAD + } + totalWidth -= HORIZONTAL_PAD + totalHeight -= VERTICAL_PAD + grid.width = totalWidth + grid.height = totalHeight +} + +func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // assume we have the following nodes to layout: // . ┌A──────────────┐ ┌B──┐ ┌C─────────┐ ┌D────────┐ ┌E────────────────┐ // . └───────────────┘ │ │ │ │ │ │ │ │ @@ -401,18 +511,6 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { } grid.width = maxX grid.height = maxY - - // position labels and icons - for _, n := range grid.nodes { - if n.Attributes.Icon != nil { - n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) - } else { - n.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) - } - } - - return grid, nil } // cleanup restores the graph after the core layout engine finishes From 69ceb5be1a88b92bb27d5ad3d1c66bd81d2487e4 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 18:56:40 -0700 Subject: [PATCH 21/33] add grid_tests test --- e2etests/stable_test.go | 1 + e2etests/testdata/files/grid_tests.d2 | 119 + e2etests/testdata/files/teleport_grid.d2 | 1 - .../stable/grid_tests/dagre/board.exp.json | 3328 +++++++++++++++++ .../stable/grid_tests/dagre/sketch.exp.svg | 102 + .../stable/grid_tests/elk/board.exp.json | 3328 +++++++++++++++++ .../stable/grid_tests/elk/sketch.exp.svg | 102 + 7 files changed, 6980 insertions(+), 1 deletion(-) create mode 100644 e2etests/testdata/files/grid_tests.d2 create mode 100644 e2etests/testdata/stable/grid_tests/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/grid_tests/elk/board.exp.json create mode 100644 e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 4499dafca..325a79759 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2467,6 +2467,7 @@ scenarios: { loadFromFile(t, "arrowhead_scaling"), loadFromFile(t, "teleport_grid"), loadFromFile(t, "dagger_grid"), + loadFromFile(t, "grid_tests"), } runa(t, tcs) diff --git a/e2etests/testdata/files/grid_tests.d2 b/e2etests/testdata/files/grid_tests.d2 new file mode 100644 index 000000000..d4b02f841 --- /dev/null +++ b/e2etests/testdata/files/grid_tests.d2 @@ -0,0 +1,119 @@ +rows 1: { + rows: 1 + a + b + c + d + e + f + g +} + +columns 1: { + columns: 1 + a + b + c + d + e + f + g +} + +rows 2: { + rows: 2 + a + b + c + d + e + f + g +} + +columns 2: { + columns: 2 + a + b + c + d + e + f + g +} + +rows 2 columns 2: { + rows: 2 + columns: 2 + + a + b + c + d + e + f + g +} + +columns 2 rows 2: { + columns: 2 + rows: 2 + + a + b + c + d + e + f + g +} + +rows 3 columns 3: { + rows: 3 + columns: 3 + + a + b + c + d + e + f + g +} + +columns 3 rows 3: { + columns: 3 + rows: 3 + + a + b + c + d + e + f + g +} + +rows 3: { + rows: 3 + + a + b + c + d + e + f + g +} + +columns 3: { + columns: 3 + + a + b + c + d + e + f + g +} diff --git a/e2etests/testdata/files/teleport_grid.d2 b/e2etests/testdata/files/teleport_grid.d2 index 3a269c43b..baec9fe60 100644 --- a/e2etests/testdata/files/teleport_grid.d2 +++ b/e2etests/testdata/files/teleport_grid.d2 @@ -33,7 +33,6 @@ via: "" { teleport: Teleport { rows: 2 - columns: 2 inp: |md # Identity Native Proxy diff --git a/e2etests/testdata/stable/grid_tests/dagre/board.exp.json b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json new file mode 100644 index 000000000..431f1dd28 --- /dev/null +++ b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json @@ -0,0 +1,3328 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "rows 1", + "type": "rectangle", + "pos": { + "x": 0, + "y": 318 + }, + "width": 731, + "height": 186, + "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": "rows 1", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 1.a", + "type": "rectangle", + "pos": { + "x": 60, + "y": 378 + }, + "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": "rows 1.b", + "type": "rectangle", + "pos": { + "x": 153, + "y": 378 + }, + "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": "rows 1.c", + "type": "rectangle", + "pos": { + "x": 246, + "y": 378 + }, + "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": "rows 1.d", + "type": "rectangle", + "pos": { + "x": 339, + "y": 378 + }, + "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": "rows 1.e", + "type": "rectangle", + "pos": { + "x": 433, + "y": 378 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 1.f", + "type": "rectangle", + "pos": { + "x": 526, + "y": 378 + }, + "width": 51, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 1.g", + "type": "rectangle", + "pos": { + "x": 617, + "y": 378 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 1", + "type": "rectangle", + "pos": { + "x": 791, + "y": 0 + }, + "width": 174, + "height": 822, + "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": "columns 1", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 119, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 1.a", + "type": "rectangle", + "pos": { + "x": 851, + "y": 60 + }, + "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": "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": "columns 1.b", + "type": "rectangle", + "pos": { + "x": 851, + "y": 166 + }, + "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": "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": "columns 1.c", + "type": "rectangle", + "pos": { + "x": 851, + "y": 272 + }, + "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": "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": "columns 1.d", + "type": "rectangle", + "pos": { + "x": 851, + "y": 378 + }, + "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": "columns 1.e", + "type": "rectangle", + "pos": { + "x": 851, + "y": 484 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 1.f", + "type": "rectangle", + "pos": { + "x": 851, + "y": 590 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 1.g", + "type": "rectangle", + "pos": { + "x": 851, + "y": 696 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2", + "type": "rectangle", + "pos": { + "x": 1025, + "y": 265 + }, + "width": 452, + "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": "rows 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 2.a", + "type": "rectangle", + "pos": { + "x": 1085, + "y": 325 + }, + "width": 84, + "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": "rows 2.b", + "type": "rectangle", + "pos": { + "x": 1209, + "y": 325 + }, + "width": 84, + "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": "rows 2.c", + "type": "rectangle", + "pos": { + "x": 1333, + "y": 325 + }, + "width": 84, + "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": "rows 2.d", + "type": "rectangle", + "pos": { + "x": 1085, + "y": 431 + }, + "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": "rows 2.e", + "type": "rectangle", + "pos": { + "x": 1179, + "y": 431 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2.f", + "type": "rectangle", + "pos": { + "x": 1272, + "y": 431 + }, + "width": 51, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2.g", + "type": "rectangle", + "pos": { + "x": 1363, + "y": 431 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2", + "type": "rectangle", + "pos": { + "x": 1537, + "y": 159 + }, + "width": 268, + "height": 504, + "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": "columns 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 119, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 2.a", + "type": "rectangle", + "pos": { + "x": 1597, + "y": 219 + }, + "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": "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": "columns 2.b", + "type": "rectangle", + "pos": { + "x": 1597, + "y": 325 + }, + "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": "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": "columns 2.c", + "type": "rectangle", + "pos": { + "x": 1597, + "y": 431 + }, + "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": "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": "columns 2.d", + "type": "rectangle", + "pos": { + "x": 1597, + "y": 537 + }, + "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": "columns 2.e", + "type": "rectangle", + "pos": { + "x": 1691, + "y": 219 + }, + "width": 54, + "height": 101, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2.f", + "type": "rectangle", + "pos": { + "x": 1691, + "y": 360 + }, + "width": 54, + "height": 101, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2.g", + "type": "rectangle", + "pos": { + "x": 1691, + "y": 501 + }, + "width": 54, + "height": 101, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2 columns 2", + "type": "rectangle", + "pos": { + "x": 1865, + "y": 159 + }, + "width": 268, + "height": 504, + "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": "rows 2 columns 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 200, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 2 columns 2.a", + "type": "rectangle", + "pos": { + "x": 1925, + "y": 219 + }, + "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": "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": "rows 2 columns 2.b", + "type": "rectangle", + "pos": { + "x": 2019, + "y": 219 + }, + "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": "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": "rows 2 columns 2.c", + "type": "rectangle", + "pos": { + "x": 1925, + "y": 325 + }, + "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": "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": "rows 2 columns 2.d", + "type": "rectangle", + "pos": { + "x": 2019, + "y": 325 + }, + "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": "rows 2 columns 2.e", + "type": "rectangle", + "pos": { + "x": 1925, + "y": 431 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2 columns 2.f", + "type": "rectangle", + "pos": { + "x": 2019, + "y": 431 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2 columns 2.g", + "type": "rectangle", + "pos": { + "x": 1925, + "y": 537 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2 rows 2", + "type": "rectangle", + "pos": { + "x": 2193, + "y": 265 + }, + "width": 454, + "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": "columns 2 rows 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 201, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 2 rows 2.a", + "type": "rectangle", + "pos": { + "x": 2253, + "y": 325 + }, + "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": "columns 2 rows 2.b", + "type": "rectangle", + "pos": { + "x": 2253, + "y": 431 + }, + "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": "columns 2 rows 2.c", + "type": "rectangle", + "pos": { + "x": 2346, + "y": 325 + }, + "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": "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": "columns 2 rows 2.d", + "type": "rectangle", + "pos": { + "x": 2346, + "y": 431 + }, + "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": "columns 2 rows 2.e", + "type": "rectangle", + "pos": { + "x": 2440, + "y": 325 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2 rows 2.f", + "type": "rectangle", + "pos": { + "x": 2440, + "y": 431 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2 rows 2.g", + "type": "rectangle", + "pos": { + "x": 2533, + "y": 325 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3 columns 3", + "type": "rectangle", + "pos": { + "x": 2707, + "y": 212 + }, + "width": 360, + "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": "rows 3 columns 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 200, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 3 columns 3.a", + "type": "rectangle", + "pos": { + "x": 2767, + "y": 272 + }, + "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": "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": "rows 3 columns 3.b", + "type": "rectangle", + "pos": { + "x": 2861, + "y": 272 + }, + "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": "rows 3 columns 3.c", + "type": "rectangle", + "pos": { + "x": 2954, + "y": 272 + }, + "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": "rows 3 columns 3.d", + "type": "rectangle", + "pos": { + "x": 2767, + "y": 378 + }, + "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": "rows 3 columns 3.e", + "type": "rectangle", + "pos": { + "x": 2861, + "y": 378 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3 columns 3.f", + "type": "rectangle", + "pos": { + "x": 2954, + "y": 378 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3 columns 3.g", + "type": "rectangle", + "pos": { + "x": 2767, + "y": 484 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3 rows 3", + "type": "rectangle", + "pos": { + "x": 3127, + "y": 212 + }, + "width": 361, + "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": "columns 3 rows 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 201, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 3 rows 3.a", + "type": "rectangle", + "pos": { + "x": 3187, + "y": 272 + }, + "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": "columns 3 rows 3.b", + "type": "rectangle", + "pos": { + "x": 3187, + "y": 378 + }, + "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": "columns 3 rows 3.c", + "type": "rectangle", + "pos": { + "x": 3187, + "y": 484 + }, + "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": "columns 3 rows 3.d", + "type": "rectangle", + "pos": { + "x": 3280, + "y": 272 + }, + "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": "columns 3 rows 3.e", + "type": "rectangle", + "pos": { + "x": 3280, + "y": 378 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3 rows 3.f", + "type": "rectangle", + "pos": { + "x": 3280, + "y": 484 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3 rows 3.g", + "type": "rectangle", + "pos": { + "x": 3374, + "y": 272 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3", + "type": "rectangle", + "pos": { + "x": 3548, + "y": 159 + }, + "width": 267, + "height": 504, + "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": "rows 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 3.a", + "type": "rectangle", + "pos": { + "x": 3608, + "y": 219 + }, + "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": "rows 3.b", + "type": "rectangle", + "pos": { + "x": 3701, + "y": 219 + }, + "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": "rows 3.c", + "type": "rectangle", + "pos": { + "x": 3608, + "y": 325 + }, + "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": "rows 3.d", + "type": "rectangle", + "pos": { + "x": 3701, + "y": 325 + }, + "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": "rows 3.e", + "type": "rectangle", + "pos": { + "x": 3608, + "y": 431 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3.f", + "type": "rectangle", + "pos": { + "x": 3701, + "y": 431 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3.g", + "type": "rectangle", + "pos": { + "x": 3608, + "y": 537 + }, + "width": 147, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3", + "type": "rectangle", + "pos": { + "x": 3875, + "y": 265 + }, + "width": 454, + "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": "columns 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 119, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 3.a", + "type": "rectangle", + "pos": { + "x": 3935, + "y": 325 + }, + "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": "columns 3.b", + "type": "rectangle", + "pos": { + "x": 3935, + "y": 431 + }, + "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": "columns 3.c", + "type": "rectangle", + "pos": { + "x": 4028, + "y": 325 + }, + "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": "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": "columns 3.d", + "type": "rectangle", + "pos": { + "x": 4028, + "y": 431 + }, + "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": "columns 3.e", + "type": "rectangle", + "pos": { + "x": 4122, + "y": 325 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3.f", + "type": "rectangle", + "pos": { + "x": 4122, + "y": 431 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3.g", + "type": "rectangle", + "pos": { + "x": 4215, + "y": 325 + }, + "width": 54, + "height": 172, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [], + "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/grid_tests/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg new file mode 100644 index 000000000..9e87e99d6 --- /dev/null +++ b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg @@ -0,0 +1,102 @@ +rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/grid_tests/elk/board.exp.json b/e2etests/testdata/stable/grid_tests/elk/board.exp.json new file mode 100644 index 000000000..e1fd68bee --- /dev/null +++ b/e2etests/testdata/stable/grid_tests/elk/board.exp.json @@ -0,0 +1,3328 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "rows 1", + "type": "rectangle", + "pos": { + "x": 12, + "y": 330 + }, + "width": 731, + "height": 186, + "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": "rows 1", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 1.a", + "type": "rectangle", + "pos": { + "x": 72, + "y": 390 + }, + "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": "rows 1.b", + "type": "rectangle", + "pos": { + "x": 165, + "y": 390 + }, + "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": "rows 1.c", + "type": "rectangle", + "pos": { + "x": 258, + "y": 390 + }, + "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": "rows 1.d", + "type": "rectangle", + "pos": { + "x": 351, + "y": 390 + }, + "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": "rows 1.e", + "type": "rectangle", + "pos": { + "x": 445, + "y": 390 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 1.f", + "type": "rectangle", + "pos": { + "x": 538, + "y": 390 + }, + "width": 51, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 1.g", + "type": "rectangle", + "pos": { + "x": 629, + "y": 390 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 1", + "type": "rectangle", + "pos": { + "x": 763, + "y": 12 + }, + "width": 174, + "height": 822, + "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": "columns 1", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 119, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 1.a", + "type": "rectangle", + "pos": { + "x": 823, + "y": 72 + }, + "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": "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": "columns 1.b", + "type": "rectangle", + "pos": { + "x": 823, + "y": 178 + }, + "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": "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": "columns 1.c", + "type": "rectangle", + "pos": { + "x": 823, + "y": 284 + }, + "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": "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": "columns 1.d", + "type": "rectangle", + "pos": { + "x": 823, + "y": 390 + }, + "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": "columns 1.e", + "type": "rectangle", + "pos": { + "x": 823, + "y": 496 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 1.f", + "type": "rectangle", + "pos": { + "x": 823, + "y": 602 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 1.g", + "type": "rectangle", + "pos": { + "x": 823, + "y": 708 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2", + "type": "rectangle", + "pos": { + "x": 957, + "y": 277 + }, + "width": 452, + "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": "rows 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 2.a", + "type": "rectangle", + "pos": { + "x": 1017, + "y": 337 + }, + "width": 84, + "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": "rows 2.b", + "type": "rectangle", + "pos": { + "x": 1141, + "y": 337 + }, + "width": 84, + "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": "rows 2.c", + "type": "rectangle", + "pos": { + "x": 1265, + "y": 337 + }, + "width": 84, + "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": "rows 2.d", + "type": "rectangle", + "pos": { + "x": 1017, + "y": 443 + }, + "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": "rows 2.e", + "type": "rectangle", + "pos": { + "x": 1111, + "y": 443 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2.f", + "type": "rectangle", + "pos": { + "x": 1204, + "y": 443 + }, + "width": 51, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2.g", + "type": "rectangle", + "pos": { + "x": 1295, + "y": 443 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2", + "type": "rectangle", + "pos": { + "x": 1429, + "y": 171 + }, + "width": 268, + "height": 504, + "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": "columns 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 119, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 2.a", + "type": "rectangle", + "pos": { + "x": 1489, + "y": 231 + }, + "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": "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": "columns 2.b", + "type": "rectangle", + "pos": { + "x": 1489, + "y": 337 + }, + "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": "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": "columns 2.c", + "type": "rectangle", + "pos": { + "x": 1489, + "y": 443 + }, + "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": "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": "columns 2.d", + "type": "rectangle", + "pos": { + "x": 1489, + "y": 549 + }, + "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": "columns 2.e", + "type": "rectangle", + "pos": { + "x": 1583, + "y": 231 + }, + "width": 54, + "height": 101, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2.f", + "type": "rectangle", + "pos": { + "x": 1583, + "y": 372 + }, + "width": 54, + "height": 101, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2.g", + "type": "rectangle", + "pos": { + "x": 1583, + "y": 513 + }, + "width": 54, + "height": 101, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2 columns 2", + "type": "rectangle", + "pos": { + "x": 1717, + "y": 171 + }, + "width": 268, + "height": 504, + "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": "rows 2 columns 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 200, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 2 columns 2.a", + "type": "rectangle", + "pos": { + "x": 1777, + "y": 231 + }, + "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": "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": "rows 2 columns 2.b", + "type": "rectangle", + "pos": { + "x": 1871, + "y": 231 + }, + "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": "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": "rows 2 columns 2.c", + "type": "rectangle", + "pos": { + "x": 1777, + "y": 337 + }, + "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": "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": "rows 2 columns 2.d", + "type": "rectangle", + "pos": { + "x": 1871, + "y": 337 + }, + "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": "rows 2 columns 2.e", + "type": "rectangle", + "pos": { + "x": 1777, + "y": 443 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2 columns 2.f", + "type": "rectangle", + "pos": { + "x": 1871, + "y": 443 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 2 columns 2.g", + "type": "rectangle", + "pos": { + "x": 1777, + "y": 549 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2 rows 2", + "type": "rectangle", + "pos": { + "x": 2005, + "y": 277 + }, + "width": 454, + "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": "columns 2 rows 2", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 201, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 2 rows 2.a", + "type": "rectangle", + "pos": { + "x": 2065, + "y": 337 + }, + "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": "columns 2 rows 2.b", + "type": "rectangle", + "pos": { + "x": 2065, + "y": 443 + }, + "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": "columns 2 rows 2.c", + "type": "rectangle", + "pos": { + "x": 2158, + "y": 337 + }, + "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": "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": "columns 2 rows 2.d", + "type": "rectangle", + "pos": { + "x": 2158, + "y": 443 + }, + "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": "columns 2 rows 2.e", + "type": "rectangle", + "pos": { + "x": 2252, + "y": 337 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2 rows 2.f", + "type": "rectangle", + "pos": { + "x": 2252, + "y": 443 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 2 rows 2.g", + "type": "rectangle", + "pos": { + "x": 2345, + "y": 337 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3 columns 3", + "type": "rectangle", + "pos": { + "x": 2479, + "y": 224 + }, + "width": 360, + "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": "rows 3 columns 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 200, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 3 columns 3.a", + "type": "rectangle", + "pos": { + "x": 2539, + "y": 284 + }, + "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": "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": "rows 3 columns 3.b", + "type": "rectangle", + "pos": { + "x": 2633, + "y": 284 + }, + "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": "rows 3 columns 3.c", + "type": "rectangle", + "pos": { + "x": 2726, + "y": 284 + }, + "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": "rows 3 columns 3.d", + "type": "rectangle", + "pos": { + "x": 2539, + "y": 390 + }, + "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": "rows 3 columns 3.e", + "type": "rectangle", + "pos": { + "x": 2633, + "y": 390 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3 columns 3.f", + "type": "rectangle", + "pos": { + "x": 2726, + "y": 390 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3 columns 3.g", + "type": "rectangle", + "pos": { + "x": 2539, + "y": 496 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3 rows 3", + "type": "rectangle", + "pos": { + "x": 2859, + "y": 224 + }, + "width": 361, + "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": "columns 3 rows 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 201, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 3 rows 3.a", + "type": "rectangle", + "pos": { + "x": 2919, + "y": 284 + }, + "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": "columns 3 rows 3.b", + "type": "rectangle", + "pos": { + "x": 2919, + "y": 390 + }, + "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": "columns 3 rows 3.c", + "type": "rectangle", + "pos": { + "x": 2919, + "y": 496 + }, + "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": "columns 3 rows 3.d", + "type": "rectangle", + "pos": { + "x": 3012, + "y": 284 + }, + "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": "columns 3 rows 3.e", + "type": "rectangle", + "pos": { + "x": 3012, + "y": 390 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3 rows 3.f", + "type": "rectangle", + "pos": { + "x": 3012, + "y": 496 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3 rows 3.g", + "type": "rectangle", + "pos": { + "x": 3106, + "y": 284 + }, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3", + "type": "rectangle", + "pos": { + "x": 3240, + "y": 171 + }, + "width": 267, + "height": 504, + "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": "rows 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "rows 3.a", + "type": "rectangle", + "pos": { + "x": 3300, + "y": 231 + }, + "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": "rows 3.b", + "type": "rectangle", + "pos": { + "x": 3393, + "y": 231 + }, + "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": "rows 3.c", + "type": "rectangle", + "pos": { + "x": 3300, + "y": 337 + }, + "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": "rows 3.d", + "type": "rectangle", + "pos": { + "x": 3393, + "y": 337 + }, + "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": "rows 3.e", + "type": "rectangle", + "pos": { + "x": 3300, + "y": 443 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3.f", + "type": "rectangle", + "pos": { + "x": 3393, + "y": 443 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "rows 3.g", + "type": "rectangle", + "pos": { + "x": 3300, + "y": 549 + }, + "width": 147, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3", + "type": "rectangle", + "pos": { + "x": 3527, + "y": 277 + }, + "width": 454, + "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": "columns 3", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 119, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "columns 3.a", + "type": "rectangle", + "pos": { + "x": 3587, + "y": 337 + }, + "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": "columns 3.b", + "type": "rectangle", + "pos": { + "x": 3587, + "y": 443 + }, + "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": "columns 3.c", + "type": "rectangle", + "pos": { + "x": 3680, + "y": 337 + }, + "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": "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": "columns 3.d", + "type": "rectangle", + "pos": { + "x": 3680, + "y": 443 + }, + "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": "columns 3.e", + "type": "rectangle", + "pos": { + "x": 3774, + "y": 337 + }, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3.f", + "type": "rectangle", + "pos": { + "x": 3774, + "y": 443 + }, + "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": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "columns 3.g", + "type": "rectangle", + "pos": { + "x": 3867, + "y": 337 + }, + "width": 54, + "height": 172, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [], + "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/grid_tests/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg new file mode 100644 index 000000000..0004db37f --- /dev/null +++ b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg @@ -0,0 +1,102 @@ +rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg + + + \ No newline at end of file From 18e72880e0c699d33c2f773602fd6fe575d0e2a2 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 20:19:42 -0700 Subject: [PATCH 22/33] add executive_grid test --- e2etests/stable_test.go | 1 + e2etests/testdata/files/executive_grid.d2 | 15 + .../executive_grid/dagre/board.exp.json | 458 ++++++++++++++++++ .../executive_grid/dagre/sketch.exp.svg | 95 ++++ .../stable/executive_grid/elk/board.exp.json | 458 ++++++++++++++++++ .../stable/executive_grid/elk/sketch.exp.svg | 95 ++++ 6 files changed, 1122 insertions(+) create mode 100644 e2etests/testdata/files/executive_grid.d2 create mode 100644 e2etests/testdata/stable/executive_grid/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/executive_grid/elk/board.exp.json create mode 100644 e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 325a79759..99aff1872 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2468,6 +2468,7 @@ scenarios: { loadFromFile(t, "teleport_grid"), loadFromFile(t, "dagger_grid"), loadFromFile(t, "grid_tests"), + loadFromFile(t, "executive_grid"), } runa(t, tcs) diff --git a/e2etests/testdata/files/executive_grid.d2 b/e2etests/testdata/files/executive_grid.d2 new file mode 100644 index 000000000..580d00622 --- /dev/null +++ b/e2etests/testdata/files/executive_grid.d2 @@ -0,0 +1,15 @@ +rows: 3 + +Executive Services.width: 1000 + +I/O\nManager.width: 100 +Security\nReference\nMonitor.width: 100 +IPC\nManager.width: 100 +Virtual\nMemory\nManager\n(VMM).width: 100 +Process\nManager.width: 100 +PnP\nManager.width: 100 +Power\nManager.width: 100 +# TODO recursive grids +Window\nManager\n\nGDI.width: 100 + +Object Manager.width: 1000 diff --git a/e2etests/testdata/stable/executive_grid/dagre/board.exp.json b/e2etests/testdata/stable/executive_grid/dagre/board.exp.json new file mode 100644 index 000000000..b9f09e5b5 --- /dev/null +++ b/e2etests/testdata/stable/executive_grid/dagre/board.exp.json @@ -0,0 +1,458 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "Executive Services", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 1080, + "height": 61, + "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": "Executive Services", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 131, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"I/O\\nManager\"", + "type": "rectangle", + "pos": { + "x": 0, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "I/O\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Security\\nReference\\nMonitor\"", + "type": "rectangle", + "pos": { + "x": 140, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Security\nReference\nMonitor", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 72, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"IPC\\nManager\"", + "type": "rectangle", + "pos": { + "x": 280, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "IPC\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Virtual\\nMemory\\nManager\\n(VMM)\"", + "type": "rectangle", + "pos": { + "x": 420, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Virtual\nMemory\nManager\n(VMM)", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 64, + "labelHeight": 69, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Process\\nManager\"", + "type": "rectangle", + "pos": { + "x": 560, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Process\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"PnP\\nManager\"", + "type": "rectangle", + "pos": { + "x": 700, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "PnP\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Power\\nManager\"", + "type": "rectangle", + "pos": { + "x": 840, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Power\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Window\\nManager\\n\\nGDI\"", + "type": "rectangle", + "pos": { + "x": 980, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Window\nManager\n\nGDI", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 63, + "labelHeight": 69, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Object Manager", + "type": "rectangle", + "pos": { + "x": 0, + "y": 250 + }, + "width": 1080, + "height": 61, + "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": "Object Manager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 112, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "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/executive_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg new file mode 100644 index 000000000..7ac1c0a8a --- /dev/null +++ b/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg @@ -0,0 +1,95 @@ +Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/executive_grid/elk/board.exp.json b/e2etests/testdata/stable/executive_grid/elk/board.exp.json new file mode 100644 index 000000000..b9f09e5b5 --- /dev/null +++ b/e2etests/testdata/stable/executive_grid/elk/board.exp.json @@ -0,0 +1,458 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "Executive Services", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 1080, + "height": 61, + "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": "Executive Services", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 131, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"I/O\\nManager\"", + "type": "rectangle", + "pos": { + "x": 0, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "I/O\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Security\\nReference\\nMonitor\"", + "type": "rectangle", + "pos": { + "x": 140, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Security\nReference\nMonitor", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 72, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"IPC\\nManager\"", + "type": "rectangle", + "pos": { + "x": 280, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "IPC\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Virtual\\nMemory\\nManager\\n(VMM)\"", + "type": "rectangle", + "pos": { + "x": 420, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Virtual\nMemory\nManager\n(VMM)", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 64, + "labelHeight": 69, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Process\\nManager\"", + "type": "rectangle", + "pos": { + "x": 560, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Process\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"PnP\\nManager\"", + "type": "rectangle", + "pos": { + "x": 700, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "PnP\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Power\\nManager\"", + "type": "rectangle", + "pos": { + "x": 840, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Power\nManager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 62, + "labelHeight": 37, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"Window\\nManager\\n\\nGDI\"", + "type": "rectangle", + "pos": { + "x": 980, + "y": 101 + }, + "width": 100, + "height": 109, + "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": "Window\nManager\n\nGDI", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 63, + "labelHeight": 69, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Object Manager", + "type": "rectangle", + "pos": { + "x": 0, + "y": 250 + }, + "width": 1080, + "height": 61, + "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": "Object Manager", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 112, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "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/executive_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg new file mode 100644 index 000000000..7ac1c0a8a --- /dev/null +++ b/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg @@ -0,0 +1,95 @@ +Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager + + + \ No newline at end of file From 0dc6a808e3fb876d7a288e13af331f202033020b Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 20:23:18 -0700 Subject: [PATCH 23/33] update test --- e2etests/testdata/files/executive_grid.d2 | 1 + .../executive_grid/dagre/board.exp.json | 18 +- .../executive_grid/dagre/sketch.exp.svg | 154 +++++++++--------- .../stable/executive_grid/elk/board.exp.json | 18 +- .../stable/executive_grid/elk/sketch.exp.svg | 154 +++++++++--------- 5 files changed, 173 insertions(+), 172 deletions(-) diff --git a/e2etests/testdata/files/executive_grid.d2 b/e2etests/testdata/files/executive_grid.d2 index 580d00622..4a3a5c3ab 100644 --- a/e2etests/testdata/files/executive_grid.d2 +++ b/e2etests/testdata/files/executive_grid.d2 @@ -3,6 +3,7 @@ rows: 3 Executive Services.width: 1000 I/O\nManager.width: 100 +I/O\nManager.height: 200 Security\nReference\nMonitor.width: 100 IPC\nManager.width: 100 Virtual\nMemory\nManager\n(VMM).width: 100 diff --git a/e2etests/testdata/stable/executive_grid/dagre/board.exp.json b/e2etests/testdata/stable/executive_grid/dagre/board.exp.json index b9f09e5b5..6ec7a989f 100644 --- a/e2etests/testdata/stable/executive_grid/dagre/board.exp.json +++ b/e2etests/testdata/stable/executive_grid/dagre/board.exp.json @@ -52,7 +52,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -93,7 +93,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -134,7 +134,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -175,7 +175,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -216,7 +216,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -257,7 +257,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -298,7 +298,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -339,7 +339,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -377,7 +377,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 250 + "y": 341 }, "width": 1080, "height": 61, diff --git a/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg index 7ac1c0a8a..8b27b5168 100644 --- a/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager - + .d2-2060964008 .fill-N1{fill:#0A0F25;} + .d2-2060964008 .fill-N2{fill:#676C7E;} + .d2-2060964008 .fill-N3{fill:#9499AB;} + .d2-2060964008 .fill-N4{fill:#CFD2DD;} + .d2-2060964008 .fill-N5{fill:#DEE1EB;} + .d2-2060964008 .fill-N6{fill:#EEF1F8;} + .d2-2060964008 .fill-N7{fill:#FFFFFF;} + .d2-2060964008 .fill-B1{fill:#0D32B2;} + .d2-2060964008 .fill-B2{fill:#0D32B2;} + .d2-2060964008 .fill-B3{fill:#E3E9FD;} + .d2-2060964008 .fill-B4{fill:#E3E9FD;} + .d2-2060964008 .fill-B5{fill:#EDF0FD;} + .d2-2060964008 .fill-B6{fill:#F7F8FE;} + .d2-2060964008 .fill-AA2{fill:#4A6FF3;} + .d2-2060964008 .fill-AA4{fill:#EDF0FD;} + .d2-2060964008 .fill-AA5{fill:#F7F8FE;} + .d2-2060964008 .fill-AB4{fill:#EDF0FD;} + .d2-2060964008 .fill-AB5{fill:#F7F8FE;} + .d2-2060964008 .stroke-N1{stroke:#0A0F25;} + .d2-2060964008 .stroke-N2{stroke:#676C7E;} + .d2-2060964008 .stroke-N3{stroke:#9499AB;} + .d2-2060964008 .stroke-N4{stroke:#CFD2DD;} + .d2-2060964008 .stroke-N5{stroke:#DEE1EB;} + .d2-2060964008 .stroke-N6{stroke:#EEF1F8;} + .d2-2060964008 .stroke-N7{stroke:#FFFFFF;} + .d2-2060964008 .stroke-B1{stroke:#0D32B2;} + .d2-2060964008 .stroke-B2{stroke:#0D32B2;} + .d2-2060964008 .stroke-B3{stroke:#E3E9FD;} + .d2-2060964008 .stroke-B4{stroke:#E3E9FD;} + .d2-2060964008 .stroke-B5{stroke:#EDF0FD;} + .d2-2060964008 .stroke-B6{stroke:#F7F8FE;} + .d2-2060964008 .stroke-AA2{stroke:#4A6FF3;} + .d2-2060964008 .stroke-AA4{stroke:#EDF0FD;} + .d2-2060964008 .stroke-AA5{stroke:#F7F8FE;} + .d2-2060964008 .stroke-AB4{stroke:#EDF0FD;} + .d2-2060964008 .stroke-AB5{stroke:#F7F8FE;} + .d2-2060964008 .background-color-N1{background-color:#0A0F25;} + .d2-2060964008 .background-color-N2{background-color:#676C7E;} + .d2-2060964008 .background-color-N3{background-color:#9499AB;} + .d2-2060964008 .background-color-N4{background-color:#CFD2DD;} + .d2-2060964008 .background-color-N5{background-color:#DEE1EB;} + .d2-2060964008 .background-color-N6{background-color:#EEF1F8;} + .d2-2060964008 .background-color-N7{background-color:#FFFFFF;} + .d2-2060964008 .background-color-B1{background-color:#0D32B2;} + .d2-2060964008 .background-color-B2{background-color:#0D32B2;} + .d2-2060964008 .background-color-B3{background-color:#E3E9FD;} + .d2-2060964008 .background-color-B4{background-color:#E3E9FD;} + .d2-2060964008 .background-color-B5{background-color:#EDF0FD;} + .d2-2060964008 .background-color-B6{background-color:#F7F8FE;} + .d2-2060964008 .background-color-AA2{background-color:#4A6FF3;} + .d2-2060964008 .background-color-AA4{background-color:#EDF0FD;} + .d2-2060964008 .background-color-AA5{background-color:#F7F8FE;} + .d2-2060964008 .background-color-AB4{background-color:#EDF0FD;} + .d2-2060964008 .background-color-AB5{background-color:#F7F8FE;} + .d2-2060964008 .color-N1{color:#0A0F25;} + .d2-2060964008 .color-N2{color:#676C7E;} + .d2-2060964008 .color-N3{color:#9499AB;} + .d2-2060964008 .color-N4{color:#CFD2DD;} + .d2-2060964008 .color-N5{color:#DEE1EB;} + .d2-2060964008 .color-N6{color:#EEF1F8;} + .d2-2060964008 .color-N7{color:#FFFFFF;} + .d2-2060964008 .color-B1{color:#0D32B2;} + .d2-2060964008 .color-B2{color:#0D32B2;} + .d2-2060964008 .color-B3{color:#E3E9FD;} + .d2-2060964008 .color-B4{color:#E3E9FD;} + .d2-2060964008 .color-B5{color:#EDF0FD;} + .d2-2060964008 .color-B6{color:#F7F8FE;} + .d2-2060964008 .color-AA2{color:#4A6FF3;} + .d2-2060964008 .color-AA4{color:#EDF0FD;} + .d2-2060964008 .color-AA5{color:#F7F8FE;} + .d2-2060964008 .color-AB4{color:#EDF0FD;} + .d2-2060964008 .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}]]>Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager + \ No newline at end of file diff --git a/e2etests/testdata/stable/executive_grid/elk/board.exp.json b/e2etests/testdata/stable/executive_grid/elk/board.exp.json index b9f09e5b5..6ec7a989f 100644 --- a/e2etests/testdata/stable/executive_grid/elk/board.exp.json +++ b/e2etests/testdata/stable/executive_grid/elk/board.exp.json @@ -52,7 +52,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -93,7 +93,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -134,7 +134,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -175,7 +175,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -216,7 +216,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -257,7 +257,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -298,7 +298,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -339,7 +339,7 @@ "y": 101 }, "width": 100, - "height": 109, + "height": 200, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -377,7 +377,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 250 + "y": 341 }, "width": 1080, "height": 61, diff --git a/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg index 7ac1c0a8a..8b27b5168 100644 --- a/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager - + .d2-2060964008 .fill-N1{fill:#0A0F25;} + .d2-2060964008 .fill-N2{fill:#676C7E;} + .d2-2060964008 .fill-N3{fill:#9499AB;} + .d2-2060964008 .fill-N4{fill:#CFD2DD;} + .d2-2060964008 .fill-N5{fill:#DEE1EB;} + .d2-2060964008 .fill-N6{fill:#EEF1F8;} + .d2-2060964008 .fill-N7{fill:#FFFFFF;} + .d2-2060964008 .fill-B1{fill:#0D32B2;} + .d2-2060964008 .fill-B2{fill:#0D32B2;} + .d2-2060964008 .fill-B3{fill:#E3E9FD;} + .d2-2060964008 .fill-B4{fill:#E3E9FD;} + .d2-2060964008 .fill-B5{fill:#EDF0FD;} + .d2-2060964008 .fill-B6{fill:#F7F8FE;} + .d2-2060964008 .fill-AA2{fill:#4A6FF3;} + .d2-2060964008 .fill-AA4{fill:#EDF0FD;} + .d2-2060964008 .fill-AA5{fill:#F7F8FE;} + .d2-2060964008 .fill-AB4{fill:#EDF0FD;} + .d2-2060964008 .fill-AB5{fill:#F7F8FE;} + .d2-2060964008 .stroke-N1{stroke:#0A0F25;} + .d2-2060964008 .stroke-N2{stroke:#676C7E;} + .d2-2060964008 .stroke-N3{stroke:#9499AB;} + .d2-2060964008 .stroke-N4{stroke:#CFD2DD;} + .d2-2060964008 .stroke-N5{stroke:#DEE1EB;} + .d2-2060964008 .stroke-N6{stroke:#EEF1F8;} + .d2-2060964008 .stroke-N7{stroke:#FFFFFF;} + .d2-2060964008 .stroke-B1{stroke:#0D32B2;} + .d2-2060964008 .stroke-B2{stroke:#0D32B2;} + .d2-2060964008 .stroke-B3{stroke:#E3E9FD;} + .d2-2060964008 .stroke-B4{stroke:#E3E9FD;} + .d2-2060964008 .stroke-B5{stroke:#EDF0FD;} + .d2-2060964008 .stroke-B6{stroke:#F7F8FE;} + .d2-2060964008 .stroke-AA2{stroke:#4A6FF3;} + .d2-2060964008 .stroke-AA4{stroke:#EDF0FD;} + .d2-2060964008 .stroke-AA5{stroke:#F7F8FE;} + .d2-2060964008 .stroke-AB4{stroke:#EDF0FD;} + .d2-2060964008 .stroke-AB5{stroke:#F7F8FE;} + .d2-2060964008 .background-color-N1{background-color:#0A0F25;} + .d2-2060964008 .background-color-N2{background-color:#676C7E;} + .d2-2060964008 .background-color-N3{background-color:#9499AB;} + .d2-2060964008 .background-color-N4{background-color:#CFD2DD;} + .d2-2060964008 .background-color-N5{background-color:#DEE1EB;} + .d2-2060964008 .background-color-N6{background-color:#EEF1F8;} + .d2-2060964008 .background-color-N7{background-color:#FFFFFF;} + .d2-2060964008 .background-color-B1{background-color:#0D32B2;} + .d2-2060964008 .background-color-B2{background-color:#0D32B2;} + .d2-2060964008 .background-color-B3{background-color:#E3E9FD;} + .d2-2060964008 .background-color-B4{background-color:#E3E9FD;} + .d2-2060964008 .background-color-B5{background-color:#EDF0FD;} + .d2-2060964008 .background-color-B6{background-color:#F7F8FE;} + .d2-2060964008 .background-color-AA2{background-color:#4A6FF3;} + .d2-2060964008 .background-color-AA4{background-color:#EDF0FD;} + .d2-2060964008 .background-color-AA5{background-color:#F7F8FE;} + .d2-2060964008 .background-color-AB4{background-color:#EDF0FD;} + .d2-2060964008 .background-color-AB5{background-color:#F7F8FE;} + .d2-2060964008 .color-N1{color:#0A0F25;} + .d2-2060964008 .color-N2{color:#676C7E;} + .d2-2060964008 .color-N3{color:#9499AB;} + .d2-2060964008 .color-N4{color:#CFD2DD;} + .d2-2060964008 .color-N5{color:#DEE1EB;} + .d2-2060964008 .color-N6{color:#EEF1F8;} + .d2-2060964008 .color-N7{color:#FFFFFF;} + .d2-2060964008 .color-B1{color:#0D32B2;} + .d2-2060964008 .color-B2{color:#0D32B2;} + .d2-2060964008 .color-B3{color:#E3E9FD;} + .d2-2060964008 .color-B4{color:#E3E9FD;} + .d2-2060964008 .color-B5{color:#EDF0FD;} + .d2-2060964008 .color-B6{color:#F7F8FE;} + .d2-2060964008 .color-AA2{color:#4A6FF3;} + .d2-2060964008 .color-AA4{color:#EDF0FD;} + .d2-2060964008 .color-AA5{color:#F7F8FE;} + .d2-2060964008 .color-AB4{color:#EDF0FD;} + .d2-2060964008 .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}]]>Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager + \ No newline at end of file From 04775c849168942277d02d20d40830dede51475d Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 4 Apr 2023 21:00:40 -0700 Subject: [PATCH 24/33] validate descendants --- d2compiler/compile.go | 6 ++++++ d2compiler/compile_test.go | 15 +++++++++++++++ .../d2compiler/TestCompile/grid_nested.exp.json | 16 ++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 testdata/d2compiler/TestCompile/grid_nested.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 0236a9ce2..aea9cbfa2 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -705,6 +705,12 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) { if !in && arrowheadIn { c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid shape, can only set "%s" for arrowheads`, obj.Attributes.Shape.Value)) } + case "rows", "columns": + for _, child := range obj.ChildrenArray { + if child.IsContainer() { + c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid grid %#v. can only set %#v with no descendants (see %#v)`, obj.AbsID(), keyword, child.ChildrenArray[0].AbsID())) + } + } } return } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 4afc52fbf..570163653 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2303,6 +2303,21 @@ obj { d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge "c -> hey.b" cannot enter grid "hey" d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot enter grid "hey"`, }, + { + name: "grid_nested", + text: `hey: { + rows: 200 + columns: 200 + + a + b + c + d.invalid descendant +} +`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid "hey". can only set "rows" with no descendants (see "hey.d.invalid descendant") +d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid "hey". can only set "columns" with no descendants (see "hey.d.invalid descendant")`, + }, } for _, tc := range testCases { diff --git a/testdata/d2compiler/TestCompile/grid_nested.exp.json b/testdata/d2compiler/TestCompile/grid_nested.exp.json new file mode 100644 index 000000000..22f85db05 --- /dev/null +++ b/testdata/d2compiler/TestCompile/grid_nested.exp.json @@ -0,0 +1,16 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,1:1:8-1:10:17", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid \"hey\". can only set \"rows\" with no descendants (see \"hey.d.invalid descendant\")" + }, + { + "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,2:1:19-2:13:31", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid \"hey\". can only set \"columns\" with no descendants (see \"hey.d.invalid descendant\")" + } + ] + } +} From 44f2d7a47f395c0b072eae6ce88c918e6389f505 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 5 Apr 2023 11:03:04 -0700 Subject: [PATCH 25/33] update grid_tests --- e2etests/testdata/files/grid_tests.d2 | 15 + .../stable/grid_tests/dagre/board.exp.json | 410 ++++++++++++++++++ .../stable/grid_tests/dagre/sketch.exp.svg | 164 +++---- .../stable/grid_tests/elk/board.exp.json | 410 ++++++++++++++++++ .../stable/grid_tests/elk/sketch.exp.svg | 164 +++---- 5 files changed, 999 insertions(+), 164 deletions(-) diff --git a/e2etests/testdata/files/grid_tests.d2 b/e2etests/testdata/files/grid_tests.d2 index d4b02f841..501c9ea24 100644 --- a/e2etests/testdata/files/grid_tests.d2 +++ b/e2etests/testdata/files/grid_tests.d2 @@ -117,3 +117,18 @@ columns 3: { f g } + +widths heights: { + rows: 3 + columns: 3 + + a w200.width: 200 + b h300.height: 300 + c + d h200.height: 200 + e + f w400.width: 400 + g + h + i +} diff --git a/e2etests/testdata/stable/grid_tests/dagre/board.exp.json b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json index 431f1dd28..a82de5acf 100644 --- a/e2etests/testdata/stable/grid_tests/dagre/board.exp.json +++ b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json @@ -3282,6 +3282,416 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 + }, + { + "id": "widths heights", + "type": "rectangle", + "pos": { + "x": 4389, + "y": 28 + }, + "width": 886, + "height": 766, + "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": "widths heights", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 171, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "widths heights.a w200", + "type": "rectangle", + "pos": { + "x": 4449, + "y": 88 + }, + "width": 200, + "height": 300, + "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 w200", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 49, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.b h300", + "type": "rectangle", + "pos": { + "x": 4689, + "y": 88 + }, + "width": 86, + "height": 300, + "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 h300", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 46, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.c", + "type": "rectangle", + "pos": { + "x": 4815, + "y": 88 + }, + "width": 400, + "height": 300, + "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": "widths heights.d h200", + "type": "rectangle", + "pos": { + "x": 4449, + "y": 428 + }, + "width": 200, + "height": 200, + "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 h200", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 47, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.e", + "type": "rectangle", + "pos": { + "x": 4689, + "y": 428 + }, + "width": 86, + "height": 200, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.f w400", + "type": "rectangle", + "pos": { + "x": 4815, + "y": 428 + }, + "width": 400, + "height": 200, + "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": "f w400", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 46, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.g", + "type": "rectangle", + "pos": { + "x": 4449, + "y": 668 + }, + "width": 200, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.h", + "type": "rectangle", + "pos": { + "x": 4689, + "y": 668 + }, + "width": 86, + "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": "h", + "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": "widths heights.i", + "type": "rectangle", + "pos": { + "x": 4815, + "y": 668 + }, + "width": 400, + "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": "i", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 4, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 } ], "connections": [], diff --git a/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg index 9e87e99d6..43be0cd45 100644 --- a/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg @@ -1,17 +1,17 @@ -rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg - + .d2-433946113 .fill-N1{fill:#0A0F25;} + .d2-433946113 .fill-N2{fill:#676C7E;} + .d2-433946113 .fill-N3{fill:#9499AB;} + .d2-433946113 .fill-N4{fill:#CFD2DD;} + .d2-433946113 .fill-N5{fill:#DEE1EB;} + .d2-433946113 .fill-N6{fill:#EEF1F8;} + .d2-433946113 .fill-N7{fill:#FFFFFF;} + .d2-433946113 .fill-B1{fill:#0D32B2;} + .d2-433946113 .fill-B2{fill:#0D32B2;} + .d2-433946113 .fill-B3{fill:#E3E9FD;} + .d2-433946113 .fill-B4{fill:#E3E9FD;} + .d2-433946113 .fill-B5{fill:#EDF0FD;} + .d2-433946113 .fill-B6{fill:#F7F8FE;} + .d2-433946113 .fill-AA2{fill:#4A6FF3;} + .d2-433946113 .fill-AA4{fill:#EDF0FD;} + .d2-433946113 .fill-AA5{fill:#F7F8FE;} + .d2-433946113 .fill-AB4{fill:#EDF0FD;} + .d2-433946113 .fill-AB5{fill:#F7F8FE;} + .d2-433946113 .stroke-N1{stroke:#0A0F25;} + .d2-433946113 .stroke-N2{stroke:#676C7E;} + .d2-433946113 .stroke-N3{stroke:#9499AB;} + .d2-433946113 .stroke-N4{stroke:#CFD2DD;} + .d2-433946113 .stroke-N5{stroke:#DEE1EB;} + .d2-433946113 .stroke-N6{stroke:#EEF1F8;} + .d2-433946113 .stroke-N7{stroke:#FFFFFF;} + .d2-433946113 .stroke-B1{stroke:#0D32B2;} + .d2-433946113 .stroke-B2{stroke:#0D32B2;} + .d2-433946113 .stroke-B3{stroke:#E3E9FD;} + .d2-433946113 .stroke-B4{stroke:#E3E9FD;} + .d2-433946113 .stroke-B5{stroke:#EDF0FD;} + .d2-433946113 .stroke-B6{stroke:#F7F8FE;} + .d2-433946113 .stroke-AA2{stroke:#4A6FF3;} + .d2-433946113 .stroke-AA4{stroke:#EDF0FD;} + .d2-433946113 .stroke-AA5{stroke:#F7F8FE;} + .d2-433946113 .stroke-AB4{stroke:#EDF0FD;} + .d2-433946113 .stroke-AB5{stroke:#F7F8FE;} + .d2-433946113 .background-color-N1{background-color:#0A0F25;} + .d2-433946113 .background-color-N2{background-color:#676C7E;} + .d2-433946113 .background-color-N3{background-color:#9499AB;} + .d2-433946113 .background-color-N4{background-color:#CFD2DD;} + .d2-433946113 .background-color-N5{background-color:#DEE1EB;} + .d2-433946113 .background-color-N6{background-color:#EEF1F8;} + .d2-433946113 .background-color-N7{background-color:#FFFFFF;} + .d2-433946113 .background-color-B1{background-color:#0D32B2;} + .d2-433946113 .background-color-B2{background-color:#0D32B2;} + .d2-433946113 .background-color-B3{background-color:#E3E9FD;} + .d2-433946113 .background-color-B4{background-color:#E3E9FD;} + .d2-433946113 .background-color-B5{background-color:#EDF0FD;} + .d2-433946113 .background-color-B6{background-color:#F7F8FE;} + .d2-433946113 .background-color-AA2{background-color:#4A6FF3;} + .d2-433946113 .background-color-AA4{background-color:#EDF0FD;} + .d2-433946113 .background-color-AA5{background-color:#F7F8FE;} + .d2-433946113 .background-color-AB4{background-color:#EDF0FD;} + .d2-433946113 .background-color-AB5{background-color:#F7F8FE;} + .d2-433946113 .color-N1{color:#0A0F25;} + .d2-433946113 .color-N2{color:#676C7E;} + .d2-433946113 .color-N3{color:#9499AB;} + .d2-433946113 .color-N4{color:#CFD2DD;} + .d2-433946113 .color-N5{color:#DEE1EB;} + .d2-433946113 .color-N6{color:#EEF1F8;} + .d2-433946113 .color-N7{color:#FFFFFF;} + .d2-433946113 .color-B1{color:#0D32B2;} + .d2-433946113 .color-B2{color:#0D32B2;} + .d2-433946113 .color-B3{color:#E3E9FD;} + .d2-433946113 .color-B4{color:#E3E9FD;} + .d2-433946113 .color-B5{color:#EDF0FD;} + .d2-433946113 .color-B6{color:#F7F8FE;} + .d2-433946113 .color-AA2{color:#4A6FF3;} + .d2-433946113 .color-AA4{color:#EDF0FD;} + .d2-433946113 .color-AA5{color:#F7F8FE;} + .d2-433946113 .color-AB4{color:#EDF0FD;} + .d2-433946113 .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}]]>rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi + \ No newline at end of file diff --git a/e2etests/testdata/stable/grid_tests/elk/board.exp.json b/e2etests/testdata/stable/grid_tests/elk/board.exp.json index e1fd68bee..bb7e1930e 100644 --- a/e2etests/testdata/stable/grid_tests/elk/board.exp.json +++ b/e2etests/testdata/stable/grid_tests/elk/board.exp.json @@ -3282,6 +3282,416 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 + }, + { + "id": "widths heights", + "type": "rectangle", + "pos": { + "x": 4001, + "y": 40 + }, + "width": 886, + "height": 766, + "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": "widths heights", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 171, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "widths heights.a w200", + "type": "rectangle", + "pos": { + "x": 4061, + "y": 100 + }, + "width": 200, + "height": 300, + "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 w200", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 49, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.b h300", + "type": "rectangle", + "pos": { + "x": 4301, + "y": 100 + }, + "width": 86, + "height": 300, + "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 h300", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 46, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.c", + "type": "rectangle", + "pos": { + "x": 4427, + "y": 100 + }, + "width": 400, + "height": 300, + "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": "widths heights.d h200", + "type": "rectangle", + "pos": { + "x": 4061, + "y": 440 + }, + "width": 200, + "height": 200, + "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 h200", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 47, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.e", + "type": "rectangle", + "pos": { + "x": 4301, + "y": 440 + }, + "width": 86, + "height": 200, + "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": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.f w400", + "type": "rectangle", + "pos": { + "x": 4427, + "y": 440 + }, + "width": 400, + "height": 200, + "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": "f w400", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 46, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.g", + "type": "rectangle", + "pos": { + "x": 4061, + "y": 680 + }, + "width": 200, + "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": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "widths heights.h", + "type": "rectangle", + "pos": { + "x": 4301, + "y": 680 + }, + "width": 86, + "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": "h", + "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": "widths heights.i", + "type": "rectangle", + "pos": { + "x": 4427, + "y": 680 + }, + "width": 400, + "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": "i", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 4, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 } ], "connections": [], diff --git a/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg index 0004db37f..bfcf25d48 100644 --- a/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg @@ -1,17 +1,17 @@ -rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg - + .d2-253581586 .fill-N1{fill:#0A0F25;} + .d2-253581586 .fill-N2{fill:#676C7E;} + .d2-253581586 .fill-N3{fill:#9499AB;} + .d2-253581586 .fill-N4{fill:#CFD2DD;} + .d2-253581586 .fill-N5{fill:#DEE1EB;} + .d2-253581586 .fill-N6{fill:#EEF1F8;} + .d2-253581586 .fill-N7{fill:#FFFFFF;} + .d2-253581586 .fill-B1{fill:#0D32B2;} + .d2-253581586 .fill-B2{fill:#0D32B2;} + .d2-253581586 .fill-B3{fill:#E3E9FD;} + .d2-253581586 .fill-B4{fill:#E3E9FD;} + .d2-253581586 .fill-B5{fill:#EDF0FD;} + .d2-253581586 .fill-B6{fill:#F7F8FE;} + .d2-253581586 .fill-AA2{fill:#4A6FF3;} + .d2-253581586 .fill-AA4{fill:#EDF0FD;} + .d2-253581586 .fill-AA5{fill:#F7F8FE;} + .d2-253581586 .fill-AB4{fill:#EDF0FD;} + .d2-253581586 .fill-AB5{fill:#F7F8FE;} + .d2-253581586 .stroke-N1{stroke:#0A0F25;} + .d2-253581586 .stroke-N2{stroke:#676C7E;} + .d2-253581586 .stroke-N3{stroke:#9499AB;} + .d2-253581586 .stroke-N4{stroke:#CFD2DD;} + .d2-253581586 .stroke-N5{stroke:#DEE1EB;} + .d2-253581586 .stroke-N6{stroke:#EEF1F8;} + .d2-253581586 .stroke-N7{stroke:#FFFFFF;} + .d2-253581586 .stroke-B1{stroke:#0D32B2;} + .d2-253581586 .stroke-B2{stroke:#0D32B2;} + .d2-253581586 .stroke-B3{stroke:#E3E9FD;} + .d2-253581586 .stroke-B4{stroke:#E3E9FD;} + .d2-253581586 .stroke-B5{stroke:#EDF0FD;} + .d2-253581586 .stroke-B6{stroke:#F7F8FE;} + .d2-253581586 .stroke-AA2{stroke:#4A6FF3;} + .d2-253581586 .stroke-AA4{stroke:#EDF0FD;} + .d2-253581586 .stroke-AA5{stroke:#F7F8FE;} + .d2-253581586 .stroke-AB4{stroke:#EDF0FD;} + .d2-253581586 .stroke-AB5{stroke:#F7F8FE;} + .d2-253581586 .background-color-N1{background-color:#0A0F25;} + .d2-253581586 .background-color-N2{background-color:#676C7E;} + .d2-253581586 .background-color-N3{background-color:#9499AB;} + .d2-253581586 .background-color-N4{background-color:#CFD2DD;} + .d2-253581586 .background-color-N5{background-color:#DEE1EB;} + .d2-253581586 .background-color-N6{background-color:#EEF1F8;} + .d2-253581586 .background-color-N7{background-color:#FFFFFF;} + .d2-253581586 .background-color-B1{background-color:#0D32B2;} + .d2-253581586 .background-color-B2{background-color:#0D32B2;} + .d2-253581586 .background-color-B3{background-color:#E3E9FD;} + .d2-253581586 .background-color-B4{background-color:#E3E9FD;} + .d2-253581586 .background-color-B5{background-color:#EDF0FD;} + .d2-253581586 .background-color-B6{background-color:#F7F8FE;} + .d2-253581586 .background-color-AA2{background-color:#4A6FF3;} + .d2-253581586 .background-color-AA4{background-color:#EDF0FD;} + .d2-253581586 .background-color-AA5{background-color:#F7F8FE;} + .d2-253581586 .background-color-AB4{background-color:#EDF0FD;} + .d2-253581586 .background-color-AB5{background-color:#F7F8FE;} + .d2-253581586 .color-N1{color:#0A0F25;} + .d2-253581586 .color-N2{color:#676C7E;} + .d2-253581586 .color-N3{color:#9499AB;} + .d2-253581586 .color-N4{color:#CFD2DD;} + .d2-253581586 .color-N5{color:#DEE1EB;} + .d2-253581586 .color-N6{color:#EEF1F8;} + .d2-253581586 .color-N7{color:#FFFFFF;} + .d2-253581586 .color-B1{color:#0D32B2;} + .d2-253581586 .color-B2{color:#0D32B2;} + .d2-253581586 .color-B3{color:#E3E9FD;} + .d2-253581586 .color-B4{color:#E3E9FD;} + .d2-253581586 .color-B5{color:#EDF0FD;} + .d2-253581586 .color-B6{color:#F7F8FE;} + .d2-253581586 .color-AA2{color:#4A6FF3;} + .d2-253581586 .color-AA4{color:#EDF0FD;} + .d2-253581586 .color-AA5{color:#F7F8FE;} + .d2-253581586 .color-AB4{color:#EDF0FD;} + .d2-253581586 .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}]]>rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi + \ No newline at end of file From 06a942cf99fc0ff3189e8320cb687e57174e6a2d Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 5 Apr 2023 11:11:31 -0700 Subject: [PATCH 26/33] rename to grid diagram --- d2compiler/compile.go | 10 +- d2compiler/compile_test.go | 10 +- d2graph/{grid.go => grid_diagram.go} | 8 +- d2layouts/d2grid/{grid.go => grid_diagram.go} | 46 +++--- d2layouts/d2grid/layout.go | 144 +++++++++--------- .../d2compiler/TestCompile/grid_edge.exp.json | 6 +- .../TestCompile/grid_nested.exp.json | 4 +- 7 files changed, 114 insertions(+), 114 deletions(-) rename d2graph/{grid.go => grid_diagram.go} (54%) rename d2layouts/d2grid/{grid.go => grid_diagram.go} (71%) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index aea9cbfa2..c1a252440 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -708,7 +708,7 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) { case "rows", "columns": for _, child := range obj.ChildrenArray { if child.IsContainer() { - c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid grid %#v. can only set %#v with no descendants (see %#v)`, obj.AbsID(), keyword, child.ChildrenArray[0].AbsID())) + c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid grid diagram %#v. can only set %#v with no descendants (see %#v)`, obj.AbsID(), keyword, child.ChildrenArray[0].AbsID())) } } } @@ -796,12 +796,12 @@ func (c *compiler) validateNear(g *d2graph.Graph) { func (c *compiler) validateEdges(g *d2graph.Graph) { for _, edge := range g.Edges { - if grid := edge.Src.ClosestGrid(); grid != nil { - c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid %#v", d2format.Format(edge.GetAstEdge()), grid.AbsID()) + if gd := edge.Src.ClosestGridDiagram(); gd != nil { + c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid diagram %#v", d2format.Format(edge.GetAstEdge()), gd.AbsID()) continue } - if grid := edge.Dst.ClosestGrid(); grid != nil { - c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid %#v", d2format.Format(edge.GetAstEdge()), grid.AbsID()) + if gd := edge.Dst.ClosestGridDiagram(); gd != nil { + c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid diagram %#v", d2format.Format(edge.GetAstEdge()), gd.AbsID()) continue } } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 570163653..a031203ea 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2299,9 +2299,9 @@ obj { hey -> c: ok `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge "a -> b" cannot enter grid "hey" -d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge "c -> hey.b" cannot enter grid "hey" -d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot enter grid "hey"`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge "a -> b" cannot enter grid diagram "hey" +d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge "c -> hey.b" cannot enter grid diagram "hey" +d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot enter grid diagram "hey"`, }, { name: "grid_nested", @@ -2315,8 +2315,8 @@ d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot en d.invalid descendant } `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid "hey". can only set "rows" with no descendants (see "hey.d.invalid descendant") -d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid "hey". can only set "columns" with no descendants (see "hey.d.invalid descendant")`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid diagram "hey". can only set "rows" with no descendants (see "hey.d.invalid descendant") +d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid diagram "hey". can only set "columns" with no descendants (see "hey.d.invalid descendant")`, }, } diff --git a/d2graph/grid.go b/d2graph/grid_diagram.go similarity index 54% rename from d2graph/grid.go rename to d2graph/grid_diagram.go index 0315fe60b..ec41e0460 100644 --- a/d2graph/grid.go +++ b/d2graph/grid_diagram.go @@ -1,16 +1,16 @@ package d2graph -func (obj *Object) IsGrid() bool { +func (obj *Object) IsGridDiagram() bool { return obj != nil && obj.Attributes != nil && (obj.Attributes.Rows != nil || obj.Attributes.Columns != nil) } -func (obj *Object) ClosestGrid() *Object { +func (obj *Object) ClosestGridDiagram() *Object { if obj.Parent == nil { return nil } - if obj.Parent.IsGrid() { + if obj.Parent.IsGridDiagram() { return obj.Parent } - return obj.Parent.ClosestGrid() + return obj.Parent.ClosestGridDiagram() } diff --git a/d2layouts/d2grid/grid.go b/d2layouts/d2grid/grid_diagram.go similarity index 71% rename from d2layouts/d2grid/grid.go rename to d2layouts/d2grid/grid_diagram.go index f5d6e7b65..c26a6e917 100644 --- a/d2layouts/d2grid/grid.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -6,7 +6,7 @@ import ( "oss.terrastruct.com/d2/d2graph" ) -type grid struct { +type gridDiagram struct { root *d2graph.Object nodes []*d2graph.Object rows int @@ -18,24 +18,24 @@ type grid struct { height float64 } -func newGrid(root *d2graph.Object) *grid { - g := grid{root: root, nodes: root.ChildrenArray} +func newGridDiagram(root *d2graph.Object) *gridDiagram { + gd := gridDiagram{root: root, nodes: root.ChildrenArray} if root.Attributes.Rows != nil { - g.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) + gd.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) } if root.Attributes.Columns != nil { - g.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) + gd.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) } // compute exact row/column count based on values entered - if g.columns == 0 { - g.rowDominant = true - } else if g.rows == 0 { - g.rowDominant = false + if gd.columns == 0 { + gd.rowDominant = true + } else if gd.rows == 0 { + gd.rowDominant = false } else { // if keyword rows is first, rows are primary, columns secondary. if root.Attributes.Rows.MapKey.Range.Before(root.Attributes.Columns.MapKey.Range) { - g.rowDominant = true + gd.rowDominant = true } // rows and columns specified, but we want to continue naturally if user enters more nodes @@ -48,34 +48,34 @@ func newGrid(root *d2graph.Object) *grid { // . └───────┘ ▲ │ └───────┘ ▲ // . ▲ └─existing nodes modified │ ▲ └─existing nodes preserved // . └─existing rows preserved │ └─existing rows modified - capacity := g.rows * g.columns - for capacity < len(g.nodes) { - if g.rowDominant { - g.rows++ - capacity += g.columns + capacity := gd.rows * gd.columns + for capacity < len(gd.nodes) { + if gd.rowDominant { + gd.rows++ + capacity += gd.columns } else { - g.columns++ - capacity += g.rows + gd.columns++ + capacity += gd.rows } } } - return &g + return &gd } -func (g *grid) shift(dx, dy float64) { - for _, obj := range g.nodes { +func (gd *gridDiagram) shift(dx, dy float64) { + for _, obj := range gd.nodes { obj.TopLeft.X += dx obj.TopLeft.Y += dy } } -func (g *grid) cleanup(obj *d2graph.Object, graph *d2graph.Graph) { +func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) { obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = make([]*d2graph.Object, 0) - for _, child := range g.nodes { + for _, child := range gd.nodes { obj.Children[child.ID] = child obj.ChildrenArray = append(obj.ChildrenArray, child) } - graph.Objects = append(graph.Objects, g.nodes...) + graph.Objects = append(graph.Objects, gd.nodes...) } diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 3bdc0a4be..0b42714af 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -29,25 +29,25 @@ const ( // 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 { - grids, objectOrder, err := withoutGrids(ctx, g) + gridDiagrams, objectOrder, err := withoutGridDiagrams(ctx, g) if err != nil { return err } - if g.Root.IsGrid() && len(g.Root.ChildrenArray) != 0 { + 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, grids, objectOrder) + cleanup(g, gridDiagrams, objectOrder) return nil } } -func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*grid, objectOrder map[string]int, err error) { +func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams map[string]*gridDiagram, objectOrder map[string]int, err error) { toRemove := make(map[*d2graph.Object]struct{}) - grids := make(map[string]*grid) + gridDiagrams = make(map[string]*gridDiagram) if len(g.Objects) > 0 { queue := make([]*d2graph.Object, 1, len(g.Objects)) @@ -58,12 +58,12 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g if len(obj.ChildrenArray) == 0 { continue } - if !obj.IsGrid() { + if !obj.IsGridDiagram() { queue = append(queue, obj.ChildrenArray...) continue } - grid, err := layoutGrid(g, obj) + gd, err := layoutGrid(g, obj) if err != nil { return nil, nil, err } @@ -71,13 +71,13 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g obj.ChildrenArray = nil var dx, dy float64 - width := grid.width + 2*CONTAINER_PADDING + width := gd.width + 2*CONTAINER_PADDING labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING if labelWidth > width { dx = (labelWidth - width) / 2 width = labelWidth } - height := grid.height + 2*CONTAINER_PADDING + height := gd.height + 2*CONTAINER_PADDING labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING if labelHeight > CONTAINER_PADDING { // if the label doesn't fit within the padding, we need to add more @@ -87,14 +87,14 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g } // we need to center children if we have to expand to fit the container label if dx != 0 || dy != 0 { - grid.shift(dx, dy) + gd.shift(dx, dy) } obj.Box = geo.NewBox(nil, width, height) obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - grids[obj.AbsID()] = grid + gridDiagrams[obj.AbsID()] = gd - for _, node := range grid.nodes { + for _, node := range gd.nodes { toRemove[node] = struct{}{} } } @@ -110,20 +110,20 @@ func withoutGrids(ctx context.Context, g *d2graph.Graph) (idToGrid map[string]*g } g.Objects = layoutObjects - return grids, objectOrder, nil + return gridDiagrams, objectOrder, nil } -func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { - grid := newGrid(obj) +func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) { + gd := newGridDiagram(obj) - if grid.rows != 0 && grid.columns != 0 { - grid.layoutEvenly(g, obj) + if gd.rows != 0 && gd.columns != 0 { + gd.layoutEvenly(g, obj) } else { - grid.layoutDynamic(g, obj) + gd.layoutDynamic(g, obj) } // position labels and icons - for _, n := range grid.nodes { + for _, n := range gd.nodes { if n.Attributes.Icon != nil { n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) @@ -132,32 +132,32 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*grid, error) { } } - return grid, nil + return gd, nil } -func (grid *grid) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { +func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { // layout nodes in a grid with these 2 properties: // all nodes in the same row should have the same height // all nodes in the same column should have the same width getNode := func(rowIndex, columnIndex int) *d2graph.Object { var index int - if grid.rowDominant { - index = rowIndex*grid.columns + columnIndex + if gd.rowDominant { + index = rowIndex*gd.columns + columnIndex } else { - index = columnIndex*grid.rows + rowIndex + index = columnIndex*gd.rows + rowIndex } - if index < len(grid.nodes) { - return grid.nodes[index] + if index < len(gd.nodes) { + return gd.nodes[index] } return nil } - rowHeights := make([]float64, 0, grid.rows) - colWidths := make([]float64, 0, grid.columns) - for i := 0; i < grid.rows; i++ { + rowHeights := make([]float64, 0, gd.rows) + colWidths := make([]float64, 0, gd.columns) + for i := 0; i < gd.rows; i++ { rowHeight := 0. - for j := 0; j < grid.columns; j++ { + for j := 0; j < gd.columns; j++ { n := getNode(i, j) if n == nil { break @@ -166,9 +166,9 @@ func (grid *grid) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { } rowHeights = append(rowHeights, rowHeight) } - for j := 0; j < grid.columns; j++ { + for j := 0; j < gd.columns; j++ { columnWidth := 0. - for i := 0; i < grid.rows; i++ { + for i := 0; i < gd.rows; i++ { n := getNode(i, j) if n == nil { break @@ -179,9 +179,9 @@ func (grid *grid) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { } cursor := geo.NewPoint(0, 0) - if grid.rowDominant { - for i := 0; i < grid.rows; i++ { - for j := 0; j < grid.columns; j++ { + if gd.rowDominant { + for i := 0; i < gd.rows; i++ { + for j := 0; j < gd.columns; j++ { n := getNode(i, j) if n == nil { break @@ -195,8 +195,8 @@ func (grid *grid) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { cursor.Y += rowHeights[i] + VERTICAL_PAD } } else { - for j := 0; j < grid.columns; j++ { - for i := 0; i < grid.rows; i++ { + for j := 0; j < gd.columns; j++ { + for i := 0; i < gd.rows; i++ { n := getNode(i, j) if n == nil { break @@ -220,11 +220,11 @@ func (grid *grid) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { } totalWidth -= HORIZONTAL_PAD totalHeight -= VERTICAL_PAD - grid.width = totalWidth - grid.height = totalHeight + gd.width = totalWidth + gd.height = totalHeight } -func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { +func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // assume we have the following nodes to layout: // . ┌A──────────────┐ ┌B──┐ ┌C─────────┐ ┌D────────┐ ┌E────────────────┐ // . └───────────────┘ │ │ │ │ │ │ │ │ @@ -242,16 +242,16 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // we want to split up the total width across the N rows or columns as evenly as possible var totalWidth, totalHeight float64 - for _, n := range grid.nodes { + for _, n := range gd.nodes { totalWidth += n.Width totalHeight += n.Height } - totalWidth += HORIZONTAL_PAD * float64(len(grid.nodes)-1) - totalHeight += VERTICAL_PAD * float64(len(grid.nodes)-1) + totalWidth += HORIZONTAL_PAD * float64(len(gd.nodes)-1) + totalHeight += VERTICAL_PAD * float64(len(gd.nodes)-1) layout := [][]int{{}} - if grid.rowDominant { - targetWidth := totalWidth / float64(grid.rows) + if gd.rowDominant { + targetWidth := totalWidth / float64(gd.rows) rowWidth := 0. rowIndex := 0 addRow := func() { @@ -264,7 +264,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowWidth += n.Width + HORIZONTAL_PAD } - for i, n := range grid.nodes { + for i, n := range gd.nodes { // if the next node will be past the target, start a new row if rowWidth+n.Width+HORIZONTAL_PAD > targetWidth { // if the node is mostly past the target, put it on the next row @@ -273,7 +273,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { addNode(i, n) } else { addNode(i, n) - if i < len(grid.nodes)-1 { + if i < len(gd.nodes)-1 { addRow() } } @@ -282,7 +282,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { } } } else { - targetHeight := totalHeight / float64(grid.columns) + targetHeight := totalHeight / float64(gd.columns) colHeight := 0. colIndex := 0 addCol := func() { @@ -295,7 +295,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colHeight += n.Height + VERTICAL_PAD } - for i, n := range grid.nodes { + for i, n := range gd.nodes { // if the next node will be past the target, start a new row if colHeight+n.Height+VERTICAL_PAD > targetHeight { // if the node is mostly past the target, put it on the next row @@ -304,7 +304,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { addNode(i, n) } else { addNode(i, n) - if i < len(grid.nodes)-1 { + if i < len(gd.nodes)-1 { addCol() } } @@ -316,7 +316,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { cursor := geo.NewPoint(0, 0) var maxY, maxX float64 - if grid.rowDominant { + if gd.rowDominant { // if we have 2 rows, then each row's nodes should have the same height // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) // . ├ ─ ─ ─ ─ ─ ─ ─┤ │ │ │ │ │ @@ -333,7 +333,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { for _, row := range layout { rowHeight := 0. for _, nodeIndex := range row { - n := grid.nodes[nodeIndex] + n := gd.nodes[nodeIndex] n.TopLeft = cursor.Copy() cursor.X += n.Width + HORIZONTAL_PAD rowHeight = math.Max(rowHeight, n.Height) @@ -344,7 +344,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // set all nodes in row to the same height for _, nodeIndex := range row { - n := grid.nodes[nodeIndex] + n := gd.nodes[nodeIndex] n.Height = rowHeight } @@ -375,7 +375,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { nodes := []*d2graph.Object{} var widest float64 for _, nodeIndex := range row { - n := grid.nodes[nodeIndex] + n := gd.nodes[nodeIndex] widest = math.Max(widest, n.Width) nodes = append(nodes, n) } @@ -387,7 +387,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if n.Width < widest { var index int for i, nodeIndex := range row { - if n == grid.nodes[nodeIndex] { + if n == gd.nodes[nodeIndex] { index = i break } @@ -396,7 +396,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { n.Width += grow // shift following nodes for i := index + 1; i < len(row); i++ { - grid.nodes[row[i]].TopLeft.X += grow + gd.nodes[row[i]].TopLeft.X += grow } delta -= grow if delta <= 0 { @@ -407,7 +407,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if delta > 0 { grow := delta / float64(len(row)) for i := len(row) - 1; i >= 0; i-- { - n := grid.nodes[row[i]] + n := gd.nodes[row[i]] n.TopLeft.X += grow * float64(i) n.Width += grow delta -= grow @@ -430,7 +430,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { for _, column := range layout { colWidth := 0. for _, nodeIndex := range column { - n := grid.nodes[nodeIndex] + n := gd.nodes[nodeIndex] n.TopLeft = cursor.Copy() cursor.Y += n.Height + VERTICAL_PAD colWidth = math.Max(colWidth, n.Width) @@ -440,7 +440,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { maxY = math.Max(maxY, colHeight) // set all nodes in column to the same width for _, nodeIndex := range column { - n := grid.nodes[nodeIndex] + n := gd.nodes[nodeIndex] n.Width = colWidth } @@ -469,7 +469,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { nodes := []*d2graph.Object{} var tallest float64 for _, nodeIndex := range column { - n := grid.nodes[nodeIndex] + n := gd.nodes[nodeIndex] tallest = math.Max(tallest, n.Height) nodes = append(nodes, n) } @@ -481,7 +481,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if n.Height < tallest { var index int for i, nodeIndex := range column { - if n == grid.nodes[nodeIndex] { + if n == gd.nodes[nodeIndex] { index = i break } @@ -490,7 +490,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { n.Height += grow // shift following nodes for i := index + 1; i < len(column); i++ { - grid.nodes[column[i]].TopLeft.Y += grow + gd.nodes[column[i]].TopLeft.Y += grow } delta -= grow if delta <= 0 { @@ -501,7 +501,7 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if delta > 0 { grow := delta / float64(len(column)) for i := len(column) - 1; i >= 0; i-- { - n := grid.nodes[column[i]] + n := gd.nodes[column[i]] n.TopLeft.Y += grow * float64(i) n.Height += grow delta -= grow @@ -509,40 +509,40 @@ func (grid *grid) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { } } } - grid.width = maxX - grid.height = maxY + gd.width = maxX + gd.height = maxY } // 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, grids map[string]*grid, objectsOrder map[string]int) { +func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objectsOrder 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()] }) }() - if graph.Root.IsGrid() { - grid, exists := grids[graph.Root.AbsID()] + if graph.Root.IsGridDiagram() { + gd, exists := gridDiagrams[graph.Root.AbsID()] if exists { - grid.cleanup(graph.Root, graph) + gd.cleanup(graph.Root, graph) return } } for _, obj := range graph.Objects { - grid, exists := grids[obj.AbsID()] + gd, exists := gridDiagrams[obj.AbsID()] if !exists { continue } obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) // shift the grid from (0, 0) - grid.shift( + gd.shift( obj.TopLeft.X+CONTAINER_PADDING, obj.TopLeft.Y+CONTAINER_PADDING, ) - grid.cleanup(obj, graph) + gd.cleanup(obj, graph) } } diff --git a/testdata/d2compiler/TestCompile/grid_edge.exp.json b/testdata/d2compiler/TestCompile/grid_edge.exp.json index 1d6c84181..dee805205 100644 --- a/testdata/d2compiler/TestCompile/grid_edge.exp.json +++ b/testdata/d2compiler/TestCompile/grid_edge.exp.json @@ -5,15 +5,15 @@ "errs": [ { "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,2:1:17-2:7:23", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge \"a -> b\" cannot enter grid \"hey\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge \"a -> b\" cannot enter grid diagram \"hey\"" }, { "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,4:1:27-4:11:37", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge \"c -> hey.b\" cannot enter grid \"hey\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge \"c -> hey.b\" cannot enter grid diagram \"hey\"" }, { "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,5:1:39-5:11:49", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge \"hey.a -> c\" cannot enter grid \"hey\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge \"hey.a -> c\" cannot enter grid diagram \"hey\"" } ] } diff --git a/testdata/d2compiler/TestCompile/grid_nested.exp.json b/testdata/d2compiler/TestCompile/grid_nested.exp.json index 22f85db05..a45781692 100644 --- a/testdata/d2compiler/TestCompile/grid_nested.exp.json +++ b/testdata/d2compiler/TestCompile/grid_nested.exp.json @@ -5,11 +5,11 @@ "errs": [ { "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,1:1:8-1:10:17", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid \"hey\". can only set \"rows\" with no descendants (see \"hey.d.invalid descendant\")" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid diagram \"hey\". can only set \"rows\" with no descendants (see \"hey.d.invalid descendant\")" }, { "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,2:1:19-2:13:31", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid \"hey\". can only set \"columns\" with no descendants (see \"hey.d.invalid descendant\")" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid diagram \"hey\". can only set \"columns\" with no descendants (see \"hey.d.invalid descendant\")" } ] } From 292ac05a9e0e46561c6626bfcfe599aeb43f66a4 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 5 Apr 2023 11:33:28 -0700 Subject: [PATCH 27/33] changelog --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 5651bfee0..da0c40910 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,6 +1,7 @@ #### Features 🚀 - Multi-board SVG outputs with internal links go to their output paths [#1116](https://github.com/terrastruct/d2/pull/1116) +- New grid layout to place nodes in rows and columns [#1122](https://github.com/terrastruct/d2/pull/1122) #### Improvements 🧹 From 8eb99a46c6032694b83b8f0d551f3e0e8eeec288 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 5 Apr 2023 11:49:04 -0700 Subject: [PATCH 28/33] new method for placing nodes across rows --- d2layouts/d2grid/layout.go | 192 +++++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 81 deletions(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 0b42714af..bdfab8f98 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -246,72 +246,16 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { totalWidth += n.Width totalHeight += n.Height } - totalWidth += HORIZONTAL_PAD * float64(len(gd.nodes)-1) - totalHeight += VERTICAL_PAD * float64(len(gd.nodes)-1) + totalWidth += HORIZONTAL_PAD * float64(len(gd.nodes)-gd.rows) + totalHeight += VERTICAL_PAD * float64(len(gd.nodes)-gd.columns) - layout := [][]int{{}} + var layout [][]*d2graph.Object if gd.rowDominant { targetWidth := totalWidth / float64(gd.rows) - rowWidth := 0. - rowIndex := 0 - addRow := func() { - layout = append(layout, []int{}) - rowIndex++ - rowWidth = 0 - } - addNode := func(i int, n *d2graph.Object) { - layout[rowIndex] = append(layout[rowIndex], i) - rowWidth += n.Width + HORIZONTAL_PAD - } - - for i, n := range gd.nodes { - // if the next node will be past the target, start a new row - if rowWidth+n.Width+HORIZONTAL_PAD > targetWidth { - // if the node is mostly past the target, put it on the next row - if rowWidth+n.Width/2 > targetWidth { - addRow() - addNode(i, n) - } else { - addNode(i, n) - if i < len(gd.nodes)-1 { - addRow() - } - } - } else { - addNode(i, n) - } - } + layout = gd.getBestLayout(targetWidth, false) } else { targetHeight := totalHeight / float64(gd.columns) - colHeight := 0. - colIndex := 0 - addCol := func() { - layout = append(layout, []int{}) - colIndex++ - colHeight = 0 - } - addNode := func(i int, n *d2graph.Object) { - layout[colIndex] = append(layout[colIndex], i) - colHeight += n.Height + VERTICAL_PAD - } - - for i, n := range gd.nodes { - // if the next node will be past the target, start a new row - if colHeight+n.Height+VERTICAL_PAD > targetHeight { - // if the node is mostly past the target, put it on the next row - if colHeight+n.Height/2 > targetHeight { - addCol() - addNode(i, n) - } else { - addNode(i, n) - if i < len(gd.nodes)-1 { - addCol() - } - } - } else { - addNode(i, n) - } - } + layout = gd.getBestLayout(targetHeight, true) } cursor := geo.NewPoint(0, 0) @@ -332,8 +276,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowWidths := []float64{} for _, row := range layout { rowHeight := 0. - for _, nodeIndex := range row { - n := gd.nodes[nodeIndex] + for _, n := range row { n.TopLeft = cursor.Copy() cursor.X += n.Width + HORIZONTAL_PAD rowHeight = math.Max(rowHeight, n.Height) @@ -343,8 +286,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { maxX = math.Max(maxX, rowWidth) // set all nodes in row to the same height - for _, nodeIndex := range row { - n := gd.nodes[nodeIndex] + for _, n := range row { n.Height = rowHeight } @@ -374,8 +316,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { delta := maxX - rowWidth nodes := []*d2graph.Object{} var widest float64 - for _, nodeIndex := range row { - n := gd.nodes[nodeIndex] + for _, n := range row { widest = math.Max(widest, n.Width) nodes = append(nodes, n) } @@ -386,8 +327,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { for _, n := range nodes { if n.Width < widest { var index int - for i, nodeIndex := range row { - if n == gd.nodes[nodeIndex] { + for i, node := range row { + if n == node { index = i break } @@ -396,7 +337,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { n.Width += grow // shift following nodes for i := index + 1; i < len(row); i++ { - gd.nodes[row[i]].TopLeft.X += grow + row[i].TopLeft.X += grow } delta -= grow if delta <= 0 { @@ -407,7 +348,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if delta > 0 { grow := delta / float64(len(row)) for i := len(row) - 1; i >= 0; i-- { - n := gd.nodes[row[i]] + n := row[i] n.TopLeft.X += grow * float64(i) n.Width += grow delta -= grow @@ -429,8 +370,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colHeights := []float64{} for _, column := range layout { colWidth := 0. - for _, nodeIndex := range column { - n := gd.nodes[nodeIndex] + for _, n := range column { n.TopLeft = cursor.Copy() cursor.Y += n.Height + VERTICAL_PAD colWidth = math.Max(colWidth, n.Width) @@ -439,8 +379,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colHeights = append(colHeights, colHeight) maxY = math.Max(maxY, colHeight) // set all nodes in column to the same width - for _, nodeIndex := range column { - n := gd.nodes[nodeIndex] + for _, n := range column { n.Width = colWidth } @@ -468,8 +407,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { delta := maxY - colHeight nodes := []*d2graph.Object{} var tallest float64 - for _, nodeIndex := range column { - n := gd.nodes[nodeIndex] + for _, n := range column { tallest = math.Max(tallest, n.Height) nodes = append(nodes, n) } @@ -480,8 +418,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { for _, n := range nodes { if n.Height < tallest { var index int - for i, nodeIndex := range column { - if n == gd.nodes[nodeIndex] { + for i, node := range column { + if n == node { index = i break } @@ -490,7 +428,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { n.Height += grow // shift following nodes for i := index + 1; i < len(column); i++ { - gd.nodes[column[i]].TopLeft.Y += grow + column[i].TopLeft.Y += grow } delta -= grow if delta <= 0 { @@ -501,7 +439,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if delta > 0 { grow := delta / float64(len(column)) for i := len(column) - 1; i >= 0; i-- { - n := gd.nodes[column[i]] + n := column[i] n.TopLeft.Y += grow * float64(i) n.Height += grow delta -= grow @@ -513,6 +451,98 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { gd.height = maxY } +// generate the best layout of nodes aiming for each row to be the targetSize width +// if columns is true, each column aims to have the targetSize height +func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2graph.Object { + var nCuts int + if columns { + nCuts = gd.columns - 1 + } else { + nCuts = gd.rows - 1 + } + if nCuts == 0 { + return genLayout(gd.nodes, nil) + } + + // get all options for where to place these cuts, preferring later cuts over earlier cuts + // with 5 nodes and 2 cuts we have these options: + // . A B C │ D │ E <- these cuts would produce: ┌A─┐ ┌B─┐ ┌C─┐ + // . A B │ C D │ E └──┘ └──┘ └──┘ + // . A │ B C D │ E ┌D───────────┐ + // . A B │ C │ D E └────────────┘ + // . A │ B C │ D E ┌E───────────┐ + // . A │ B │ C D E └────────────┘ + divisions := genDivisions(gd.nodes, nCuts) + + var bestLayout [][]*d2graph.Object + bestDist := math.MaxFloat64 + // of these divisions, find the layout with rows closest to the targetSize + for _, division := range divisions { + layout := genLayout(gd.nodes, division) + dist := getDistToTarget(layout, targetSize, columns) + if dist < bestDist { + bestLayout = layout + bestDist = dist + } + } + + return bestLayout +} + +// get all possible divisions of nodes by the number of cuts +func genDivisions(nodes []*d2graph.Object, nCuts int) (divisions [][]int) { + if len(nodes) < 2 || nCuts == 0 { + return nil + } + // we go in this order to prefer extra nodes in starting rows rather than later ones + lastNode := len(nodes) - 1 + for index := lastNode; index >= nCuts; index-- { + if nCuts > 1 { + for _, inner := range genDivisions(nodes[:index], nCuts-1) { + divisions = append(divisions, append(inner, index-1)) + } + } else { + divisions = append(divisions, []int{index - 1}) + } + } + + return divisions +} + +// generate a grid of nodes from the given cut indices +func genLayout(nodes []*d2graph.Object, cutIndices []int) [][]*d2graph.Object { + layout := make([][]*d2graph.Object, len(cutIndices)+1) + nodeIndex := 0 + for i := 0; i <= len(cutIndices); i++ { + var stop int + if i < len(cutIndices) { + stop = cutIndices[i] + } else { + stop = len(nodes) - 1 + } + for ; nodeIndex <= stop; nodeIndex++ { + layout[i] = append(layout[i], nodes[nodeIndex]) + } + } + return layout +} + +func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, columns bool) float64 { + totalDelta := 0. + for _, row := range layout { + rowSize := 0. + for _, n := range row { + if columns { + rowSize += n.Height + VERTICAL_PAD + } else { + rowSize += n.Width + HORIZONTAL_PAD + } + } + totalDelta += math.Abs(rowSize - targetSize) + } + 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 From 8b3ba86da338044f023917af5885b2b132b25480 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 5 Apr 2023 20:03:07 -0700 Subject: [PATCH 29/33] update test --- .../stable/grid_tests/dagre/board.exp.json | 108 ++++++------ .../stable/grid_tests/dagre/sketch.exp.svg | 160 +++++++++--------- .../stable/grid_tests/elk/board.exp.json | 108 ++++++------ .../stable/grid_tests/elk/sketch.exp.svg | 160 +++++++++--------- 4 files changed, 268 insertions(+), 268 deletions(-) diff --git a/e2etests/testdata/stable/grid_tests/dagre/board.exp.json b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json index a82de5acf..15c3df149 100644 --- a/e2etests/testdata/stable/grid_tests/dagre/board.exp.json +++ b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json @@ -2632,10 +2632,10 @@ "type": "rectangle", "pos": { "x": 3548, - "y": 159 + "y": 212 }, - "width": 267, - "height": 504, + "width": 359, + "height": 398, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -2673,7 +2673,7 @@ "type": "rectangle", "pos": { "x": 3608, - "y": 219 + "y": 272 }, "width": 53, "height": 66, @@ -2714,7 +2714,7 @@ "type": "rectangle", "pos": { "x": 3701, - "y": 219 + "y": 272 }, "width": 53, "height": 66, @@ -2754,8 +2754,8 @@ "id": "rows 3.c", "type": "rectangle", "pos": { - "x": 3608, - "y": 325 + "x": 3794, + "y": 272 }, "width": 53, "height": 66, @@ -2795,10 +2795,10 @@ "id": "rows 3.d", "type": "rectangle", "pos": { - "x": 3701, - "y": 325 + "x": 3608, + "y": 378 }, - "width": 54, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2836,10 +2836,10 @@ "id": "rows 3.e", "type": "rectangle", "pos": { - "x": 3608, - "y": 431 + "x": 3747, + "y": 378 }, - "width": 53, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2877,10 +2877,10 @@ "id": "rows 3.f", "type": "rectangle", "pos": { - "x": 3701, - "y": 431 + "x": 3608, + "y": 484 }, - "width": 53, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2918,10 +2918,10 @@ "id": "rows 3.g", "type": "rectangle", "pos": { - "x": 3608, - "y": 537 + "x": 3747, + "y": 484 }, - "width": 147, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2959,11 +2959,11 @@ "id": "columns 3", "type": "rectangle", "pos": { - "x": 3875, - "y": 265 + "x": 3967, + "y": 212 }, - "width": 454, - "height": 292, + "width": 361, + "height": 398, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3000,8 +3000,8 @@ "id": "columns 3.a", "type": "rectangle", "pos": { - "x": 3935, - "y": 325 + "x": 4027, + "y": 272 }, "width": 53, "height": 66, @@ -3041,8 +3041,8 @@ "id": "columns 3.b", "type": "rectangle", "pos": { - "x": 3935, - "y": 431 + "x": 4027, + "y": 378 }, "width": 53, "height": 66, @@ -3082,10 +3082,10 @@ "id": "columns 3.c", "type": "rectangle", "pos": { - "x": 4028, - "y": 325 + "x": 4027, + "y": 484 }, - "width": 54, + "width": 53, "height": 66, "opacity": 1, "strokeDash": 0, @@ -3123,11 +3123,11 @@ "id": "columns 3.d", "type": "rectangle", "pos": { - "x": 4028, - "y": 431 + "x": 4120, + "y": 272 }, "width": 54, - "height": 66, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3164,11 +3164,11 @@ "id": "columns 3.e", "type": "rectangle", "pos": { - "x": 4122, - "y": 325 + "x": 4120, + "y": 431 }, - "width": 53, - "height": 66, + "width": 54, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3205,11 +3205,11 @@ "id": "columns 3.f", "type": "rectangle", "pos": { - "x": 4122, - "y": 431 + "x": 4214, + "y": 272 }, - "width": 53, - "height": 66, + "width": 54, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3246,11 +3246,11 @@ "id": "columns 3.g", "type": "rectangle", "pos": { - "x": 4215, - "y": 325 + "x": 4214, + "y": 431 }, "width": 54, - "height": 172, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3287,7 +3287,7 @@ "id": "widths heights", "type": "rectangle", "pos": { - "x": 4389, + "x": 4388, "y": 28 }, "width": 886, @@ -3328,7 +3328,7 @@ "id": "widths heights.a w200", "type": "rectangle", "pos": { - "x": 4449, + "x": 4448, "y": 88 }, "width": 200, @@ -3369,7 +3369,7 @@ "id": "widths heights.b h300", "type": "rectangle", "pos": { - "x": 4689, + "x": 4688, "y": 88 }, "width": 86, @@ -3410,7 +3410,7 @@ "id": "widths heights.c", "type": "rectangle", "pos": { - "x": 4815, + "x": 4814, "y": 88 }, "width": 400, @@ -3451,7 +3451,7 @@ "id": "widths heights.d h200", "type": "rectangle", "pos": { - "x": 4449, + "x": 4448, "y": 428 }, "width": 200, @@ -3492,7 +3492,7 @@ "id": "widths heights.e", "type": "rectangle", "pos": { - "x": 4689, + "x": 4688, "y": 428 }, "width": 86, @@ -3533,7 +3533,7 @@ "id": "widths heights.f w400", "type": "rectangle", "pos": { - "x": 4815, + "x": 4814, "y": 428 }, "width": 400, @@ -3574,7 +3574,7 @@ "id": "widths heights.g", "type": "rectangle", "pos": { - "x": 4449, + "x": 4448, "y": 668 }, "width": 200, @@ -3615,7 +3615,7 @@ "id": "widths heights.h", "type": "rectangle", "pos": { - "x": 4689, + "x": 4688, "y": 668 }, "width": 86, @@ -3656,7 +3656,7 @@ "id": "widths heights.i", "type": "rectangle", "pos": { - "x": 4815, + "x": 4814, "y": 668 }, "width": 400, diff --git a/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg index 43be0cd45..4f6c4484f 100644 --- a/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi - + .d2-161667186 .fill-N1{fill:#0A0F25;} + .d2-161667186 .fill-N2{fill:#676C7E;} + .d2-161667186 .fill-N3{fill:#9499AB;} + .d2-161667186 .fill-N4{fill:#CFD2DD;} + .d2-161667186 .fill-N5{fill:#DEE1EB;} + .d2-161667186 .fill-N6{fill:#EEF1F8;} + .d2-161667186 .fill-N7{fill:#FFFFFF;} + .d2-161667186 .fill-B1{fill:#0D32B2;} + .d2-161667186 .fill-B2{fill:#0D32B2;} + .d2-161667186 .fill-B3{fill:#E3E9FD;} + .d2-161667186 .fill-B4{fill:#E3E9FD;} + .d2-161667186 .fill-B5{fill:#EDF0FD;} + .d2-161667186 .fill-B6{fill:#F7F8FE;} + .d2-161667186 .fill-AA2{fill:#4A6FF3;} + .d2-161667186 .fill-AA4{fill:#EDF0FD;} + .d2-161667186 .fill-AA5{fill:#F7F8FE;} + .d2-161667186 .fill-AB4{fill:#EDF0FD;} + .d2-161667186 .fill-AB5{fill:#F7F8FE;} + .d2-161667186 .stroke-N1{stroke:#0A0F25;} + .d2-161667186 .stroke-N2{stroke:#676C7E;} + .d2-161667186 .stroke-N3{stroke:#9499AB;} + .d2-161667186 .stroke-N4{stroke:#CFD2DD;} + .d2-161667186 .stroke-N5{stroke:#DEE1EB;} + .d2-161667186 .stroke-N6{stroke:#EEF1F8;} + .d2-161667186 .stroke-N7{stroke:#FFFFFF;} + .d2-161667186 .stroke-B1{stroke:#0D32B2;} + .d2-161667186 .stroke-B2{stroke:#0D32B2;} + .d2-161667186 .stroke-B3{stroke:#E3E9FD;} + .d2-161667186 .stroke-B4{stroke:#E3E9FD;} + .d2-161667186 .stroke-B5{stroke:#EDF0FD;} + .d2-161667186 .stroke-B6{stroke:#F7F8FE;} + .d2-161667186 .stroke-AA2{stroke:#4A6FF3;} + .d2-161667186 .stroke-AA4{stroke:#EDF0FD;} + .d2-161667186 .stroke-AA5{stroke:#F7F8FE;} + .d2-161667186 .stroke-AB4{stroke:#EDF0FD;} + .d2-161667186 .stroke-AB5{stroke:#F7F8FE;} + .d2-161667186 .background-color-N1{background-color:#0A0F25;} + .d2-161667186 .background-color-N2{background-color:#676C7E;} + .d2-161667186 .background-color-N3{background-color:#9499AB;} + .d2-161667186 .background-color-N4{background-color:#CFD2DD;} + .d2-161667186 .background-color-N5{background-color:#DEE1EB;} + .d2-161667186 .background-color-N6{background-color:#EEF1F8;} + .d2-161667186 .background-color-N7{background-color:#FFFFFF;} + .d2-161667186 .background-color-B1{background-color:#0D32B2;} + .d2-161667186 .background-color-B2{background-color:#0D32B2;} + .d2-161667186 .background-color-B3{background-color:#E3E9FD;} + .d2-161667186 .background-color-B4{background-color:#E3E9FD;} + .d2-161667186 .background-color-B5{background-color:#EDF0FD;} + .d2-161667186 .background-color-B6{background-color:#F7F8FE;} + .d2-161667186 .background-color-AA2{background-color:#4A6FF3;} + .d2-161667186 .background-color-AA4{background-color:#EDF0FD;} + .d2-161667186 .background-color-AA5{background-color:#F7F8FE;} + .d2-161667186 .background-color-AB4{background-color:#EDF0FD;} + .d2-161667186 .background-color-AB5{background-color:#F7F8FE;} + .d2-161667186 .color-N1{color:#0A0F25;} + .d2-161667186 .color-N2{color:#676C7E;} + .d2-161667186 .color-N3{color:#9499AB;} + .d2-161667186 .color-N4{color:#CFD2DD;} + .d2-161667186 .color-N5{color:#DEE1EB;} + .d2-161667186 .color-N6{color:#EEF1F8;} + .d2-161667186 .color-N7{color:#FFFFFF;} + .d2-161667186 .color-B1{color:#0D32B2;} + .d2-161667186 .color-B2{color:#0D32B2;} + .d2-161667186 .color-B3{color:#E3E9FD;} + .d2-161667186 .color-B4{color:#E3E9FD;} + .d2-161667186 .color-B5{color:#EDF0FD;} + .d2-161667186 .color-B6{color:#F7F8FE;} + .d2-161667186 .color-AA2{color:#4A6FF3;} + .d2-161667186 .color-AA4{color:#EDF0FD;} + .d2-161667186 .color-AA5{color:#F7F8FE;} + .d2-161667186 .color-AB4{color:#EDF0FD;} + .d2-161667186 .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}]]>rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi + \ No newline at end of file diff --git a/e2etests/testdata/stable/grid_tests/elk/board.exp.json b/e2etests/testdata/stable/grid_tests/elk/board.exp.json index bb7e1930e..95b4c1c12 100644 --- a/e2etests/testdata/stable/grid_tests/elk/board.exp.json +++ b/e2etests/testdata/stable/grid_tests/elk/board.exp.json @@ -2632,10 +2632,10 @@ "type": "rectangle", "pos": { "x": 3240, - "y": 171 + "y": 224 }, - "width": 267, - "height": 504, + "width": 359, + "height": 398, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -2673,7 +2673,7 @@ "type": "rectangle", "pos": { "x": 3300, - "y": 231 + "y": 284 }, "width": 53, "height": 66, @@ -2714,7 +2714,7 @@ "type": "rectangle", "pos": { "x": 3393, - "y": 231 + "y": 284 }, "width": 53, "height": 66, @@ -2754,8 +2754,8 @@ "id": "rows 3.c", "type": "rectangle", "pos": { - "x": 3300, - "y": 337 + "x": 3486, + "y": 284 }, "width": 53, "height": 66, @@ -2795,10 +2795,10 @@ "id": "rows 3.d", "type": "rectangle", "pos": { - "x": 3393, - "y": 337 + "x": 3300, + "y": 390 }, - "width": 54, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2836,10 +2836,10 @@ "id": "rows 3.e", "type": "rectangle", "pos": { - "x": 3300, - "y": 443 + "x": 3439, + "y": 390 }, - "width": 53, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2877,10 +2877,10 @@ "id": "rows 3.f", "type": "rectangle", "pos": { - "x": 3393, - "y": 443 + "x": 3300, + "y": 496 }, - "width": 53, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2918,10 +2918,10 @@ "id": "rows 3.g", "type": "rectangle", "pos": { - "x": 3300, - "y": 549 + "x": 3439, + "y": 496 }, - "width": 147, + "width": 99, "height": 66, "opacity": 1, "strokeDash": 0, @@ -2959,11 +2959,11 @@ "id": "columns 3", "type": "rectangle", "pos": { - "x": 3527, - "y": 277 + "x": 3619, + "y": 224 }, - "width": 454, - "height": 292, + "width": 361, + "height": 398, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3000,8 +3000,8 @@ "id": "columns 3.a", "type": "rectangle", "pos": { - "x": 3587, - "y": 337 + "x": 3679, + "y": 284 }, "width": 53, "height": 66, @@ -3041,8 +3041,8 @@ "id": "columns 3.b", "type": "rectangle", "pos": { - "x": 3587, - "y": 443 + "x": 3679, + "y": 390 }, "width": 53, "height": 66, @@ -3082,10 +3082,10 @@ "id": "columns 3.c", "type": "rectangle", "pos": { - "x": 3680, - "y": 337 + "x": 3679, + "y": 496 }, - "width": 54, + "width": 53, "height": 66, "opacity": 1, "strokeDash": 0, @@ -3123,11 +3123,11 @@ "id": "columns 3.d", "type": "rectangle", "pos": { - "x": 3680, - "y": 443 + "x": 3772, + "y": 284 }, "width": 54, - "height": 66, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3164,11 +3164,11 @@ "id": "columns 3.e", "type": "rectangle", "pos": { - "x": 3774, - "y": 337 + "x": 3772, + "y": 443 }, - "width": 53, - "height": 66, + "width": 54, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3205,11 +3205,11 @@ "id": "columns 3.f", "type": "rectangle", "pos": { - "x": 3774, - "y": 443 + "x": 3866, + "y": 284 }, - "width": 53, - "height": 66, + "width": 54, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3246,11 +3246,11 @@ "id": "columns 3.g", "type": "rectangle", "pos": { - "x": 3867, - "y": 337 + "x": 3866, + "y": 443 }, "width": 54, - "height": 172, + "height": 119, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -3287,7 +3287,7 @@ "id": "widths heights", "type": "rectangle", "pos": { - "x": 4001, + "x": 4000, "y": 40 }, "width": 886, @@ -3328,7 +3328,7 @@ "id": "widths heights.a w200", "type": "rectangle", "pos": { - "x": 4061, + "x": 4060, "y": 100 }, "width": 200, @@ -3369,7 +3369,7 @@ "id": "widths heights.b h300", "type": "rectangle", "pos": { - "x": 4301, + "x": 4300, "y": 100 }, "width": 86, @@ -3410,7 +3410,7 @@ "id": "widths heights.c", "type": "rectangle", "pos": { - "x": 4427, + "x": 4426, "y": 100 }, "width": 400, @@ -3451,7 +3451,7 @@ "id": "widths heights.d h200", "type": "rectangle", "pos": { - "x": 4061, + "x": 4060, "y": 440 }, "width": 200, @@ -3492,7 +3492,7 @@ "id": "widths heights.e", "type": "rectangle", "pos": { - "x": 4301, + "x": 4300, "y": 440 }, "width": 86, @@ -3533,7 +3533,7 @@ "id": "widths heights.f w400", "type": "rectangle", "pos": { - "x": 4427, + "x": 4426, "y": 440 }, "width": 400, @@ -3574,7 +3574,7 @@ "id": "widths heights.g", "type": "rectangle", "pos": { - "x": 4061, + "x": 4060, "y": 680 }, "width": 200, @@ -3615,7 +3615,7 @@ "id": "widths heights.h", "type": "rectangle", "pos": { - "x": 4301, + "x": 4300, "y": 680 }, "width": 86, @@ -3656,7 +3656,7 @@ "id": "widths heights.i", "type": "rectangle", "pos": { - "x": 4427, + "x": 4426, "y": 680 }, "width": 400, diff --git a/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg index bfcf25d48..f85853334 100644 --- a/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi - + .d2-1021052366 .fill-N1{fill:#0A0F25;} + .d2-1021052366 .fill-N2{fill:#676C7E;} + .d2-1021052366 .fill-N3{fill:#9499AB;} + .d2-1021052366 .fill-N4{fill:#CFD2DD;} + .d2-1021052366 .fill-N5{fill:#DEE1EB;} + .d2-1021052366 .fill-N6{fill:#EEF1F8;} + .d2-1021052366 .fill-N7{fill:#FFFFFF;} + .d2-1021052366 .fill-B1{fill:#0D32B2;} + .d2-1021052366 .fill-B2{fill:#0D32B2;} + .d2-1021052366 .fill-B3{fill:#E3E9FD;} + .d2-1021052366 .fill-B4{fill:#E3E9FD;} + .d2-1021052366 .fill-B5{fill:#EDF0FD;} + .d2-1021052366 .fill-B6{fill:#F7F8FE;} + .d2-1021052366 .fill-AA2{fill:#4A6FF3;} + .d2-1021052366 .fill-AA4{fill:#EDF0FD;} + .d2-1021052366 .fill-AA5{fill:#F7F8FE;} + .d2-1021052366 .fill-AB4{fill:#EDF0FD;} + .d2-1021052366 .fill-AB5{fill:#F7F8FE;} + .d2-1021052366 .stroke-N1{stroke:#0A0F25;} + .d2-1021052366 .stroke-N2{stroke:#676C7E;} + .d2-1021052366 .stroke-N3{stroke:#9499AB;} + .d2-1021052366 .stroke-N4{stroke:#CFD2DD;} + .d2-1021052366 .stroke-N5{stroke:#DEE1EB;} + .d2-1021052366 .stroke-N6{stroke:#EEF1F8;} + .d2-1021052366 .stroke-N7{stroke:#FFFFFF;} + .d2-1021052366 .stroke-B1{stroke:#0D32B2;} + .d2-1021052366 .stroke-B2{stroke:#0D32B2;} + .d2-1021052366 .stroke-B3{stroke:#E3E9FD;} + .d2-1021052366 .stroke-B4{stroke:#E3E9FD;} + .d2-1021052366 .stroke-B5{stroke:#EDF0FD;} + .d2-1021052366 .stroke-B6{stroke:#F7F8FE;} + .d2-1021052366 .stroke-AA2{stroke:#4A6FF3;} + .d2-1021052366 .stroke-AA4{stroke:#EDF0FD;} + .d2-1021052366 .stroke-AA5{stroke:#F7F8FE;} + .d2-1021052366 .stroke-AB4{stroke:#EDF0FD;} + .d2-1021052366 .stroke-AB5{stroke:#F7F8FE;} + .d2-1021052366 .background-color-N1{background-color:#0A0F25;} + .d2-1021052366 .background-color-N2{background-color:#676C7E;} + .d2-1021052366 .background-color-N3{background-color:#9499AB;} + .d2-1021052366 .background-color-N4{background-color:#CFD2DD;} + .d2-1021052366 .background-color-N5{background-color:#DEE1EB;} + .d2-1021052366 .background-color-N6{background-color:#EEF1F8;} + .d2-1021052366 .background-color-N7{background-color:#FFFFFF;} + .d2-1021052366 .background-color-B1{background-color:#0D32B2;} + .d2-1021052366 .background-color-B2{background-color:#0D32B2;} + .d2-1021052366 .background-color-B3{background-color:#E3E9FD;} + .d2-1021052366 .background-color-B4{background-color:#E3E9FD;} + .d2-1021052366 .background-color-B5{background-color:#EDF0FD;} + .d2-1021052366 .background-color-B6{background-color:#F7F8FE;} + .d2-1021052366 .background-color-AA2{background-color:#4A6FF3;} + .d2-1021052366 .background-color-AA4{background-color:#EDF0FD;} + .d2-1021052366 .background-color-AA5{background-color:#F7F8FE;} + .d2-1021052366 .background-color-AB4{background-color:#EDF0FD;} + .d2-1021052366 .background-color-AB5{background-color:#F7F8FE;} + .d2-1021052366 .color-N1{color:#0A0F25;} + .d2-1021052366 .color-N2{color:#676C7E;} + .d2-1021052366 .color-N3{color:#9499AB;} + .d2-1021052366 .color-N4{color:#CFD2DD;} + .d2-1021052366 .color-N5{color:#DEE1EB;} + .d2-1021052366 .color-N6{color:#EEF1F8;} + .d2-1021052366 .color-N7{color:#FFFFFF;} + .d2-1021052366 .color-B1{color:#0D32B2;} + .d2-1021052366 .color-B2{color:#0D32B2;} + .d2-1021052366 .color-B3{color:#E3E9FD;} + .d2-1021052366 .color-B4{color:#E3E9FD;} + .d2-1021052366 .color-B5{color:#EDF0FD;} + .d2-1021052366 .color-B6{color:#F7F8FE;} + .d2-1021052366 .color-AA2{color:#4A6FF3;} + .d2-1021052366 .color-AA4{color:#EDF0FD;} + .d2-1021052366 .color-AA5{color:#F7F8FE;} + .d2-1021052366 .color-AB4{color:#EDF0FD;} + .d2-1021052366 .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}]]>rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi + \ No newline at end of file From bab54b4030ba90f23fb339cd126305b651b71b38 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 6 Apr 2023 14:30:45 -0700 Subject: [PATCH 30/33] cleanup --- d2layouts/d2grid/grid_diagram.go | 45 +++--- d2layouts/d2grid/layout.go | 230 +++++++++++++++---------------- 2 files changed, 140 insertions(+), 135 deletions(-) diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index c26a6e917..6b4d8dfb3 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -8,18 +8,20 @@ import ( type gridDiagram struct { root *d2graph.Object - nodes []*d2graph.Object + objects []*d2graph.Object rows int columns int - rowDominant bool + // if true, place objects left to right along rows + // if false, place objects top to bottom along columns + rowDirected bool width float64 height float64 } func newGridDiagram(root *d2graph.Object) *gridDiagram { - gd := gridDiagram{root: root, nodes: root.ChildrenArray} + gd := gridDiagram{root: root, objects: root.ChildrenArray} if root.Attributes.Rows != nil { gd.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) } @@ -27,30 +29,31 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { gd.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) } - // compute exact row/column count based on values entered - if gd.columns == 0 { - gd.rowDominant = true - } else if gd.rows == 0 { - gd.rowDominant = false - } else { - // if keyword rows is first, rows are primary, columns secondary. + if gd.rows != 0 && gd.columns != 0 { + // . row-directed column-directed + // . ┌───────┐ ┌───────┐ + // . │ a b c │ │ a d g │ + // . │ d e f │ │ b e h │ + // . │ g h i │ │ c f i │ + // . └───────┘ └───────┘ + // if keyword rows is first, make it row-directed, if columns is first it is column-directed if root.Attributes.Rows.MapKey.Range.Before(root.Attributes.Columns.MapKey.Range) { - gd.rowDominant = true + gd.rowDirected = true } - // rows and columns specified, but we want to continue naturally if user enters more nodes - // e.g. 2 rows, 3 columns specified + g node added: │ with 3 columns, 2 rows: + // rows and columns specified, but we want to continue naturally if user enters more objects + // e.g. 2 rows, 3 columns specified + g added: │ with 3 columns, 2 rows: // . original add row add column │ original add row add column // . ┌───────┐ ┌───────┐ ┌─────────┐ │ ┌───────┐ ┌───────┐ ┌─────────┐ // . │ a b c │ │ a b c │ │ a b c d │ │ │ a c e │ │ a d g │ │ a c e g │ // . │ d e f │ │ d e f │ │ e f g │ │ │ b d f │ │ b e │ │ b d f │ // . └───────┘ │ g │ └─────────┘ │ └───────┘ │ c f │ └─────────┘ // . └───────┘ ▲ │ └───────┘ ▲ - // . ▲ └─existing nodes modified │ ▲ └─existing nodes preserved - // . └─existing rows preserved │ └─existing rows modified + // . ▲ └─existing objects modified│ ▲ └─existing columns preserved + // . └─existing rows preserved │ └─existing objects modified capacity := gd.rows * gd.columns - for capacity < len(gd.nodes) { - if gd.rowDominant { + for capacity < len(gd.objects) { + if gd.rowDirected { gd.rows++ capacity += gd.columns } else { @@ -58,13 +61,15 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { capacity += gd.rows } } + } else if gd.columns == 0 { + gd.rowDirected = true } return &gd } func (gd *gridDiagram) shift(dx, dy float64) { - for _, obj := range gd.nodes { + for _, obj := range gd.objects { obj.TopLeft.X += dx obj.TopLeft.Y += dy } @@ -73,9 +78,9 @@ func (gd *gridDiagram) shift(dx, dy float64) { func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) { obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = make([]*d2graph.Object, 0) - for _, child := range gd.nodes { + for _, child := range gd.objects { obj.Children[child.ID] = child obj.ChildrenArray = append(obj.ChildrenArray, child) } - graph.Objects = append(graph.Objects, gd.nodes...) + graph.Objects = append(graph.Objects, gd.objects...) } diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index bdfab8f98..1edae9066 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -94,8 +94,8 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams ma obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) gridDiagrams[obj.AbsID()] = gd - for _, node := range gd.nodes { - toRemove[node] = struct{}{} + for _, o := range gd.objects { + toRemove[o] = struct{}{} } } } @@ -123,12 +123,12 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) { } // position labels and icons - for _, n := range gd.nodes { - if n.Attributes.Icon != nil { - n.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - n.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) + for _, o := range gd.objects { + if o.Attributes.Icon != nil { + o.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + o.IconPosition = go2.Pointer(string(label.InsideMiddleCenter)) } else { - n.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) + o.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) } } @@ -136,19 +136,19 @@ func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) { } func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { - // layout nodes in a grid with these 2 properties: - // all nodes in the same row should have the same height - // all nodes in the same column should have the same width + // layout objects in a grid with these 2 properties: + // all objects in the same row should have the same height + // all objects in the same column should have the same width - getNode := func(rowIndex, columnIndex int) *d2graph.Object { + getObject := func(rowIndex, columnIndex int) *d2graph.Object { var index int - if gd.rowDominant { + if gd.rowDirected { index = rowIndex*gd.columns + columnIndex } else { index = columnIndex*gd.rows + rowIndex } - if index < len(gd.nodes) { - return gd.nodes[index] + if index < len(gd.objects) { + return gd.objects[index] } return nil } @@ -158,38 +158,38 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { for i := 0; i < gd.rows; i++ { rowHeight := 0. for j := 0; j < gd.columns; j++ { - n := getNode(i, j) - if n == nil { + o := getObject(i, j) + if o == nil { break } - rowHeight = math.Max(rowHeight, n.Height) + rowHeight = math.Max(rowHeight, o.Height) } rowHeights = append(rowHeights, rowHeight) } for j := 0; j < gd.columns; j++ { columnWidth := 0. for i := 0; i < gd.rows; i++ { - n := getNode(i, j) - if n == nil { + o := getObject(i, j) + if o == nil { break } - columnWidth = math.Max(columnWidth, n.Width) + columnWidth = math.Max(columnWidth, o.Width) } colWidths = append(colWidths, columnWidth) } cursor := geo.NewPoint(0, 0) - if gd.rowDominant { + if gd.rowDirected { for i := 0; i < gd.rows; i++ { for j := 0; j < gd.columns; j++ { - n := getNode(i, j) - if n == nil { + o := getObject(i, j) + if o == nil { break } - n.Width = colWidths[j] - n.Height = rowHeights[i] - n.TopLeft = cursor.Copy() - cursor.X += n.Width + HORIZONTAL_PAD + o.Width = colWidths[j] + o.Height = rowHeights[i] + o.TopLeft = cursor.Copy() + cursor.X += o.Width + HORIZONTAL_PAD } cursor.X = 0 cursor.Y += rowHeights[i] + VERTICAL_PAD @@ -197,14 +197,14 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { } else { for j := 0; j < gd.columns; j++ { for i := 0; i < gd.rows; i++ { - n := getNode(i, j) - if n == nil { + o := getObject(i, j) + if o == nil { break } - n.Width = colWidths[j] - n.Height = rowHeights[i] - n.TopLeft = cursor.Copy() - cursor.Y += n.Height + VERTICAL_PAD + o.Width = colWidths[j] + o.Height = rowHeights[i] + o.TopLeft = cursor.Copy() + cursor.Y += o.Height + VERTICAL_PAD } cursor.X += colWidths[j] + HORIZONTAL_PAD cursor.Y = 0 @@ -225,14 +225,14 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { } func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { - // assume we have the following nodes to layout: + // assume we have the following objects to layout: // . ┌A──────────────┐ ┌B──┐ ┌C─────────┐ ┌D────────┐ ┌E────────────────┐ // . └───────────────┘ │ │ │ │ │ │ │ │ // . │ │ └──────────┘ │ │ │ │ // . │ │ │ │ └─────────────────┘ // . └───┘ │ │ // . └─────────┘ - // Note: if the grid is row dominant, all nodes should be the same height (same width if column dominant) + // Note: if the grid is row dominant, all objects should be the same height (same width if column dominant) // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┌D────────┐ ┌E────────────────┐ // . ├ ─ ─ ─ ─ ─ ─ ─┤ │ │ │ │ │ │ │ │ // . │ │ │ │ ├ ─ ─ ─ ─ ─┤ │ │ │ │ @@ -242,15 +242,15 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // we want to split up the total width across the N rows or columns as evenly as possible var totalWidth, totalHeight float64 - for _, n := range gd.nodes { - totalWidth += n.Width - totalHeight += n.Height + for _, o := range gd.objects { + totalWidth += o.Width + totalHeight += o.Height } - totalWidth += HORIZONTAL_PAD * float64(len(gd.nodes)-gd.rows) - totalHeight += VERTICAL_PAD * float64(len(gd.nodes)-gd.columns) + totalWidth += HORIZONTAL_PAD * float64(len(gd.objects)-gd.rows) + totalHeight += VERTICAL_PAD * float64(len(gd.objects)-gd.columns) var layout [][]*d2graph.Object - if gd.rowDominant { + if gd.rowDirected { targetWidth := totalWidth / float64(gd.rows) layout = gd.getBestLayout(targetWidth, false) } else { @@ -260,8 +260,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { cursor := geo.NewPoint(0, 0) var maxY, maxX float64 - if gd.rowDominant { - // if we have 2 rows, then each row's nodes should have the same height + if gd.rowDirected { + // if we have 2 rows, then each row's objects should have the same height // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) // . ├ ─ ─ ─ ─ ─ ─ ─┤ │ │ │ │ │ // . │ │ │ │ ├ ─ ─ ─ ─ ─┤ │ @@ -276,18 +276,18 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowWidths := []float64{} for _, row := range layout { rowHeight := 0. - for _, n := range row { - n.TopLeft = cursor.Copy() - cursor.X += n.Width + HORIZONTAL_PAD - rowHeight = math.Max(rowHeight, n.Height) + for _, o := range row { + o.TopLeft = cursor.Copy() + cursor.X += o.Width + HORIZONTAL_PAD + rowHeight = math.Max(rowHeight, o.Height) } rowWidth := cursor.X - HORIZONTAL_PAD rowWidths = append(rowWidths, rowWidth) maxX = math.Max(maxX, rowWidth) - // set all nodes in row to the same height - for _, n := range row { - n.Height = rowHeight + // set all objects in row to the same height + for _, o := range row { + o.Height = rowHeight } // new row @@ -296,7 +296,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { } maxY = cursor.Y - VERTICAL_PAD - // then expand thinnest nodes to make each row the same width + // then expand thinnest objects to make each row the same width // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) // . │ │ │ │ │ │ │ // . │ │ │ │ │ │ │ @@ -314,28 +314,28 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { continue } delta := maxX - rowWidth - nodes := []*d2graph.Object{} + objects := []*d2graph.Object{} var widest float64 - for _, n := range row { - widest = math.Max(widest, n.Width) - nodes = append(nodes, n) + for _, o := range row { + widest = math.Max(widest, o.Width) + objects = append(objects, o) } - sort.Slice(nodes, func(i, j int) bool { - return nodes[i].Width < nodes[j].Width + sort.Slice(objects, func(i, j int) bool { + return objects[i].Width < objects[j].Width }) - // expand smaller nodes to fill remaining space - for _, n := range nodes { - if n.Width < widest { + // expand smaller objects to fill remaining space + for _, o := range objects { + if o.Width < widest { var index int - for i, node := range row { - if n == node { + for i, rowObj := range row { + if o == rowObj { index = i break } } - grow := math.Min(widest-n.Width, delta) - n.Width += grow - // shift following nodes + grow := math.Min(widest-o.Width, delta) + o.Width += grow + // shift following objects for i := index + 1; i < len(row); i++ { row[i].TopLeft.X += grow } @@ -348,15 +348,15 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if delta > 0 { grow := delta / float64(len(row)) for i := len(row) - 1; i >= 0; i-- { - n := row[i] - n.TopLeft.X += grow * float64(i) - n.Width += grow + o := row[i] + o.TopLeft.X += grow * float64(i) + o.Width += grow delta -= grow } } } } else { - // if we have 3 columns, then each column's nodes should have the same width + // if we have 3 columns, then each column's objects should have the same width // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ // . └──────────────┘ │ │ │ │ @@ -370,17 +370,17 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colHeights := []float64{} for _, column := range layout { colWidth := 0. - for _, n := range column { - n.TopLeft = cursor.Copy() - cursor.Y += n.Height + VERTICAL_PAD - colWidth = math.Max(colWidth, n.Width) + for _, o := range column { + o.TopLeft = cursor.Copy() + cursor.Y += o.Height + VERTICAL_PAD + colWidth = math.Max(colWidth, o.Width) } colHeight := cursor.Y - VERTICAL_PAD colHeights = append(colHeights, colHeight) maxY = math.Max(maxY, colHeight) - // set all nodes in column to the same width - for _, n := range column { - n.Width = colWidth + // set all objects in column to the same width + for _, o := range column { + o.Width = colWidth } // new column @@ -388,7 +388,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { cursor.X += colWidth + HORIZONTAL_PAD } maxX = cursor.X - HORIZONTAL_PAD - // then expand shortest nodes to make each column the same height + // then expand shortest objects to make each column the same height // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ // . ├ ─ ─ ─ ─ ─ ─ ┤ │ │ │ │ @@ -405,28 +405,28 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { continue } delta := maxY - colHeight - nodes := []*d2graph.Object{} + objects := []*d2graph.Object{} var tallest float64 - for _, n := range column { - tallest = math.Max(tallest, n.Height) - nodes = append(nodes, n) + for _, o := range column { + tallest = math.Max(tallest, o.Height) + objects = append(objects, o) } - sort.Slice(nodes, func(i, j int) bool { - return nodes[i].Height < nodes[j].Height + sort.Slice(objects, func(i, j int) bool { + return objects[i].Height < objects[j].Height }) - // expand smaller nodes to fill remaining space - for _, n := range nodes { - if n.Height < tallest { + // expand smaller objects to fill remaining space + for _, o := range objects { + if o.Height < tallest { var index int - for i, node := range column { - if n == node { + for i, colObj := range column { + if o == colObj { index = i break } } - grow := math.Min(tallest-n.Height, delta) - n.Height += grow - // shift following nodes + grow := math.Min(tallest-o.Height, delta) + o.Height += grow + // shift following objects for i := index + 1; i < len(column); i++ { column[i].TopLeft.Y += grow } @@ -439,9 +439,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { if delta > 0 { grow := delta / float64(len(column)) for i := len(column) - 1; i >= 0; i-- { - n := column[i] - n.TopLeft.Y += grow * float64(i) - n.Height += grow + o := column[i] + o.TopLeft.Y += grow * float64(i) + o.Height += grow delta -= grow } } @@ -451,7 +451,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { gd.height = maxY } -// generate the best layout of nodes aiming for each row to be the targetSize width +// generate the best layout of objects aiming for each row to be the targetSize width // if columns is true, each column aims to have the targetSize height func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2graph.Object { var nCuts int @@ -461,24 +461,24 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr nCuts = gd.rows - 1 } if nCuts == 0 { - return genLayout(gd.nodes, nil) + return genLayout(gd.objects, nil) } // get all options for where to place these cuts, preferring later cuts over earlier cuts - // with 5 nodes and 2 cuts we have these options: + // with 5 objects and 2 cuts we have these options: // . A B C │ D │ E <- these cuts would produce: ┌A─┐ ┌B─┐ ┌C─┐ // . A B │ C D │ E └──┘ └──┘ └──┘ // . A │ B C D │ E ┌D───────────┐ // . A B │ C │ D E └────────────┘ // . A │ B C │ D E ┌E───────────┐ // . A │ B │ C D E └────────────┘ - divisions := genDivisions(gd.nodes, nCuts) + divisions := genDivisions(gd.objects, nCuts) var bestLayout [][]*d2graph.Object bestDist := math.MaxFloat64 // of these divisions, find the layout with rows closest to the targetSize for _, division := range divisions { - layout := genLayout(gd.nodes, division) + layout := genLayout(gd.objects, division) dist := getDistToTarget(layout, targetSize, columns) if dist < bestDist { bestLayout = layout @@ -489,16 +489,16 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr return bestLayout } -// get all possible divisions of nodes by the number of cuts -func genDivisions(nodes []*d2graph.Object, nCuts int) (divisions [][]int) { - if len(nodes) < 2 || nCuts == 0 { +// get all possible divisions of objects by the number of cuts +func genDivisions(objects []*d2graph.Object, nCuts int) (divisions [][]int) { + if len(objects) < 2 || nCuts == 0 { return nil } - // we go in this order to prefer extra nodes in starting rows rather than later ones - lastNode := len(nodes) - 1 - for index := lastNode; index >= nCuts; index-- { + // we go in this order to prefer extra objects in starting rows rather than later ones + lastObj := len(objects) - 1 + for index := lastObj; index >= nCuts; index-- { if nCuts > 1 { - for _, inner := range genDivisions(nodes[:index], nCuts-1) { + for _, inner := range genDivisions(objects[:index], nCuts-1) { divisions = append(divisions, append(inner, index-1)) } } else { @@ -509,19 +509,19 @@ func genDivisions(nodes []*d2graph.Object, nCuts int) (divisions [][]int) { return divisions } -// generate a grid of nodes from the given cut indices -func genLayout(nodes []*d2graph.Object, cutIndices []int) [][]*d2graph.Object { +// generate a grid of objects from the given cut indices +func genLayout(objects []*d2graph.Object, cutIndices []int) [][]*d2graph.Object { layout := make([][]*d2graph.Object, len(cutIndices)+1) - nodeIndex := 0 + objIndex := 0 for i := 0; i <= len(cutIndices); i++ { var stop int if i < len(cutIndices) { stop = cutIndices[i] } else { - stop = len(nodes) - 1 + stop = len(objects) - 1 } - for ; nodeIndex <= stop; nodeIndex++ { - layout[i] = append(layout[i], nodes[nodeIndex]) + for ; objIndex <= stop; objIndex++ { + layout[i] = append(layout[i], objects[objIndex]) } } return layout @@ -531,11 +531,11 @@ func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, columns boo totalDelta := 0. for _, row := range layout { rowSize := 0. - for _, n := range row { + for _, o := range row { if columns { - rowSize += n.Height + VERTICAL_PAD + rowSize += o.Height + VERTICAL_PAD } else { - rowSize += n.Width + HORIZONTAL_PAD + rowSize += o.Width + HORIZONTAL_PAD } } totalDelta += math.Abs(rowSize - targetSize) From 37fc3ea8e0e8336a864f2c248f3e3d64af4467d3 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 6 Apr 2023 15:32:09 -0700 Subject: [PATCH 31/33] cleanup --- d2compiler/compile.go | 11 ++++++----- d2compiler/compile_test.go | 10 +++++----- d2graph/grid_diagram.go | 6 +++--- d2layouts/d2grid/grid_diagram.go | 3 ++- d2layouts/d2near/layout.go | 2 +- d2layouts/d2sequence/layout.go | 4 ++-- testdata/d2compiler/TestCompile/grid_edge.exp.json | 6 +++--- testdata/d2compiler/TestCompile/grid_nested.exp.json | 4 ++-- 8 files changed, 24 insertions(+), 22 deletions(-) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index c1a252440..07d450257 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -708,7 +708,8 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) { case "rows", "columns": for _, child := range obj.ChildrenArray { if child.IsContainer() { - c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid grid diagram %#v. can only set %#v with no descendants (see %#v)`, obj.AbsID(), keyword, child.ChildrenArray[0].AbsID())) + c.errorf(f.LastPrimaryKey(), + fmt.Sprintf(`%#v can only be used on containers with one level of nesting right now. (%#v has nested %#v)`, keyword, child.AbsID(), child.ChildrenArray[0].ID)) } } } @@ -796,12 +797,12 @@ func (c *compiler) validateNear(g *d2graph.Graph) { func (c *compiler) validateEdges(g *d2graph.Graph) { for _, edge := range g.Edges { - if gd := edge.Src.ClosestGridDiagram(); gd != nil { - c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid diagram %#v", d2format.Format(edge.GetAstEdge()), gd.AbsID()) + if gd := edge.Src.Parent.ClosestGridDiagram(); gd != nil { + c.errorf(edge.GetAstEdge(), "edges in grid diagrams are not supported yet") continue } - if gd := edge.Dst.ClosestGridDiagram(); gd != nil { - c.errorf(edge.GetAstEdge(), "edge %#v cannot enter grid diagram %#v", d2format.Format(edge.GetAstEdge()), gd.AbsID()) + if gd := edge.Dst.Parent.ClosestGridDiagram(); gd != nil { + c.errorf(edge.GetAstEdge(), "edges in grid diagrams are not supported yet") continue } } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index a031203ea..92d8fd41e 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2299,9 +2299,9 @@ obj { hey -> c: ok `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge "a -> b" cannot enter grid diagram "hey" -d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge "c -> hey.b" cannot enter grid diagram "hey" -d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot enter grid diagram "hey"`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edges in grid diagrams are not supported yet +d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edges in grid diagrams are not supported yet +d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are not supported yet`, }, { name: "grid_nested", @@ -2315,8 +2315,8 @@ d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge "hey.a -> c" cannot en d.invalid descendant } `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid diagram "hey". can only set "rows" with no descendants (see "hey.d.invalid descendant") -d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid diagram "hey". can only set "columns" with no descendants (see "hey.d.invalid descendant")`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: "rows" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant") +d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: "columns" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant")`, }, } diff --git a/d2graph/grid_diagram.go b/d2graph/grid_diagram.go index ec41e0460..9f1aff9e9 100644 --- a/d2graph/grid_diagram.go +++ b/d2graph/grid_diagram.go @@ -6,11 +6,11 @@ func (obj *Object) IsGridDiagram() bool { } func (obj *Object) ClosestGridDiagram() *Object { - if obj.Parent == nil { + if obj == nil { return nil } - if obj.Parent.IsGridDiagram() { - return obj.Parent + if obj.IsGridDiagram() { + return obj } return obj.Parent.ClosestGridDiagram() } diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index 6b4d8dfb3..bb68aad79 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -2,6 +2,7 @@ package d2grid import ( "strconv" + "strings" "oss.terrastruct.com/d2/d2graph" ) @@ -79,7 +80,7 @@ func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) { obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = make([]*d2graph.Object, 0) for _, child := range gd.objects { - obj.Children[child.ID] = child + obj.Children[strings.ToLower(child.ID)] = child obj.ChildrenArray = append(obj.ChildrenArray, child) } graph.Objects = append(graph.Objects, gd.objects...) diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 082a0e296..695fda827 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -34,7 +34,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNears []*d2graph.Obje if processCenters == strings.Contains(d2graph.Key(obj.Attributes.NearKey)[0], "-center") { // The z-index for constant nears does not matter, as it will not collide g.Objects = append(g.Objects, obj) - obj.Parent.Children[obj.ID] = obj + obj.Parent.Children[strings.ToLower(obj.ID)] = obj obj.Parent.ChildrenArray = append(obj.Parent.ChildrenArray, obj) } } diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index a2c7df0a5..0da870f19 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -171,12 +171,12 @@ func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, obj obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = make([]*d2graph.Object, 0) for _, child := range sd.actors { - obj.Children[child.ID] = child + 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[child.ID] = child + obj.Children[strings.ToLower(child.ID)] = child obj.ChildrenArray = append(obj.ChildrenArray, child) } } diff --git a/testdata/d2compiler/TestCompile/grid_edge.exp.json b/testdata/d2compiler/TestCompile/grid_edge.exp.json index dee805205..d8b36c51b 100644 --- a/testdata/d2compiler/TestCompile/grid_edge.exp.json +++ b/testdata/d2compiler/TestCompile/grid_edge.exp.json @@ -5,15 +5,15 @@ "errs": [ { "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,2:1:17-2:7:23", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edge \"a -> b\" cannot enter grid diagram \"hey\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edges in grid diagrams are not supported yet" }, { "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,4:1:27-4:11:37", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edge \"c -> hey.b\" cannot enter grid diagram \"hey\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edges in grid diagrams are not supported yet" }, { "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,5:1:39-5:11:49", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edge \"hey.a -> c\" cannot enter grid diagram \"hey\"" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are not supported yet" } ] } diff --git a/testdata/d2compiler/TestCompile/grid_nested.exp.json b/testdata/d2compiler/TestCompile/grid_nested.exp.json index a45781692..ff55b27e7 100644 --- a/testdata/d2compiler/TestCompile/grid_nested.exp.json +++ b/testdata/d2compiler/TestCompile/grid_nested.exp.json @@ -5,11 +5,11 @@ "errs": [ { "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,1:1:8-1:10:17", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: invalid grid diagram \"hey\". can only set \"rows\" with no descendants (see \"hey.d.invalid descendant\")" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: \"rows\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")" }, { "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,2:1:19-2:13:31", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: invalid grid diagram \"hey\". can only set \"columns\" with no descendants (see \"hey.d.invalid descendant\")" + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: \"columns\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")" } ] } From a75d4dd0b91ce8f86254f26866684e86bff225f6 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 6 Apr 2023 15:43:03 -0700 Subject: [PATCH 32/33] update keywords rows -> grid-rows --- d2compiler/compile.go | 26 +++++++------- d2compiler/compile_test.go | 22 ++++++------ d2graph/d2graph.go | 34 +++++++++---------- d2graph/grid_diagram.go | 2 +- d2layouts/d2grid/grid_diagram.go | 10 +++--- d2oracle/edit.go | 12 +++---- e2etests/testdata/files/dagger_grid.d2 | 2 +- e2etests/testdata/files/executive_grid.d2 | 2 +- e2etests/testdata/files/grid_tests.d2 | 32 ++++++++--------- e2etests/testdata/files/teleport_grid.d2 | 10 +++--- testdata/d2compiler/TestCompile/grid.exp.json | 34 +++++++++---------- .../d2compiler/TestCompile/grid_edge.exp.json | 6 ++-- .../TestCompile/grid_negative.exp.json | 4 +-- .../TestCompile/grid_nested.exp.json | 8 ++--- 14 files changed, 102 insertions(+), 102 deletions(-) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 07d450257..c3d721bc7 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -363,32 +363,32 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { } attrs.Constraint.Value = scalar.ScalarString() attrs.Constraint.MapKey = f.LastPrimaryKey() - case "rows": + case "grid-rows": v, err := strconv.Atoi(scalar.ScalarString()) if err != nil { - c.errorf(scalar, "non-integer rows %#v: %s", scalar.ScalarString(), err) + c.errorf(scalar, "non-integer grid-rows %#v: %s", scalar.ScalarString(), err) return } if v <= 0 { - c.errorf(scalar, "rows must be a positive integer: %#v", scalar.ScalarString()) + c.errorf(scalar, "grid-rows must be a positive integer: %#v", scalar.ScalarString()) return } - attrs.Rows = &d2graph.Scalar{} - attrs.Rows.Value = scalar.ScalarString() - attrs.Rows.MapKey = f.LastPrimaryKey() - case "columns": + attrs.GridRows = &d2graph.Scalar{} + attrs.GridRows.Value = scalar.ScalarString() + attrs.GridRows.MapKey = f.LastPrimaryKey() + case "grid-columns": v, err := strconv.Atoi(scalar.ScalarString()) if err != nil { - c.errorf(scalar, "non-integer columns %#v: %s", scalar.ScalarString(), err) + c.errorf(scalar, "non-integer grid-columns %#v: %s", scalar.ScalarString(), err) return } if v <= 0 { - c.errorf(scalar, "columns must be a positive integer: %#v", scalar.ScalarString()) + c.errorf(scalar, "grid-columns must be a positive integer: %#v", scalar.ScalarString()) return } - attrs.Columns = &d2graph.Scalar{} - attrs.Columns.Value = scalar.ScalarString() - attrs.Columns.MapKey = f.LastPrimaryKey() + attrs.GridColumns = &d2graph.Scalar{} + attrs.GridColumns.Value = scalar.ScalarString() + attrs.GridColumns.MapKey = f.LastPrimaryKey() } if attrs.Link != nil && attrs.Tooltip != nil { @@ -705,7 +705,7 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) { if !in && arrowheadIn { c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid shape, can only set "%s" for arrowheads`, obj.Attributes.Shape.Value)) } - case "rows", "columns": + case "grid-rows", "grid-columns": for _, child := range obj.ChildrenArray { if child.IsContainer() { c.errorf(f.LastPrimaryKey(), diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 92d8fd41e..89b8b04f2 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2271,27 +2271,27 @@ obj { { name: "grid", text: `hey: { - rows: 200 - columns: 230 + grid-rows: 200 + grid-columns: 230 } `, assertions: func(t *testing.T, g *d2graph.Graph) { - tassert.Equal(t, "200", g.Objects[0].Attributes.Rows.Value) + tassert.Equal(t, "200", g.Objects[0].Attributes.GridRows.Value) }, }, { name: "grid_negative", text: `hey: { - rows: 200 - columns: -200 + grid-rows: 200 + grid-columns: -200 } `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a positive integer: "-200"`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:16: grid-columns must be a positive integer: "-200"`, }, { name: "grid_edge", text: `hey: { - rows: 1 + grid-rows: 1 a -> b } c -> hey.b @@ -2306,8 +2306,8 @@ d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are { name: "grid_nested", text: `hey: { - rows: 200 - columns: 200 + grid-rows: 200 + grid-columns: 200 a b @@ -2315,8 +2315,8 @@ d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are d.invalid descendant } `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: "rows" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant") -d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: "columns" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant")`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: "grid-rows" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant") +d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: "grid-columns" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant")`, }, } diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index d9ae9a89d..be2892e97 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -133,8 +133,8 @@ type Attributes struct { Direction Scalar `json:"direction"` Constraint Scalar `json:"constraint"` - Rows *Scalar `json:"rows,omitempty"` - Columns *Scalar `json:"columns,omitempty"` + GridRows *Scalar `json:"gridRows,omitempty"` + GridColumns *Scalar `json:"gridColumns,omitempty"` } // TODO references at the root scope should have their Scope set to root graph AST @@ -1531,21 +1531,21 @@ var ReservedKeywords2 map[string]struct{} // Non Style/Holder keywords. var SimpleReservedKeywords = map[string]struct{}{ - "label": {}, - "desc": {}, - "shape": {}, - "icon": {}, - "constraint": {}, - "tooltip": {}, - "link": {}, - "near": {}, - "width": {}, - "height": {}, - "direction": {}, - "top": {}, - "left": {}, - "rows": {}, - "columns": {}, + "label": {}, + "desc": {}, + "shape": {}, + "icon": {}, + "constraint": {}, + "tooltip": {}, + "link": {}, + "near": {}, + "width": {}, + "height": {}, + "direction": {}, + "top": {}, + "left": {}, + "grid-rows": {}, + "grid-columns": {}, } // ReservedKeywordHolders are reserved keywords that are meaningless on its own and exist solely to hold a set of reserved keywords diff --git a/d2graph/grid_diagram.go b/d2graph/grid_diagram.go index 9f1aff9e9..6c40667a5 100644 --- a/d2graph/grid_diagram.go +++ b/d2graph/grid_diagram.go @@ -2,7 +2,7 @@ package d2graph func (obj *Object) IsGridDiagram() bool { return obj != nil && obj.Attributes != nil && - (obj.Attributes.Rows != nil || obj.Attributes.Columns != nil) + (obj.Attributes.GridRows != nil || obj.Attributes.GridColumns != nil) } func (obj *Object) ClosestGridDiagram() *Object { diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index bb68aad79..264bc07cc 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -23,11 +23,11 @@ type gridDiagram struct { func newGridDiagram(root *d2graph.Object) *gridDiagram { gd := gridDiagram{root: root, objects: root.ChildrenArray} - if root.Attributes.Rows != nil { - gd.rows, _ = strconv.Atoi(root.Attributes.Rows.Value) + if root.Attributes.GridRows != nil { + gd.rows, _ = strconv.Atoi(root.Attributes.GridRows.Value) } - if root.Attributes.Columns != nil { - gd.columns, _ = strconv.Atoi(root.Attributes.Columns.Value) + if root.Attributes.GridColumns != nil { + gd.columns, _ = strconv.Atoi(root.Attributes.GridColumns.Value) } if gd.rows != 0 && gd.columns != 0 { @@ -38,7 +38,7 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { // . │ g h i │ │ c f i │ // . └───────┘ └───────┘ // if keyword rows is first, make it row-directed, if columns is first it is column-directed - if root.Attributes.Rows.MapKey.Range.Before(root.Attributes.Columns.MapKey.Range) { + if root.Attributes.GridRows.MapKey.Range.Before(root.Attributes.GridColumns.MapKey.Range) { gd.rowDirected = true } diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 376634e22..58aaab1b6 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -314,14 +314,14 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Left.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } - case "rows": - if attrs.Rows != nil && attrs.Rows.MapKey != nil { - attrs.Rows.MapKey.SetScalar(mk.Value.ScalarBox()) + case "grid-rows": + if attrs.GridRows != nil && attrs.GridRows.MapKey != nil { + attrs.GridRows.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } - case "columns": - if attrs.Columns != nil && attrs.Columns.MapKey != nil { - attrs.Columns.MapKey.SetScalar(mk.Value.ScalarBox()) + case "grid-columns": + if attrs.GridColumns != nil && attrs.GridColumns.MapKey != nil { + attrs.GridColumns.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } case "source-arrowhead", "target-arrowhead": diff --git a/e2etests/testdata/files/dagger_grid.d2 b/e2etests/testdata/files/dagger_grid.d2 index dc9d8debe..2f6167c06 100644 --- a/e2etests/testdata/files/dagger_grid.d2 +++ b/e2etests/testdata/files/dagger_grid.d2 @@ -1,4 +1,4 @@ -rows: 5 +grid-rows: 5 style.fill: black flow1: "" { diff --git a/e2etests/testdata/files/executive_grid.d2 b/e2etests/testdata/files/executive_grid.d2 index 4a3a5c3ab..a5178fbd6 100644 --- a/e2etests/testdata/files/executive_grid.d2 +++ b/e2etests/testdata/files/executive_grid.d2 @@ -1,4 +1,4 @@ -rows: 3 +grid-rows: 3 Executive Services.width: 1000 diff --git a/e2etests/testdata/files/grid_tests.d2 b/e2etests/testdata/files/grid_tests.d2 index 501c9ea24..aab1481e9 100644 --- a/e2etests/testdata/files/grid_tests.d2 +++ b/e2etests/testdata/files/grid_tests.d2 @@ -1,5 +1,5 @@ rows 1: { - rows: 1 + grid-rows: 1 a b c @@ -10,7 +10,7 @@ rows 1: { } columns 1: { - columns: 1 + grid-columns: 1 a b c @@ -21,7 +21,7 @@ columns 1: { } rows 2: { - rows: 2 + grid-rows: 2 a b c @@ -32,7 +32,7 @@ rows 2: { } columns 2: { - columns: 2 + grid-columns: 2 a b c @@ -43,8 +43,8 @@ columns 2: { } rows 2 columns 2: { - rows: 2 - columns: 2 + grid-rows: 2 + grid-columns: 2 a b @@ -56,8 +56,8 @@ rows 2 columns 2: { } columns 2 rows 2: { - columns: 2 - rows: 2 + grid-columns: 2 + grid-rows: 2 a b @@ -69,8 +69,8 @@ columns 2 rows 2: { } rows 3 columns 3: { - rows: 3 - columns: 3 + grid-rows: 3 + grid-columns: 3 a b @@ -82,8 +82,8 @@ rows 3 columns 3: { } columns 3 rows 3: { - columns: 3 - rows: 3 + grid-columns: 3 + grid-rows: 3 a b @@ -95,7 +95,7 @@ columns 3 rows 3: { } rows 3: { - rows: 3 + grid-rows: 3 a b @@ -107,7 +107,7 @@ rows 3: { } columns 3: { - columns: 3 + grid-columns: 3 a b @@ -119,8 +119,8 @@ columns 3: { } widths heights: { - rows: 3 - columns: 3 + grid-rows: 3 + grid-columns: 3 a w200.width: 200 b h300.height: 300 diff --git a/e2etests/testdata/files/teleport_grid.d2 b/e2etests/testdata/files/teleport_grid.d2 index baec9fe60..d0e737513 100644 --- a/e2etests/testdata/files/teleport_grid.d2 +++ b/e2etests/testdata/files/teleport_grid.d2 @@ -9,7 +9,7 @@ teleport -> identity provider teleport <- identity provider users: "" { - columns: 1 + grid-columns: 1 Engineers: { shape: circle @@ -22,7 +22,7 @@ users: "" { } via: "" { - columns: 1 + grid-columns: 1 https: "HTTPS://" kubectl: "> kubectl" @@ -32,7 +32,7 @@ via: "" { } teleport: Teleport { - rows: 2 + grid-rows: 2 inp: |md # Identity Native Proxy @@ -45,7 +45,7 @@ teleport: Teleport { } jita: "Just-in-time Access via" { - rows: 1 + grid-rows: 1 Slack.icon: https://icons.terrastruct.com/dev%2Fslack.svg Mattermost @@ -55,7 +55,7 @@ jita: "Just-in-time Access via" { } infra: Infrastructure { - rows: 2 + grid-rows: 2 ssh.icon: https://icons.terrastruct.com/essentials%2F112-server.svg Kubernetes.icon: https://icons.terrastruct.com/azure%2F_Companies%2FKubernetes.svg diff --git a/testdata/d2compiler/TestCompile/grid.exp.json b/testdata/d2compiler/TestCompile/grid.exp.json index 8cad38d75..8b4e621bc 100644 --- a/testdata/d2compiler/TestCompile/grid.exp.json +++ b/testdata/d2compiler/TestCompile/grid.exp.json @@ -3,11 +3,11 @@ "name": "", "isFolderOnly": false, "ast": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-4:0:34", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-4:0:44", "nodes": [ { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-3:1:33", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-3:1:43", "key": { "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3", "path": [ @@ -27,21 +27,21 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:5:5-3:0:32", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:5:5-3:0:42", "nodes": [ { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:10:17", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:15:22", "key": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:5:12", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:10:17", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:5:12", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:10:17", "value": [ { - "string": "rows", - "raw_string": "rows" + "string": "grid-rows", + "raw_string": "grid-rows" } ] } @@ -51,7 +51,7 @@ "primary": {}, "value": { "number": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:7:14-1:10:17", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:12:19-1:15:22", "raw": "200", "value": "200" } @@ -60,17 +60,17 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:19-2:13:31", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:24-2:18:41", "key": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:19-2:8:26", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:24-2:13:36", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:19-2:8:26", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:24-2:13:36", "value": [ { - "string": "columns", - "raw_string": "columns" + "string": "grid-columns", + "raw_string": "grid-columns" } ] } @@ -80,7 +80,7 @@ "primary": {}, "value": { "number": { - "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:10:28-2:13:31", + "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:15:38-2:18:41", "raw": "230", "value": "230" } @@ -165,10 +165,10 @@ "constraint": { "value": "" }, - "rows": { + "gridRows": { "value": "200" }, - "columns": { + "gridColumns": { "value": "230" } }, diff --git a/testdata/d2compiler/TestCompile/grid_edge.exp.json b/testdata/d2compiler/TestCompile/grid_edge.exp.json index d8b36c51b..52a77accb 100644 --- a/testdata/d2compiler/TestCompile/grid_edge.exp.json +++ b/testdata/d2compiler/TestCompile/grid_edge.exp.json @@ -4,15 +4,15 @@ "ioerr": null, "errs": [ { - "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,2:1:17-2:7:23", + "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,2:1:22-2:7:28", "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edges in grid diagrams are not supported yet" }, { - "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,4:1:27-4:11:37", + "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,4:1:32-4:11:42", "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edges in grid diagrams are not supported yet" }, { - "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,5:1:39-5:11:49", + "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,5:1:44-5:11:54", "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are not supported yet" } ] diff --git a/testdata/d2compiler/TestCompile/grid_negative.exp.json b/testdata/d2compiler/TestCompile/grid_negative.exp.json index 5551871da..7999bc2b6 100644 --- a/testdata/d2compiler/TestCompile/grid_negative.exp.json +++ b/testdata/d2compiler/TestCompile/grid_negative.exp.json @@ -4,8 +4,8 @@ "ioerr": null, "errs": [ { - "range": "d2/testdata/d2compiler/TestCompile/grid_negative.d2,2:10:28-2:14:32", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:11: columns must be a positive integer: \"-200\"" + "range": "d2/testdata/d2compiler/TestCompile/grid_negative.d2,2:15:38-2:19:42", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:16: grid-columns must be a positive integer: \"-200\"" } ] } diff --git a/testdata/d2compiler/TestCompile/grid_nested.exp.json b/testdata/d2compiler/TestCompile/grid_nested.exp.json index ff55b27e7..c8db27f4f 100644 --- a/testdata/d2compiler/TestCompile/grid_nested.exp.json +++ b/testdata/d2compiler/TestCompile/grid_nested.exp.json @@ -4,12 +4,12 @@ "ioerr": null, "errs": [ { - "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,1:1:8-1:10:17", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: \"rows\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")" + "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,1:1:8-1:15:22", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: \"grid-rows\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")" }, { - "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,2:1:19-2:13:31", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: \"columns\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")" + "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,2:1:24-2:18:41", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: \"grid-columns\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")" } ] } From 1ed2fdbbef2099f3063d644d2c1fa7de8fc3ee7f Mon Sep 17 00:00:00 2001 From: Omar Zeghouani <59267627+ram02z@users.noreply.github.com> Date: Thu, 6 Apr 2023 23:54:40 +0100 Subject: [PATCH 33/33] Add d2-filter as community plugin --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 18e2f34b9..99f11d3c6 100644 --- a/README.md +++ b/README.md @@ -226,6 +226,7 @@ let us know and we'll be happy to include it here! - **CIL (C#, Visual Basic, F#, C++ CLR) to D2**: [https://github.com/HugoVG/AppDiagram](https://github.com/HugoVG/AppDiagram) - **D2 Snippets (for text editors)**: [https://github.com/Paracelsus-Rose/D2-Language-Code-Snippets](https://github.com/Paracelsus-Rose/D2-Language-Code-Snippets) - **Mongo to D2**: [https://github.com/novuhq/mongo-to-D2](https://github.com/novuhq/mongo-to-D2) +- **Pandoc filter**: [https://github.com/ram02z/d2-filter](https://github.com/ram02z/d2-filter) ### Misc