2022-11-28 09:39:36PM

This commit is contained in:
Alexander Wang 2022-11-28 21:39:36 -08:00
parent 1db6939cce
commit b1cfeb19e6
No known key found for this signature in database
GPG key ID: D89FA31966BDBECE
15 changed files with 2552 additions and 55 deletions

View file

@ -356,6 +356,13 @@ func (c *compiler) applyScalar(attrs *d2graph.Attributes, reserved string, box d
case "link":
attrs.Link = scalar.ScalarString()
return
case "orientation":
if scalar.ScalarString() != "horizontal" && scalar.ScalarString() != "vertical" {
c.errorf(scalar.GetRange().Start, scalar.GetRange().End, `expected "horizontal" or "vertical" orientation, got %q`, scalar.ScalarString())
return
}
attrs.Orientation.Value = scalar.ScalarString()
return
}
if _, ok := d2graph.StyleKeywords[reserved]; ok {

View file

@ -1521,6 +1521,14 @@ dst.id <-> src.dst_id
diff.AssertStringEq(t, "sequence_diagram", g.Root.Attributes.Shape.Value)
},
},
{
name: "root_orientation",
text: `orientation: horizontal`,
assertions: func(t *testing.T, g *d2graph.Graph) {
diff.AssertStringEq(t, "horizontal", g.Root.Attributes.Orientation.Value)
},
},
{
name: "default_orientation",
@ -1529,6 +1537,25 @@ dst.id <-> src.dst_id
diff.AssertStringEq(t, "vertical", g.Objects[0].Attributes.Orientation.Value)
},
},
{
name: "set_orientation",
text: `x: {
orientation: horizontal
}`,
assertions: func(t *testing.T, g *d2graph.Graph) {
diff.AssertStringEq(t, "horizontal", g.Objects[0].Attributes.Orientation.Value)
},
},
{
name: "invalid_orientation",
text: `x: {
orientation: diagonal
}`,
expErr: `d2/testdata/d2compiler/TestCompile/invalid_orientation.d2:2:16: expected "horizontal" or "vertical" orientation, got "diagonal"
`,
},
}
for _, tc := range testCases {

View file

@ -1052,16 +1052,17 @@ func Key(k *d2ast.KeyPath) []string {
}
var ReservedKeywords = map[string]struct{}{
"label": {},
"desc": {},
"shape": {},
"icon": {},
"constraint": {},
"tooltip": {},
"link": {},
"near": {},
"width": {},
"height": {},
"label": {},
"desc": {},
"shape": {},
"icon": {},
"constraint": {},
"tooltip": {},
"link": {},
"near": {},
"width": {},
"height": {},
"orientation": {},
}
// ReservedKeywordHolders are reserved keywords that are meaningless on its own and exist solely to hold a set of reserved keywords

View file

@ -60,12 +60,16 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
return err
}
configJS := setGraphAttrs(dagreGraphAttrs{
rootAttrs := dagreGraphAttrs{
ranksep: 100,
edgesep: 40,
nodesep: 60,
rankdir: "tb",
})
rankdir: "TB",
}
if d2graph.Root.Attributes.Orientation.Value == "horizontal" {
rootAttrs.rankdir = "LR"
}
configJS := setGraphAttrs(rootAttrs)
if _, err := v8ctx.RunScript(configJS, "config.js"); err != nil {
return err
}

View file

@ -80,6 +80,7 @@ type ELKLayoutOptions struct {
NodeSpacing float64 `json:"spacing.nodeNodeBetweenLayers,omitempty"`
Padding string `json:"elk.padding,omitempty"`
EdgeNodeSpacing float64 `json:"spacing.edgeNodeBetweenLayers,omitempty"`
Direction string `json:"elk.direction"`
}
func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
@ -119,8 +120,12 @@ func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
HierarchyHandling: "INCLUDE_CHILDREN",
NodeSpacing: 100.0,
EdgeNodeSpacing: 50.0,
Direction: "DOWN",
},
}
if g.Root.Attributes.Orientation.Value == "horizontal" {
elkGraph.LayoutOptions.Direction = "RIGHT"
}
elkNodes := make(map[*d2graph.Object]*ELKNode)
elkEdges := make(map[*d2graph.Edge]*ELKEdge)

View file

@ -986,6 +986,20 @@ sugar -> c
c: mixed together
c -> solution: we get
`,
},
{
name: "orientation",
script: `a -> b -> c -> d -> e
b: {
orientation: horizontal
1 -> 2 -> 3 -> 4 -> 5
2: {
orientation: vertical
a -> b -> c -> d -> e
}
}
`,
},
}

View file

@ -8,7 +8,7 @@
"x": 0,
"y": 0
},
"width": 494,
"width": 524,
"height": 426,
"level": 1,
"opacity": 1,
@ -46,7 +46,7 @@
"x": 40,
"y": 50
},
"width": 414,
"width": 444,
"height": 326,
"level": 2,
"opacity": 1,
@ -84,7 +84,7 @@
"x": 80,
"y": 100
},
"width": 334,
"width": 364,
"height": 226,
"level": 3,
"opacity": 1,
@ -182,55 +182,55 @@
"route": [
{
"x": 244,
"y": 173.24723247232473
"y": 174.66192170818505
},
{
"x": 270.66666666666663,
"y": 154.64944649446494
"x": 273.33333333333337,
"y": 154.932384341637
},
{
"x": 279,
"x": 282.5,
"y": 150
},
{
"x": 281.5,
"x": 285.25,
"y": 150
},
{
"x": 284,
"x": 288,
"y": 150
},
{
"x": 287.33333333333337,
"x": 291.66666666666663,
"y": 162.6
},
{
"x": 289.83333333333337,
"x": 294.41666666666663,
"y": 181.5
},
{
"x": 292.3333333333333,
"x": 297.1666666666667,
"y": 200.4
},
{
"x": 292.3333333333333,
"x": 297.1666666666667,
"y": 225.6
},
{
"x": 289.83333333333337,
"x": 294.41666666666663,
"y": 244.5
},
{
"x": 287.33333333333337,
"x": 291.66666666666663,
"y": 263.4
},
{
"x": 270.66666666666663,
"y": 271.35055350553506
"x": 273.33333333333337,
"y": 271.06761565836297
},
{
"x": 244,
"y": 252.75276752767527
"y": 251.33807829181495
}
],
"isCurve": true,
@ -265,55 +265,55 @@
"route": [
{
"x": 244,
"y": 182.30769230769232
"y": 184.7244094488189
},
{
"x": 292,
"y": 156.46153846153845
"x": 300,
"y": 156.9448818897638
},
{
"x": 307,
"x": 317.5,
"y": 150
},
{
"x": 311.5,
"x": 322.75,
"y": 150
},
{
"x": 316,
"x": 328,
"y": 150
},
{
"x": 322,
"x": 335,
"y": 162.6
},
{
"x": 326.5,
"x": 340.25,
"y": 181.5
},
{
"x": 331,
"x": 345.5,
"y": 200.4
},
{
"x": 331,
"x": 345.5,
"y": 225.6
},
{
"x": 326.5,
"x": 340.25,
"y": 244.5
},
{
"x": 322,
"x": 335,
"y": 263.4
},
{
"x": 292,
"y": 269.53846153846155
"x": 300,
"y": 269.0551181102362
},
{
"x": 244,
"y": 243.69230769230768
"y": 241.2755905511811
}
],
"isCurve": true,
@ -347,20 +347,20 @@
"labelPercentage": 0,
"route": [
{
"x": 243.66666666666669,
"y": 238
"x": 244.33333333333331,
"y": 235
},
{
"x": 243.93333333333334,
"y": 237.99628770301624
"x": 244.06666666666666,
"y": 235.3176715176715
},
{
"x": 243.73333333333335,
"y": 237.99907192575407
"x": 244.26666666666665,
"y": 235.0794178794179
},
{
"x": 244,
"y": 237.9953596287703
"y": 235.3970893970894
}
],
"isCurve": true,

View file

@ -2,7 +2,7 @@
<svg
style="background: white;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="694" height="626" viewBox="-100 -100 694 626"><style type="text/css">
width="724" height="626" viewBox="-100 -100 724 626"><style type="text/css">
<![CDATA[
.shape {
shape-rendering: geometricPrecision;
@ -14,7 +14,7 @@ width="694" height="626" viewBox="-100 -100 694 626"><style type="text/css">
}
]]>
</style><g id="a"><g class="shape" ><rect x="0" y="0" width="494" height="426" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="247.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.b"><g class="shape" ><rect x="40" y="50" width="414" height="326" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="247.000000" y="79.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">b</text></g><g id="a.b.c"><g class="shape" ><rect x="80" y="100" width="334" height="226" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="247.000000" y="125.000000" style="text-anchor:middle;font-size:20px;fill:#0A0F25">c</text></g><g id="a.b.c.d"><g class="shape" ><rect x="130" y="150" width="114" height="126" style="fill:#FFFFFF;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="187.000000" y="216.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(a.b -&gt; a)[0]"><marker id="mk-3990223579" 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 class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 245.640452 172.103153 C 270.666667 154.649446 279.000000 150.000000 281.500000 150.000000 C 284.000000 150.000000 287.333333 162.600000 289.833333 181.500000 C 292.333333 200.400000 292.333333 225.600000 289.833333 244.500000 C 287.333333 263.400000 270.666667 271.350554 247.280904 255.040926" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><g id="a.(b -&gt; b.c)[0]"><path d="M 245.760942 181.359493 C 292.000000 156.461538 307.000000 150.000000 311.500000 150.000000 C 316.000000 150.000000 322.000000 162.600000 326.500000 181.500000 C 331.000000 200.400000 331.000000 225.600000 326.500000 244.500000 C 322.000000 263.400000 292.000000 269.538462 247.521884 245.588707" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><g id="a.(b.c.d -&gt; b)[0]"><path d="M 245.666473 237.972160 C 243.933333 237.996288 243.733333 237.999072 240.000388 238.051039" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><style type="text/css"><![CDATA[
</style><g id="a"><g class="shape" ><rect x="0" y="0" width="524" height="426" style="fill:#E3E9FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="262.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.b"><g class="shape" ><rect x="40" y="50" width="444" height="326" style="fill:#EDF0FD;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="262.000000" y="79.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">b</text></g><g id="a.b.c"><g class="shape" ><rect x="80" y="100" width="364" height="226" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="262.000000" y="125.000000" style="text-anchor:middle;font-size:20px;fill:#0A0F25">c</text></g><g id="a.b.c.d"><g class="shape" ><rect x="130" y="150" width="114" height="126" style="fill:#FFFFFF;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="187.000000" y="216.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(a.b -&gt; a)[0]"><marker id="mk-3990223579" 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 class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 245.659544 173.545716 C 273.333333 154.932384 282.500000 150.000000 285.250000 150.000000 C 288.000000 150.000000 291.666667 162.600000 294.416667 181.500000 C 297.166667 200.400000 297.166667 225.600000 294.416667 244.500000 C 291.666667 263.400000 273.333333 271.067616 247.319087 253.570489" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><g id="a.(b -&gt; b.c)[0]"><path d="M 245.791667 183.835630 C 300.000000 156.944882 317.500000 150.000000 322.750000 150.000000 C 328.000000 150.000000 335.000000 162.600000 340.250000 181.500000 C 345.500000 200.400000 345.500000 225.600000 340.250000 244.500000 C 335.000000 263.400000 300.000000 269.055118 247.583334 243.053150" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><g id="a.(b.c.d -&gt; b)[0]"><path d="M 243.047451 236.531831 C 244.066667 235.317672 244.266667 235.079418 246.571765 232.333427" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><style type="text/css"><![CDATA[
.text-bold {
font-family: "font-bold";
}

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 326 KiB

1141
e2etests/testdata/stable/orientation/dagre/board.exp.json generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 330 KiB

1033
e2etests/testdata/stable/orientation/elk/board.exp.json generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 330 KiB

View file

@ -0,0 +1,12 @@
{
"graph": null,
"err": {
"ioerr": null,
"errs": [
{
"range": "d2/testdata/d2compiler/TestCompile/invalid_orientation.d2,1:15:20-1:23:28",
"errmsg": "d2/testdata/d2compiler/TestCompile/invalid_orientation.d2:2:16: expected \"horizontal\" or \"vertical\" orientation, got \"diagonal\""
}
]
}
}

View file

@ -0,0 +1,66 @@
{
"graph": {
"ast": {
"range": "d2/testdata/d2compiler/TestCompile/root_orientation.d2,0:0:0-0:23:23",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/root_orientation.d2,0:0:0-0:23:23",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/root_orientation.d2,0:0:0-0:11:11",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/root_orientation.d2,0:0:0-0:11:11",
"value": [
{
"string": "orientation",
"raw_string": "orientation"
}
]
}
}
]
},
"primary": {},
"value": {
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/root_orientation.d2,0:13:13-0:23:23",
"value": [
{
"string": "horizontal",
"raw_string": "horizontal"
}
]
}
}
}
}
]
},
"root": {
"id": "",
"id_val": "",
"label_dimensions": {
"width": 0,
"height": 0
},
"attributes": {
"label": {
"value": ""
},
"style": {},
"near_key": null,
"shape": {
"value": ""
},
"orientation": {
"value": "horizontal"
}
}
},
"edges": null,
"objects": null
},
"err": null
}

View file

@ -0,0 +1,139 @@
{
"graph": {
"ast": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,0:0:0-2:1:32",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,0:0:0-2:1:32",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,0:0:0-0:1:1",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,0:0:0-0:1:1",
"value": [
{
"string": "x",
"raw_string": "x"
}
]
}
}
]
},
"primary": {},
"value": {
"map": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,0:3:3-2:0:31",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,1:2:7-1:25:30",
"key": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,1:2:7-1:13:18",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,1:2:7-1:13:18",
"value": [
{
"string": "orientation",
"raw_string": "orientation"
}
]
}
}
]
},
"primary": {},
"value": {
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,1:15:20-1:25:30",
"value": [
{
"string": "horizontal",
"raw_string": "horizontal"
}
]
}
}
}
}
]
}
}
}
}
]
},
"root": {
"id": "",
"id_val": "",
"label_dimensions": {
"width": 0,
"height": 0
},
"attributes": {
"label": {
"value": ""
},
"style": {},
"near_key": null,
"shape": {
"value": ""
},
"orientation": {
"value": ""
}
}
},
"edges": null,
"objects": [
{
"id": "x",
"id_val": "x",
"label_dimensions": {
"width": 0,
"height": 0
},
"references": [
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.d2,0:0:0-0:1:1",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile/set_orientation.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": {},
"near_key": null,
"shape": {
"value": ""
},
"orientation": {
"value": "horizontal"
}
}
}
]
},
"err": null
}