From c20c122ee42edc1a6ca9f14f80645b59445599f8 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 18:18:48 -0700 Subject: [PATCH 1/9] add grid-gap keywords --- d2compiler/compile.go | 41 +++++++++++++++++++++++++++++++++++++++- d2graph/d2graph.go | 44 ++++++++++++++++++++++++------------------- d2oracle/edit.go | 15 +++++++++++++++ 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 817f4169f..867b8a756 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -420,6 +420,45 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { attrs.GridColumns = &d2graph.Scalar{} attrs.GridColumns.Value = scalar.ScalarString() attrs.GridColumns.MapKey = f.LastPrimaryKey() + case "grid-gap": + v, err := strconv.Atoi(scalar.ScalarString()) + if err != nil { + c.errorf(scalar, "non-integer grid-gap %#v: %s", scalar.ScalarString(), err) + return + } + if v < 0 { + c.errorf(scalar, "grid-gap must be a non-negative integer: %#v", scalar.ScalarString()) + return + } + attrs.GridGap = &d2graph.Scalar{} + attrs.GridGap.Value = scalar.ScalarString() + attrs.GridGap.MapKey = f.LastPrimaryKey() + case "grid-gap-rows": + v, err := strconv.Atoi(scalar.ScalarString()) + if err != nil { + c.errorf(scalar, "non-integer grid-gap-rows %#v: %s", scalar.ScalarString(), err) + return + } + if v < 0 { + c.errorf(scalar, "grid-gap-rows must be a non-negative integer: %#v", scalar.ScalarString()) + return + } + attrs.GridGapRows = &d2graph.Scalar{} + attrs.GridGapRows.Value = scalar.ScalarString() + attrs.GridGapRows.MapKey = f.LastPrimaryKey() + case "grid-gap-columns": + v, err := strconv.Atoi(scalar.ScalarString()) + if err != nil { + c.errorf(scalar, "non-integer grid-gap-columns %#v: %s", scalar.ScalarString(), err) + return + } + if v < 0 { + c.errorf(scalar, "grid-gap-columns must be a non-negative integer: %#v", scalar.ScalarString()) + return + } + attrs.GridGapColumns = &d2graph.Scalar{} + attrs.GridGapColumns.Value = scalar.ScalarString() + attrs.GridGapColumns.MapKey = f.LastPrimaryKey() case "class": attrs.Classes = append(attrs.Classes, scalar.ScalarString()) case "classes": @@ -757,7 +796,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 "grid-rows", "grid-columns": + case "grid-rows", "grid-columns", "grid-gap", "grid-gap-rows", "grid-gap-columns": for _, child := range obj.ChildrenArray { if child.IsContainer() { c.errorf(f.LastPrimaryKey(), diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 8b5e27696..261e1af5f 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -136,8 +136,11 @@ type Attributes struct { Direction Scalar `json:"direction"` Constraint Scalar `json:"constraint"` - GridRows *Scalar `json:"gridRows,omitempty"` - GridColumns *Scalar `json:"gridColumns,omitempty"` + GridRows *Scalar `json:"gridRows,omitempty"` + GridColumns *Scalar `json:"gridColumns,omitempty"` + GridGap *Scalar `json:"gridGap,omitempty"` + GridGapRows *Scalar `json:"gridGapRows,omitempty"` + GridGapColumns *Scalar `json:"gridGapColumns,omitempty"` // These names are attached to the rendered elements in SVG // so that users can target them however they like outside of D2 @@ -1588,23 +1591,26 @@ 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": {}, - "grid-rows": {}, - "grid-columns": {}, - "class": {}, - "classes": {}, + "label": {}, + "desc": {}, + "shape": {}, + "icon": {}, + "constraint": {}, + "tooltip": {}, + "link": {}, + "near": {}, + "width": {}, + "height": {}, + "direction": {}, + "top": {}, + "left": {}, + "grid-rows": {}, + "grid-columns": {}, + "grid-gap": {}, + "grid-gap-rows": {}, + "grid-gap-columns": {}, + "class": {}, + "classes": {}, } // ReservedKeywordHolders are reserved keywords that are meaningless on its own and exist solely to hold a set of reserved keywords diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 58aaab1b6..7849aefea 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -324,6 +324,21 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.GridColumns.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } + case "grid-gap": + if attrs.GridGap != nil && attrs.GridGap.MapKey != nil { + attrs.GridGap.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "grid-gap-rows": + if attrs.GridGapRows != nil && attrs.GridGapRows.MapKey != nil { + attrs.GridGapRows.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "grid-gap-columns": + if attrs.GridGapColumns != nil && attrs.GridGapColumns.MapKey != nil { + attrs.GridGapColumns.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } case "source-arrowhead", "target-arrowhead": if reservedKey == "source-arrowhead" { attrs = edge.SrcArrowhead From e871cee0bb9b0ad6465af899c8f0e7646c0b7dee Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 18:21:26 -0700 Subject: [PATCH 2/9] add compile test --- d2compiler/compile_test.go | 10 ++++++++++ .../TestCompile/grid_gap_negative.exp.json | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 testdata/d2compiler/TestCompile/grid_gap_negative.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index c484dd4e0..ceb751603 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2301,6 +2301,16 @@ obj { `, expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:16: grid-columns must be a positive integer: "-200"`, }, + { + name: "grid_gap_negative", + text: `hey: { + grid-gap-columns: -200 + grid-gap-rows: -30 +} +`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:2:20: grid-gap-columns must be a non-negative integer: "-200" +d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:3:17: grid-gap-rows must be a non-negative integer: "-30"`, + }, { name: "grid_edge", text: `hey: { diff --git a/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json b/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json new file mode 100644 index 000000000..a37b783c0 --- /dev/null +++ b/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json @@ -0,0 +1,16 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2,1:19:26-1:23:30", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:2:20: grid-gap-columns must be a non-negative integer: \"-200\"" + }, + { + "range": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2,2:16:47-2:19:50", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:3:17: grid-gap-rows must be a non-negative integer: \"-30\"" + } + ] + } +} From c8cd27dc5dd2e46260131a1926e1172c3fa680cc Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 18:23:31 -0700 Subject: [PATCH 3/9] add grid_gap e2e test --- e2etests/stable_test.go | 1 + e2etests/testdata/files/grid_gap.d2 | 66 + .../stable/grid_gap/dagre/board.exp.json | 1688 +++++++++++++++++ .../stable/grid_gap/dagre/sketch.exp.svg | 102 + .../stable/grid_gap/elk/board.exp.json | 1688 +++++++++++++++++ .../stable/grid_gap/elk/sketch.exp.svg | 102 + 6 files changed, 3647 insertions(+) create mode 100644 e2etests/testdata/files/grid_gap.d2 create mode 100644 e2etests/testdata/stable/grid_gap/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/grid_gap/elk/board.exp.json create mode 100644 e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index fb258af92..584a2969a 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2572,6 +2572,7 @@ scenarios: { loadFromFile(t, "grid_tests"), loadFromFile(t, "executive_grid"), loadFromFile(t, "grid_animated"), + loadFromFile(t, "grid_gap"), } runa(t, tcs) diff --git a/e2etests/testdata/files/grid_gap.d2 b/e2etests/testdata/files/grid_gap.d2 new file mode 100644 index 000000000..f8520902a --- /dev/null +++ b/e2etests/testdata/files/grid_gap.d2 @@ -0,0 +1,66 @@ +gap-rows 30 gap-columns 100: { + grid-rows: 3 + grid-columns: 3 + grid-gap-rows: 30 + grid-gap-columns: 100 + + a + b + c + d + e + f + g + h + i +} + +gap-rows 100 gap-columns 30: { + grid-rows: 3 + grid-columns: 3 + grid-gap-rows: 100 + grid-gap-columns: 30 + + a + b + c + d + e + f + g + h + i +} + +gap 0: { + grid-rows: 3 + grid-columns: 3 + grid-gap: 0 + + a + b + c + d + e + f + g + h + i +} + +gap 10 gap-rows 100: { + grid-rows: 3 + grid-columns: 3 + grid-gap: 10 + grid-gap-rows: 100 + + a + b + c + d + e + f + g + h + i +} diff --git a/e2etests/testdata/stable/grid_gap/dagre/board.exp.json b/e2etests/testdata/stable/grid_gap/dagre/board.exp.json new file mode 100644 index 000000000..5bf58ff02 --- /dev/null +++ b/e2etests/testdata/stable/grid_gap/dagre/board.exp.json @@ -0,0 +1,1688 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "gap-rows 30 gap-columns 100", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "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": "gap-rows 30 gap-columns 100", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 347, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap-rows 30 gap-columns 100.a", + "type": "rectangle", + "pos": { + "x": 60, + "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": "gap-rows 30 gap-columns 100.b", + "type": "rectangle", + "pos": { + "x": 154, + "y": 60 + }, + "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": "gap-rows 30 gap-columns 100.c", + "type": "rectangle", + "pos": { + "x": 247, + "y": 60 + }, + "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": "gap-rows 30 gap-columns 100.d", + "type": "rectangle", + "pos": { + "x": 60, + "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": "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": "gap-rows 30 gap-columns 100.e", + "type": "rectangle", + "pos": { + "x": 154, + "y": 166 + }, + "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": "gap-rows 30 gap-columns 100.f", + "type": "rectangle", + "pos": { + "x": 247, + "y": 166 + }, + "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": "gap-rows 30 gap-columns 100.g", + "type": "rectangle", + "pos": { + "x": 60, + "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": "gap-rows 30 gap-columns 100.h", + "type": "rectangle", + "pos": { + "x": 154, + "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": "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": "gap-rows 30 gap-columns 100.i", + "type": "rectangle", + "pos": { + "x": 247, + "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": "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 + }, + { + "id": "gap-rows 100 gap-columns 30", + "type": "rectangle", + "pos": { + "x": 420, + "y": 0 + }, + "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": "gap-rows 100 gap-columns 30", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 347, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap-rows 100 gap-columns 30.a", + "type": "rectangle", + "pos": { + "x": 480, + "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": "gap-rows 100 gap-columns 30.b", + "type": "rectangle", + "pos": { + "x": 574, + "y": 60 + }, + "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": "gap-rows 100 gap-columns 30.c", + "type": "rectangle", + "pos": { + "x": 667, + "y": 60 + }, + "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": "gap-rows 100 gap-columns 30.d", + "type": "rectangle", + "pos": { + "x": 480, + "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": "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": "gap-rows 100 gap-columns 30.e", + "type": "rectangle", + "pos": { + "x": 574, + "y": 166 + }, + "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": "gap-rows 100 gap-columns 30.f", + "type": "rectangle", + "pos": { + "x": 667, + "y": 166 + }, + "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": "gap-rows 100 gap-columns 30.g", + "type": "rectangle", + "pos": { + "x": 480, + "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": "gap-rows 100 gap-columns 30.h", + "type": "rectangle", + "pos": { + "x": 574, + "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": "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": "gap-rows 100 gap-columns 30.i", + "type": "rectangle", + "pos": { + "x": 667, + "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": "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 + }, + { + "id": "gap 0", + "type": "rectangle", + "pos": { + "x": 840, + "y": 0 + }, + "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": "gap 0", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 62, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap 0.a", + "type": "rectangle", + "pos": { + "x": 900, + "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": "gap 0.b", + "type": "rectangle", + "pos": { + "x": 994, + "y": 60 + }, + "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": "gap 0.c", + "type": "rectangle", + "pos": { + "x": 1087, + "y": 60 + }, + "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": "gap 0.d", + "type": "rectangle", + "pos": { + "x": 900, + "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": "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": "gap 0.e", + "type": "rectangle", + "pos": { + "x": 994, + "y": 166 + }, + "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": "gap 0.f", + "type": "rectangle", + "pos": { + "x": 1087, + "y": 166 + }, + "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": "gap 0.g", + "type": "rectangle", + "pos": { + "x": 900, + "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": "gap 0.h", + "type": "rectangle", + "pos": { + "x": 994, + "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": "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": "gap 0.i", + "type": "rectangle", + "pos": { + "x": 1087, + "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": "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 + }, + { + "id": "gap 10 gap-rows 100", + "type": "rectangle", + "pos": { + "x": 1260, + "y": 0 + }, + "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": "gap 10 gap-rows 100", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 238, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap 10 gap-rows 100.a", + "type": "rectangle", + "pos": { + "x": 1320, + "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": "gap 10 gap-rows 100.b", + "type": "rectangle", + "pos": { + "x": 1414, + "y": 60 + }, + "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": "gap 10 gap-rows 100.c", + "type": "rectangle", + "pos": { + "x": 1507, + "y": 60 + }, + "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": "gap 10 gap-rows 100.d", + "type": "rectangle", + "pos": { + "x": 1320, + "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": "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": "gap 10 gap-rows 100.e", + "type": "rectangle", + "pos": { + "x": 1414, + "y": 166 + }, + "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": "gap 10 gap-rows 100.f", + "type": "rectangle", + "pos": { + "x": 1507, + "y": 166 + }, + "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": "gap 10 gap-rows 100.g", + "type": "rectangle", + "pos": { + "x": 1320, + "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": "gap 10 gap-rows 100.h", + "type": "rectangle", + "pos": { + "x": 1414, + "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": "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": "gap 10 gap-rows 100.i", + "type": "rectangle", + "pos": { + "x": 1507, + "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": "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": [], + "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_gap/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg new file mode 100644 index 000000000..1be6b8dda --- /dev/null +++ b/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg @@ -0,0 +1,102 @@ +gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/grid_gap/elk/board.exp.json b/e2etests/testdata/stable/grid_gap/elk/board.exp.json new file mode 100644 index 000000000..a9928b1c6 --- /dev/null +++ b/e2etests/testdata/stable/grid_gap/elk/board.exp.json @@ -0,0 +1,1688 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "gap-rows 30 gap-columns 100", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "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": "gap-rows 30 gap-columns 100", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 347, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap-rows 30 gap-columns 100.a", + "type": "rectangle", + "pos": { + "x": 72, + "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": "gap-rows 30 gap-columns 100.b", + "type": "rectangle", + "pos": { + "x": 166, + "y": 72 + }, + "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": "gap-rows 30 gap-columns 100.c", + "type": "rectangle", + "pos": { + "x": 259, + "y": 72 + }, + "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": "gap-rows 30 gap-columns 100.d", + "type": "rectangle", + "pos": { + "x": 72, + "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": "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": "gap-rows 30 gap-columns 100.e", + "type": "rectangle", + "pos": { + "x": 166, + "y": 178 + }, + "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": "gap-rows 30 gap-columns 100.f", + "type": "rectangle", + "pos": { + "x": 259, + "y": 178 + }, + "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": "gap-rows 30 gap-columns 100.g", + "type": "rectangle", + "pos": { + "x": 72, + "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": "gap-rows 30 gap-columns 100.h", + "type": "rectangle", + "pos": { + "x": 166, + "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": "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": "gap-rows 30 gap-columns 100.i", + "type": "rectangle", + "pos": { + "x": 259, + "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": "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 + }, + { + "id": "gap-rows 100 gap-columns 30", + "type": "rectangle", + "pos": { + "x": 392, + "y": 12 + }, + "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": "gap-rows 100 gap-columns 30", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 347, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap-rows 100 gap-columns 30.a", + "type": "rectangle", + "pos": { + "x": 452, + "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": "gap-rows 100 gap-columns 30.b", + "type": "rectangle", + "pos": { + "x": 546, + "y": 72 + }, + "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": "gap-rows 100 gap-columns 30.c", + "type": "rectangle", + "pos": { + "x": 639, + "y": 72 + }, + "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": "gap-rows 100 gap-columns 30.d", + "type": "rectangle", + "pos": { + "x": 452, + "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": "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": "gap-rows 100 gap-columns 30.e", + "type": "rectangle", + "pos": { + "x": 546, + "y": 178 + }, + "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": "gap-rows 100 gap-columns 30.f", + "type": "rectangle", + "pos": { + "x": 639, + "y": 178 + }, + "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": "gap-rows 100 gap-columns 30.g", + "type": "rectangle", + "pos": { + "x": 452, + "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": "gap-rows 100 gap-columns 30.h", + "type": "rectangle", + "pos": { + "x": 546, + "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": "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": "gap-rows 100 gap-columns 30.i", + "type": "rectangle", + "pos": { + "x": 639, + "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": "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 + }, + { + "id": "gap 0", + "type": "rectangle", + "pos": { + "x": 772, + "y": 12 + }, + "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": "gap 0", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 62, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap 0.a", + "type": "rectangle", + "pos": { + "x": 832, + "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": "gap 0.b", + "type": "rectangle", + "pos": { + "x": 926, + "y": 72 + }, + "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": "gap 0.c", + "type": "rectangle", + "pos": { + "x": 1019, + "y": 72 + }, + "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": "gap 0.d", + "type": "rectangle", + "pos": { + "x": 832, + "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": "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": "gap 0.e", + "type": "rectangle", + "pos": { + "x": 926, + "y": 178 + }, + "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": "gap 0.f", + "type": "rectangle", + "pos": { + "x": 1019, + "y": 178 + }, + "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": "gap 0.g", + "type": "rectangle", + "pos": { + "x": 832, + "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": "gap 0.h", + "type": "rectangle", + "pos": { + "x": 926, + "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": "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": "gap 0.i", + "type": "rectangle", + "pos": { + "x": 1019, + "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": "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 + }, + { + "id": "gap 10 gap-rows 100", + "type": "rectangle", + "pos": { + "x": 1152, + "y": 12 + }, + "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": "gap 10 gap-rows 100", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 238, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "gap 10 gap-rows 100.a", + "type": "rectangle", + "pos": { + "x": 1212, + "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": "gap 10 gap-rows 100.b", + "type": "rectangle", + "pos": { + "x": 1306, + "y": 72 + }, + "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": "gap 10 gap-rows 100.c", + "type": "rectangle", + "pos": { + "x": 1399, + "y": 72 + }, + "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": "gap 10 gap-rows 100.d", + "type": "rectangle", + "pos": { + "x": 1212, + "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": "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": "gap 10 gap-rows 100.e", + "type": "rectangle", + "pos": { + "x": 1306, + "y": 178 + }, + "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": "gap 10 gap-rows 100.f", + "type": "rectangle", + "pos": { + "x": 1399, + "y": 178 + }, + "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": "gap 10 gap-rows 100.g", + "type": "rectangle", + "pos": { + "x": 1212, + "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": "gap 10 gap-rows 100.h", + "type": "rectangle", + "pos": { + "x": 1306, + "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": "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": "gap 10 gap-rows 100.i", + "type": "rectangle", + "pos": { + "x": 1399, + "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": "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": [], + "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_gap/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg new file mode 100644 index 000000000..43cef7f13 --- /dev/null +++ b/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg @@ -0,0 +1,102 @@ +gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi + + + \ No newline at end of file From a7050f3ca770e05d1db9833964fee9625727df3f Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 20:02:54 -0700 Subject: [PATCH 4/9] use grid-gap values for layout --- d2layouts/d2grid/grid_diagram.go | 23 +++++++++++++++- d2layouts/d2grid/layout.go | 47 ++++++++++++++++---------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index 264bc07cc..0cb9514e6 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -19,10 +19,19 @@ type gridDiagram struct { width float64 height float64 + + gapRows float64 + gapColumns float64 } func newGridDiagram(root *d2graph.Object) *gridDiagram { - gd := gridDiagram{root: root, objects: root.ChildrenArray} + gd := gridDiagram{ + root: root, + objects: root.ChildrenArray, + gapRows: DEFAULT_GAP, + gapColumns: DEFAULT_GAP, + } + if root.Attributes.GridRows != nil { gd.rows, _ = strconv.Atoi(root.Attributes.GridRows.Value) } @@ -66,6 +75,18 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { gd.rowDirected = true } + // grid gap sets both, but can be overridden + if root.Attributes.GridGap != nil { + gd.gapRows, _ = strconv.ParseFloat(root.Attributes.GridGap.Value, 64) + gd.gapColumns = gd.gapRows + } + if root.Attributes.GridGapRows != nil { + gd.gapRows, _ = strconv.ParseFloat(root.Attributes.GridGapRows.Value, 64) + } + if root.Attributes.GridGapColumns != nil { + gd.gapColumns, _ = strconv.ParseFloat(root.Attributes.GridGapColumns.Value, 64) + } + return &gd } diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 1edae9066..e51f70d02 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -13,8 +13,7 @@ import ( const ( CONTAINER_PADDING = 60 - HORIZONTAL_PAD = 40. - VERTICAL_PAD = 40. + DEFAULT_GAP = 40. ) // Layout runs the grid layout on containers with rows/columns @@ -189,10 +188,10 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.X += o.Width + HORIZONTAL_PAD + cursor.X += o.Width + gd.gapColumns } cursor.X = 0 - cursor.Y += rowHeights[i] + VERTICAL_PAD + cursor.Y += rowHeights[i] + gd.gapRows } } else { for j := 0; j < gd.columns; j++ { @@ -204,22 +203,22 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.Y += o.Height + VERTICAL_PAD + cursor.Y += o.Height + gd.gapRows } - cursor.X += colWidths[j] + HORIZONTAL_PAD + cursor.X += colWidths[j] + gd.gapColumns cursor.Y = 0 } } var totalWidth, totalHeight float64 for _, w := range colWidths { - totalWidth += w + HORIZONTAL_PAD + totalWidth += w + gd.gapColumns } for _, h := range rowHeights { - totalHeight += h + VERTICAL_PAD + totalHeight += h + gd.gapRows } - totalWidth -= HORIZONTAL_PAD - totalHeight -= VERTICAL_PAD + totalWidth -= gd.gapColumns + totalHeight -= gd.gapRows gd.width = totalWidth gd.height = totalHeight } @@ -246,8 +245,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { totalWidth += o.Width totalHeight += o.Height } - totalWidth += HORIZONTAL_PAD * float64(len(gd.objects)-gd.rows) - totalHeight += VERTICAL_PAD * float64(len(gd.objects)-gd.columns) + totalWidth += gd.gapColumns * float64(len(gd.objects)-gd.rows) + totalHeight += gd.gapRows * float64(len(gd.objects)-gd.columns) var layout [][]*d2graph.Object if gd.rowDirected { @@ -278,10 +277,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowHeight := 0. for _, o := range row { o.TopLeft = cursor.Copy() - cursor.X += o.Width + HORIZONTAL_PAD + cursor.X += o.Width + gd.gapColumns rowHeight = math.Max(rowHeight, o.Height) } - rowWidth := cursor.X - HORIZONTAL_PAD + rowWidth := cursor.X - gd.gapColumns rowWidths = append(rowWidths, rowWidth) maxX = math.Max(maxX, rowWidth) @@ -292,9 +291,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new row cursor.X = 0 - cursor.Y += rowHeight + VERTICAL_PAD + cursor.Y += rowHeight + gd.gapRows } - maxY = cursor.Y - VERTICAL_PAD + maxY = cursor.Y - gd.gapRows // then expand thinnest objects to make each row the same width // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) @@ -372,10 +371,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colWidth := 0. for _, o := range column { o.TopLeft = cursor.Copy() - cursor.Y += o.Height + VERTICAL_PAD + cursor.Y += o.Height + gd.gapRows colWidth = math.Max(colWidth, o.Width) } - colHeight := cursor.Y - VERTICAL_PAD + colHeight := cursor.Y - gd.gapRows colHeights = append(colHeights, colHeight) maxY = math.Max(maxY, colHeight) // set all objects in column to the same width @@ -385,9 +384,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new column cursor.Y = 0 - cursor.X += colWidth + HORIZONTAL_PAD + cursor.X += colWidth + gd.gapColumns } - maxX = cursor.X - HORIZONTAL_PAD + maxX = cursor.X - gd.gapColumns // then expand shortest objects to make each column the same height // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ @@ -479,7 +478,7 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr // of these divisions, find the layout with rows closest to the targetSize for _, division := range divisions { layout := genLayout(gd.objects, division) - dist := getDistToTarget(layout, targetSize, columns) + dist := getDistToTarget(layout, targetSize, gd.gapRows, gd.gapColumns, columns) if dist < bestDist { bestLayout = layout bestDist = dist @@ -527,15 +526,15 @@ func genLayout(objects []*d2graph.Object, cutIndices []int) [][]*d2graph.Object return layout } -func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, columns bool) float64 { +func getDistToTarget(layout [][]*d2graph.Object, targetSize, gapRows, gapColumns float64, columns bool) float64 { totalDelta := 0. for _, row := range layout { rowSize := 0. for _, o := range row { if columns { - rowSize += o.Height + VERTICAL_PAD + rowSize += o.Height + gapRows } else { - rowSize += o.Width + HORIZONTAL_PAD + rowSize += o.Width + gapColumns } } totalDelta += math.Abs(rowSize - targetSize) From 22a2b80f5fcfeb1edfce1d968415978ba0e6a5b0 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 20:06:06 -0700 Subject: [PATCH 5/9] update test --- .../stable/grid_gap/dagre/board.exp.json | 152 ++++++++--------- .../stable/grid_gap/dagre/sketch.exp.svg | 160 +++++++++--------- .../stable/grid_gap/elk/board.exp.json | 152 ++++++++--------- .../stable/grid_gap/elk/sketch.exp.svg | 160 +++++++++--------- 4 files changed, 312 insertions(+), 312 deletions(-) diff --git a/e2etests/testdata/stable/grid_gap/dagre/board.exp.json b/e2etests/testdata/stable/grid_gap/dagre/board.exp.json index 5bf58ff02..702505891 100644 --- a/e2etests/testdata/stable/grid_gap/dagre/board.exp.json +++ b/e2etests/testdata/stable/grid_gap/dagre/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 0, - "y": 0 + "y": 70 }, - "width": 360, - "height": 398, + "width": 480, + "height": 378, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -49,7 +49,7 @@ "type": "rectangle", "pos": { "x": 60, - "y": 60 + "y": 130 }, "width": 54, "height": 66, @@ -89,8 +89,8 @@ "id": "gap-rows 30 gap-columns 100.b", "type": "rectangle", "pos": { - "x": 154, - "y": 60 + "x": 214, + "y": 130 }, "width": 53, "height": 66, @@ -130,8 +130,8 @@ "id": "gap-rows 30 gap-columns 100.c", "type": "rectangle", "pos": { - "x": 247, - "y": 60 + "x": 367, + "y": 130 }, "width": 53, "height": 66, @@ -172,7 +172,7 @@ "type": "rectangle", "pos": { "x": 60, - "y": 166 + "y": 226 }, "width": 54, "height": 66, @@ -212,8 +212,8 @@ "id": "gap-rows 30 gap-columns 100.e", "type": "rectangle", "pos": { - "x": 154, - "y": 166 + "x": 214, + "y": 226 }, "width": 53, "height": 66, @@ -253,8 +253,8 @@ "id": "gap-rows 30 gap-columns 100.f", "type": "rectangle", "pos": { - "x": 247, - "y": 166 + "x": 367, + "y": 226 }, "width": 53, "height": 66, @@ -295,7 +295,7 @@ "type": "rectangle", "pos": { "x": 60, - "y": 272 + "y": 322 }, "width": 54, "height": 66, @@ -335,8 +335,8 @@ "id": "gap-rows 30 gap-columns 100.h", "type": "rectangle", "pos": { - "x": 154, - "y": 272 + "x": 214, + "y": 322 }, "width": 53, "height": 66, @@ -376,8 +376,8 @@ "id": "gap-rows 30 gap-columns 100.i", "type": "rectangle", "pos": { - "x": 247, - "y": 272 + "x": 367, + "y": 322 }, "width": 53, "height": 66, @@ -417,11 +417,11 @@ "id": "gap-rows 100 gap-columns 30", "type": "rectangle", "pos": { - "x": 420, + "x": 540, "y": 0 }, - "width": 360, - "height": 398, + "width": 357, + "height": 518, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -458,7 +458,7 @@ "id": "gap-rows 100 gap-columns 30.a", "type": "rectangle", "pos": { - "x": 480, + "x": 608, "y": 60 }, "width": 54, @@ -499,7 +499,7 @@ "id": "gap-rows 100 gap-columns 30.b", "type": "rectangle", "pos": { - "x": 574, + "x": 692, "y": 60 }, "width": 53, @@ -540,7 +540,7 @@ "id": "gap-rows 100 gap-columns 30.c", "type": "rectangle", "pos": { - "x": 667, + "x": 775, "y": 60 }, "width": 53, @@ -581,8 +581,8 @@ "id": "gap-rows 100 gap-columns 30.d", "type": "rectangle", "pos": { - "x": 480, - "y": 166 + "x": 608, + "y": 226 }, "width": 54, "height": 66, @@ -622,8 +622,8 @@ "id": "gap-rows 100 gap-columns 30.e", "type": "rectangle", "pos": { - "x": 574, - "y": 166 + "x": 692, + "y": 226 }, "width": 53, "height": 66, @@ -663,8 +663,8 @@ "id": "gap-rows 100 gap-columns 30.f", "type": "rectangle", "pos": { - "x": 667, - "y": 166 + "x": 775, + "y": 226 }, "width": 53, "height": 66, @@ -704,8 +704,8 @@ "id": "gap-rows 100 gap-columns 30.g", "type": "rectangle", "pos": { - "x": 480, - "y": 272 + "x": 608, + "y": 392 }, "width": 54, "height": 66, @@ -745,8 +745,8 @@ "id": "gap-rows 100 gap-columns 30.h", "type": "rectangle", "pos": { - "x": 574, - "y": 272 + "x": 692, + "y": 392 }, "width": 53, "height": 66, @@ -786,8 +786,8 @@ "id": "gap-rows 100 gap-columns 30.i", "type": "rectangle", "pos": { - "x": 667, - "y": 272 + "x": 775, + "y": 392 }, "width": 53, "height": 66, @@ -827,11 +827,11 @@ "id": "gap 0", "type": "rectangle", "pos": { - "x": 840, - "y": 0 + "x": 957, + "y": 100 }, - "width": 360, - "height": 398, + "width": 280, + "height": 318, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -868,8 +868,8 @@ "id": "gap 0.a", "type": "rectangle", "pos": { - "x": 900, - "y": 60 + "x": 1017, + "y": 160 }, "width": 54, "height": 66, @@ -909,8 +909,8 @@ "id": "gap 0.b", "type": "rectangle", "pos": { - "x": 994, - "y": 60 + "x": 1071, + "y": 160 }, "width": 53, "height": 66, @@ -950,8 +950,8 @@ "id": "gap 0.c", "type": "rectangle", "pos": { - "x": 1087, - "y": 60 + "x": 1124, + "y": 160 }, "width": 53, "height": 66, @@ -991,8 +991,8 @@ "id": "gap 0.d", "type": "rectangle", "pos": { - "x": 900, - "y": 166 + "x": 1017, + "y": 226 }, "width": 54, "height": 66, @@ -1032,8 +1032,8 @@ "id": "gap 0.e", "type": "rectangle", "pos": { - "x": 994, - "y": 166 + "x": 1071, + "y": 226 }, "width": 53, "height": 66, @@ -1073,8 +1073,8 @@ "id": "gap 0.f", "type": "rectangle", "pos": { - "x": 1087, - "y": 166 + "x": 1124, + "y": 226 }, "width": 53, "height": 66, @@ -1114,8 +1114,8 @@ "id": "gap 0.g", "type": "rectangle", "pos": { - "x": 900, - "y": 272 + "x": 1017, + "y": 292 }, "width": 54, "height": 66, @@ -1155,8 +1155,8 @@ "id": "gap 0.h", "type": "rectangle", "pos": { - "x": 994, - "y": 272 + "x": 1071, + "y": 292 }, "width": 53, "height": 66, @@ -1196,8 +1196,8 @@ "id": "gap 0.i", "type": "rectangle", "pos": { - "x": 1087, - "y": 272 + "x": 1124, + "y": 292 }, "width": 53, "height": 66, @@ -1237,11 +1237,11 @@ "id": "gap 10 gap-rows 100", "type": "rectangle", "pos": { - "x": 1260, + "x": 1297, "y": 0 }, - "width": 360, - "height": 398, + "width": 300, + "height": 518, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1278,7 +1278,7 @@ "id": "gap 10 gap-rows 100.a", "type": "rectangle", "pos": { - "x": 1320, + "x": 1357, "y": 60 }, "width": 54, @@ -1319,7 +1319,7 @@ "id": "gap 10 gap-rows 100.b", "type": "rectangle", "pos": { - "x": 1414, + "x": 1421, "y": 60 }, "width": 53, @@ -1360,7 +1360,7 @@ "id": "gap 10 gap-rows 100.c", "type": "rectangle", "pos": { - "x": 1507, + "x": 1484, "y": 60 }, "width": 53, @@ -1401,8 +1401,8 @@ "id": "gap 10 gap-rows 100.d", "type": "rectangle", "pos": { - "x": 1320, - "y": 166 + "x": 1357, + "y": 226 }, "width": 54, "height": 66, @@ -1442,8 +1442,8 @@ "id": "gap 10 gap-rows 100.e", "type": "rectangle", "pos": { - "x": 1414, - "y": 166 + "x": 1421, + "y": 226 }, "width": 53, "height": 66, @@ -1483,8 +1483,8 @@ "id": "gap 10 gap-rows 100.f", "type": "rectangle", "pos": { - "x": 1507, - "y": 166 + "x": 1484, + "y": 226 }, "width": 53, "height": 66, @@ -1524,8 +1524,8 @@ "id": "gap 10 gap-rows 100.g", "type": "rectangle", "pos": { - "x": 1320, - "y": 272 + "x": 1357, + "y": 392 }, "width": 54, "height": 66, @@ -1565,8 +1565,8 @@ "id": "gap 10 gap-rows 100.h", "type": "rectangle", "pos": { - "x": 1414, - "y": 272 + "x": 1421, + "y": 392 }, "width": 53, "height": 66, @@ -1606,8 +1606,8 @@ "id": "gap 10 gap-rows 100.i", "type": "rectangle", "pos": { - "x": 1507, - "y": 272 + "x": 1484, + "y": 392 }, "width": 53, "height": 66, diff --git a/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg index 1be6b8dda..baf862336 100644 --- a/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi - + .d2-543557256 .fill-N1{fill:#0A0F25;} + .d2-543557256 .fill-N2{fill:#676C7E;} + .d2-543557256 .fill-N3{fill:#9499AB;} + .d2-543557256 .fill-N4{fill:#CFD2DD;} + .d2-543557256 .fill-N5{fill:#DEE1EB;} + .d2-543557256 .fill-N6{fill:#EEF1F8;} + .d2-543557256 .fill-N7{fill:#FFFFFF;} + .d2-543557256 .fill-B1{fill:#0D32B2;} + .d2-543557256 .fill-B2{fill:#0D32B2;} + .d2-543557256 .fill-B3{fill:#E3E9FD;} + .d2-543557256 .fill-B4{fill:#E3E9FD;} + .d2-543557256 .fill-B5{fill:#EDF0FD;} + .d2-543557256 .fill-B6{fill:#F7F8FE;} + .d2-543557256 .fill-AA2{fill:#4A6FF3;} + .d2-543557256 .fill-AA4{fill:#EDF0FD;} + .d2-543557256 .fill-AA5{fill:#F7F8FE;} + .d2-543557256 .fill-AB4{fill:#EDF0FD;} + .d2-543557256 .fill-AB5{fill:#F7F8FE;} + .d2-543557256 .stroke-N1{stroke:#0A0F25;} + .d2-543557256 .stroke-N2{stroke:#676C7E;} + .d2-543557256 .stroke-N3{stroke:#9499AB;} + .d2-543557256 .stroke-N4{stroke:#CFD2DD;} + .d2-543557256 .stroke-N5{stroke:#DEE1EB;} + .d2-543557256 .stroke-N6{stroke:#EEF1F8;} + .d2-543557256 .stroke-N7{stroke:#FFFFFF;} + .d2-543557256 .stroke-B1{stroke:#0D32B2;} + .d2-543557256 .stroke-B2{stroke:#0D32B2;} + .d2-543557256 .stroke-B3{stroke:#E3E9FD;} + .d2-543557256 .stroke-B4{stroke:#E3E9FD;} + .d2-543557256 .stroke-B5{stroke:#EDF0FD;} + .d2-543557256 .stroke-B6{stroke:#F7F8FE;} + .d2-543557256 .stroke-AA2{stroke:#4A6FF3;} + .d2-543557256 .stroke-AA4{stroke:#EDF0FD;} + .d2-543557256 .stroke-AA5{stroke:#F7F8FE;} + .d2-543557256 .stroke-AB4{stroke:#EDF0FD;} + .d2-543557256 .stroke-AB5{stroke:#F7F8FE;} + .d2-543557256 .background-color-N1{background-color:#0A0F25;} + .d2-543557256 .background-color-N2{background-color:#676C7E;} + .d2-543557256 .background-color-N3{background-color:#9499AB;} + .d2-543557256 .background-color-N4{background-color:#CFD2DD;} + .d2-543557256 .background-color-N5{background-color:#DEE1EB;} + .d2-543557256 .background-color-N6{background-color:#EEF1F8;} + .d2-543557256 .background-color-N7{background-color:#FFFFFF;} + .d2-543557256 .background-color-B1{background-color:#0D32B2;} + .d2-543557256 .background-color-B2{background-color:#0D32B2;} + .d2-543557256 .background-color-B3{background-color:#E3E9FD;} + .d2-543557256 .background-color-B4{background-color:#E3E9FD;} + .d2-543557256 .background-color-B5{background-color:#EDF0FD;} + .d2-543557256 .background-color-B6{background-color:#F7F8FE;} + .d2-543557256 .background-color-AA2{background-color:#4A6FF3;} + .d2-543557256 .background-color-AA4{background-color:#EDF0FD;} + .d2-543557256 .background-color-AA5{background-color:#F7F8FE;} + .d2-543557256 .background-color-AB4{background-color:#EDF0FD;} + .d2-543557256 .background-color-AB5{background-color:#F7F8FE;} + .d2-543557256 .color-N1{color:#0A0F25;} + .d2-543557256 .color-N2{color:#676C7E;} + .d2-543557256 .color-N3{color:#9499AB;} + .d2-543557256 .color-N4{color:#CFD2DD;} + .d2-543557256 .color-N5{color:#DEE1EB;} + .d2-543557256 .color-N6{color:#EEF1F8;} + .d2-543557256 .color-N7{color:#FFFFFF;} + .d2-543557256 .color-B1{color:#0D32B2;} + .d2-543557256 .color-B2{color:#0D32B2;} + .d2-543557256 .color-B3{color:#E3E9FD;} + .d2-543557256 .color-B4{color:#E3E9FD;} + .d2-543557256 .color-B5{color:#EDF0FD;} + .d2-543557256 .color-B6{color:#F7F8FE;} + .d2-543557256 .color-AA2{color:#4A6FF3;} + .d2-543557256 .color-AA4{color:#EDF0FD;} + .d2-543557256 .color-AA5{color:#F7F8FE;} + .d2-543557256 .color-AB4{color:#EDF0FD;} + .d2-543557256 .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}]]>gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi + \ No newline at end of file diff --git a/e2etests/testdata/stable/grid_gap/elk/board.exp.json b/e2etests/testdata/stable/grid_gap/elk/board.exp.json index a9928b1c6..aee05b201 100644 --- a/e2etests/testdata/stable/grid_gap/elk/board.exp.json +++ b/e2etests/testdata/stable/grid_gap/elk/board.exp.json @@ -8,10 +8,10 @@ "type": "rectangle", "pos": { "x": 12, - "y": 12 + "y": 82 }, - "width": 360, - "height": 398, + "width": 480, + "height": 378, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -49,7 +49,7 @@ "type": "rectangle", "pos": { "x": 72, - "y": 72 + "y": 142 }, "width": 54, "height": 66, @@ -89,8 +89,8 @@ "id": "gap-rows 30 gap-columns 100.b", "type": "rectangle", "pos": { - "x": 166, - "y": 72 + "x": 226, + "y": 142 }, "width": 53, "height": 66, @@ -130,8 +130,8 @@ "id": "gap-rows 30 gap-columns 100.c", "type": "rectangle", "pos": { - "x": 259, - "y": 72 + "x": 379, + "y": 142 }, "width": 53, "height": 66, @@ -172,7 +172,7 @@ "type": "rectangle", "pos": { "x": 72, - "y": 178 + "y": 238 }, "width": 54, "height": 66, @@ -212,8 +212,8 @@ "id": "gap-rows 30 gap-columns 100.e", "type": "rectangle", "pos": { - "x": 166, - "y": 178 + "x": 226, + "y": 238 }, "width": 53, "height": 66, @@ -253,8 +253,8 @@ "id": "gap-rows 30 gap-columns 100.f", "type": "rectangle", "pos": { - "x": 259, - "y": 178 + "x": 379, + "y": 238 }, "width": 53, "height": 66, @@ -295,7 +295,7 @@ "type": "rectangle", "pos": { "x": 72, - "y": 284 + "y": 334 }, "width": 54, "height": 66, @@ -335,8 +335,8 @@ "id": "gap-rows 30 gap-columns 100.h", "type": "rectangle", "pos": { - "x": 166, - "y": 284 + "x": 226, + "y": 334 }, "width": 53, "height": 66, @@ -376,8 +376,8 @@ "id": "gap-rows 30 gap-columns 100.i", "type": "rectangle", "pos": { - "x": 259, - "y": 284 + "x": 379, + "y": 334 }, "width": 53, "height": 66, @@ -417,11 +417,11 @@ "id": "gap-rows 100 gap-columns 30", "type": "rectangle", "pos": { - "x": 392, + "x": 512, "y": 12 }, - "width": 360, - "height": 398, + "width": 357, + "height": 518, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -458,7 +458,7 @@ "id": "gap-rows 100 gap-columns 30.a", "type": "rectangle", "pos": { - "x": 452, + "x": 580, "y": 72 }, "width": 54, @@ -499,7 +499,7 @@ "id": "gap-rows 100 gap-columns 30.b", "type": "rectangle", "pos": { - "x": 546, + "x": 664, "y": 72 }, "width": 53, @@ -540,7 +540,7 @@ "id": "gap-rows 100 gap-columns 30.c", "type": "rectangle", "pos": { - "x": 639, + "x": 747, "y": 72 }, "width": 53, @@ -581,8 +581,8 @@ "id": "gap-rows 100 gap-columns 30.d", "type": "rectangle", "pos": { - "x": 452, - "y": 178 + "x": 580, + "y": 238 }, "width": 54, "height": 66, @@ -622,8 +622,8 @@ "id": "gap-rows 100 gap-columns 30.e", "type": "rectangle", "pos": { - "x": 546, - "y": 178 + "x": 664, + "y": 238 }, "width": 53, "height": 66, @@ -663,8 +663,8 @@ "id": "gap-rows 100 gap-columns 30.f", "type": "rectangle", "pos": { - "x": 639, - "y": 178 + "x": 747, + "y": 238 }, "width": 53, "height": 66, @@ -704,8 +704,8 @@ "id": "gap-rows 100 gap-columns 30.g", "type": "rectangle", "pos": { - "x": 452, - "y": 284 + "x": 580, + "y": 404 }, "width": 54, "height": 66, @@ -745,8 +745,8 @@ "id": "gap-rows 100 gap-columns 30.h", "type": "rectangle", "pos": { - "x": 546, - "y": 284 + "x": 664, + "y": 404 }, "width": 53, "height": 66, @@ -786,8 +786,8 @@ "id": "gap-rows 100 gap-columns 30.i", "type": "rectangle", "pos": { - "x": 639, - "y": 284 + "x": 747, + "y": 404 }, "width": 53, "height": 66, @@ -827,11 +827,11 @@ "id": "gap 0", "type": "rectangle", "pos": { - "x": 772, - "y": 12 + "x": 889, + "y": 112 }, - "width": 360, - "height": 398, + "width": 280, + "height": 318, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -868,8 +868,8 @@ "id": "gap 0.a", "type": "rectangle", "pos": { - "x": 832, - "y": 72 + "x": 949, + "y": 172 }, "width": 54, "height": 66, @@ -909,8 +909,8 @@ "id": "gap 0.b", "type": "rectangle", "pos": { - "x": 926, - "y": 72 + "x": 1003, + "y": 172 }, "width": 53, "height": 66, @@ -950,8 +950,8 @@ "id": "gap 0.c", "type": "rectangle", "pos": { - "x": 1019, - "y": 72 + "x": 1056, + "y": 172 }, "width": 53, "height": 66, @@ -991,8 +991,8 @@ "id": "gap 0.d", "type": "rectangle", "pos": { - "x": 832, - "y": 178 + "x": 949, + "y": 238 }, "width": 54, "height": 66, @@ -1032,8 +1032,8 @@ "id": "gap 0.e", "type": "rectangle", "pos": { - "x": 926, - "y": 178 + "x": 1003, + "y": 238 }, "width": 53, "height": 66, @@ -1073,8 +1073,8 @@ "id": "gap 0.f", "type": "rectangle", "pos": { - "x": 1019, - "y": 178 + "x": 1056, + "y": 238 }, "width": 53, "height": 66, @@ -1114,8 +1114,8 @@ "id": "gap 0.g", "type": "rectangle", "pos": { - "x": 832, - "y": 284 + "x": 949, + "y": 304 }, "width": 54, "height": 66, @@ -1155,8 +1155,8 @@ "id": "gap 0.h", "type": "rectangle", "pos": { - "x": 926, - "y": 284 + "x": 1003, + "y": 304 }, "width": 53, "height": 66, @@ -1196,8 +1196,8 @@ "id": "gap 0.i", "type": "rectangle", "pos": { - "x": 1019, - "y": 284 + "x": 1056, + "y": 304 }, "width": 53, "height": 66, @@ -1237,11 +1237,11 @@ "id": "gap 10 gap-rows 100", "type": "rectangle", "pos": { - "x": 1152, + "x": 1189, "y": 12 }, - "width": 360, - "height": 398, + "width": 300, + "height": 518, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -1278,7 +1278,7 @@ "id": "gap 10 gap-rows 100.a", "type": "rectangle", "pos": { - "x": 1212, + "x": 1249, "y": 72 }, "width": 54, @@ -1319,7 +1319,7 @@ "id": "gap 10 gap-rows 100.b", "type": "rectangle", "pos": { - "x": 1306, + "x": 1313, "y": 72 }, "width": 53, @@ -1360,7 +1360,7 @@ "id": "gap 10 gap-rows 100.c", "type": "rectangle", "pos": { - "x": 1399, + "x": 1376, "y": 72 }, "width": 53, @@ -1401,8 +1401,8 @@ "id": "gap 10 gap-rows 100.d", "type": "rectangle", "pos": { - "x": 1212, - "y": 178 + "x": 1249, + "y": 238 }, "width": 54, "height": 66, @@ -1442,8 +1442,8 @@ "id": "gap 10 gap-rows 100.e", "type": "rectangle", "pos": { - "x": 1306, - "y": 178 + "x": 1313, + "y": 238 }, "width": 53, "height": 66, @@ -1483,8 +1483,8 @@ "id": "gap 10 gap-rows 100.f", "type": "rectangle", "pos": { - "x": 1399, - "y": 178 + "x": 1376, + "y": 238 }, "width": 53, "height": 66, @@ -1524,8 +1524,8 @@ "id": "gap 10 gap-rows 100.g", "type": "rectangle", "pos": { - "x": 1212, - "y": 284 + "x": 1249, + "y": 404 }, "width": 54, "height": 66, @@ -1565,8 +1565,8 @@ "id": "gap 10 gap-rows 100.h", "type": "rectangle", "pos": { - "x": 1306, - "y": 284 + "x": 1313, + "y": 404 }, "width": 53, "height": 66, @@ -1606,8 +1606,8 @@ "id": "gap 10 gap-rows 100.i", "type": "rectangle", "pos": { - "x": 1399, - "y": 284 + "x": 1376, + "y": 404 }, "width": 53, "height": 66, diff --git a/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg index 43cef7f13..5706fc96e 100644 --- a/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi - + .d2-2329623851 .fill-N1{fill:#0A0F25;} + .d2-2329623851 .fill-N2{fill:#676C7E;} + .d2-2329623851 .fill-N3{fill:#9499AB;} + .d2-2329623851 .fill-N4{fill:#CFD2DD;} + .d2-2329623851 .fill-N5{fill:#DEE1EB;} + .d2-2329623851 .fill-N6{fill:#EEF1F8;} + .d2-2329623851 .fill-N7{fill:#FFFFFF;} + .d2-2329623851 .fill-B1{fill:#0D32B2;} + .d2-2329623851 .fill-B2{fill:#0D32B2;} + .d2-2329623851 .fill-B3{fill:#E3E9FD;} + .d2-2329623851 .fill-B4{fill:#E3E9FD;} + .d2-2329623851 .fill-B5{fill:#EDF0FD;} + .d2-2329623851 .fill-B6{fill:#F7F8FE;} + .d2-2329623851 .fill-AA2{fill:#4A6FF3;} + .d2-2329623851 .fill-AA4{fill:#EDF0FD;} + .d2-2329623851 .fill-AA5{fill:#F7F8FE;} + .d2-2329623851 .fill-AB4{fill:#EDF0FD;} + .d2-2329623851 .fill-AB5{fill:#F7F8FE;} + .d2-2329623851 .stroke-N1{stroke:#0A0F25;} + .d2-2329623851 .stroke-N2{stroke:#676C7E;} + .d2-2329623851 .stroke-N3{stroke:#9499AB;} + .d2-2329623851 .stroke-N4{stroke:#CFD2DD;} + .d2-2329623851 .stroke-N5{stroke:#DEE1EB;} + .d2-2329623851 .stroke-N6{stroke:#EEF1F8;} + .d2-2329623851 .stroke-N7{stroke:#FFFFFF;} + .d2-2329623851 .stroke-B1{stroke:#0D32B2;} + .d2-2329623851 .stroke-B2{stroke:#0D32B2;} + .d2-2329623851 .stroke-B3{stroke:#E3E9FD;} + .d2-2329623851 .stroke-B4{stroke:#E3E9FD;} + .d2-2329623851 .stroke-B5{stroke:#EDF0FD;} + .d2-2329623851 .stroke-B6{stroke:#F7F8FE;} + .d2-2329623851 .stroke-AA2{stroke:#4A6FF3;} + .d2-2329623851 .stroke-AA4{stroke:#EDF0FD;} + .d2-2329623851 .stroke-AA5{stroke:#F7F8FE;} + .d2-2329623851 .stroke-AB4{stroke:#EDF0FD;} + .d2-2329623851 .stroke-AB5{stroke:#F7F8FE;} + .d2-2329623851 .background-color-N1{background-color:#0A0F25;} + .d2-2329623851 .background-color-N2{background-color:#676C7E;} + .d2-2329623851 .background-color-N3{background-color:#9499AB;} + .d2-2329623851 .background-color-N4{background-color:#CFD2DD;} + .d2-2329623851 .background-color-N5{background-color:#DEE1EB;} + .d2-2329623851 .background-color-N6{background-color:#EEF1F8;} + .d2-2329623851 .background-color-N7{background-color:#FFFFFF;} + .d2-2329623851 .background-color-B1{background-color:#0D32B2;} + .d2-2329623851 .background-color-B2{background-color:#0D32B2;} + .d2-2329623851 .background-color-B3{background-color:#E3E9FD;} + .d2-2329623851 .background-color-B4{background-color:#E3E9FD;} + .d2-2329623851 .background-color-B5{background-color:#EDF0FD;} + .d2-2329623851 .background-color-B6{background-color:#F7F8FE;} + .d2-2329623851 .background-color-AA2{background-color:#4A6FF3;} + .d2-2329623851 .background-color-AA4{background-color:#EDF0FD;} + .d2-2329623851 .background-color-AA5{background-color:#F7F8FE;} + .d2-2329623851 .background-color-AB4{background-color:#EDF0FD;} + .d2-2329623851 .background-color-AB5{background-color:#F7F8FE;} + .d2-2329623851 .color-N1{color:#0A0F25;} + .d2-2329623851 .color-N2{color:#676C7E;} + .d2-2329623851 .color-N3{color:#9499AB;} + .d2-2329623851 .color-N4{color:#CFD2DD;} + .d2-2329623851 .color-N5{color:#DEE1EB;} + .d2-2329623851 .color-N6{color:#EEF1F8;} + .d2-2329623851 .color-N7{color:#FFFFFF;} + .d2-2329623851 .color-B1{color:#0D32B2;} + .d2-2329623851 .color-B2{color:#0D32B2;} + .d2-2329623851 .color-B3{color:#E3E9FD;} + .d2-2329623851 .color-B4{color:#E3E9FD;} + .d2-2329623851 .color-B5{color:#EDF0FD;} + .d2-2329623851 .color-B6{color:#F7F8FE;} + .d2-2329623851 .color-AA2{color:#4A6FF3;} + .d2-2329623851 .color-AA4{color:#EDF0FD;} + .d2-2329623851 .color-AA5{color:#F7F8FE;} + .d2-2329623851 .color-AB4{color:#EDF0FD;} + .d2-2329623851 .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}]]>gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi + \ No newline at end of file From 42993b09f09ed05568f3cf032524eb235394628c Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 20:09:01 -0700 Subject: [PATCH 6/9] 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 d7ff59fef..cddda9036 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,6 +1,7 @@ #### Features 🚀 - Export diagrams to `.pptx` (PowerPoint)[#1139](https://github.com/terrastruct/d2/pull/1139) +- Customize gap size in grid diagrams with `grid-gap`, `grid-gap-rows`, or `grid-gap-columns` [#1178](https://github.com/terrastruct/d2/issues/1178) #### Improvements 🧹 From d835ef19a913d97a7dabb1f3309b45cf753f5f26 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 11 Apr 2023 11:20:21 -0700 Subject: [PATCH 7/9] if storing int and casting float64 each use --- d2layouts/d2grid/grid_diagram.go | 10 ++++---- d2layouts/d2grid/layout.go | 44 ++++++++++++++++---------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index 0cb9514e6..852a324c4 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -20,8 +20,8 @@ type gridDiagram struct { width float64 height float64 - gapRows float64 - gapColumns float64 + gapRows int + gapColumns int } func newGridDiagram(root *d2graph.Object) *gridDiagram { @@ -77,14 +77,14 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { // grid gap sets both, but can be overridden if root.Attributes.GridGap != nil { - gd.gapRows, _ = strconv.ParseFloat(root.Attributes.GridGap.Value, 64) + gd.gapRows, _ = strconv.Atoi(root.Attributes.GridGap.Value) gd.gapColumns = gd.gapRows } if root.Attributes.GridGapRows != nil { - gd.gapRows, _ = strconv.ParseFloat(root.Attributes.GridGapRows.Value, 64) + gd.gapRows, _ = strconv.Atoi(root.Attributes.GridGapRows.Value) } if root.Attributes.GridGapColumns != nil { - gd.gapColumns, _ = strconv.ParseFloat(root.Attributes.GridGapColumns.Value, 64) + gd.gapColumns, _ = strconv.Atoi(root.Attributes.GridGapColumns.Value) } return &gd diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index e51f70d02..69cdf210c 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -13,7 +13,7 @@ import ( const ( CONTAINER_PADDING = 60 - DEFAULT_GAP = 40. + DEFAULT_GAP = 40 ) // Layout runs the grid layout on containers with rows/columns @@ -188,10 +188,10 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.X += o.Width + gd.gapColumns + cursor.X += o.Width + float64(gd.gapColumns) } cursor.X = 0 - cursor.Y += rowHeights[i] + gd.gapRows + cursor.Y += rowHeights[i] + float64(gd.gapRows) } } else { for j := 0; j < gd.columns; j++ { @@ -203,22 +203,22 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.Y += o.Height + gd.gapRows + cursor.Y += o.Height + float64(gd.gapRows) } - cursor.X += colWidths[j] + gd.gapColumns + cursor.X += colWidths[j] + float64(gd.gapColumns) cursor.Y = 0 } } var totalWidth, totalHeight float64 for _, w := range colWidths { - totalWidth += w + gd.gapColumns + totalWidth += w + float64(gd.gapColumns) } for _, h := range rowHeights { - totalHeight += h + gd.gapRows + totalHeight += h + float64(gd.gapRows) } - totalWidth -= gd.gapColumns - totalHeight -= gd.gapRows + totalWidth -= float64(gd.gapColumns) + totalHeight -= float64(gd.gapRows) gd.width = totalWidth gd.height = totalHeight } @@ -245,8 +245,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { totalWidth += o.Width totalHeight += o.Height } - totalWidth += gd.gapColumns * float64(len(gd.objects)-gd.rows) - totalHeight += gd.gapRows * float64(len(gd.objects)-gd.columns) + totalWidth += float64(gd.gapColumns * (len(gd.objects) - gd.rows)) + totalHeight += float64(gd.gapRows * (len(gd.objects) - gd.columns)) var layout [][]*d2graph.Object if gd.rowDirected { @@ -277,10 +277,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowHeight := 0. for _, o := range row { o.TopLeft = cursor.Copy() - cursor.X += o.Width + gd.gapColumns + cursor.X += o.Width + float64(gd.gapColumns) rowHeight = math.Max(rowHeight, o.Height) } - rowWidth := cursor.X - gd.gapColumns + rowWidth := cursor.X - float64(gd.gapColumns) rowWidths = append(rowWidths, rowWidth) maxX = math.Max(maxX, rowWidth) @@ -291,9 +291,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new row cursor.X = 0 - cursor.Y += rowHeight + gd.gapRows + cursor.Y += rowHeight + float64(gd.gapRows) } - maxY = cursor.Y - gd.gapRows + maxY = cursor.Y - float64(gd.gapRows) // then expand thinnest objects to make each row the same width // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) @@ -371,10 +371,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colWidth := 0. for _, o := range column { o.TopLeft = cursor.Copy() - cursor.Y += o.Height + gd.gapRows + cursor.Y += o.Height + float64(gd.gapRows) colWidth = math.Max(colWidth, o.Width) } - colHeight := cursor.Y - gd.gapRows + colHeight := cursor.Y - float64(gd.gapRows) colHeights = append(colHeights, colHeight) maxY = math.Max(maxY, colHeight) // set all objects in column to the same width @@ -384,9 +384,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new column cursor.Y = 0 - cursor.X += colWidth + gd.gapColumns + cursor.X += colWidth + float64(gd.gapColumns) } - maxX = cursor.X - gd.gapColumns + maxX = cursor.X - float64(gd.gapColumns) // then expand shortest objects to make each column the same height // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ @@ -526,15 +526,15 @@ func genLayout(objects []*d2graph.Object, cutIndices []int) [][]*d2graph.Object return layout } -func getDistToTarget(layout [][]*d2graph.Object, targetSize, gapRows, gapColumns float64, columns bool) float64 { +func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, gapRows, gapColumns int, columns bool) float64 { totalDelta := 0. for _, row := range layout { rowSize := 0. for _, o := range row { if columns { - rowSize += o.Height + gapRows + rowSize += o.Height + float64(gapRows) } else { - rowSize += o.Width + gapColumns + rowSize += o.Width + float64(gapColumns) } } totalDelta += math.Abs(rowSize - targetSize) From 7631efce2bfe91a5878676b6134ba3f5d153f2d4 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Tue, 11 Apr 2023 11:32:35 -0700 Subject: [PATCH 8/9] cleanup --- d2layouts/d2grid/layout.go | 50 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 69cdf210c..242e50c05 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -177,6 +177,9 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { colWidths = append(colWidths, columnWidth) } + horizontalGap := float64(gd.gapColumns) + verticalGap := float64(gd.gapRows) + cursor := geo.NewPoint(0, 0) if gd.rowDirected { for i := 0; i < gd.rows; i++ { @@ -188,10 +191,10 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.X += o.Width + float64(gd.gapColumns) + cursor.X += o.Width + horizontalGap } cursor.X = 0 - cursor.Y += rowHeights[i] + float64(gd.gapRows) + cursor.Y += rowHeights[i] + verticalGap } } else { for j := 0; j < gd.columns; j++ { @@ -203,22 +206,22 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.Y += o.Height + float64(gd.gapRows) + cursor.Y += o.Height + verticalGap } - cursor.X += colWidths[j] + float64(gd.gapColumns) + cursor.X += colWidths[j] + horizontalGap cursor.Y = 0 } } var totalWidth, totalHeight float64 for _, w := range colWidths { - totalWidth += w + float64(gd.gapColumns) + totalWidth += w + horizontalGap } for _, h := range rowHeights { - totalHeight += h + float64(gd.gapRows) + totalHeight += h + verticalGap } - totalWidth -= float64(gd.gapColumns) - totalHeight -= float64(gd.gapRows) + totalWidth -= horizontalGap + totalHeight -= verticalGap gd.width = totalWidth gd.height = totalHeight } @@ -239,14 +242,17 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // . │ │ ├ ─ ┤ │ │ │ │ │ │ // . └──────────────┘ └───┘ └──────────┘ └─────────┘ └─────────────────┘ + horizontalGap := float64(gd.gapColumns) + verticalGap := float64(gd.gapRows) + // we want to split up the total width across the N rows or columns as evenly as possible var totalWidth, totalHeight float64 for _, o := range gd.objects { totalWidth += o.Width totalHeight += o.Height } - totalWidth += float64(gd.gapColumns * (len(gd.objects) - gd.rows)) - totalHeight += float64(gd.gapRows * (len(gd.objects) - gd.columns)) + totalWidth += horizontalGap * float64(len(gd.objects)-gd.rows) + totalHeight += verticalGap * float64(len(gd.objects)-gd.columns) var layout [][]*d2graph.Object if gd.rowDirected { @@ -277,10 +283,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowHeight := 0. for _, o := range row { o.TopLeft = cursor.Copy() - cursor.X += o.Width + float64(gd.gapColumns) + cursor.X += o.Width + horizontalGap rowHeight = math.Max(rowHeight, o.Height) } - rowWidth := cursor.X - float64(gd.gapColumns) + rowWidth := cursor.X - horizontalGap rowWidths = append(rowWidths, rowWidth) maxX = math.Max(maxX, rowWidth) @@ -291,9 +297,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new row cursor.X = 0 - cursor.Y += rowHeight + float64(gd.gapRows) + cursor.Y += rowHeight + verticalGap } - maxY = cursor.Y - float64(gd.gapRows) + maxY = cursor.Y - horizontalGap // then expand thinnest objects to make each row the same width // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) @@ -371,10 +377,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colWidth := 0. for _, o := range column { o.TopLeft = cursor.Copy() - cursor.Y += o.Height + float64(gd.gapRows) + cursor.Y += o.Height + verticalGap colWidth = math.Max(colWidth, o.Width) } - colHeight := cursor.Y - float64(gd.gapRows) + colHeight := cursor.Y - verticalGap colHeights = append(colHeights, colHeight) maxY = math.Max(maxY, colHeight) // set all objects in column to the same width @@ -384,9 +390,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new column cursor.Y = 0 - cursor.X += colWidth + float64(gd.gapColumns) + cursor.X += colWidth + horizontalGap } - maxX = cursor.X - float64(gd.gapColumns) + maxX = cursor.X - horizontalGap // then expand shortest objects to make each column the same height // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ @@ -478,7 +484,7 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr // of these divisions, find the layout with rows closest to the targetSize for _, division := range divisions { layout := genLayout(gd.objects, division) - dist := getDistToTarget(layout, targetSize, gd.gapRows, gd.gapColumns, columns) + dist := getDistToTarget(layout, targetSize, float64(gd.gapColumns), float64(gd.gapRows), columns) if dist < bestDist { bestLayout = layout bestDist = dist @@ -526,15 +532,15 @@ func genLayout(objects []*d2graph.Object, cutIndices []int) [][]*d2graph.Object return layout } -func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, gapRows, gapColumns int, columns bool) float64 { +func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, horizontalGap, verticalGap float64, columns bool) float64 { totalDelta := 0. for _, row := range layout { rowSize := 0. for _, o := range row { if columns { - rowSize += o.Height + float64(gapRows) + rowSize += o.Height + verticalGap } else { - rowSize += o.Width + float64(gapColumns) + rowSize += o.Width + horizontalGap } } totalDelta += math.Abs(rowSize - targetSize) From c0e164e44bb692c1fe6918189fd0fc80953bd64f Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 12 Apr 2023 13:48:53 -0700 Subject: [PATCH 9/9] rename to horizontal-gap and vertical-gap --- ci/release/changelogs/next.md | 2 +- d2compiler/compile.go | 26 +-- d2compiler/compile_test.go | 8 +- d2graph/d2graph.go | 50 +++--- d2layouts/d2grid/grid_diagram.go | 24 +-- d2layouts/d2grid/layout.go | 10 +- d2oracle/edit.go | 12 +- e2etests/testdata/files/grid_gap.d2 | 16 +- .../stable/grid_gap/dagre/board.exp.json | 132 +++++++------- .../stable/grid_gap/dagre/sketch.exp.svg | 164 +++++++++--------- .../stable/grid_gap/elk/board.exp.json | 132 +++++++------- .../stable/grid_gap/elk/sketch.exp.svg | 164 +++++++++--------- .../TestCompile/grid_gap_negative.exp.json | 8 +- 13 files changed, 374 insertions(+), 374 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index cddda9036..a8a1cb5ec 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,7 +1,7 @@ #### Features 🚀 - Export diagrams to `.pptx` (PowerPoint)[#1139](https://github.com/terrastruct/d2/pull/1139) -- Customize gap size in grid diagrams with `grid-gap`, `grid-gap-rows`, or `grid-gap-columns` [#1178](https://github.com/terrastruct/d2/issues/1178) +- Customize gap size in grid diagrams with `grid-gap`, `vertical-gap`, or `horizontal-gap` [#1178](https://github.com/terrastruct/d2/issues/1178) #### Improvements 🧹 diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 867b8a756..fc3b1bfec 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -433,32 +433,32 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { attrs.GridGap = &d2graph.Scalar{} attrs.GridGap.Value = scalar.ScalarString() attrs.GridGap.MapKey = f.LastPrimaryKey() - case "grid-gap-rows": + case "vertical-gap": v, err := strconv.Atoi(scalar.ScalarString()) if err != nil { - c.errorf(scalar, "non-integer grid-gap-rows %#v: %s", scalar.ScalarString(), err) + c.errorf(scalar, "non-integer vertical-gap %#v: %s", scalar.ScalarString(), err) return } if v < 0 { - c.errorf(scalar, "grid-gap-rows must be a non-negative integer: %#v", scalar.ScalarString()) + c.errorf(scalar, "vertical-gap must be a non-negative integer: %#v", scalar.ScalarString()) return } - attrs.GridGapRows = &d2graph.Scalar{} - attrs.GridGapRows.Value = scalar.ScalarString() - attrs.GridGapRows.MapKey = f.LastPrimaryKey() - case "grid-gap-columns": + attrs.VerticalGap = &d2graph.Scalar{} + attrs.VerticalGap.Value = scalar.ScalarString() + attrs.VerticalGap.MapKey = f.LastPrimaryKey() + case "horizontal-gap": v, err := strconv.Atoi(scalar.ScalarString()) if err != nil { - c.errorf(scalar, "non-integer grid-gap-columns %#v: %s", scalar.ScalarString(), err) + c.errorf(scalar, "non-integer horizontal-gap %#v: %s", scalar.ScalarString(), err) return } if v < 0 { - c.errorf(scalar, "grid-gap-columns must be a non-negative integer: %#v", scalar.ScalarString()) + c.errorf(scalar, "horizontal-gap must be a non-negative integer: %#v", scalar.ScalarString()) return } - attrs.GridGapColumns = &d2graph.Scalar{} - attrs.GridGapColumns.Value = scalar.ScalarString() - attrs.GridGapColumns.MapKey = f.LastPrimaryKey() + attrs.HorizontalGap = &d2graph.Scalar{} + attrs.HorizontalGap.Value = scalar.ScalarString() + attrs.HorizontalGap.MapKey = f.LastPrimaryKey() case "class": attrs.Classes = append(attrs.Classes, scalar.ScalarString()) case "classes": @@ -796,7 +796,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 "grid-rows", "grid-columns", "grid-gap", "grid-gap-rows", "grid-gap-columns": + case "grid-rows", "grid-columns", "grid-gap", "vertical-gap", "horizontal-gap": 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 ceb751603..c5750ff88 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2304,12 +2304,12 @@ obj { { name: "grid_gap_negative", text: `hey: { - grid-gap-columns: -200 - grid-gap-rows: -30 + horizontal-gap: -200 + vertical-gap: -30 } `, - expErr: `d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:2:20: grid-gap-columns must be a non-negative integer: "-200" -d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:3:17: grid-gap-rows must be a non-negative integer: "-30"`, + expErr: `d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:2:18: horizontal-gap must be a non-negative integer: "-200" +d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:3:16: vertical-gap must be a non-negative integer: "-30"`, }, { name: "grid_edge", diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 261e1af5f..d8ebc011e 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -136,11 +136,11 @@ type Attributes struct { Direction Scalar `json:"direction"` Constraint Scalar `json:"constraint"` - GridRows *Scalar `json:"gridRows,omitempty"` - GridColumns *Scalar `json:"gridColumns,omitempty"` - GridGap *Scalar `json:"gridGap,omitempty"` - GridGapRows *Scalar `json:"gridGapRows,omitempty"` - GridGapColumns *Scalar `json:"gridGapColumns,omitempty"` + GridRows *Scalar `json:"gridRows,omitempty"` + GridColumns *Scalar `json:"gridColumns,omitempty"` + GridGap *Scalar `json:"gridGap,omitempty"` + VerticalGap *Scalar `json:"verticalGap,omitempty"` + HorizontalGap *Scalar `json:"horizontalGap,omitempty"` // These names are attached to the rendered elements in SVG // so that users can target them however they like outside of D2 @@ -1591,26 +1591,26 @@ 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": {}, - "grid-rows": {}, - "grid-columns": {}, - "grid-gap": {}, - "grid-gap-rows": {}, - "grid-gap-columns": {}, - "class": {}, - "classes": {}, + "label": {}, + "desc": {}, + "shape": {}, + "icon": {}, + "constraint": {}, + "tooltip": {}, + "link": {}, + "near": {}, + "width": {}, + "height": {}, + "direction": {}, + "top": {}, + "left": {}, + "grid-rows": {}, + "grid-columns": {}, + "grid-gap": {}, + "vertical-gap": {}, + "horizontal-gap": {}, + "class": {}, + "classes": {}, } // ReservedKeywordHolders are reserved keywords that are meaningless on its own and exist solely to hold a set of reserved keywords diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index 852a324c4..462f54b69 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -20,16 +20,16 @@ type gridDiagram struct { width float64 height float64 - gapRows int - gapColumns int + verticalGap int + horizontalGap int } func newGridDiagram(root *d2graph.Object) *gridDiagram { gd := gridDiagram{ - root: root, - objects: root.ChildrenArray, - gapRows: DEFAULT_GAP, - gapColumns: DEFAULT_GAP, + root: root, + objects: root.ChildrenArray, + verticalGap: DEFAULT_GAP, + horizontalGap: DEFAULT_GAP, } if root.Attributes.GridRows != nil { @@ -77,14 +77,14 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { // grid gap sets both, but can be overridden if root.Attributes.GridGap != nil { - gd.gapRows, _ = strconv.Atoi(root.Attributes.GridGap.Value) - gd.gapColumns = gd.gapRows + gd.verticalGap, _ = strconv.Atoi(root.Attributes.GridGap.Value) + gd.horizontalGap = gd.verticalGap } - if root.Attributes.GridGapRows != nil { - gd.gapRows, _ = strconv.Atoi(root.Attributes.GridGapRows.Value) + if root.Attributes.VerticalGap != nil { + gd.verticalGap, _ = strconv.Atoi(root.Attributes.VerticalGap.Value) } - if root.Attributes.GridGapColumns != nil { - gd.gapColumns, _ = strconv.Atoi(root.Attributes.GridGapColumns.Value) + if root.Attributes.HorizontalGap != nil { + gd.horizontalGap, _ = strconv.Atoi(root.Attributes.HorizontalGap.Value) } return &gd diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 242e50c05..6650bd2c7 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -177,8 +177,8 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { colWidths = append(colWidths, columnWidth) } - horizontalGap := float64(gd.gapColumns) - verticalGap := float64(gd.gapRows) + horizontalGap := float64(gd.horizontalGap) + verticalGap := float64(gd.verticalGap) cursor := geo.NewPoint(0, 0) if gd.rowDirected { @@ -242,8 +242,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // . │ │ ├ ─ ┤ │ │ │ │ │ │ // . └──────────────┘ └───┘ └──────────┘ └─────────┘ └─────────────────┘ - horizontalGap := float64(gd.gapColumns) - verticalGap := float64(gd.gapRows) + horizontalGap := float64(gd.horizontalGap) + verticalGap := float64(gd.verticalGap) // we want to split up the total width across the N rows or columns as evenly as possible var totalWidth, totalHeight float64 @@ -484,7 +484,7 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr // of these divisions, find the layout with rows closest to the targetSize for _, division := range divisions { layout := genLayout(gd.objects, division) - dist := getDistToTarget(layout, targetSize, float64(gd.gapColumns), float64(gd.gapRows), columns) + dist := getDistToTarget(layout, targetSize, float64(gd.horizontalGap), float64(gd.verticalGap), columns) if dist < bestDist { bestLayout = layout bestDist = dist diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 7849aefea..2e3408114 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -329,14 +329,14 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.GridGap.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } - case "grid-gap-rows": - if attrs.GridGapRows != nil && attrs.GridGapRows.MapKey != nil { - attrs.GridGapRows.MapKey.SetScalar(mk.Value.ScalarBox()) + case "vertical-gap": + if attrs.VerticalGap != nil && attrs.VerticalGap.MapKey != nil { + attrs.VerticalGap.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } - case "grid-gap-columns": - if attrs.GridGapColumns != nil && attrs.GridGapColumns.MapKey != nil { - attrs.GridGapColumns.MapKey.SetScalar(mk.Value.ScalarBox()) + case "horizontal-gap": + if attrs.HorizontalGap != nil && attrs.HorizontalGap.MapKey != nil { + attrs.HorizontalGap.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } case "source-arrowhead", "target-arrowhead": diff --git a/e2etests/testdata/files/grid_gap.d2 b/e2etests/testdata/files/grid_gap.d2 index f8520902a..da62991c2 100644 --- a/e2etests/testdata/files/grid_gap.d2 +++ b/e2etests/testdata/files/grid_gap.d2 @@ -1,8 +1,8 @@ -gap-rows 30 gap-columns 100: { +vertical-gap 30 horizontal-gap 100: { grid-rows: 3 grid-columns: 3 - grid-gap-rows: 30 - grid-gap-columns: 100 + vertical-gap: 30 + horizontal-gap: 100 a b @@ -15,11 +15,11 @@ gap-rows 30 gap-columns 100: { i } -gap-rows 100 gap-columns 30: { +vertical-gap 100 horizontal-gap 30: { grid-rows: 3 grid-columns: 3 - grid-gap-rows: 100 - grid-gap-columns: 30 + vertical-gap: 100 + horizontal-gap: 30 a b @@ -48,11 +48,11 @@ gap 0: { i } -gap 10 gap-rows 100: { +gap 10 vertical-gap 100: { grid-rows: 3 grid-columns: 3 grid-gap: 10 - grid-gap-rows: 100 + vertical-gap: 100 a b diff --git a/e2etests/testdata/stable/grid_gap/dagre/board.exp.json b/e2etests/testdata/stable/grid_gap/dagre/board.exp.json index 702505891..3b198f9f0 100644 --- a/e2etests/testdata/stable/grid_gap/dagre/board.exp.json +++ b/e2etests/testdata/stable/grid_gap/dagre/board.exp.json @@ -4,7 +4,7 @@ "fontFamily": "SourceSansPro", "shapes": [ { - "id": "gap-rows 30 gap-columns 100", + "id": "vertical-gap 30 horizontal-gap 100", "type": "rectangle", "pos": { "x": 0, @@ -30,7 +30,7 @@ "fields": null, "methods": null, "columns": null, - "label": "gap-rows 30 gap-columns 100", + "label": "vertical-gap 30 horizontal-gap 100", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -38,14 +38,14 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 347, + "labelWidth": 398, "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "gap-rows 30 gap-columns 100.a", + "id": "vertical-gap 30 horizontal-gap 100.a", "type": "rectangle", "pos": { "x": 60, @@ -86,7 +86,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.b", + "id": "vertical-gap 30 horizontal-gap 100.b", "type": "rectangle", "pos": { "x": 214, @@ -127,7 +127,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.c", + "id": "vertical-gap 30 horizontal-gap 100.c", "type": "rectangle", "pos": { "x": 367, @@ -168,7 +168,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.d", + "id": "vertical-gap 30 horizontal-gap 100.d", "type": "rectangle", "pos": { "x": 60, @@ -209,7 +209,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.e", + "id": "vertical-gap 30 horizontal-gap 100.e", "type": "rectangle", "pos": { "x": 214, @@ -250,7 +250,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.f", + "id": "vertical-gap 30 horizontal-gap 100.f", "type": "rectangle", "pos": { "x": 367, @@ -291,7 +291,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.g", + "id": "vertical-gap 30 horizontal-gap 100.g", "type": "rectangle", "pos": { "x": 60, @@ -332,7 +332,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.h", + "id": "vertical-gap 30 horizontal-gap 100.h", "type": "rectangle", "pos": { "x": 214, @@ -373,7 +373,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.i", + "id": "vertical-gap 30 horizontal-gap 100.i", "type": "rectangle", "pos": { "x": 367, @@ -414,13 +414,13 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30", + "id": "vertical-gap 100 horizontal-gap 30", "type": "rectangle", "pos": { "x": 540, "y": 0 }, - "width": 357, + "width": 408, "height": 518, "opacity": 1, "strokeDash": 0, @@ -440,7 +440,7 @@ "fields": null, "methods": null, "columns": null, - "label": "gap-rows 100 gap-columns 30", + "label": "vertical-gap 100 horizontal-gap 30", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -448,17 +448,17 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 347, + "labelWidth": 398, "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "gap-rows 100 gap-columns 30.a", + "id": "vertical-gap 100 horizontal-gap 30.a", "type": "rectangle", "pos": { - "x": 608, + "x": 634, "y": 60 }, "width": 54, @@ -496,10 +496,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.b", + "id": "vertical-gap 100 horizontal-gap 30.b", "type": "rectangle", "pos": { - "x": 692, + "x": 718, "y": 60 }, "width": 53, @@ -537,10 +537,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.c", + "id": "vertical-gap 100 horizontal-gap 30.c", "type": "rectangle", "pos": { - "x": 775, + "x": 801, "y": 60 }, "width": 53, @@ -578,10 +578,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.d", + "id": "vertical-gap 100 horizontal-gap 30.d", "type": "rectangle", "pos": { - "x": 608, + "x": 634, "y": 226 }, "width": 54, @@ -619,10 +619,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.e", + "id": "vertical-gap 100 horizontal-gap 30.e", "type": "rectangle", "pos": { - "x": 692, + "x": 718, "y": 226 }, "width": 53, @@ -660,10 +660,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.f", + "id": "vertical-gap 100 horizontal-gap 30.f", "type": "rectangle", "pos": { - "x": 775, + "x": 801, "y": 226 }, "width": 53, @@ -701,10 +701,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.g", + "id": "vertical-gap 100 horizontal-gap 30.g", "type": "rectangle", "pos": { - "x": 608, + "x": 634, "y": 392 }, "width": 54, @@ -742,10 +742,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.h", + "id": "vertical-gap 100 horizontal-gap 30.h", "type": "rectangle", "pos": { - "x": 692, + "x": 718, "y": 392 }, "width": 53, @@ -783,10 +783,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.i", + "id": "vertical-gap 100 horizontal-gap 30.i", "type": "rectangle", "pos": { - "x": 775, + "x": 801, "y": 392 }, "width": 53, @@ -827,7 +827,7 @@ "id": "gap 0", "type": "rectangle", "pos": { - "x": 957, + "x": 1008, "y": 100 }, "width": 280, @@ -868,7 +868,7 @@ "id": "gap 0.a", "type": "rectangle", "pos": { - "x": 1017, + "x": 1068, "y": 160 }, "width": 54, @@ -909,7 +909,7 @@ "id": "gap 0.b", "type": "rectangle", "pos": { - "x": 1071, + "x": 1122, "y": 160 }, "width": 53, @@ -950,7 +950,7 @@ "id": "gap 0.c", "type": "rectangle", "pos": { - "x": 1124, + "x": 1175, "y": 160 }, "width": 53, @@ -991,7 +991,7 @@ "id": "gap 0.d", "type": "rectangle", "pos": { - "x": 1017, + "x": 1068, "y": 226 }, "width": 54, @@ -1032,7 +1032,7 @@ "id": "gap 0.e", "type": "rectangle", "pos": { - "x": 1071, + "x": 1122, "y": 226 }, "width": 53, @@ -1073,7 +1073,7 @@ "id": "gap 0.f", "type": "rectangle", "pos": { - "x": 1124, + "x": 1175, "y": 226 }, "width": 53, @@ -1114,7 +1114,7 @@ "id": "gap 0.g", "type": "rectangle", "pos": { - "x": 1017, + "x": 1068, "y": 292 }, "width": 54, @@ -1155,7 +1155,7 @@ "id": "gap 0.h", "type": "rectangle", "pos": { - "x": 1071, + "x": 1122, "y": 292 }, "width": 53, @@ -1196,7 +1196,7 @@ "id": "gap 0.i", "type": "rectangle", "pos": { - "x": 1124, + "x": 1175, "y": 292 }, "width": 53, @@ -1234,10 +1234,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100", + "id": "gap 10 vertical-gap 100", "type": "rectangle", "pos": { - "x": 1297, + "x": 1348, "y": 0 }, "width": 300, @@ -1260,7 +1260,7 @@ "fields": null, "methods": null, "columns": null, - "label": "gap 10 gap-rows 100", + "label": "gap 10 vertical-gap 100", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -1268,17 +1268,17 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 238, + "labelWidth": 268, "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "gap 10 gap-rows 100.a", + "id": "gap 10 vertical-gap 100.a", "type": "rectangle", "pos": { - "x": 1357, + "x": 1408, "y": 60 }, "width": 54, @@ -1316,10 +1316,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.b", + "id": "gap 10 vertical-gap 100.b", "type": "rectangle", "pos": { - "x": 1421, + "x": 1472, "y": 60 }, "width": 53, @@ -1357,10 +1357,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.c", + "id": "gap 10 vertical-gap 100.c", "type": "rectangle", "pos": { - "x": 1484, + "x": 1535, "y": 60 }, "width": 53, @@ -1398,10 +1398,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.d", + "id": "gap 10 vertical-gap 100.d", "type": "rectangle", "pos": { - "x": 1357, + "x": 1408, "y": 226 }, "width": 54, @@ -1439,10 +1439,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.e", + "id": "gap 10 vertical-gap 100.e", "type": "rectangle", "pos": { - "x": 1421, + "x": 1472, "y": 226 }, "width": 53, @@ -1480,10 +1480,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.f", + "id": "gap 10 vertical-gap 100.f", "type": "rectangle", "pos": { - "x": 1484, + "x": 1535, "y": 226 }, "width": 53, @@ -1521,10 +1521,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.g", + "id": "gap 10 vertical-gap 100.g", "type": "rectangle", "pos": { - "x": 1357, + "x": 1408, "y": 392 }, "width": 54, @@ -1562,10 +1562,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.h", + "id": "gap 10 vertical-gap 100.h", "type": "rectangle", "pos": { - "x": 1421, + "x": 1472, "y": 392 }, "width": 53, @@ -1603,10 +1603,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.i", + "id": "gap 10 vertical-gap 100.i", "type": "rectangle", "pos": { - "x": 1484, + "x": 1535, "y": 392 }, "width": 53, diff --git a/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg index baf862336..f70772277 100644 --- a/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_gap/dagre/sketch.exp.svg @@ -1,17 +1,17 @@ -gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi - + .d2-719907901 .fill-N1{fill:#0A0F25;} + .d2-719907901 .fill-N2{fill:#676C7E;} + .d2-719907901 .fill-N3{fill:#9499AB;} + .d2-719907901 .fill-N4{fill:#CFD2DD;} + .d2-719907901 .fill-N5{fill:#DEE1EB;} + .d2-719907901 .fill-N6{fill:#EEF1F8;} + .d2-719907901 .fill-N7{fill:#FFFFFF;} + .d2-719907901 .fill-B1{fill:#0D32B2;} + .d2-719907901 .fill-B2{fill:#0D32B2;} + .d2-719907901 .fill-B3{fill:#E3E9FD;} + .d2-719907901 .fill-B4{fill:#E3E9FD;} + .d2-719907901 .fill-B5{fill:#EDF0FD;} + .d2-719907901 .fill-B6{fill:#F7F8FE;} + .d2-719907901 .fill-AA2{fill:#4A6FF3;} + .d2-719907901 .fill-AA4{fill:#EDF0FD;} + .d2-719907901 .fill-AA5{fill:#F7F8FE;} + .d2-719907901 .fill-AB4{fill:#EDF0FD;} + .d2-719907901 .fill-AB5{fill:#F7F8FE;} + .d2-719907901 .stroke-N1{stroke:#0A0F25;} + .d2-719907901 .stroke-N2{stroke:#676C7E;} + .d2-719907901 .stroke-N3{stroke:#9499AB;} + .d2-719907901 .stroke-N4{stroke:#CFD2DD;} + .d2-719907901 .stroke-N5{stroke:#DEE1EB;} + .d2-719907901 .stroke-N6{stroke:#EEF1F8;} + .d2-719907901 .stroke-N7{stroke:#FFFFFF;} + .d2-719907901 .stroke-B1{stroke:#0D32B2;} + .d2-719907901 .stroke-B2{stroke:#0D32B2;} + .d2-719907901 .stroke-B3{stroke:#E3E9FD;} + .d2-719907901 .stroke-B4{stroke:#E3E9FD;} + .d2-719907901 .stroke-B5{stroke:#EDF0FD;} + .d2-719907901 .stroke-B6{stroke:#F7F8FE;} + .d2-719907901 .stroke-AA2{stroke:#4A6FF3;} + .d2-719907901 .stroke-AA4{stroke:#EDF0FD;} + .d2-719907901 .stroke-AA5{stroke:#F7F8FE;} + .d2-719907901 .stroke-AB4{stroke:#EDF0FD;} + .d2-719907901 .stroke-AB5{stroke:#F7F8FE;} + .d2-719907901 .background-color-N1{background-color:#0A0F25;} + .d2-719907901 .background-color-N2{background-color:#676C7E;} + .d2-719907901 .background-color-N3{background-color:#9499AB;} + .d2-719907901 .background-color-N4{background-color:#CFD2DD;} + .d2-719907901 .background-color-N5{background-color:#DEE1EB;} + .d2-719907901 .background-color-N6{background-color:#EEF1F8;} + .d2-719907901 .background-color-N7{background-color:#FFFFFF;} + .d2-719907901 .background-color-B1{background-color:#0D32B2;} + .d2-719907901 .background-color-B2{background-color:#0D32B2;} + .d2-719907901 .background-color-B3{background-color:#E3E9FD;} + .d2-719907901 .background-color-B4{background-color:#E3E9FD;} + .d2-719907901 .background-color-B5{background-color:#EDF0FD;} + .d2-719907901 .background-color-B6{background-color:#F7F8FE;} + .d2-719907901 .background-color-AA2{background-color:#4A6FF3;} + .d2-719907901 .background-color-AA4{background-color:#EDF0FD;} + .d2-719907901 .background-color-AA5{background-color:#F7F8FE;} + .d2-719907901 .background-color-AB4{background-color:#EDF0FD;} + .d2-719907901 .background-color-AB5{background-color:#F7F8FE;} + .d2-719907901 .color-N1{color:#0A0F25;} + .d2-719907901 .color-N2{color:#676C7E;} + .d2-719907901 .color-N3{color:#9499AB;} + .d2-719907901 .color-N4{color:#CFD2DD;} + .d2-719907901 .color-N5{color:#DEE1EB;} + .d2-719907901 .color-N6{color:#EEF1F8;} + .d2-719907901 .color-N7{color:#FFFFFF;} + .d2-719907901 .color-B1{color:#0D32B2;} + .d2-719907901 .color-B2{color:#0D32B2;} + .d2-719907901 .color-B3{color:#E3E9FD;} + .d2-719907901 .color-B4{color:#E3E9FD;} + .d2-719907901 .color-B5{color:#EDF0FD;} + .d2-719907901 .color-B6{color:#F7F8FE;} + .d2-719907901 .color-AA2{color:#4A6FF3;} + .d2-719907901 .color-AA4{color:#EDF0FD;} + .d2-719907901 .color-AA5{color:#F7F8FE;} + .d2-719907901 .color-AB4{color:#EDF0FD;} + .d2-719907901 .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}]]>vertical-gap 30 horizontal-gap 100vertical-gap 100 horizontal-gap 30gap 0gap 10 vertical-gap 100abcdefghiabcdefghiabcdefghiabcdefghi + \ No newline at end of file diff --git a/e2etests/testdata/stable/grid_gap/elk/board.exp.json b/e2etests/testdata/stable/grid_gap/elk/board.exp.json index aee05b201..97349cc99 100644 --- a/e2etests/testdata/stable/grid_gap/elk/board.exp.json +++ b/e2etests/testdata/stable/grid_gap/elk/board.exp.json @@ -4,7 +4,7 @@ "fontFamily": "SourceSansPro", "shapes": [ { - "id": "gap-rows 30 gap-columns 100", + "id": "vertical-gap 30 horizontal-gap 100", "type": "rectangle", "pos": { "x": 12, @@ -30,7 +30,7 @@ "fields": null, "methods": null, "columns": null, - "label": "gap-rows 30 gap-columns 100", + "label": "vertical-gap 30 horizontal-gap 100", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -38,14 +38,14 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 347, + "labelWidth": 398, "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "gap-rows 30 gap-columns 100.a", + "id": "vertical-gap 30 horizontal-gap 100.a", "type": "rectangle", "pos": { "x": 72, @@ -86,7 +86,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.b", + "id": "vertical-gap 30 horizontal-gap 100.b", "type": "rectangle", "pos": { "x": 226, @@ -127,7 +127,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.c", + "id": "vertical-gap 30 horizontal-gap 100.c", "type": "rectangle", "pos": { "x": 379, @@ -168,7 +168,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.d", + "id": "vertical-gap 30 horizontal-gap 100.d", "type": "rectangle", "pos": { "x": 72, @@ -209,7 +209,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.e", + "id": "vertical-gap 30 horizontal-gap 100.e", "type": "rectangle", "pos": { "x": 226, @@ -250,7 +250,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.f", + "id": "vertical-gap 30 horizontal-gap 100.f", "type": "rectangle", "pos": { "x": 379, @@ -291,7 +291,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.g", + "id": "vertical-gap 30 horizontal-gap 100.g", "type": "rectangle", "pos": { "x": 72, @@ -332,7 +332,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.h", + "id": "vertical-gap 30 horizontal-gap 100.h", "type": "rectangle", "pos": { "x": 226, @@ -373,7 +373,7 @@ "level": 2 }, { - "id": "gap-rows 30 gap-columns 100.i", + "id": "vertical-gap 30 horizontal-gap 100.i", "type": "rectangle", "pos": { "x": 379, @@ -414,13 +414,13 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30", + "id": "vertical-gap 100 horizontal-gap 30", "type": "rectangle", "pos": { "x": 512, "y": 12 }, - "width": 357, + "width": 408, "height": 518, "opacity": 1, "strokeDash": 0, @@ -440,7 +440,7 @@ "fields": null, "methods": null, "columns": null, - "label": "gap-rows 100 gap-columns 30", + "label": "vertical-gap 100 horizontal-gap 30", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -448,17 +448,17 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 347, + "labelWidth": 398, "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "gap-rows 100 gap-columns 30.a", + "id": "vertical-gap 100 horizontal-gap 30.a", "type": "rectangle", "pos": { - "x": 580, + "x": 606, "y": 72 }, "width": 54, @@ -496,10 +496,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.b", + "id": "vertical-gap 100 horizontal-gap 30.b", "type": "rectangle", "pos": { - "x": 664, + "x": 690, "y": 72 }, "width": 53, @@ -537,10 +537,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.c", + "id": "vertical-gap 100 horizontal-gap 30.c", "type": "rectangle", "pos": { - "x": 747, + "x": 773, "y": 72 }, "width": 53, @@ -578,10 +578,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.d", + "id": "vertical-gap 100 horizontal-gap 30.d", "type": "rectangle", "pos": { - "x": 580, + "x": 606, "y": 238 }, "width": 54, @@ -619,10 +619,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.e", + "id": "vertical-gap 100 horizontal-gap 30.e", "type": "rectangle", "pos": { - "x": 664, + "x": 690, "y": 238 }, "width": 53, @@ -660,10 +660,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.f", + "id": "vertical-gap 100 horizontal-gap 30.f", "type": "rectangle", "pos": { - "x": 747, + "x": 773, "y": 238 }, "width": 53, @@ -701,10 +701,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.g", + "id": "vertical-gap 100 horizontal-gap 30.g", "type": "rectangle", "pos": { - "x": 580, + "x": 606, "y": 404 }, "width": 54, @@ -742,10 +742,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.h", + "id": "vertical-gap 100 horizontal-gap 30.h", "type": "rectangle", "pos": { - "x": 664, + "x": 690, "y": 404 }, "width": 53, @@ -783,10 +783,10 @@ "level": 2 }, { - "id": "gap-rows 100 gap-columns 30.i", + "id": "vertical-gap 100 horizontal-gap 30.i", "type": "rectangle", "pos": { - "x": 747, + "x": 773, "y": 404 }, "width": 53, @@ -827,7 +827,7 @@ "id": "gap 0", "type": "rectangle", "pos": { - "x": 889, + "x": 940, "y": 112 }, "width": 280, @@ -868,7 +868,7 @@ "id": "gap 0.a", "type": "rectangle", "pos": { - "x": 949, + "x": 1000, "y": 172 }, "width": 54, @@ -909,7 +909,7 @@ "id": "gap 0.b", "type": "rectangle", "pos": { - "x": 1003, + "x": 1054, "y": 172 }, "width": 53, @@ -950,7 +950,7 @@ "id": "gap 0.c", "type": "rectangle", "pos": { - "x": 1056, + "x": 1107, "y": 172 }, "width": 53, @@ -991,7 +991,7 @@ "id": "gap 0.d", "type": "rectangle", "pos": { - "x": 949, + "x": 1000, "y": 238 }, "width": 54, @@ -1032,7 +1032,7 @@ "id": "gap 0.e", "type": "rectangle", "pos": { - "x": 1003, + "x": 1054, "y": 238 }, "width": 53, @@ -1073,7 +1073,7 @@ "id": "gap 0.f", "type": "rectangle", "pos": { - "x": 1056, + "x": 1107, "y": 238 }, "width": 53, @@ -1114,7 +1114,7 @@ "id": "gap 0.g", "type": "rectangle", "pos": { - "x": 949, + "x": 1000, "y": 304 }, "width": 54, @@ -1155,7 +1155,7 @@ "id": "gap 0.h", "type": "rectangle", "pos": { - "x": 1003, + "x": 1054, "y": 304 }, "width": 53, @@ -1196,7 +1196,7 @@ "id": "gap 0.i", "type": "rectangle", "pos": { - "x": 1056, + "x": 1107, "y": 304 }, "width": 53, @@ -1234,10 +1234,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100", + "id": "gap 10 vertical-gap 100", "type": "rectangle", "pos": { - "x": 1189, + "x": 1240, "y": 12 }, "width": 300, @@ -1260,7 +1260,7 @@ "fields": null, "methods": null, "columns": null, - "label": "gap 10 gap-rows 100", + "label": "gap 10 vertical-gap 100", "fontSize": 28, "fontFamily": "DEFAULT", "language": "", @@ -1268,17 +1268,17 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 238, + "labelWidth": 268, "labelHeight": 36, "labelPosition": "INSIDE_TOP_CENTER", "zIndex": 0, "level": 1 }, { - "id": "gap 10 gap-rows 100.a", + "id": "gap 10 vertical-gap 100.a", "type": "rectangle", "pos": { - "x": 1249, + "x": 1300, "y": 72 }, "width": 54, @@ -1316,10 +1316,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.b", + "id": "gap 10 vertical-gap 100.b", "type": "rectangle", "pos": { - "x": 1313, + "x": 1364, "y": 72 }, "width": 53, @@ -1357,10 +1357,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.c", + "id": "gap 10 vertical-gap 100.c", "type": "rectangle", "pos": { - "x": 1376, + "x": 1427, "y": 72 }, "width": 53, @@ -1398,10 +1398,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.d", + "id": "gap 10 vertical-gap 100.d", "type": "rectangle", "pos": { - "x": 1249, + "x": 1300, "y": 238 }, "width": 54, @@ -1439,10 +1439,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.e", + "id": "gap 10 vertical-gap 100.e", "type": "rectangle", "pos": { - "x": 1313, + "x": 1364, "y": 238 }, "width": 53, @@ -1480,10 +1480,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.f", + "id": "gap 10 vertical-gap 100.f", "type": "rectangle", "pos": { - "x": 1376, + "x": 1427, "y": 238 }, "width": 53, @@ -1521,10 +1521,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.g", + "id": "gap 10 vertical-gap 100.g", "type": "rectangle", "pos": { - "x": 1249, + "x": 1300, "y": 404 }, "width": 54, @@ -1562,10 +1562,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.h", + "id": "gap 10 vertical-gap 100.h", "type": "rectangle", "pos": { - "x": 1313, + "x": 1364, "y": 404 }, "width": 53, @@ -1603,10 +1603,10 @@ "level": 2 }, { - "id": "gap 10 gap-rows 100.i", + "id": "gap 10 vertical-gap 100.i", "type": "rectangle", "pos": { - "x": 1376, + "x": 1427, "y": 404 }, "width": 53, diff --git a/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg index 5706fc96e..34b1ea88a 100644 --- a/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/grid_gap/elk/sketch.exp.svg @@ -1,17 +1,17 @@ -gap-rows 30 gap-columns 100gap-rows 100 gap-columns 30gap 0gap 10 gap-rows 100abcdefghiabcdefghiabcdefghiabcdefghi - + .d2-3196763014 .fill-N1{fill:#0A0F25;} + .d2-3196763014 .fill-N2{fill:#676C7E;} + .d2-3196763014 .fill-N3{fill:#9499AB;} + .d2-3196763014 .fill-N4{fill:#CFD2DD;} + .d2-3196763014 .fill-N5{fill:#DEE1EB;} + .d2-3196763014 .fill-N6{fill:#EEF1F8;} + .d2-3196763014 .fill-N7{fill:#FFFFFF;} + .d2-3196763014 .fill-B1{fill:#0D32B2;} + .d2-3196763014 .fill-B2{fill:#0D32B2;} + .d2-3196763014 .fill-B3{fill:#E3E9FD;} + .d2-3196763014 .fill-B4{fill:#E3E9FD;} + .d2-3196763014 .fill-B5{fill:#EDF0FD;} + .d2-3196763014 .fill-B6{fill:#F7F8FE;} + .d2-3196763014 .fill-AA2{fill:#4A6FF3;} + .d2-3196763014 .fill-AA4{fill:#EDF0FD;} + .d2-3196763014 .fill-AA5{fill:#F7F8FE;} + .d2-3196763014 .fill-AB4{fill:#EDF0FD;} + .d2-3196763014 .fill-AB5{fill:#F7F8FE;} + .d2-3196763014 .stroke-N1{stroke:#0A0F25;} + .d2-3196763014 .stroke-N2{stroke:#676C7E;} + .d2-3196763014 .stroke-N3{stroke:#9499AB;} + .d2-3196763014 .stroke-N4{stroke:#CFD2DD;} + .d2-3196763014 .stroke-N5{stroke:#DEE1EB;} + .d2-3196763014 .stroke-N6{stroke:#EEF1F8;} + .d2-3196763014 .stroke-N7{stroke:#FFFFFF;} + .d2-3196763014 .stroke-B1{stroke:#0D32B2;} + .d2-3196763014 .stroke-B2{stroke:#0D32B2;} + .d2-3196763014 .stroke-B3{stroke:#E3E9FD;} + .d2-3196763014 .stroke-B4{stroke:#E3E9FD;} + .d2-3196763014 .stroke-B5{stroke:#EDF0FD;} + .d2-3196763014 .stroke-B6{stroke:#F7F8FE;} + .d2-3196763014 .stroke-AA2{stroke:#4A6FF3;} + .d2-3196763014 .stroke-AA4{stroke:#EDF0FD;} + .d2-3196763014 .stroke-AA5{stroke:#F7F8FE;} + .d2-3196763014 .stroke-AB4{stroke:#EDF0FD;} + .d2-3196763014 .stroke-AB5{stroke:#F7F8FE;} + .d2-3196763014 .background-color-N1{background-color:#0A0F25;} + .d2-3196763014 .background-color-N2{background-color:#676C7E;} + .d2-3196763014 .background-color-N3{background-color:#9499AB;} + .d2-3196763014 .background-color-N4{background-color:#CFD2DD;} + .d2-3196763014 .background-color-N5{background-color:#DEE1EB;} + .d2-3196763014 .background-color-N6{background-color:#EEF1F8;} + .d2-3196763014 .background-color-N7{background-color:#FFFFFF;} + .d2-3196763014 .background-color-B1{background-color:#0D32B2;} + .d2-3196763014 .background-color-B2{background-color:#0D32B2;} + .d2-3196763014 .background-color-B3{background-color:#E3E9FD;} + .d2-3196763014 .background-color-B4{background-color:#E3E9FD;} + .d2-3196763014 .background-color-B5{background-color:#EDF0FD;} + .d2-3196763014 .background-color-B6{background-color:#F7F8FE;} + .d2-3196763014 .background-color-AA2{background-color:#4A6FF3;} + .d2-3196763014 .background-color-AA4{background-color:#EDF0FD;} + .d2-3196763014 .background-color-AA5{background-color:#F7F8FE;} + .d2-3196763014 .background-color-AB4{background-color:#EDF0FD;} + .d2-3196763014 .background-color-AB5{background-color:#F7F8FE;} + .d2-3196763014 .color-N1{color:#0A0F25;} + .d2-3196763014 .color-N2{color:#676C7E;} + .d2-3196763014 .color-N3{color:#9499AB;} + .d2-3196763014 .color-N4{color:#CFD2DD;} + .d2-3196763014 .color-N5{color:#DEE1EB;} + .d2-3196763014 .color-N6{color:#EEF1F8;} + .d2-3196763014 .color-N7{color:#FFFFFF;} + .d2-3196763014 .color-B1{color:#0D32B2;} + .d2-3196763014 .color-B2{color:#0D32B2;} + .d2-3196763014 .color-B3{color:#E3E9FD;} + .d2-3196763014 .color-B4{color:#E3E9FD;} + .d2-3196763014 .color-B5{color:#EDF0FD;} + .d2-3196763014 .color-B6{color:#F7F8FE;} + .d2-3196763014 .color-AA2{color:#4A6FF3;} + .d2-3196763014 .color-AA4{color:#EDF0FD;} + .d2-3196763014 .color-AA5{color:#F7F8FE;} + .d2-3196763014 .color-AB4{color:#EDF0FD;} + .d2-3196763014 .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}]]>vertical-gap 30 horizontal-gap 100vertical-gap 100 horizontal-gap 30gap 0gap 10 vertical-gap 100abcdefghiabcdefghiabcdefghiabcdefghi + \ No newline at end of file diff --git a/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json b/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json index a37b783c0..70f2a05d4 100644 --- a/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json +++ b/testdata/d2compiler/TestCompile/grid_gap_negative.exp.json @@ -4,12 +4,12 @@ "ioerr": null, "errs": [ { - "range": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2,1:19:26-1:23:30", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:2:20: grid-gap-columns must be a non-negative integer: \"-200\"" + "range": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2,1:17:24-1:21:28", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:2:18: horizontal-gap must be a non-negative integer: \"-200\"" }, { - "range": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2,2:16:47-2:19:50", - "errmsg": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:3:17: grid-gap-rows must be a non-negative integer: \"-30\"" + "range": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2,2:15:44-2:18:47", + "errmsg": "d2/testdata/d2compiler/TestCompile/grid_gap_negative.d2:3:16: vertical-gap must be a non-negative integer: \"-30\"" } ] }