diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 27eb33bdc..94d61a45d 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -9,3 +9,5 @@ - Appendix seperator line no longer added to PNG export when appendix doesn't exist. [#582](https://github.com/terrastruct/d2/pull/582) - Watch mode only fits to screen on initial load. [#601](https://github.com/terrastruct/d2/pull/601) +- Dimensions (`width`/`height`) were incorrectly giving compiler errors when applied on a shape with style. [#614](https://github.com/terrastruct/d2/pull/614) +- `near` would collide with labels if they were on the diagram boundaries in the same position. [#617](https://github.com/terrastruct/d2/pull/617) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 2e4d75c3b..9b3edefd8 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -836,7 +836,7 @@ func (c *compiler) validateKey(obj *d2graph.Object, m *d2ast.Map, mk *d2ast.Key) switch strings.ToLower(obj.Attributes.Shape.Value) { case d2target.ShapeSQLTable, d2target.ShapeClass: default: - if len(obj.Children) > 0 && (reserved == "width" || reserved == "height") { + if len(obj.Children) > 0 && !(len(obj.Children) == 1 && obj.ChildrenArray[0].ID == "style") && (reserved == "width" || reserved == "height") { c.errorf(mk.Range.Start, mk.Range.End, fmt.Sprintf("%s cannot be used on container: %s", reserved, obj.AbsID())) } } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 52a2e3149..885a48da2 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -208,6 +208,15 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:25:3: width ca d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:26:3: height cannot be used on container: containers.oval container d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:36:3: width cannot be used on container: containers.hexagon container d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height cannot be used on container: containers.hexagon container +`, + }, + { + name: "dimension_with_style", + + text: `x: { + width: 200 + style.multiple: true +} `, }, { diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 99e8a10e1..e05709169 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -139,6 +139,16 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { y1 = math.Min(y1, obj.TopLeft.Y) x2 = math.Max(x2, obj.TopLeft.X+obj.Width) y2 = math.Max(y2, obj.TopLeft.Y+obj.Height) + if obj.Attributes.Label.Value != "" && obj.LabelPosition != nil { + labelPosition := label.Position(*obj.LabelPosition) + if labelPosition.IsOutside() { + labelTL := labelPosition.GetPointOnBox(obj.Box, label.PADDING, float64(*obj.LabelWidth), float64(*obj.LabelHeight)) + x1 = math.Min(x1, labelTL.X) + y1 = math.Min(y1, labelTL.Y) + x2 = math.Max(x2, labelTL.X+float64(*obj.LabelWidth)) + y2 = math.Max(y2, labelTL.Y+float64(*obj.LabelHeight)) + } + } } } diff --git a/testdata/d2compiler/TestCompile/dimension_with_style.exp.json b/testdata/d2compiler/TestCompile/dimension_with_style.exp.json new file mode 100644 index 000000000..dd47fddc0 --- /dev/null +++ b/testdata/d2compiler/TestCompile/dimension_with_style.exp.json @@ -0,0 +1,183 @@ +{ + "graph": { + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:0:0-4:0:43", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:0:0-3:1:42", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:3:3-3:0:41", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,1:2:7-1:12:17", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,1:2:7-1:7:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,1:2:7-1:7:12", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,1:9:14-1:12:17", + "raw": "200", + "value": "200" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,2:2:20-2:22:40", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,2:2:20-2:16:34", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,2:2:20-2:7:25", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,2:8:26-2:16:34", + "value": [ + { + "string": "multiple", + "raw_string": "multiple" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "boolean": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,2:18:36-2:22:40", + "value": true + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimension_with_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": { + "multiple": { + "value": "true" + } + }, + "width": { + "value": "200" + }, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": null +}