From 320d63111365ba3cb399f5da620467058f9e177e Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 19 Jan 2023 15:03:52 -0800 Subject: [PATCH 1/4] fix constant-near panic --- d2layouts/d2near/layout.go | 4 +- d2layouts/d2sequence/layout.go | 72 +++++----- e2etests/stable_test.go | 14 ++ .../stable/near-alone/dagre/board.exp.json | 127 ++++++++++++++++++ .../stable/near-alone/dagre/sketch.exp.svg | 52 +++++++ .../stable/near-alone/elk/board.exp.json | 127 ++++++++++++++++++ .../stable/near-alone/elk/sketch.exp.svg | 52 +++++++ 7 files changed, 411 insertions(+), 37 deletions(-) create mode 100644 e2etests/testdata/stable/near-alone/dagre/board.exp.json create mode 100644 e2etests/testdata/stable/near-alone/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/stable/near-alone/elk/board.exp.json create mode 100644 e2etests/testdata/stable/near-alone/elk/sketch.exp.svg diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index e05709169..85ef8ff72 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -27,12 +27,12 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNears []*d2graph.Obje // So place the center ones first, then the later ones will consider them for bounding box for _, processCenters := range []bool{true, false} { for _, obj := range constantNears { - if processCenters == strings.Contains(d2graph.Key(obj.Attributes.NearKey)[0], "center") { + if processCenters == strings.Contains(d2graph.Key(obj.Attributes.NearKey)[0], "-center") { obj.TopLeft = geo.NewPoint(place(obj)) } } for _, obj := range constantNears { - if processCenters == strings.Contains(d2graph.Key(obj.Attributes.NearKey)[0], "center") { + if processCenters == strings.Contains(d2graph.Key(obj.Attributes.NearKey)[0], "-center") { // The z-index for constant nears does not matter, as it will not collide g.Objects = append(g.Objects, obj) obj.Parent.Children[obj.ID] = obj diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index 49ae00b43..14e4c6f80 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -17,43 +17,45 @@ func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string] edgesToRemove := make(map[*d2graph.Edge]struct{}) sequenceDiagrams := make(map[string]*sequenceDiagram) - queue := make([]*d2graph.Object, 1, len(g.Objects)) - queue[0] = g.Root - for len(queue) > 0 { - obj := queue[0] - queue = queue[1:] - if len(obj.ChildrenArray) == 0 { - continue - } - if obj.Attributes.Shape.Value != d2target.ShapeSequenceDiagram { - queue = append(queue, obj.ChildrenArray...) - continue - } + if len(g.Objects) > 0 { + queue := make([]*d2graph.Object, 1, len(g.Objects)) + queue[0] = g.Root + for len(queue) > 0 { + obj := queue[0] + queue = queue[1:] + if len(obj.ChildrenArray) == 0 { + continue + } + if obj.Attributes.Shape.Value != d2target.ShapeSequenceDiagram { + queue = append(queue, obj.ChildrenArray...) + continue + } - sd, err := layoutSequenceDiagram(g, obj) - if err != nil { - return nil, nil, nil, err - } - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = nil - obj.Box = geo.NewBox(nil, sd.getWidth()+GROUP_CONTAINER_PADDING*2, sd.getHeight()+GROUP_CONTAINER_PADDING*2) - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - sequenceDiagrams[obj.AbsID()] = sd + sd, err := layoutSequenceDiagram(g, obj) + if err != nil { + return nil, nil, nil, err + } + obj.Children = make(map[string]*d2graph.Object) + obj.ChildrenArray = nil + obj.Box = geo.NewBox(nil, sd.getWidth()+GROUP_CONTAINER_PADDING*2, sd.getHeight()+GROUP_CONTAINER_PADDING*2) + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + sequenceDiagrams[obj.AbsID()] = sd - for _, edge := range sd.messages { - edgesToRemove[edge] = struct{}{} - } - for _, obj := range sd.actors { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.notes { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.groups { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.spans { - objectsToRemove[obj] = struct{}{} + for _, edge := range sd.messages { + edgesToRemove[edge] = struct{}{} + } + for _, obj := range sd.actors { + objectsToRemove[obj] = struct{}{} + } + for _, obj := range sd.notes { + objectsToRemove[obj] = struct{}{} + } + for _, obj := range sd.groups { + objectsToRemove[obj] = struct{}{} + } + for _, obj := range sd.spans { + objectsToRemove[obj] = struct{}{} + } } } diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index fb9f7399a..7ec142f3a 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -1815,6 +1815,20 @@ x.y -> a.b: { style.animated: true target-arrowhead.shape: cf-many } +`, + }, + { + name: "near-alone", + script: ` +x: { + near: top-center +} +y: { + near: bottom-center +} +z: { + near: center-left +} `, }, } diff --git a/e2etests/testdata/stable/near-alone/dagre/board.exp.json b/e2etests/testdata/stable/near-alone/dagre/board.exp.json new file mode 100644 index 000000000..dba43ee30 --- /dev/null +++ b/e2etests/testdata/stable/near-alone/dagre/board.exp.json @@ -0,0 +1,127 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "x", + "type": "", + "pos": { + "x": -56, + "y": -146 + }, + "width": 113, + "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": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y", + "type": "", + "pos": { + "x": -57, + "y": 20 + }, + "width": 114, + "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": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 14, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "z", + "type": "", + "pos": { + "x": -189, + "y": 0 + }, + "width": 112, + "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": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/stable/near-alone/dagre/sketch.exp.svg b/e2etests/testdata/stable/near-alone/dagre/sketch.exp.svg new file mode 100644 index 000000000..3944c699c --- /dev/null +++ b/e2etests/testdata/stable/near-alone/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +xyz + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/near-alone/elk/board.exp.json b/e2etests/testdata/stable/near-alone/elk/board.exp.json new file mode 100644 index 000000000..dba43ee30 --- /dev/null +++ b/e2etests/testdata/stable/near-alone/elk/board.exp.json @@ -0,0 +1,127 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "x", + "type": "", + "pos": { + "x": -56, + "y": -146 + }, + "width": 113, + "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": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y", + "type": "", + "pos": { + "x": -57, + "y": 20 + }, + "width": 114, + "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": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 14, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "z", + "type": "", + "pos": { + "x": -189, + "y": 0 + }, + "width": 112, + "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": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/stable/near-alone/elk/sketch.exp.svg b/e2etests/testdata/stable/near-alone/elk/sketch.exp.svg new file mode 100644 index 000000000..3944c699c --- /dev/null +++ b/e2etests/testdata/stable/near-alone/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +xyz + + + \ No newline at end of file From 568742e50aeff5f02ed838593f6493d621193899 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 19 Jan 2023 15:04:41 -0800 Subject: [PATCH 2/4] test --- .../constant_near_stress/dagre/board.exp.json | 84 +++++++++---------- .../constant_near_stress/dagre/sketch.exp.svg | 8 +- .../constant_near_stress/elk/board.exp.json | 84 +++++++++---------- .../constant_near_stress/elk/sketch.exp.svg | 8 +- 4 files changed, 92 insertions(+), 92 deletions(-) diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json b/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json index e081c8884..8afeff0d2 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json +++ b/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json @@ -122,11 +122,51 @@ "zIndex": 0, "level": 1 }, + { + "id": "bottom", + "type": "text", + "pos": { + "x": -414, + "y": 372 + }, + "width": 943, + "height": 131, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 943, + "labelHeight": 131, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "Joe", "type": "person", "pos": { - "x": -151, + "x": -565, "y": 113 }, "width": 131, @@ -166,7 +206,7 @@ "id": "Donald", "type": "person", "pos": { - "x": 134, + "x": 548, "y": 113 }, "width": 155, @@ -202,46 +242,6 @@ "zIndex": 0, "level": 1 }, - { - "id": "bottom", - "type": "text", - "pos": { - "x": -414, - "y": 372 - }, - "width": 943, - "height": 131, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "#0A0F25", - "shadow": false, - "3d": false, - "multiple": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 943, - "labelHeight": 131, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "i am top left", "type": "text", diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg index 7c4a6bc7c..59a33a536 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg @@ -3,7 +3,7 @@ id="d2-svg" style="background: white;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" -width="1410" height="748" viewBox="-643 -143 1410 748">xyThe top of the mountainJoeDonald

Cats, no less liquid than their shadows, offer no angles to the wind.

+xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
i am top lefti am top righti am bottom lefti am bottom right - +
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right + xyThe top of the mountainJoeDonald

Cats, no less liquid than their shadows, offer no angles to the wind.

+xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
i am top lefti am top righti am bottom lefti am bottom right - +
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right +