diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index c7a47bae9..bfadf2bd1 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -28,6 +28,7 @@ #### Bugfixes ⛑️ - Fixes groups overlapping in sequence diagrams when they end in a self loop. [#728](https://github.com/terrastruct/d2/pull/728) -- Fixed dimensions of unlabeled squares or circles with only a set width or height. [#702](https://github.com/terrastruct/d2/pull/702) -- Fixed scaling of actor shapes in sequence diagrams. [#702](https://github.com/terrastruct/d2/pull/702) +- Fixes dimensions of unlabeled squares or circles with only a set width or height. [#702](https://github.com/terrastruct/d2/pull/702) +- Fixes scaling of actor shapes in sequence diagrams. [#702](https://github.com/terrastruct/d2/pull/702) - Images can now be set to sizes smaller than 128x128. [#702](https://github.com/terrastruct/d2/pull/702) +- Fixes class height when there are no rows. [#756](https://github.com/terrastruct/d2/pull/756) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index a37c93b77..0b95146e9 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -828,7 +828,7 @@ func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.R rowHeight := GetTextDimensions(mtexts, ruler, anyRowText, go2.Pointer(d2fonts.SourceCodePro)).Height + d2target.VerticalPadding dims.Height = rowHeight * (len(obj.Class.Fields) + len(obj.Class.Methods) + 2) } else { - dims.Height = go2.Max(12, labelDims.Height) + dims.Height = 2*go2.Max(12, labelDims.Height) + d2target.VerticalPadding } case d2target.ShapeSQLTable: diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index 02d82f9b5..4e70e1f5b 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -1,7 +1,10 @@ package e2etests import ( + "math" "testing" + + "oss.terrastruct.com/d2/d2target" ) func testRegression(t *testing.T) { @@ -446,6 +449,30 @@ b -> c `, }, + { + name: "empty_class_height", + script: ` +class1: class with rows { + shape: class + -num: int + -timeout: int +} + +class2: class without rows { + shape: class +} +`, + assertions: func(t *testing.T, g *d2target.Diagram) { + if len(g.Shapes) != 2 { + t.Fatal("expected 2 shapes") + } + c1Height := float64(g.Shapes[0].Height) + c2Height := float64(g.Shapes[1].Height) + if math.Round(c1Height/2.) != c2Height { + t.Fatal("expected rowless class to be 1/2 height of class with 2 rows") + } + }, + }, } runa(t, tcs) diff --git a/e2etests/testdata/measured/empty-class/dagre/board.exp.json b/e2etests/testdata/measured/empty-class/dagre/board.exp.json index 6a7752e8b..43926e6d3 100644 --- a/e2etests/testdata/measured/empty-class/dagre/board.exp.json +++ b/e2etests/testdata/measured/empty-class/dagre/board.exp.json @@ -10,7 +10,7 @@ "y": 0 }, "width": 112, - "height": 12, + "height": 44, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/measured/empty-class/dagre/sketch.exp.svg b/e2etests/testdata/measured/empty-class/dagre/sketch.exp.svg index a87ea964c..6927edd4b 100644 --- a/e2etests/testdata/measured/empty-class/dagre/sketch.exp.svg +++ b/e2etests/testdata/measured/empty-class/dagre/sketch.exp.svg @@ -3,7 +3,7 @@ id="d2-svg" style="background: white;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" -width="316" height="216" viewBox="-102 -102 316 216"> \ No newline at end of file diff --git a/e2etests/testdata/regression/empty_class_height/dagre/board.exp.json b/e2etests/testdata/regression/empty_class_height/dagre/board.exp.json new file mode 100644 index 000000000..8ba549b2c --- /dev/null +++ b/e2etests/testdata/regression/empty_class_height/dagre/board.exp.json @@ -0,0 +1,104 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "class1", + "type": "class", + "pos": { + "x": 0, + "y": 0 + }, + "width": 319, + "height": 184, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#0A0F25", + "stroke": "#FFFFFF", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": [ + { + "name": "num", + "type": "int", + "visibility": "private" + }, + { + "name": "timeout", + "type": "int", + "visibility": "private" + } + ], + "methods": null, + "columns": null, + "label": "class with rows", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 214, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "#0D32B2", + "secondaryAccentColor": "#4A6FF3", + "neutralAccentColor": "#676C7E" + }, + { + "id": "class2", + "type": "class", + "pos": { + "x": 379, + "y": 46 + }, + "width": 362, + "height": 92, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#0A0F25", + "stroke": "#FFFFFF", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "class without rows", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 257, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "#0D32B2", + "secondaryAccentColor": "#4A6FF3", + "neutralAccentColor": "#676C7E" + } + ], + "connections": [] +} diff --git a/e2etests/testdata/regression/empty_class_height/dagre/sketch.exp.svg b/e2etests/testdata/regression/empty_class_height/dagre/sketch.exp.svg new file mode 100644 index 000000000..e27a99065 --- /dev/null +++ b/e2etests/testdata/regression/empty_class_height/dagre/sketch.exp.svg @@ -0,0 +1,56 @@ + +class with rows- +num +int- +timeout +intclass without rows + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/empty_class_height/elk/board.exp.json b/e2etests/testdata/regression/empty_class_height/elk/board.exp.json new file mode 100644 index 000000000..e2cad4326 --- /dev/null +++ b/e2etests/testdata/regression/empty_class_height/elk/board.exp.json @@ -0,0 +1,104 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "class1", + "type": "class", + "pos": { + "x": 12, + "y": 12 + }, + "width": 319, + "height": 184, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#0A0F25", + "stroke": "#FFFFFF", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": [ + { + "name": "num", + "type": "int", + "visibility": "private" + }, + { + "name": "timeout", + "type": "int", + "visibility": "private" + } + ], + "methods": null, + "columns": null, + "label": "class with rows", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 214, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "#0D32B2", + "secondaryAccentColor": "#4A6FF3", + "neutralAccentColor": "#676C7E" + }, + { + "id": "class2", + "type": "class", + "pos": { + "x": 351, + "y": 58 + }, + "width": 362, + "height": 92, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#0A0F25", + "stroke": "#FFFFFF", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "class without rows", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 257, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "#0D32B2", + "secondaryAccentColor": "#4A6FF3", + "neutralAccentColor": "#676C7E" + } + ], + "connections": [] +} diff --git a/e2etests/testdata/regression/empty_class_height/elk/sketch.exp.svg b/e2etests/testdata/regression/empty_class_height/elk/sketch.exp.svg new file mode 100644 index 000000000..58188b652 --- /dev/null +++ b/e2etests/testdata/regression/empty_class_height/elk/sketch.exp.svg @@ -0,0 +1,56 @@ + +class with rows- +num +int- +timeout +intclass without rows + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/only_header_class_table/dagre/board.exp.json b/e2etests/testdata/regression/only_header_class_table/dagre/board.exp.json index 4c412e4b6..87d63c1cb 100644 --- a/e2etests/testdata/regression/only_header_class_table/dagre/board.exp.json +++ b/e2etests/testdata/regression/only_header_class_table/dagre/board.exp.json @@ -10,7 +10,7 @@ "y": 0 }, "width": 1082, - "height": 36, + "height": 92, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -50,7 +50,7 @@ "type": "sql_table", "pos": { "x": 341, - "y": 136 + "y": 192 }, "width": 401, "height": 36, @@ -93,7 +93,7 @@ "type": "sql_table", "pos": { "x": 341, - "y": 272 + "y": 328 }, "width": 401, "height": 72, @@ -189,19 +189,19 @@ "route": [ { "x": 541, - "y": 36 + "y": 92 }, { "x": 541, - "y": 76 + "y": 132 }, { "x": 541, - "y": 96 + "y": 152 }, { "x": 541, - "y": 136 + "y": 192 } ], "isCurve": true, @@ -237,19 +237,19 @@ "route": [ { "x": 541, - "y": 172 + "y": 228 }, { "x": 541, - "y": 212 + "y": 268 }, { "x": 541, - "y": 232 + "y": 288 }, { "x": 541, - "y": 272 + "y": 328 } ], "isCurve": true, diff --git a/e2etests/testdata/regression/only_header_class_table/dagre/sketch.exp.svg b/e2etests/testdata/regression/only_header_class_table/dagre/sketch.exp.svg index d4104ee0f..e10f558fc 100644 --- a/e2etests/testdata/regression/only_header_class_table/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/only_header_class_table/dagre/sketch.exp.svg @@ -3,7 +3,7 @@ id="d2-svg" style="background: white;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" -width="1286" height="548" viewBox="-102 -102 1286 548">