diff --git a/d2compiler/compile.go b/d2compiler/compile.go
index 86e6e63d3..5429bdea4 100644
--- a/d2compiler/compile.go
+++ b/d2compiler/compile.go
@@ -801,13 +801,6 @@ func (c *compiler) validateKey(obj *d2graph.Object, m *d2ast.Map, mk *d2ast.Key)
c.errorf(mk.Range.Start, mk.Range.End, "image shapes cannot have children.")
}
- if reserved == "width" && obj.Attributes.Shape.Value != d2target.ShapeImage {
- c.errorf(mk.Range.Start, mk.Range.End, "width is only applicable to image shapes.")
- }
- if reserved == "height" && obj.Attributes.Shape.Value != d2target.ShapeImage {
- c.errorf(mk.Range.Start, mk.Range.End, "height is only applicable to image shapes.")
- }
-
in := d2target.IsShape(obj.Attributes.Shape.Value)
_, arrowheadIn := d2target.Arrowheads[obj.Attributes.Shape.Value]
if !in && arrowheadIn {
diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go
index cf7283649..207211e1d 100644
--- a/d2compiler/compile_test.go
+++ b/d2compiler/compile_test.go
@@ -94,9 +94,6 @@ x: {
width: 200
height: 230
}
-`,
- expErr: `d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2:3:2: width is only applicable to image shapes.
-d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2:4:2: height is only applicable to image shapes.
`,
},
{
diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go
index 6ab44e7f1..53f682942 100644
--- a/d2graph/d2graph.go
+++ b/d2graph/d2graph.go
@@ -898,17 +898,36 @@ func appendTextDedup(texts []*d2target.MText, t *d2target.MText) []*d2target.MTe
func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, fontFamily *d2fonts.FontFamily) error {
for _, obj := range g.Objects {
obj.Box = &geo.Box{}
- // TODO fix edge cases for unnamed class etc
- // Image shapes can set their own widths/heights
- if obj.Attributes.Label.Value == "" && obj.Attributes.Shape.Value != d2target.ShapeImage {
- obj.Width = 100
- obj.Height = 100
- continue
+
+ var setWidth int
+ var setHeight int
+ if obj.Attributes.Width != nil {
+ setWidth, _ = strconv.Atoi(obj.Attributes.Width.Value)
+ }
+ if obj.Attributes.Height != nil {
+ setHeight, _ = strconv.Atoi(obj.Attributes.Height.Value)
+ }
+ shapeType := strings.ToLower(obj.Attributes.Shape.Value)
+
+ switch shapeType {
+ case d2target.ShapeClass,
+ d2target.ShapeSQLTable,
+ d2target.ShapeCode,
+ d2target.ShapeImage,
+ d2target.ShapeText:
+ // edge cases for unnamed class, etc
+ default:
+ if obj.Attributes.Label.Value == "" && setWidth == 0 && setHeight == 0 {
+ obj.Width = 100
+ obj.Height = 100
+ continue
+ }
}
var dims *d2target.TextDimensions
var innerLabelPadding = INNER_LABEL_PADDING
- if obj.Attributes.Shape.Value == d2target.ShapeText {
+ switch shapeType {
+ case d2target.ShapeText:
if obj.Attributes.Language == "latex" {
width, height, err := d2latex.Measure(obj.Text().Text)
if err != nil {
@@ -925,20 +944,30 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
dims = GetTextDimensions(mtexts, ruler, obj.Text(), fontFamily)
}
innerLabelPadding = 0
- } else if obj.Attributes.Shape.Value == d2target.ShapeClass {
+
+ case d2target.ShapeClass:
dims = GetTextDimensions(mtexts, ruler, obj.Text(), go2.Pointer(d2fonts.SourceCodePro))
- } else {
+
+ default:
dims = GetTextDimensions(mtexts, ruler, obj.Text(), fontFamily)
}
+
+ if shapeType == d2target.ShapeSQLTable && obj.Attributes.Label.Value == "" {
+ // measure with placeholder text to determine height
+ placeholder := *obj.Text()
+ placeholder.Text = "Table"
+ dims = GetTextDimensions(mtexts, ruler, &placeholder, fontFamily)
+ }
+
if dims == nil {
- if obj.Attributes.Shape.Value == d2target.ShapeImage {
+ if shapeType == d2target.ShapeImage {
dims = d2target.NewTextDimensions(0, 0)
} else {
return fmt.Errorf("dimensions for object label %#v not found", obj.Text())
}
}
- switch obj.Attributes.Shape.Value {
+ switch shapeType {
case d2target.ShapeText, d2target.ShapeClass, d2target.ShapeSQLTable, d2target.ShapeCode:
// no labels
default:
@@ -954,29 +983,39 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
obj.Width = float64(dims.Width)
obj.Height = float64(dims.Height)
- switch strings.ToLower(obj.Attributes.Shape.Value) {
+ // the set dimensions must be at least as large as the text
+ if float64(setWidth) > obj.Width {
+ obj.Width = float64(setWidth)
+ }
+ if float64(setHeight) > obj.Height {
+ obj.Height = float64(setHeight)
+ }
+
+ switch shapeType {
default:
- obj.Width += 100
- obj.Height += 100
+ if setWidth == 0 {
+ obj.Width += 100
+ }
+ if setHeight == 0 {
+ obj.Height += 100
+ }
case d2target.ShapeImage:
- if obj.Attributes.Width != nil {
- w, _ := strconv.Atoi(obj.Attributes.Width.Value)
- obj.Width = float64(w)
- } else {
+ if setWidth == 0 {
obj.Width = 128
}
- if obj.Attributes.Height != nil {
- h, _ := strconv.Atoi(obj.Attributes.Height.Value)
- obj.Height = float64(h)
- } else {
+ if setHeight == 0 {
obj.Height = 128
}
case d2target.ShapeSquare, d2target.ShapeCircle:
sideLength := go2.Max(obj.Width, obj.Height)
- obj.Width = sideLength + 100
- obj.Height = sideLength + 100
+ padding := 0.
+ if setWidth == 0 && setHeight == 0 {
+ padding = 100.
+ }
+ obj.Width = sideLength + padding
+ obj.Height = sideLength + padding
case d2target.ShapeClass:
maxWidth := dims.Width
@@ -1059,6 +1098,20 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
case d2target.ShapeText, d2target.ShapeCode:
}
+
+ switch shapeType {
+ case d2target.ShapeClass,
+ d2target.ShapeSQLTable,
+ d2target.ShapeCode,
+ d2target.ShapeText:
+ if float64(setWidth) > obj.Width {
+ obj.Width = float64(setWidth)
+ }
+ if float64(setHeight) > obj.Height {
+ obj.Height = float64(setHeight)
+ }
+ }
+
}
for _, edge := range g.Edges {
endpointLabels := []string{}
diff --git a/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json b/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json
index c01b08b63..f96e89a36 100644
--- a/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json
+++ b/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json
@@ -6,11 +6,11 @@
"id": "class",
"type": "class",
"pos": {
- "x": 48,
+ "x": 0,
"y": 0
},
- "width": 100,
- "height": 100,
+ "width": 422,
+ "height": 368,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -68,8 +68,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0,
+ "labelWidth": 5,
+ "labelHeight": 5,
"zIndex": 0,
"level": 1,
"primaryAccentColor": "#0D32B2",
@@ -80,11 +80,11 @@
"id": "users",
"type": "sql_table",
"pos": {
- "x": 48,
- "y": 200
+ "x": 107,
+ "y": 468
},
- "width": 100,
- "height": 100,
+ "width": 208,
+ "height": 216,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -112,8 +112,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 15,
+ "labelHeight": 26
},
"type": {
"label": "int",
@@ -124,8 +124,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 23,
+ "labelHeight": 26
},
"constraint": "",
"reference": ""
@@ -140,8 +140,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 47,
+ "labelHeight": 26
},
"type": {
"label": "string",
@@ -152,8 +152,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 48,
+ "labelHeight": 26
},
"constraint": "",
"reference": ""
@@ -168,8 +168,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 47,
+ "labelHeight": 26
},
"type": {
"label": "string",
@@ -180,8 +180,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 48,
+ "labelHeight": 26
},
"constraint": "",
"reference": ""
@@ -196,8 +196,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 80,
+ "labelHeight": 26
},
"type": {
"label": "string",
@@ -208,8 +208,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 48,
+ "labelHeight": 26
},
"constraint": "",
"reference": ""
@@ -224,8 +224,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 81,
+ "labelHeight": 26
},
"type": {
"label": "datetime",
@@ -236,8 +236,8 @@
"italic": false,
"bold": false,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0
+ "labelWidth": 77,
+ "labelHeight": 26
},
"constraint": "",
"reference": ""
@@ -251,8 +251,8 @@
"italic": false,
"bold": true,
"underline": false,
- "labelWidth": 0,
- "labelHeight": 0,
+ "labelWidth": 64,
+ "labelHeight": 36,
"zIndex": 0,
"level": 1,
"primaryAccentColor": "#0D32B2",
@@ -263,8 +263,8 @@
"id": "code",
"type": "code",
"pos": {
- "x": 0,
- "y": 400
+ "x": 113,
+ "y": 784
},
"width": 196,
"height": 70,
@@ -326,20 +326,20 @@
"labelPercentage": 0,
"route": [
{
- "x": 98,
- "y": 100
+ "x": 211,
+ "y": 368
},
{
- "x": 98,
- "y": 140
+ "x": 211,
+ "y": 408
},
{
- "x": 98,
- "y": 160
+ "x": 211,
+ "y": 428
},
{
- "x": 98,
- "y": 200
+ "x": 211,
+ "y": 468
}
],
"isCurve": true,
@@ -374,20 +374,20 @@
"labelPercentage": 0,
"route": [
{
- "x": 98,
- "y": 300
+ "x": 211,
+ "y": 684
},
{
- "x": 98,
- "y": 340
+ "x": 211,
+ "y": 724
},
{
- "x": 98,
- "y": 360
+ "x": 211,
+ "y": 744
},
{
- "x": 98,
- "y": 400
+ "x": 211,
+ "y": 784
}
],
"isCurve": true,
diff --git a/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg b/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg
index 323da486e..15c3051ff 100644
--- a/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg
+++ b/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg
@@ -2,7 +2,7 @@
\ No newline at end of file
diff --git a/e2etests/testdata/todo/shape_set_width_height/elk/board.exp.json b/e2etests/testdata/todo/shape_set_width_height/elk/board.exp.json
new file mode 100644
index 000000000..61577b1dd
--- /dev/null
+++ b/e2etests/testdata/todo/shape_set_width_height/elk/board.exp.json
@@ -0,0 +1,1097 @@
+{
+ "name": "",
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "containers",
+ "type": "",
+ "pos": {
+ "x": 12,
+ "y": 12
+ },
+ "width": 1322,
+ "height": 428,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#E3E9FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "containers",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 128,
+ "labelHeight": 41,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "containers.circle container",
+ "type": "oval",
+ "pos": {
+ "x": 87,
+ "y": 119
+ },
+ "width": 278,
+ "height": 214,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "circle container",
+ "fontSize": 24,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 161,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "containers.circle container.diamond",
+ "type": "diamond",
+ "pos": {
+ "x": 162,
+ "y": 194
+ },
+ "width": 128,
+ "height": 64,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#CFD2DD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "diamond",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 68,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "containers.diamond container",
+ "type": "diamond",
+ "pos": {
+ "x": 385,
+ "y": 87
+ },
+ "width": 278,
+ "height": 278,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#CFD2DD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "diamond container",
+ "fontSize": 24,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 197,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "containers.diamond container.circle",
+ "type": "oval",
+ "pos": {
+ "x": 460,
+ "y": 162
+ },
+ "width": 128,
+ "height": 128,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "circle",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 44,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "containers.oval container",
+ "type": "oval",
+ "pos": {
+ "x": 683,
+ "y": 119
+ },
+ "width": 278,
+ "height": 214,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "oval container",
+ "fontSize": 24,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 149,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "containers.oval container.hexagon",
+ "type": "hexagon",
+ "pos": {
+ "x": 758,
+ "y": 194
+ },
+ "width": 128,
+ "height": 64,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#DEE1EB",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "hexagon",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 65,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "containers.hexagon container",
+ "type": "hexagon",
+ "pos": {
+ "x": 981,
+ "y": 119
+ },
+ "width": 278,
+ "height": 214,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#DEE1EB",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "hexagon container",
+ "fontSize": 24,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 193,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "containers.hexagon container.oval",
+ "type": "oval",
+ "pos": {
+ "x": 1056,
+ "y": 194
+ },
+ "width": 128,
+ "height": 64,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "oval",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 36,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "cloud",
+ "type": "cloud",
+ "pos": {
+ "x": 1354,
+ "y": 184
+ },
+ "width": 512,
+ "height": 256,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "cloud",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 45,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "tall cylinder",
+ "type": "cylinder",
+ "pos": {
+ "x": 1482,
+ "y": 1440
+ },
+ "width": 256,
+ "height": 512,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "tall cylinder",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 91,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "users",
+ "type": "sql_table",
+ "pos": {
+ "x": 1210,
+ "y": 2052
+ },
+ "width": 800,
+ "height": 400,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#0A0F25",
+ "stroke": "#FFFFFF",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": {
+ "label": "id",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 15,
+ "labelHeight": 26
+ },
+ "type": {
+ "label": "int",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 23,
+ "labelHeight": 26
+ },
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": {
+ "label": "name",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 47,
+ "labelHeight": 26
+ },
+ "type": {
+ "label": "string",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 48,
+ "labelHeight": 26
+ },
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": {
+ "label": "email",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 47,
+ "labelHeight": 26
+ },
+ "type": {
+ "label": "string",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 48,
+ "labelHeight": 26
+ },
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": {
+ "label": "password",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 80,
+ "labelHeight": 26
+ },
+ "type": {
+ "label": "string",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 48,
+ "labelHeight": 26
+ },
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": {
+ "label": "last_login",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 81,
+ "labelHeight": 26
+ },
+ "type": {
+ "label": "datetime",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 77,
+ "labelHeight": 26
+ },
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "users",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 61,
+ "labelHeight": 36,
+ "zIndex": 0,
+ "level": 1,
+ "primaryAccentColor": "#0D32B2",
+ "secondaryAccentColor": "#4A6FF3",
+ "neutralAccentColor": "#676C7E"
+ },
+ {
+ "id": "class",
+ "type": "class",
+ "pos": {
+ "x": 1210,
+ "y": 740
+ },
+ "width": 800,
+ "height": 400,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#0A0F25",
+ "stroke": "#FFFFFF",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": [
+ {
+ "name": "num",
+ "type": "int",
+ "visibility": "private"
+ },
+ {
+ "name": "timeout",
+ "type": "int",
+ "visibility": "private"
+ },
+ {
+ "name": "pid",
+ "type": "",
+ "visibility": "private"
+ }
+ ],
+ "methods": [
+ {
+ "name": "getStatus()",
+ "return": "Enum",
+ "visibility": "public"
+ },
+ {
+ "name": "getJobs()",
+ "return": "Job[]",
+ "visibility": "public"
+ },
+ {
+ "name": "setTimeout(seconds int)",
+ "return": "void",
+ "visibility": "public"
+ }
+ ],
+ "columns": null,
+ "label": "class",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 75,
+ "labelHeight": 36,
+ "zIndex": 0,
+ "level": 1,
+ "primaryAccentColor": "#0D32B2",
+ "secondaryAccentColor": "#4A6FF3",
+ "neutralAccentColor": "#676C7E"
+ },
+ {
+ "id": "text",
+ "type": "",
+ "pos": {
+ "x": 2030,
+ "y": 540
+ },
+ "width": 400,
+ "height": 800,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "markdown text expanded to 800x400",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 266,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "code",
+ "type": "code",
+ "pos": {
+ "x": 2030,
+ "y": 1546
+ },
+ "width": 400,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "a := 5\nb := a + 7\nfmt.Printf(\"%d\", b)",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "golang",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 196,
+ "labelHeight": 70,
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "small code",
+ "type": "code",
+ "pos": {
+ "x": 2132,
+ "y": 2052
+ },
+ "width": 196,
+ "height": 70,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "a := 5\nb := a + 7\nfmt.Printf(\"%d\", b)",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "golang",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 196,
+ "labelHeight": 70,
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "container",
+ "type": "",
+ "pos": {
+ "x": 2143,
+ "y": 314
+ },
+ "width": 174,
+ "height": 126,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "container",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ }
+ ],
+ "connections": [
+ {
+ "id": "(cloud -> class)[0]",
+ "src": "cloud",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "class",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1610,
+ "y": 440
+ },
+ {
+ "x": 1610,
+ "y": 740
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(class -> tall cylinder)[0]",
+ "src": "class",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "tall cylinder",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1610,
+ "y": 1140
+ },
+ {
+ "x": 1610,
+ "y": 1440
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(tall cylinder -> users)[0]",
+ "src": "tall cylinder",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "users",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1610,
+ "y": 1952
+ },
+ {
+ "x": 1610,
+ "y": 2052
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(container -> text)[0]",
+ "src": "container",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "text",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 2230,
+ "y": 440
+ },
+ {
+ "x": 2230,
+ "y": 540
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(text -> code)[0]",
+ "src": "text",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "code",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 2230,
+ "y": 1340
+ },
+ {
+ "x": 2230,
+ "y": 1546
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(code -> small code)[0]",
+ "src": "code",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "small code",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 2230,
+ "y": 1846
+ },
+ {
+ "x": 2230,
+ "y": 2052
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ }
+ ]
+}
diff --git a/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg b/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg
new file mode 100644
index 000000000..509a9bf1e
--- /dev/null
+++ b/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg
@@ -0,0 +1,71 @@
+
+
\ No newline at end of file
diff --git a/testdata/d2compiler/TestCompile/dimensions_on_nonimage.exp.json b/testdata/d2compiler/TestCompile/dimensions_on_nonimage.exp.json
index 405923ccf..d094c9039 100644
--- a/testdata/d2compiler/TestCompile/dimensions_on_nonimage.exp.json
+++ b/testdata/d2compiler/TestCompile/dimensions_on_nonimage.exp.json
@@ -1,16 +1,210 @@
{
- "graph": null,
- "err": {
- "ioerr": null,
- "errs": [
- {
- "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,2:1:28-2:11:38",
- "errmsg": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2:3:2: width is only applicable to image shapes."
+ "graph": {
+ "ast": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:0:0-5:0:54",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:0:0-4:1:53",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:0:0-0:3:3",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:0:0-0:3:3",
+ "value": [
+ {
+ "string": "hey",
+ "raw_string": "hey"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {
+ "double_quoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:5:5-0:7:7",
+ "value": null
+ }
+ },
+ "value": {
+ "map": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:8:8-4:0:52",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,1:2:12-1:16:26",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,1:2:12-1:7:17",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,1:2:12-1:7:17",
+ "value": [
+ {
+ "string": "shape",
+ "raw_string": "shape"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,1:9:19-1:16:26",
+ "value": [
+ {
+ "string": "hexagon",
+ "raw_string": "hexagon"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,2:1:28-2:11:38",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,2:1:28-2:6:33",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,2:1:28-2:6:33",
+ "value": [
+ {
+ "string": "width",
+ "raw_string": "width"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "number": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,2:8:35-2:11:38",
+ "raw": "200",
+ "value": "200"
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,3:1:40-3:12:51",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,3:1:40-3:7:46",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,3:1:40-3:7:46",
+ "value": [
+ {
+ "string": "height",
+ "raw_string": "height"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "number": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,3:9:48-3:12:51",
+ "raw": "230",
+ "value": "230"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "root": {
+ "id": "",
+ "id_val": "",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
},
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": ""
+ },
+ "direction": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
+ },
+ "edges": null,
+ "objects": [
{
- "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,3:1:40-3:12:51",
- "errmsg": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2:4:2: height is only applicable to image shapes."
+ "id": "hey",
+ "id_val": "hey",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "references": [
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:0:0-0:3:3",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_nonimage.d2,0:0:0-0:3:3",
+ "value": [
+ {
+ "string": "hey",
+ "raw_string": "hey"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": 0
+ }
+ ],
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "width": {
+ "value": "200"
+ },
+ "height": {
+ "value": "230"
+ },
+ "near_key": null,
+ "shape": {
+ "value": "hexagon"
+ },
+ "direction": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
}
]
- }
+ },
+ "err": null
}