From b8c41226cca43d8c2ad91be1bc914a931b587faf Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 3 May 2023 19:50:52 -0700 Subject: [PATCH 1/5] add cylinder_grid_label test --- e2etests/regression_test.go | 1 + .../testdata/files/cylinder_grid_label.d2 | 6 + .../cylinder_grid_label/dagre/board.exp.json | 171 ++++++++++++++++++ .../cylinder_grid_label/dagre/sketch.exp.svg | 102 +++++++++++ .../cylinder_grid_label/elk/board.exp.json | 171 ++++++++++++++++++ .../cylinder_grid_label/elk/sketch.exp.svg | 102 +++++++++++ 6 files changed, 553 insertions(+) create mode 100644 e2etests/testdata/files/cylinder_grid_label.d2 create mode 100644 e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json create mode 100644 e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json create mode 100644 e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index a2d16828f..e0453a15e 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -946,6 +946,7 @@ a -> b -> c }, loadFromFile(t, "slow_grid"), loadFromFile(t, "grid_oom"), + loadFromFile(t, "cylinder_grid_label"), } runa(t, tcs) diff --git a/e2etests/testdata/files/cylinder_grid_label.d2 b/e2etests/testdata/files/cylinder_grid_label.d2 new file mode 100644 index 000000000..a5048b659 --- /dev/null +++ b/e2etests/testdata/files/cylinder_grid_label.d2 @@ -0,0 +1,6 @@ +container title is hidden: { + shape: cylinder + grid-columns: 1 + first + second +} diff --git a/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json b/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json new file mode 100644 index 000000000..e105f9f8a --- /dev/null +++ b/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json @@ -0,0 +1,171 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "container title is hidden", + "type": "cylinder", + "pos": { + "x": 0, + "y": 0 + }, + "width": 286, + "height": 292, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "container title is hidden", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 276, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "container title is hidden.first", + "type": "rectangle", + "pos": { + "x": 95, + "y": 60 + }, + "width": 95, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "first", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 30, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "container title is hidden.second", + "type": "rectangle", + "pos": { + "x": 95, + "y": 166 + }, + "width": 95, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "second", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 50, + "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/regression/cylinder_grid_label/dagre/sketch.exp.svg b/e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg new file mode 100644 index 000000000..e9b80636d --- /dev/null +++ b/e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg @@ -0,0 +1,102 @@ +container title is hiddenfirstsecond + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json b/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json new file mode 100644 index 000000000..19a1594e6 --- /dev/null +++ b/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json @@ -0,0 +1,171 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "container title is hidden", + "type": "cylinder", + "pos": { + "x": 12, + "y": 12 + }, + "width": 286, + "height": 292, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "container title is hidden", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 276, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "container title is hidden.first", + "type": "rectangle", + "pos": { + "x": 107, + "y": 72 + }, + "width": 95, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "first", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 30, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "container title is hidden.second", + "type": "rectangle", + "pos": { + "x": 107, + "y": 178 + }, + "width": 95, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "second", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 50, + "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/regression/cylinder_grid_label/elk/sketch.exp.svg b/e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg new file mode 100644 index 000000000..7e6989bd0 --- /dev/null +++ b/e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg @@ -0,0 +1,102 @@ +container title is hiddenfirstsecond + + + \ No newline at end of file From d116f7d9184c796a6423620fac5ccdaf921f2a5c Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 3 May 2023 19:34:57 -0700 Subject: [PATCH 2/5] size grid container according to shape --- d2graph/d2graph.go | 51 ++++++++++++++++++++---------------- d2layouts/d2grid/layout.go | 53 ++++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 41 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 1bab9c273..86240947a 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1052,6 +1052,34 @@ func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.R return &dims, nil } +func (obj *Object) SizeToContent(contentBox *geo.Box, paddingX, paddingY, desiredWidth, desiredHeight float64, labelDims d2target.TextDimensions) { + dslShape := strings.ToLower(obj.Shape.Value) + shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] + s := shape.NewShape(shapeType, contentBox) + + var fitWidth, fitHeight float64 + if shapeType == shape.PERSON_TYPE { + fitWidth = contentBox.Width + paddingX + fitHeight = contentBox.Height + paddingY + } else { + fitWidth, fitHeight = s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX, paddingY) + } + obj.Width = math.Max(float64(desiredWidth), fitWidth) + obj.Height = math.Max(float64(desiredHeight), fitHeight) + if s.AspectRatio1() { + sideLength := math.Max(obj.Width, obj.Height) + obj.Width = sideLength + obj.Height = sideLength + } else if desiredHeight == 0 || desiredWidth == 0 { + switch s.GetType() { + case shape.PERSON_TYPE: + obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.PERSON_AR_LIMIT) + case shape.OVAL_TYPE: + obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.OVAL_AR_LIMIT) + } + } +} + func (obj *Object) OuterNearContainer() *Object { for obj != nil { if obj.NearKey != nil { @@ -1435,7 +1463,6 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(defaultDims.Width), float64(defaultDims.Height)) shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] s := shape.NewShape(shapeType, contentBox) - paddingX, paddingY := s.GetDefaultPadding() if desiredWidth != 0 { paddingX = 0. @@ -1468,27 +1495,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } } - var fitWidth, fitHeight float64 - if shapeType == shape.PERSON_TYPE { - fitWidth = contentBox.Width + paddingX - fitHeight = contentBox.Height + paddingY - } else { - fitWidth, fitHeight = s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX, paddingY) - } - obj.Width = math.Max(float64(desiredWidth), fitWidth) - obj.Height = math.Max(float64(desiredHeight), fitHeight) - if s.AspectRatio1() { - sideLength := math.Max(obj.Width, obj.Height) - obj.Width = sideLength - obj.Height = sideLength - } else if desiredHeight == 0 || desiredWidth == 0 { - switch s.GetType() { - case shape.PERSON_TYPE: - obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.PERSON_AR_LIMIT) - case shape.OVAL_TYPE: - obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.OVAL_AR_LIMIT) - } - } + obj.SizeToContent(contentBox, paddingX, paddingY, float64(desiredWidth), float64(desiredHeight), *labelDims) } for _, edge := range g.Edges { usedFont := fontFamily diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index dd87f4cb6..2e8d4f30d 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -5,10 +5,13 @@ import ( "fmt" "math" "sort" + "strings" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/lib/geo" "oss.terrastruct.com/d2/lib/label" + "oss.terrastruct.com/d2/lib/shape" "oss.terrastruct.com/util-go/go2" ) @@ -70,26 +73,38 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams ma obj.Children = make(map[string]*d2graph.Object) obj.ChildrenArray = nil - var dx, dy float64 - width := gd.width + 2*CONTAINER_PADDING - labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING - if labelWidth > width { - dx = (labelWidth - width) / 2 - width = labelWidth + if obj.Box != nil { + // size shape according to grid + contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(gd.width), float64(gd.height)) + obj.SizeToContent(contentBox, 2*CONTAINER_PADDING, 2*CONTAINER_PADDING, 0, 0, obj.LabelDimensions) + + // compute where the grid should be placed inside shape + dslShape := strings.ToLower(obj.Shape.Value) + shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] + s := shape.NewShape(shapeType, geo.NewBox(geo.NewPoint(0, 0), obj.Width, obj.Height)) + innerBox := s.GetInnerBox() + if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 { + gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y) + } + + var dx, dy float64 + labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING + if labelWidth > obj.Width { + dx = (labelWidth - obj.Width) / 2 + obj.Width = labelWidth + } + labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING + if labelHeight > CONTAINER_PADDING { + // if the label doesn't fit within the padding, we need to add more + grow := labelHeight - CONTAINER_PADDING + dy = grow / 2 + obj.Height += grow + } + // we need to center children if we have to expand to fit the container label + if dx != 0 || dy != 0 { + gd.shift(dx, dy) + } } - height := gd.height + 2*CONTAINER_PADDING - labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING - if labelHeight > CONTAINER_PADDING { - // if the label doesn't fit within the padding, we need to add more - grow := labelHeight - CONTAINER_PADDING - dy = grow / 2 - height += grow - } - // we need to center children if we have to expand to fit the container label - if dx != 0 || dy != 0 { - gd.shift(dx, dy) - } - obj.Box = geo.NewBox(nil, width, height) obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) gridDiagrams[obj.AbsID()] = gd From f66044c2d2ec0c2639f67bb109e430556c4c62c8 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 3 May 2023 20:01:48 -0700 Subject: [PATCH 3/5] update test --- .../cylinder_grid_label/dagre/board.exp.json | 6 +- .../cylinder_grid_label/dagre/sketch.exp.svg | 160 +++++++++--------- .../cylinder_grid_label/elk/board.exp.json | 6 +- .../cylinder_grid_label/elk/sketch.exp.svg | 160 +++++++++--------- 4 files changed, 166 insertions(+), 166 deletions(-) diff --git a/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json b/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json index e105f9f8a..d51e98a67 100644 --- a/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json +++ b/e2etests/testdata/regression/cylinder_grid_label/dagre/board.exp.json @@ -11,7 +11,7 @@ "y": 0 }, "width": 286, - "height": 292, + "height": 364, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -49,7 +49,7 @@ "type": "rectangle", "pos": { "x": 95, - "y": 60 + "y": 108 }, "width": 95, "height": 66, @@ -90,7 +90,7 @@ "type": "rectangle", "pos": { "x": 95, - "y": 166 + "y": 214 }, "width": 95, "height": 66, diff --git a/e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg b/e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg index e9b80636d..2d1f01190 100644 --- a/e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/cylinder_grid_label/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -container title is hiddenfirstsecond - + .d2-308635667 .fill-N1{fill:#0A0F25;} + .d2-308635667 .fill-N2{fill:#676C7E;} + .d2-308635667 .fill-N3{fill:#9499AB;} + .d2-308635667 .fill-N4{fill:#CFD2DD;} + .d2-308635667 .fill-N5{fill:#DEE1EB;} + .d2-308635667 .fill-N6{fill:#EEF1F8;} + .d2-308635667 .fill-N7{fill:#FFFFFF;} + .d2-308635667 .fill-B1{fill:#0D32B2;} + .d2-308635667 .fill-B2{fill:#0D32B2;} + .d2-308635667 .fill-B3{fill:#E3E9FD;} + .d2-308635667 .fill-B4{fill:#E3E9FD;} + .d2-308635667 .fill-B5{fill:#EDF0FD;} + .d2-308635667 .fill-B6{fill:#F7F8FE;} + .d2-308635667 .fill-AA2{fill:#4A6FF3;} + .d2-308635667 .fill-AA4{fill:#EDF0FD;} + .d2-308635667 .fill-AA5{fill:#F7F8FE;} + .d2-308635667 .fill-AB4{fill:#EDF0FD;} + .d2-308635667 .fill-AB5{fill:#F7F8FE;} + .d2-308635667 .stroke-N1{stroke:#0A0F25;} + .d2-308635667 .stroke-N2{stroke:#676C7E;} + .d2-308635667 .stroke-N3{stroke:#9499AB;} + .d2-308635667 .stroke-N4{stroke:#CFD2DD;} + .d2-308635667 .stroke-N5{stroke:#DEE1EB;} + .d2-308635667 .stroke-N6{stroke:#EEF1F8;} + .d2-308635667 .stroke-N7{stroke:#FFFFFF;} + .d2-308635667 .stroke-B1{stroke:#0D32B2;} + .d2-308635667 .stroke-B2{stroke:#0D32B2;} + .d2-308635667 .stroke-B3{stroke:#E3E9FD;} + .d2-308635667 .stroke-B4{stroke:#E3E9FD;} + .d2-308635667 .stroke-B5{stroke:#EDF0FD;} + .d2-308635667 .stroke-B6{stroke:#F7F8FE;} + .d2-308635667 .stroke-AA2{stroke:#4A6FF3;} + .d2-308635667 .stroke-AA4{stroke:#EDF0FD;} + .d2-308635667 .stroke-AA5{stroke:#F7F8FE;} + .d2-308635667 .stroke-AB4{stroke:#EDF0FD;} + .d2-308635667 .stroke-AB5{stroke:#F7F8FE;} + .d2-308635667 .background-color-N1{background-color:#0A0F25;} + .d2-308635667 .background-color-N2{background-color:#676C7E;} + .d2-308635667 .background-color-N3{background-color:#9499AB;} + .d2-308635667 .background-color-N4{background-color:#CFD2DD;} + .d2-308635667 .background-color-N5{background-color:#DEE1EB;} + .d2-308635667 .background-color-N6{background-color:#EEF1F8;} + .d2-308635667 .background-color-N7{background-color:#FFFFFF;} + .d2-308635667 .background-color-B1{background-color:#0D32B2;} + .d2-308635667 .background-color-B2{background-color:#0D32B2;} + .d2-308635667 .background-color-B3{background-color:#E3E9FD;} + .d2-308635667 .background-color-B4{background-color:#E3E9FD;} + .d2-308635667 .background-color-B5{background-color:#EDF0FD;} + .d2-308635667 .background-color-B6{background-color:#F7F8FE;} + .d2-308635667 .background-color-AA2{background-color:#4A6FF3;} + .d2-308635667 .background-color-AA4{background-color:#EDF0FD;} + .d2-308635667 .background-color-AA5{background-color:#F7F8FE;} + .d2-308635667 .background-color-AB4{background-color:#EDF0FD;} + .d2-308635667 .background-color-AB5{background-color:#F7F8FE;} + .d2-308635667 .color-N1{color:#0A0F25;} + .d2-308635667 .color-N2{color:#676C7E;} + .d2-308635667 .color-N3{color:#9499AB;} + .d2-308635667 .color-N4{color:#CFD2DD;} + .d2-308635667 .color-N5{color:#DEE1EB;} + .d2-308635667 .color-N6{color:#EEF1F8;} + .d2-308635667 .color-N7{color:#FFFFFF;} + .d2-308635667 .color-B1{color:#0D32B2;} + .d2-308635667 .color-B2{color:#0D32B2;} + .d2-308635667 .color-B3{color:#E3E9FD;} + .d2-308635667 .color-B4{color:#E3E9FD;} + .d2-308635667 .color-B5{color:#EDF0FD;} + .d2-308635667 .color-B6{color:#F7F8FE;} + .d2-308635667 .color-AA2{color:#4A6FF3;} + .d2-308635667 .color-AA4{color:#EDF0FD;} + .d2-308635667 .color-AA5{color:#F7F8FE;} + .d2-308635667 .color-AB4{color:#EDF0FD;} + .d2-308635667 .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}]]>container title is hiddenfirstsecond + \ No newline at end of file diff --git a/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json b/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json index 19a1594e6..7539ef058 100644 --- a/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json +++ b/e2etests/testdata/regression/cylinder_grid_label/elk/board.exp.json @@ -11,7 +11,7 @@ "y": 12 }, "width": 286, - "height": 292, + "height": 364, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -49,7 +49,7 @@ "type": "rectangle", "pos": { "x": 107, - "y": 72 + "y": 120 }, "width": 95, "height": 66, @@ -90,7 +90,7 @@ "type": "rectangle", "pos": { "x": 107, - "y": 178 + "y": 226 }, "width": 95, "height": 66, diff --git a/e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg b/e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg index 7e6989bd0..371c838d9 100644 --- a/e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/cylinder_grid_label/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -container title is hiddenfirstsecond - + .d2-1024055490 .fill-N1{fill:#0A0F25;} + .d2-1024055490 .fill-N2{fill:#676C7E;} + .d2-1024055490 .fill-N3{fill:#9499AB;} + .d2-1024055490 .fill-N4{fill:#CFD2DD;} + .d2-1024055490 .fill-N5{fill:#DEE1EB;} + .d2-1024055490 .fill-N6{fill:#EEF1F8;} + .d2-1024055490 .fill-N7{fill:#FFFFFF;} + .d2-1024055490 .fill-B1{fill:#0D32B2;} + .d2-1024055490 .fill-B2{fill:#0D32B2;} + .d2-1024055490 .fill-B3{fill:#E3E9FD;} + .d2-1024055490 .fill-B4{fill:#E3E9FD;} + .d2-1024055490 .fill-B5{fill:#EDF0FD;} + .d2-1024055490 .fill-B6{fill:#F7F8FE;} + .d2-1024055490 .fill-AA2{fill:#4A6FF3;} + .d2-1024055490 .fill-AA4{fill:#EDF0FD;} + .d2-1024055490 .fill-AA5{fill:#F7F8FE;} + .d2-1024055490 .fill-AB4{fill:#EDF0FD;} + .d2-1024055490 .fill-AB5{fill:#F7F8FE;} + .d2-1024055490 .stroke-N1{stroke:#0A0F25;} + .d2-1024055490 .stroke-N2{stroke:#676C7E;} + .d2-1024055490 .stroke-N3{stroke:#9499AB;} + .d2-1024055490 .stroke-N4{stroke:#CFD2DD;} + .d2-1024055490 .stroke-N5{stroke:#DEE1EB;} + .d2-1024055490 .stroke-N6{stroke:#EEF1F8;} + .d2-1024055490 .stroke-N7{stroke:#FFFFFF;} + .d2-1024055490 .stroke-B1{stroke:#0D32B2;} + .d2-1024055490 .stroke-B2{stroke:#0D32B2;} + .d2-1024055490 .stroke-B3{stroke:#E3E9FD;} + .d2-1024055490 .stroke-B4{stroke:#E3E9FD;} + .d2-1024055490 .stroke-B5{stroke:#EDF0FD;} + .d2-1024055490 .stroke-B6{stroke:#F7F8FE;} + .d2-1024055490 .stroke-AA2{stroke:#4A6FF3;} + .d2-1024055490 .stroke-AA4{stroke:#EDF0FD;} + .d2-1024055490 .stroke-AA5{stroke:#F7F8FE;} + .d2-1024055490 .stroke-AB4{stroke:#EDF0FD;} + .d2-1024055490 .stroke-AB5{stroke:#F7F8FE;} + .d2-1024055490 .background-color-N1{background-color:#0A0F25;} + .d2-1024055490 .background-color-N2{background-color:#676C7E;} + .d2-1024055490 .background-color-N3{background-color:#9499AB;} + .d2-1024055490 .background-color-N4{background-color:#CFD2DD;} + .d2-1024055490 .background-color-N5{background-color:#DEE1EB;} + .d2-1024055490 .background-color-N6{background-color:#EEF1F8;} + .d2-1024055490 .background-color-N7{background-color:#FFFFFF;} + .d2-1024055490 .background-color-B1{background-color:#0D32B2;} + .d2-1024055490 .background-color-B2{background-color:#0D32B2;} + .d2-1024055490 .background-color-B3{background-color:#E3E9FD;} + .d2-1024055490 .background-color-B4{background-color:#E3E9FD;} + .d2-1024055490 .background-color-B5{background-color:#EDF0FD;} + .d2-1024055490 .background-color-B6{background-color:#F7F8FE;} + .d2-1024055490 .background-color-AA2{background-color:#4A6FF3;} + .d2-1024055490 .background-color-AA4{background-color:#EDF0FD;} + .d2-1024055490 .background-color-AA5{background-color:#F7F8FE;} + .d2-1024055490 .background-color-AB4{background-color:#EDF0FD;} + .d2-1024055490 .background-color-AB5{background-color:#F7F8FE;} + .d2-1024055490 .color-N1{color:#0A0F25;} + .d2-1024055490 .color-N2{color:#676C7E;} + .d2-1024055490 .color-N3{color:#9499AB;} + .d2-1024055490 .color-N4{color:#CFD2DD;} + .d2-1024055490 .color-N5{color:#DEE1EB;} + .d2-1024055490 .color-N6{color:#EEF1F8;} + .d2-1024055490 .color-N7{color:#FFFFFF;} + .d2-1024055490 .color-B1{color:#0D32B2;} + .d2-1024055490 .color-B2{color:#0D32B2;} + .d2-1024055490 .color-B3{color:#E3E9FD;} + .d2-1024055490 .color-B4{color:#E3E9FD;} + .d2-1024055490 .color-B5{color:#EDF0FD;} + .d2-1024055490 .color-B6{color:#F7F8FE;} + .d2-1024055490 .color-AA2{color:#4A6FF3;} + .d2-1024055490 .color-AA4{color:#EDF0FD;} + .d2-1024055490 .color-AA5{color:#F7F8FE;} + .d2-1024055490 .color-AB4{color:#EDF0FD;} + .d2-1024055490 .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}]]>container title is hiddenfirstsecond + \ No newline at end of file From 5a3fa6b5afe7fabd5b786b82911a153ab02b6534 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 3 May 2023 20:05:52 -0700 Subject: [PATCH 4/5] changelog --- ci/release/changelogs/next.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f3c0d2a77..f8c1119ab 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -2,4 +2,6 @@ #### Improvements 🧹 +- Use shape specific sizing for grid containers [#1294](https://github.com/terrastruct/d2/pull/1294) + #### Bugfixes ⛑️ From 45d798dc532dc9a7da7507ca0b79281e47f968da Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Thu, 4 May 2023 20:58:39 -0700 Subject: [PATCH 5/5] simplify func --- d2graph/d2graph.go | 23 +++++++++++++++++------ d2layouts/d2grid/layout.go | 3 +-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 86240947a..aa211bb7e 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1052,17 +1052,28 @@ func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.R return &dims, nil } -func (obj *Object) SizeToContent(contentBox *geo.Box, paddingX, paddingY, desiredWidth, desiredHeight float64, labelDims d2target.TextDimensions) { +// resizes the object to fit content of the given width and height in its inner box with the given padding. +// this accounts for the shape of the object, and if there is a desired width or height set for the object +func (obj *Object) SizeToContent(contentWidth, contentHeight, paddingX, paddingY float64) { + var desiredWidth int + var desiredHeight int + if obj.WidthAttr != nil { + desiredWidth, _ = strconv.Atoi(obj.WidthAttr.Value) + } + if obj.HeightAttr != nil { + desiredHeight, _ = strconv.Atoi(obj.HeightAttr.Value) + } + dslShape := strings.ToLower(obj.Shape.Value) shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] - s := shape.NewShape(shapeType, contentBox) + s := shape.NewShape(shapeType, geo.NewBox(geo.NewPoint(0, 0), contentWidth, contentHeight)) var fitWidth, fitHeight float64 if shapeType == shape.PERSON_TYPE { - fitWidth = contentBox.Width + paddingX - fitHeight = contentBox.Height + paddingY + fitWidth = contentWidth + paddingX + fitHeight = contentHeight + paddingY } else { - fitWidth, fitHeight = s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX, paddingY) + fitWidth, fitHeight = s.GetDimensionsToFit(contentWidth, contentHeight, paddingX, paddingY) } obj.Width = math.Max(float64(desiredWidth), fitWidth) obj.Height = math.Max(float64(desiredHeight), fitHeight) @@ -1495,7 +1506,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } } - obj.SizeToContent(contentBox, paddingX, paddingY, float64(desiredWidth), float64(desiredHeight), *labelDims) + obj.SizeToContent(contentBox.Width, contentBox.Height, paddingX, paddingY) } for _, edge := range g.Edges { usedFont := fontFamily diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 2e8d4f30d..d46475518 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -75,8 +75,7 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams ma if obj.Box != nil { // size shape according to grid - contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(gd.width), float64(gd.height)) - obj.SizeToContent(contentBox, 2*CONTAINER_PADDING, 2*CONTAINER_PADDING, 0, 0, obj.LabelDimensions) + obj.SizeToContent(float64(gd.width), float64(gd.height), 2*CONTAINER_PADDING, 2*CONTAINER_PADDING) // compute where the grid should be placed inside shape dslShape := strings.ToLower(obj.Shape.Value)