From c90a35ccaa558ec1d64155f1b8637098bc520ab8 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 1 Oct 2024 15:22:01 -0600 Subject: [PATCH] d2render: fix bounding box of 3d shapes with outside labels --- ci/release/changelogs/next.md | 2 + d2target/d2target.go | 12 ++ .../themes/3d-sides/dagre/board.exp.json | 184 ++++++++++++++++++ .../themes/3d-sides/dagre/sketch.exp.svg | 131 +++++++++++++ .../themes/3d-sides/elk/board.exp.json | 184 ++++++++++++++++++ .../themes/3d-sides/elk/sketch.exp.svg | 131 +++++++++++++ e2etests/themes_test.go | 18 ++ 7 files changed, 662 insertions(+) create mode 100644 e2etests/testdata/themes/3d-sides/dagre/board.exp.json create mode 100644 e2etests/testdata/themes/3d-sides/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/themes/3d-sides/elk/board.exp.json create mode 100644 e2etests/testdata/themes/3d-sides/elk/sketch.exp.svg diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f3c0d2a77..570f0d777 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -3,3 +3,5 @@ #### Improvements 🧹 #### Bugfixes ⛑️ + +- Render: fixes edge case of a 3d shape with outside label being cut off [#2132](https://github.com/terrastruct/d2/pull/2132) diff --git a/d2target/d2target.go b/d2target/d2target.go index 381461bef..d7825d8bc 100644 --- a/d2target/d2target.go +++ b/d2target/d2target.go @@ -324,6 +324,18 @@ func (diagram Diagram) BoundingBox() (topLeft, bottomRight Point) { ) labelTL := labelPosition.GetPointOnBox(s.GetBox(), label.PADDING, float64(targetShape.LabelWidth), float64(targetShape.LabelHeight)) + if targetShape.ThreeDee { + offset := THREE_DEE_OFFSET + if targetShape.Type == ShapeHexagon { + offset /= 2 + } + if strings.HasPrefix(targetShape.LabelPosition, "OUTSIDE_RIGHT") { + labelTL.X += float64(offset) + } + if strings.HasPrefix(targetShape.LabelPosition, "OUTSIDE_TOP") { + labelTL.Y -= float64(offset) + } + } x1 = go2.Min(x1, int(labelTL.X)) y1 = go2.Min(y1, int(labelTL.Y)) x2 = go2.Max(x2, int(labelTL.X)+targetShape.LabelWidth) diff --git a/e2etests/testdata/themes/3d-sides/dagre/board.exp.json b/e2etests/testdata/themes/3d-sides/dagre/board.exp.json new file mode 100644 index 000000000..188f34ea6 --- /dev/null +++ b/e2etests/testdata/themes/3d-sides/dagre/board.exp.json @@ -0,0 +1,184 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceCodePro", + "shapes": [ + { + "id": "beats", + "type": "rectangle", + "pos": { + "x": 10, + "y": 20 + }, + "width": 1522, + "height": 308, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "fillPattern": "dots", + "stroke": "B1", + "shadow": false, + "3d": true, + "multiple": false, + "double-border": true, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "BEATS", + "fontSize": 28, + "fontFamily": "mono", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 82, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "beats.Explanation", + "type": "rectangle", + "pos": { + "x": 40, + "y": 50 + }, + "width": 1462, + "height": 248, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "B5", + "fillPattern": "dots", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "BEATS IS A FAMILY OF \"DATA SHIPPERS,\" DISTINCT SERVICES THAT SEND A SINGLE TYPE OF DATA FROM MACHINES", + "fontSize": 24, + "fontFamily": "mono", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 1452, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "beats.Explanation.Image", + "type": "image", + "pos": { + "x": 707, + "y": 110 + }, + "width": 128, + "height": 128, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "www.pngkey.com", + "Path": "/png/full/75-752805_elastic-beats-logo-png-transparent-design.png", + "RawPath": "", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "mono", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 3 + } + ], + "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/themes/3d-sides/dagre/sketch.exp.svg b/e2etests/testdata/themes/3d-sides/dagre/sketch.exp.svg new file mode 100644 index 000000000..783f78f51 --- /dev/null +++ b/e2etests/testdata/themes/3d-sides/dagre/sketch.exp.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BEATSBEATS IS A FAMILY OF "DATA SHIPPERS," DISTINCT SERVICES THAT SEND A SINGLE TYPE OF DATA FROM MACHINES + + + + \ No newline at end of file diff --git a/e2etests/testdata/themes/3d-sides/elk/board.exp.json b/e2etests/testdata/themes/3d-sides/elk/board.exp.json new file mode 100644 index 000000000..ff8b25c2d --- /dev/null +++ b/e2etests/testdata/themes/3d-sides/elk/board.exp.json @@ -0,0 +1,184 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceCodePro", + "shapes": [ + { + "id": "beats", + "type": "rectangle", + "pos": { + "x": 12, + "y": 27 + }, + "width": 1547, + "height": 333, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "fillPattern": "dots", + "stroke": "B1", + "shadow": false, + "3d": true, + "multiple": false, + "double-border": true, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "BEATS", + "fontSize": 28, + "fontFamily": "mono", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 82, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "beats.Explanation", + "type": "rectangle", + "pos": { + "x": 54, + "y": 69 + }, + "width": 1462, + "height": 248, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "B5", + "fillPattern": "dots", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "BEATS IS A FAMILY OF \"DATA SHIPPERS,\" DISTINCT SERVICES THAT SEND A SINGLE TYPE OF DATA FROM MACHINES", + "fontSize": 24, + "fontFamily": "mono", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 1452, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "beats.Explanation.Image", + "type": "image", + "pos": { + "x": 721, + "y": 129 + }, + "width": 128, + "height": 128, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": { + "Scheme": "https", + "Opaque": "", + "User": null, + "Host": "www.pngkey.com", + "Path": "/png/full/75-752805_elastic-beats-logo-png-transparent-design.png", + "RawPath": "", + "OmitHost": false, + "ForceQuery": false, + "RawQuery": "", + "Fragment": "", + "RawFragment": "" + }, + "iconPosition": "INSIDE_MIDDLE_CENTER", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "mono", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 3 + } + ], + "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/themes/3d-sides/elk/sketch.exp.svg b/e2etests/testdata/themes/3d-sides/elk/sketch.exp.svg new file mode 100644 index 000000000..53fbafd2d --- /dev/null +++ b/e2etests/testdata/themes/3d-sides/elk/sketch.exp.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BEATSBEATS IS A FAMILY OF "DATA SHIPPERS," DISTINCT SERVICES THAT SEND A SINGLE TYPE OF DATA FROM MACHINES + + + + \ No newline at end of file diff --git a/e2etests/themes_test.go b/e2etests/themes_test.go index 702cfda66..4691ffce9 100644 --- a/e2etests/themes_test.go +++ b/e2etests/themes_test.go @@ -340,6 +340,24 @@ api server -> logs: 持続する logs: ログ { shape: page; style.multiple: true } network.data processor -> api server +`, + }, + { + name: "3d-sides", + themeID: &d2themescatalog.Terminal.ID, + script: ` +beats: Beats { + Explanation: Beats is a family of "data shippers," distinct services that send a single type of data from machines { + grid-columns: 1 + style.stroke-width: 0 + Image: "" { + icon: https://www.pngkey.com/png/full/75-752805_elastic-beats-logo-png-transparent-design.png + shape: image + } + } + + style.3d: true +} `, }, }