Merge pull request #2132 from alixander/3d-sides

d2render: fix bounding box of 3d shapes with outside labels
This commit is contained in:
Alexander Wang 2024-10-01 15:36:28 -06:00 committed by GitHub
commit 5216f5b342
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 665 additions and 3 deletions

View file

@ -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)

View file

@ -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)

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.7-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 1663 349"><svg id="d2-svg" class="d2-4084110625" width="1663" height="349" viewBox="9 -36 1663 349"><rect x="9.000000" y="-36.000000" width="1663.000000" height="349.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.7-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 1663 364"><svg id="d2-svg" class="d2-4084110625" width="1663" height="364" viewBox="9 -51 1663 364"><rect x="9.000000" y="-51.000000" width="1663.000000" height="364.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-4084110625 .text {
font-family: "d2-4084110625-font-regular";
}
@ -114,8 +114,8 @@
<rect x="1557" y="35" width="68" height="81" fill="white"></rect>
<path d="M1557,50L1572,35L1625,35L1625,101L1610,116L1557,116L1557,50L1610,50L1610,116M1610,50L1625,35" style="stroke-width:2;;stroke:#000;fill:none;opacity:1;"/></mask></defs><rect x="1557.000000" y="50.000000" width="53.000000" height="66.000000" mask="url(#border-mask-n10.a)" stroke="none" class=" fill-B5" style="stroke-width:2;" /><polygon mask="url(#border-mask-n10.a)" points="1557,50 1572,35 1625,35 1625,101 1610,116 1610,50" class=" fill-B4" style="stroke-width:2;" /><path d="M1557,50 L1572,35 L1625,35 L1625,101 L1610,116 L1557,116 L1557,50 L1610,50 L1610,116 M1610,50 L1625,35" fill="none" class=" stroke-B1" style="stroke-width:2;" /></g><text x="1583.500000" y="88.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">a</text></g><g id="n10.b"><g class="shape" ><defs><mask id="border-mask-n10.b" maskUnits="userSpaceOnUse" x="1557" y="201" width="68" height="81">
<rect x="1557" y="201" width="68" height="81" fill="white"></rect>
<path d="M1557,216L1572,201L1625,201L1625,267L1610,282L1557,282L1557,216L1610,216L1610,282M1610,216L1625,201" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;;stroke:#000;fill:none;opacity:1;"/></mask></defs><rect x="1557.000000" y="216.000000" width="53.000000" height="66.000000" mask="url(#border-mask-n10.b)" stroke="none" class=" fill-B5" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;" /><polygon mask="url(#border-mask-n10.b)" points="1557,216 1572,201 1625,201 1625,267 1610,282 1610,216" class=" fill-B4" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;" /><path d="M1557,216 L1572,201 L1625,201 L1625,267 L1610,282 L1557,282 L1557,216 L1610,216 L1610,282 M1610,216 L1625,201" fill="none" class=" stroke-B2" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;" /></g><text x="1583.500000" y="254.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">b</text></g><g id="n1.(a -&gt; b)[0]"><marker id="mk-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 66.500000 118.000000 C 66.500000 156.000000 66.500000 174.000000 66.500000 202.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n2.(a -&gt; b)[0]"><path d="M 229.500000 118.000000 C 229.500000 156.000000 229.500000 173.000000 229.500000 197.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n3.(a -&gt; b)[0]"><path d="M 397.500000 118.000000 C 397.500000 156.000000 397.500000 174.000000 397.500000 202.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n4.(a -&gt; b)[0]"><path d="M 570.500000 118.000000 C 570.500000 156.000000 570.500000 173.000000 570.500000 197.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n5.(a -&gt; b)[0]"><path d="M 743.500000 118.000000 C 743.500000 156.000000 743.500000 176.000000 743.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n6.(a -&gt; b)[0]"><path d="M 901.500000 118.000000 C 901.500000 156.000000 901.500000 176.000000 901.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n7.(a -&gt; b)[0]"><path d="M 1064.500000 118.000000 C 1064.500000 156.000000 1064.500000 176.000000 1064.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n8.(a -&gt; b)[0]"><path d="M 1227.500000 118.000000 C 1227.500000 156.000000 1227.500000 176.000000 1227.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n9.(a -&gt; b)[0]"><path d="M 1410.500000 118.000000 C 1410.500000 156.000000 1410.500000 174.000000 1410.500000 202.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n10.(a -&gt; b)[0]"><path d="M 1583.500000 118.000000 C 1583.500000 156.000000 1583.500000 173.000000 1583.500000 197.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><mask id="d2-4084110625" maskUnits="userSpaceOnUse" x="9" y="-36" width="1663" height="349">
<rect x="9" y="-36" width="1663" height="349" fill="white"></rect>
<path d="M1557,216L1572,201L1625,201L1625,267L1610,282L1557,282L1557,216L1610,216L1610,282M1610,216L1625,201" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;;stroke:#000;fill:none;opacity:1;"/></mask></defs><rect x="1557.000000" y="216.000000" width="53.000000" height="66.000000" mask="url(#border-mask-n10.b)" stroke="none" class=" fill-B5" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;" /><polygon mask="url(#border-mask-n10.b)" points="1557,216 1572,201 1625,201 1625,267 1610,282 1610,216" class=" fill-B4" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;" /><path d="M1557,216 L1572,201 L1625,201 L1625,267 L1610,282 L1557,282 L1557,216 L1610,216 L1610,282 M1610,216 L1625,201" fill="none" class=" stroke-B2" style="stroke-width:2;stroke-dasharray:10.000000,9.865639;" /></g><text x="1583.500000" y="254.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">b</text></g><g id="n1.(a -&gt; b)[0]"><marker id="mk-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 66.500000 118.000000 C 66.500000 156.000000 66.500000 174.000000 66.500000 202.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n2.(a -&gt; b)[0]"><path d="M 229.500000 118.000000 C 229.500000 156.000000 229.500000 173.000000 229.500000 197.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n3.(a -&gt; b)[0]"><path d="M 397.500000 118.000000 C 397.500000 156.000000 397.500000 174.000000 397.500000 202.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n4.(a -&gt; b)[0]"><path d="M 570.500000 118.000000 C 570.500000 156.000000 570.500000 173.000000 570.500000 197.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n5.(a -&gt; b)[0]"><path d="M 743.500000 118.000000 C 743.500000 156.000000 743.500000 176.000000 743.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n6.(a -&gt; b)[0]"><path d="M 901.500000 118.000000 C 901.500000 156.000000 901.500000 176.000000 901.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n7.(a -&gt; b)[0]"><path d="M 1064.500000 118.000000 C 1064.500000 156.000000 1064.500000 176.000000 1064.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n8.(a -&gt; b)[0]"><path d="M 1227.500000 118.000000 C 1227.500000 156.000000 1227.500000 176.000000 1227.500000 212.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n9.(a -&gt; b)[0]"><path d="M 1410.500000 118.000000 C 1410.500000 156.000000 1410.500000 174.000000 1410.500000 202.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><g id="n10.(a -&gt; b)[0]"><path d="M 1583.500000 118.000000 C 1583.500000 156.000000 1583.500000 173.000000 1583.500000 197.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-4084110625)" /></g><mask id="d2-4084110625" maskUnits="userSpaceOnUse" x="9" y="-51" width="1663" height="364">
<rect x="9" y="-51" width="1663" height="364" fill="white"></rect>
<rect x="58.000000" y="-21.000000" width="27" height="36" fill="rgba(0,0,0,0.75)"></rect>
<rect x="223.500000" y="-21.000000" width="27" height="36" fill="rgba(0,0,0,0.75)"></rect>
<rect x="394.000000" y="-31.000000" width="27" height="36" fill="rgba(0,0,0,0.75)"></rect>

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

184
e2etests/testdata/themes/3d-sides/dagre/board.exp.json generated vendored Normal file
View file

@ -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
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

184
e2etests/testdata/themes/3d-sides/elk/board.exp.json generated vendored Normal file
View file

@ -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
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -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
}
`,
},
}