diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index db9486ee7..c8c1b0434 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -17,6 +17,7 @@ - Sequence diagram: multi-line edge labels no longer can collide with other elements [#2049](https://github.com/terrastruct/d2/pull/2049) - Sequence diagram: long self-referential edge labels no longer can collide neighboring actors (or its own) lifeline edges [#2050](https://github.com/terrastruct/d2/pull/2050) +- Sequence diagram: fixes layout when sequence diagrams are in children boards (e.g. a layer) [#1692](https://github.com/terrastruct/d2/issues/1692) - Globs: An edge case was fixed where globs used in edges were creating nodes when it shouldn't have [#2051](https://github.com/terrastruct/d2/pull/2051) - Render: Multi-line class labels/headers are rendered correctly [#2057](https://github.com/terrastruct/d2/pull/2057) - CLI: Watch mode uses correct backlinks (`_` usages) [#2058](https://github.com/terrastruct/d2/pull/2058) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index f077bccd4..662fe1062 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2979,8 +2979,8 @@ qa: { assertions: func(t *testing.T, g *d2graph.Graph) { tassert.Equal(t, "dev.env", g.Objects[1].AbsID()) tassert.Equal(t, "Dev Environment", g.Objects[1].Label.Value) - tassert.Equal(t, "qa.env", g.Objects[2].AbsID()) - tassert.Equal(t, "Qa Environment", g.Objects[2].Label.Value) + tassert.Equal(t, "qa.env", g.Objects[4].AbsID()) + tassert.Equal(t, "Qa Environment", g.Objects[4].Label.Value) }, }, { diff --git a/d2graph/seqdiagram.go b/d2graph/seqdiagram.go index 3cd2cf171..472a1d3ed 100644 --- a/d2graph/seqdiagram.go +++ b/d2graph/seqdiagram.go @@ -1,6 +1,8 @@ package d2graph -import "oss.terrastruct.com/d2/d2target" +import ( + "oss.terrastruct.com/d2/d2target" +) func (obj *Object) IsSequenceDiagram() bool { return obj != nil && obj.Shape.Value == d2target.ShapeSequenceDiagram diff --git a/d2ir/import.go b/d2ir/import.go index c415cf138..ef80d358c 100644 --- a/d2ir/import.go +++ b/d2ir/import.go @@ -61,15 +61,18 @@ func (c *compiler) _import(imp *d2ast.Import) (Node, bool) { if !ok { return nil, false } - nilScopeMap(ir) if len(imp.IDA()) > 0 { f := ir.GetField(imp.IDA()...) if f == nil { c.errorf(imp, "import key %q doesn't exist inside import", imp.IDA()) return nil, false } + if f.Map() != nil { + nilScopeMap(f.Map()) + } return f, true } + nilScopeMap(ir) return ir, true } @@ -132,15 +135,9 @@ func nilScopeMap(n Node) { for _, r := range n.References { r.Context_.ScopeMap = nil } - if n.Map() != nil { - nilScopeMap(n.Map()) - } case *Field: for _, r := range n.References { r.Context_.ScopeMap = nil } - if n.Map() != nil { - nilScopeMap(n.Map()) - } } } diff --git a/d2layouts/d2sequence/sequence_diagram.go b/d2layouts/d2sequence/sequence_diagram.go index e5ec4d4d7..4b85cbe13 100644 --- a/d2layouts/d2sequence/sequence_diagram.go +++ b/d2layouts/d2sequence/sequence_diagram.go @@ -1,9 +1,11 @@ package d2sequence import ( + "cmp" "errors" "fmt" "math" + "slices" "sort" "strconv" "strings" @@ -76,6 +78,13 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) (*s var actors []*d2graph.Object var groups []*d2graph.Object + slices.SortFunc(objects, func(a, b *d2graph.Object) int { + return cmp.Compare(getObjEarliestLineNum(a), getObjEarliestLineNum(b)) + }) + slices.SortFunc(messages, func(a, b *d2graph.Edge) int { + return cmp.Compare(getEdgeEarliestLineNum(a), getEdgeEarliestLineNum(b)) + }) + for _, obj := range objects { if obj.IsSequenceDiagramGroup() { queue := []*d2graph.Object{obj} diff --git a/e2etests-cli/main_test.go b/e2etests-cli/main_test.go index d58629912..273112a7f 100644 --- a/e2etests-cli/main_test.go +++ b/e2etests-cli/main_test.go @@ -94,6 +94,30 @@ func TestCLI_E2E(t *testing.T) { assert.TestdataDir(t, filepath.Join(dir, "layer-link")) }, }, + { + name: "sequence-layer", + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "index.d2", `k; layers: { seq: @seq.d2 }`) + writeFile(t, dir, "seq.d2", `shape: sequence_diagram +a: me +b: github.com/terrastruct/d2 + +a -> b: issue about a bug +a."some note about the bug" + +if i'm right: { + a <- b: fix +} + +if i'm wrong: { + a <- b: nah, intended +}`) + err := runTestMain(t, ctx, dir, env, "index.d2") + assert.Success(t, err) + + assert.TestdataDir(t, filepath.Join(dir, "index")) + }, + }, { // Skip the empty base board so the animation doesn't show blank for 1400ms name: "empty-base", diff --git a/e2etests-cli/testdata/TestCLI_E2E/sequence-layer/index.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/sequence-layer/index.exp.svg new file mode 100644 index 000000000..29a8a55da --- /dev/null +++ b/e2etests-cli/testdata/TestCLI_E2E/sequence-layer/index.exp.svg @@ -0,0 +1,95 @@ +k + + + diff --git a/e2etests-cli/testdata/TestCLI_E2E/sequence-layer/seq.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/sequence-layer/seq.exp.svg new file mode 100644 index 000000000..f8f8b973d --- /dev/null +++ b/e2etests-cli/testdata/TestCLI_E2E/sequence-layer/seq.exp.svg @@ -0,0 +1,109 @@ +megithub.com/terrastruct/d2if i'm rightif i'm wrong fixnah, intended issue about a bugsome note about the bug + + + + + + + + + + diff --git a/testdata/d2compiler/TestCompile/vars-in-imports.exp.json b/testdata/d2compiler/TestCompile/vars-in-imports.exp.json index 05c63f5e3..fad97a840 100644 --- a/testdata/d2compiler/TestCompile/vars-in-imports.exp.json +++ b/testdata/d2compiler/TestCompile/vars-in-imports.exp.json @@ -344,51 +344,6 @@ }, "zIndex": 0 }, - { - "id": "env", - "id_val": "env", - "references": [ - { - "key": { - "range": "d2/testdata/d2compiler/TestCompile/template.d2,0:0:0-0:3:3", - "path": [ - { - "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/template.d2,0:0:0-0:3:3", - "value": [ - { - "string": "env", - "raw_string": "env" - } - ] - } - } - ] - }, - "key_path_index": 0, - "map_key_edge_index": -1 - } - ], - "attributes": { - "label": { - "value": "Qa Environment" - }, - "labelDimensions": { - "width": 0, - "height": 0 - }, - "style": {}, - "near_key": null, - "shape": { - "value": "rectangle" - }, - "direction": { - "value": "" - }, - "constraint": null - }, - "zIndex": 0 - }, { "id": "vm", "id_val": "vm", @@ -434,6 +389,74 @@ }, "zIndex": 0 }, + { + "id": "env", + "id_val": "env", + "attributes": { + "label": { + "value": "env" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "env", + "id_val": "env", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/template.d2,0:0:0-0:3:3", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/template.d2,0:0:0-0:3:3", + "value": [ + { + "string": "env", + "raw_string": "env" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "Qa Environment" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, { "id": "vm", "id_val": "vm",