diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 4a542a974..be71308b8 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -59,6 +59,8 @@ func compileIR(ast *d2ast.Map, m *d2ir.Map) (*d2graph.Graph, error) { } func (c *compiler) compileBoard(g *d2graph.Graph, ir *d2ir.Map) *d2graph.Graph { + ir = ir.Copy(nil).(*d2ir.Map) + // c.preprocessSeqDiagrams(ir) c.compileMap(g.Root, ir) if len(c.err.Errors) == 0 { c.validateKeys(g.Root, ir) @@ -100,7 +102,8 @@ func (c *compiler) compileBoardsField(g *d2graph.Graph, ir *d2ir.Map, fieldName } type compiler struct { - err d2parser.ParseError + inEdgeGroup bool + err d2parser.ParseError } func (c *compiler) errorf(n d2ast.Node, f string, v ...interface{}) { @@ -658,3 +661,127 @@ func d2graphIDA(irIDA []string) (ida []string) { } return ida } + +// Unused for now until shape: edge_group +func (c *compiler) preprocessSeqDiagrams(m *d2ir.Map) { + for _, f := range m.Fields { + if f.Name == "shape" && f.Primary_.Value.ScalarString() == d2target.ShapeSequenceDiagram { + c.preprocessEdgeGroup(m, m) + return + } + if f.Map() != nil { + c.preprocessSeqDiagrams(f.Map()) + } + } +} + +func (c *compiler) preprocessEdgeGroup(seqDiagram, m *d2ir.Map) { + // Any child of a sequence diagram can be either an actor, edge group or a span. + // 1. Actors are shapes without edges inside them defined at the top level scope of a + // sequence diagram. + // 2. Spans are the children of actors. For our purposes we can ignore them. + // 3. Edge groups are defined as having at least one connection within them and also not + // being connected to anything. All direct children of an edge group are either edge + // groups or top level actors. + + // Go through all the fields and hoist actors from edge groups while also processing + // the edge groups recursively. + for _, f := range m.Fields { + if isEdgeGroup(f) { + if f.Map() != nil { + c.preprocessEdgeGroup(seqDiagram, f.Map()) + } + } else { + if m == seqDiagram { + // Ignore for root. + continue + } + hoistActor(seqDiagram, f) + } + } + + // We need to adjust all edges recursively to point to actual actors instead. + for _, e := range m.Edges { + if isCrossEdgeGroupEdge(m, e) { + c.errorf(e.References[0].AST(), "illegal edge between edge groups") + continue + } + + if m == seqDiagram { + // Root edges between actors directly do not require hoisting. + continue + } + + srcParent := seqDiagram + for i, el := range e.ID.SrcPath { + f := srcParent.GetField(el) + if !isEdgeGroup(f) { + for j := 0; j < i+1; j++ { + e.ID.SrcPath = append([]string{"_"}, e.ID.SrcPath...) + e.ID.DstPath = append([]string{"_"}, e.ID.DstPath...) + } + break + } + srcParent = f.Map() + } + } +} + +func hoistActor(seqDiagram *d2ir.Map, f *d2ir.Field) { + f2 := seqDiagram.GetField(f.Name) + if f2 == nil { + seqDiagram.Fields = append(seqDiagram.Fields, f.Copy(seqDiagram).(*d2ir.Field)) + } else { + d2ir.OverlayField(f2, f) + d2ir.ParentMap(f).DeleteField(f.Name) + } +} + +func isCrossEdgeGroupEdge(m *d2ir.Map, e *d2ir.Edge) bool { + srcParent := m + for _, el := range e.ID.SrcPath { + f := srcParent.GetField(el) + if f == nil { + // Hoisted already. + break + } + if isEdgeGroup(f) { + return true + } + srcParent = f.Map() + } + + dstParent := m + for _, el := range e.ID.DstPath { + f := dstParent.GetField(el) + if f == nil { + // Hoisted already. + break + } + if isEdgeGroup(f) { + return true + } + dstParent = f.Map() + } + + return false +} + +func isEdgeGroup(n d2ir.Node) bool { + return n.Map().EdgeCountRecursive() > 0 +} + +func parentSeqDiagram(n d2ir.Node) *d2ir.Map { + for { + m := d2ir.ParentMap(n) + if m == nil { + return nil + } + for _, f := range m.Fields { + if f.Name == "shape" && f.Primary_.Value.ScalarString() == d2target.ShapeSequenceDiagram { + return m + } + } + n = m + } +} diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 67c66e8f4..37e68632c 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1947,6 +1947,7 @@ func TestCompile2(t *testing.T) { t.Parallel() t.Run("boards", testBoards) + t.Run("seqdiagrams", testSeqDiagrams) } func testBoards(t *testing.T) { @@ -2032,6 +2033,57 @@ steps: { } } +func testSeqDiagrams(t *testing.T) { + t.Parallel() + + t.Run("errs", func(t *testing.T) { + t.Parallel() + + tca := []struct { + name string + skip bool + run func(t *testing.T) + }{ + { + name: "sequence_diagram_edge_between_edge_groups", + // New sequence diagram scoping implementation is disabled. + skip: true, + run: func(t *testing.T) { + assertCompile(t, ` +Office chatter: { + shape: sequence_diagram + alice: Alice + bob: Bobby + awkward small talk: { + alice -> bob: uhm, hi + bob -> alice: oh, hello + icebreaker attempt: { + alice -> bob: what did you have for lunch? + } + unfortunate outcome: { + bob -> alice: that's personal + } + } + awkward small talk.icebreaker attempt.alice -> awkward small talk.unfortunate outcome.bob +} +`, "d2/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.d2:16:3: edges between edge groups are not allowed") + }, + }, + } + + for _, tc := range tca { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if tc.skip { + t.SkipNow() + } + tc.run(t) + }) + } + }) +} + func assertCompile(t *testing.T, text string, expErr string) *d2graph.Graph { d2Path := fmt.Sprintf("d2/testdata/d2compiler/%v.d2", t.Name()) g, err := d2compiler.Compile(d2Path, strings.NewReader(text), nil) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 49ff3e211..11e2c179a 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -645,15 +645,16 @@ func (obj *Object) FindEdges(mk *d2ast.Key) ([]*Edge, bool) { return ea, true } -func (obj *Object) ensureChildEdge(ids []string) *Object { - for i := range ids { +func (obj *Object) ensureChildEdge(ida []string) *Object { + for i := range ida { switch obj.Attributes.Shape.Value { case d2target.ShapeClass, d2target.ShapeSQLTable: // This will only be called for connecting edges where we want to truncate to the // container. return obj + default: + obj = obj.EnsureChild(ida[i : i+1]) } - obj = obj.EnsureChild(ids[i : i+1]) } return obj } @@ -665,11 +666,22 @@ func (obj *Object) EnsureChild(ida []string) *Object { if seq != nil { for _, c := range seq.ChildrenArray { if c.ID == ida[0] { + if obj.ID == ida[0] { + // In cases of a.a where EnsureChild is called on the parent a, the second a should + // be created as a child of a and not as a child of the diagram. This is super + // unfortunate code but alas. + break + } obj = seq break } } } + + if len(ida) == 0 { + return obj + } + _, is := ReservedKeywordHolders[ida[0]] if len(ida) == 1 && !is { _, ok := ReservedKeywords[ida[0]] @@ -681,6 +693,10 @@ func (obj *Object) EnsureChild(ida []string) *Object { id := ida[0] ida = ida[1:] + if id == "_" { + return obj.Parent.EnsureChild(ida) + } + child, ok := obj.Children[strings.ToLower(id)] if !ok { child = obj.newObject(id) diff --git a/d2graph/seqdiagram.go b/d2graph/seqdiagram.go index b9cddac8d..c7497fa9a 100644 --- a/d2graph/seqdiagram.go +++ b/d2graph/seqdiagram.go @@ -33,7 +33,7 @@ func (obj *Object) IsSequenceDiagramGroup() bool { return false } } - return obj.ContainsAnyObject(obj.Graph.Objects) || obj.ContainsAnyEdge(obj.Graph.Edges) + return len(obj.ChildrenArray) > 0 || obj.ContainsAnyEdge(obj.Graph.Edges) } // notes are descendant of actors with no edges and no children diff --git a/d2ir/compile.go b/d2ir/compile.go index 70839d85c..03cc04b85 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -42,7 +42,8 @@ func (c *compiler) compileScenarios(m *Map) { continue } base := m.CopyBase(sf) - sf.Composite = Overlay(base, sf.Map()) + OverlayMap(base, sf.Map()) + sf.Composite = base c.compileScenarios(sf.Map()) c.compileSteps(sf.Map()) } @@ -67,7 +68,8 @@ func (c *compiler) compileSteps(m *Map) { } else { base = steps.Fields[i-1].Map().CopyBase(sf) } - sf.Composite = Overlay(base, sf.Map()) + OverlayMap(base, sf.Map()) + sf.Composite = base c.compileScenarios(sf.Map()) c.compileSteps(sf.Map()) } diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index cddacba2f..1a90d8d5c 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -179,6 +179,9 @@ func (m *Map) Copy(newParent Node) Node { for i := range m.Edges { m.Edges[i] = m.Edges[i].Copy(m).(*Edge) } + if m.parent == nil { + m.initRoot() + } return m } diff --git a/d2ir/merge.go b/d2ir/merge.go index 9d0834b4f..15ba2a9ec 100644 --- a/d2ir/merge.go +++ b/d2ir/merge.go @@ -1,25 +1,13 @@ package d2ir -func Overlay(base, overlay *Map) *Map { +func OverlayMap(base, overlay *Map) { for _, of := range overlay.Fields { bf := base.GetField(of.Name) if bf == nil { base.Fields = append(base.Fields, of.Copy(base).(*Field)) continue } - if of.Primary_ != nil { - bf.Primary_ = of.Primary_.Copy(bf).(*Scalar) - } - switch ofc := of.Composite.(type) { - case *Array: - bf.Composite = ofc.Copy(bf).(*Map) - case *Map: - if bf.Map() != nil { - bf.Composite = Overlay(bf.Map(), ofc) - } else { - bf.Composite = of.Composite.Copy(bf).(*Map) - } - } + OverlayField(bf, of) } for _, oe := range overlay.Edges { @@ -29,17 +17,36 @@ func Overlay(base, overlay *Map) *Map { continue } be := bea[0] - if oe.Primary_ != nil { - be.Primary_ = oe.Primary_.Copy(be).(*Scalar) - } - if oe.Map_ != nil { - if be.Map_ != nil { - be.Map_ = Overlay(be.Map(), oe.Map_) - } else { - be.Map_ = oe.Map_.Copy(be).(*Map) - } + OverlayEdge(be, oe) + } +} + +func OverlayField(bf, of *Field) { + if of.Primary_ != nil { + bf.Primary_ = of.Primary_.Copy(bf).(*Scalar) + } + + if of.Composite != nil { + if bf.Map() != nil && of.Map() != nil { + OverlayMap(bf.Map(), of.Map()) + } else { + bf.Composite = of.Composite.Copy(bf).(*Map) } } - return base + bf.References = append(bf.References, of.References...) +} + +func OverlayEdge(be, oe *Edge) { + if oe.Primary_ != nil { + be.Primary_ = oe.Primary_.Copy(be).(*Scalar) + } + if oe.Map_ != nil { + if be.Map_ != nil { + OverlayMap(be.Map(), oe.Map_) + } else { + be.Map_ = oe.Map_.Copy(be).(*Map) + } + } + be.References = append(be.References, oe.References...) } diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index 02d82f9b5..b96ad0b77 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -444,6 +444,27 @@ group 11: { } b -> c +`, + }, + { + name: "sequence_diagram_ambiguous_edge_group", + script: ` +Office chatter: { + shape: sequence_diagram + alice: Alice + bob: Bobby + awkward small talk: { + awkward small talk.ok + alice -> bob: uhm, hi + bob -> alice: oh, hello + icebreaker attempt: { + alice -> bob: what did you have for lunch? + } + unfortunate outcome: { + bob -> alice: that's personal + } + } +} `, }, } diff --git a/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/dagre/board.exp.json b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/dagre/board.exp.json new file mode 100644 index 000000000..1b7df691c --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/dagre/board.exp.json @@ -0,0 +1,606 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "Office chatter", + "type": "sequence_diagram", + "pos": { + "x": 0, + "y": 0 + }, + "width": 741, + "height": 1166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Office chatter", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 164, + "labelHeight": 41, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Office chatter.alice", + "type": "rectangle", + "pos": { + "x": 24, + "y": 110 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Alice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.bob", + "type": "rectangle", + "pos": { + "x": 274, + "y": 110 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Bobby", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.awkward small talk", + "type": "rectangle", + "pos": { + "x": 482, + "y": 110 + }, + "width": 235, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "awkward small talk", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 135, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.awkward small talk.awkward small talk", + "type": "rectangle", + "pos": { + "x": 593, + "y": 350 + }, + "width": 12, + "height": 158, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 135, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + }, + { + "id": "Office chatter.awkward small talk.awkward small talk.ok", + "type": "page", + "pos": { + "x": 538, + "y": 366 + }, + "width": 122, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ok", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 22, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "Office chatter.awkward small talk.icebreaker attempt", + "type": "rectangle", + "pos": { + "x": 593, + "y": -9223372036854775808 + }, + "width": 12, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 134, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + }, + { + "id": "Office chatter.awkward small talk.unfortunate outcome", + "type": "rectangle", + "pos": { + "x": 593, + "y": -9223372036854775808 + }, + "width": 12, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 148, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + } + ], + "connections": [ + { + "id": "Office chatter.(alice -> bob)[1]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.bob", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "uhm, hi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 50, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 622 + }, + { + "x": 349, + "y": 622 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(bob -> alice)[1]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.alice", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "oh, hello", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 56, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 349, + "y": 752 + }, + { + "x": 99, + "y": 752 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(alice -> bob)[0]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.bob", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "what did you have for lunch?", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 187, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 882 + }, + { + "x": 349, + "y": 882 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(bob -> alice)[0]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.alice", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "that's personal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 99, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 349, + "y": 1012 + }, + { + "x": 99, + "y": 1012 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(Office chatter.alice -- )[0]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "alice-lifeline-end-3851299086", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 99, + "y": 236 + }, + { + "x": 99, + "y": 1142 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(Office chatter.bob -- )[0]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "bob-lifeline-end-3036726343", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 349, + "y": 236 + }, + { + "x": 349, + "y": 1142 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(Office chatter.awkward small talk -- )[0]", + "src": "Office chatter.awkward small talk", + "srcArrow": "none", + "srcLabel": "", + "dst": "awkward small talk-lifeline-end-861194358", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 599.5, + "y": 236 + }, + { + "x": 599.5, + "y": 1142 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/dagre/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/dagre/sketch.exp.svg new file mode 100644 index 000000000..dce56d71f --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/dagre/sketch.exp.svg @@ -0,0 +1,62 @@ + +Office chatterAliceBobbyawkward small talk uhm, hioh, hellowhat did you have for lunch?that's personalok + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/elk/board.exp.json b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/elk/board.exp.json new file mode 100644 index 000000000..42dba2171 --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/elk/board.exp.json @@ -0,0 +1,606 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "Office chatter", + "type": "sequence_diagram", + "pos": { + "x": 12, + "y": 12 + }, + "width": 741, + "height": 1166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Office chatter", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 164, + "labelHeight": 41, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Office chatter.alice", + "type": "rectangle", + "pos": { + "x": 36, + "y": 122 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Alice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.bob", + "type": "rectangle", + "pos": { + "x": 286, + "y": 122 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Bobby", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.awkward small talk", + "type": "rectangle", + "pos": { + "x": 494, + "y": 122 + }, + "width": 235, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "awkward small talk", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 135, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.awkward small talk.awkward small talk", + "type": "rectangle", + "pos": { + "x": 605, + "y": 362 + }, + "width": 12, + "height": 158, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 135, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + }, + { + "id": "Office chatter.awkward small talk.awkward small talk.ok", + "type": "page", + "pos": { + "x": 550, + "y": 378 + }, + "width": 122, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ok", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 22, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "Office chatter.awkward small talk.icebreaker attempt", + "type": "rectangle", + "pos": { + "x": 605, + "y": -9223372036854775808 + }, + "width": 12, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 134, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + }, + { + "id": "Office chatter.awkward small talk.unfortunate outcome", + "type": "rectangle", + "pos": { + "x": 605, + "y": -9223372036854775808 + }, + "width": 12, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 148, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + } + ], + "connections": [ + { + "id": "Office chatter.(alice -> bob)[1]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.bob", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "uhm, hi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 50, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 111, + "y": 634 + }, + { + "x": 361, + "y": 634 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(bob -> alice)[1]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.alice", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "oh, hello", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 56, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 361, + "y": 764 + }, + { + "x": 111, + "y": 764 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(alice -> bob)[0]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.bob", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "what did you have for lunch?", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 187, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 111, + "y": 894 + }, + { + "x": 361, + "y": 894 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(bob -> alice)[0]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.alice", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "that's personal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 99, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 361, + "y": 1024 + }, + { + "x": 111, + "y": 1024 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(Office chatter.alice -- )[0]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "alice-lifeline-end-3851299086", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 111, + "y": 248 + }, + { + "x": 111, + "y": 1154 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(Office chatter.bob -- )[0]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "bob-lifeline-end-3036726343", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 361, + "y": 248 + }, + { + "x": 361, + "y": 1154 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(Office chatter.awkward small talk -- )[0]", + "src": "Office chatter.awkward small talk", + "srcArrow": "none", + "srcLabel": "", + "dst": "awkward small talk-lifeline-end-861194358", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 611.5, + "y": 248 + }, + { + "x": 611.5, + "y": 1154 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/elk/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/elk/sketch.exp.svg new file mode 100644 index 000000000..4f4934866 --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_ambiguous_edge_group/elk/sketch.exp.svg @@ -0,0 +1,62 @@ + +Office chatterAliceBobbyawkward small talk uhm, hioh, hellowhat did you have for lunch?that's personalok + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/board.exp.json b/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/board.exp.json index 8e59a4826..3f9dcd83c 100644 --- a/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/board.exp.json +++ b/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/board.exp.json @@ -248,14 +248,54 @@ "zIndex": 3, "level": 1 }, + { + "id": "a.a", + "type": "rectangle", + "pos": { + "x": 93, + "y": 734 + }, + "width": 12, + "height": 162, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "zIndex": 2, + "level": 2 + }, { "id": "group 4", "type": "rectangle", "pos": { - "x": 49, + "x": 55, "y": 840 }, - "width": 350, + "width": 344, "height": 80, "opacity": 1, "strokeDash": 0, @@ -665,11 +705,11 @@ "zIndex": 4 }, { - "id": "(a -> a)[1]", + "id": "(a -> a.a)[0]", "src": "a", "srcArrow": "none", "srcLabel": "", - "dst": "a", + "dst": "a.a", "dstArrow": "triangle", "dstLabel": "", "opacity": 1, @@ -702,7 +742,7 @@ "y": 750 }, { - "x": 99, + "x": 105, "y": 750 } ], @@ -712,8 +752,8 @@ "zIndex": 4 }, { - "id": "(a -> b)[1]", - "src": "a", + "id": "(a.a -> b)[0]", + "src": "a.a", "srcArrow": "none", "srcLabel": "", "dst": "b", @@ -737,7 +777,7 @@ "labelPercentage": 0, "route": [ { - "x": 99, + "x": 105, "y": 880 }, { @@ -883,6 +923,53 @@ "icon": null, "zIndex": 4 }, + { + "id": "(a -> a)[1]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "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": 99, + "y": 1480 + }, + { + "x": 199, + "y": 1480 + }, + { + "x": 199, + "y": 1560 + }, + { + "x": 99, + "y": 1560 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, { "id": "(a -> a)[2]", "src": "a", @@ -907,53 +994,6 @@ "labelHeight": 0, "labelPosition": "", "labelPercentage": 0, - "route": [ - { - "x": 99, - "y": 1480 - }, - { - "x": 199, - "y": 1480 - }, - { - "x": 199, - "y": 1560 - }, - { - "x": 99, - "y": 1560 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 4 - }, - { - "id": "(a -> a)[3]", - "src": "a", - "srcArrow": "none", - "srcLabel": "", - "dst": "a", - "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": 99, @@ -977,53 +1017,6 @@ "icon": null, "zIndex": 4 }, - { - "id": "(a -> a)[5]", - "src": "a", - "srcArrow": "none", - "srcLabel": "", - "dst": "a", - "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": 99, - "y": 1900 - }, - { - "x": 199, - "y": 1900 - }, - { - "x": 199, - "y": 1980 - }, - { - "x": 99, - "y": 1980 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 4 - }, { "id": "(a -> a)[4]", "src": "a", @@ -1048,6 +1041,53 @@ "labelHeight": 0, "labelPosition": "", "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 1900 + }, + { + "x": 199, + "y": 1900 + }, + { + "x": 199, + "y": 1980 + }, + { + "x": 99, + "y": 1980 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(a -> a)[3]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "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": 99, @@ -1072,7 +1112,7 @@ "zIndex": 4 }, { - "id": "(a -> a)[6]", + "id": "(a -> a)[5]", "src": "a", "srcArrow": "none", "srcLabel": "", diff --git a/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/sketch.exp.svg index f2bfc06d5..b9a9742f1 100644 --- a/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/sequence_diagram_self_edge_group_overlap/dagre/sketch.exp.svg @@ -39,12 +39,12 @@ width="927" height="3388" viewBox="-78 -28 927 3388">Office chatterAliceBobbyawkward small talkicebreaker attemptunfortunate outcome uhm, hioh, hellowhat did you have for lunch?that's personal + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/todo/sequence_diagram_edge_group_span_field/elk/board.exp.json b/e2etests/testdata/todo/sequence_diagram_edge_group_span_field/elk/board.exp.json new file mode 100644 index 000000000..4069e2c56 --- /dev/null +++ b/e2etests/testdata/todo/sequence_diagram_edge_group_span_field/elk/board.exp.json @@ -0,0 +1,568 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "Office chatter", + "type": "sequence_diagram", + "pos": { + "x": 12, + "y": 12 + }, + "width": 448, + "height": 910, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Office chatter", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 164, + "labelHeight": 41, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Office chatter.alice", + "type": "rectangle", + "pos": { + "x": 36, + "y": 122 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Alice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 38, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.alice.a", + "type": "rectangle", + "pos": { + "x": 105, + "y": 752 + }, + "width": 12, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + }, + { + "id": "Office chatter.bob", + "type": "rectangle", + "pos": { + "x": 286, + "y": 122 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Bobby", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "Office chatter.awkward small talk", + "type": "rectangle", + "pos": { + "x": 37, + "y": 338 + }, + "width": 398, + "height": 494, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "awkward small talk", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 135, + "labelHeight": 26, + "labelPosition": "INSIDE_TOP_LEFT", + "zIndex": 3, + "level": 2 + }, + { + "id": "Office chatter.awkward small talk.icebreaker attempt", + "type": "rectangle", + "pos": { + "x": 61, + "y": 598 + }, + "width": 350, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "icebreaker attempt", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 134, + "labelHeight": 26, + "labelPosition": "INSIDE_TOP_LEFT", + "zIndex": 3, + "level": 3 + }, + { + "id": "Office chatter.awkward small talk.unfortunate outcome", + "type": "rectangle", + "pos": { + "x": 67, + "y": 728 + }, + "width": 338, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "#DEE1EB", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": true, + "fields": null, + "methods": null, + "columns": null, + "label": "unfortunate outcome", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 148, + "labelHeight": 26, + "labelPosition": "INSIDE_TOP_LEFT", + "zIndex": 3, + "level": 3 + }, + { + "id": "Office chatter.bob.a", + "type": "rectangle", + "pos": { + "x": 355, + "y": 752 + }, + "width": 12, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "zIndex": 2, + "level": 3 + } + ], + "connections": [ + { + "id": "Office chatter.(alice -> bob)[1]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.bob", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "uhm, hi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 50, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 111, + "y": 378 + }, + { + "x": 361, + "y": 378 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(bob -> alice)[0]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.alice", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "oh, hello", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 56, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 361, + "y": 508 + }, + { + "x": 111, + "y": 508 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(alice -> bob)[0]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.bob", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "what did you have for lunch?", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 187, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 111, + "y": 638 + }, + { + "x": 361, + "y": 638 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "Office chatter.(bob.a -> alice.a)[0]", + "src": "Office chatter.bob.a", + "srcArrow": "none", + "srcLabel": "", + "dst": "Office chatter.alice.a", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "that's personal", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 99, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 355, + "y": 768 + }, + { + "x": 117, + "y": 768 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(Office chatter.alice -- )[0]", + "src": "Office chatter.alice", + "srcArrow": "none", + "srcLabel": "", + "dst": "alice-lifeline-end-3851299086", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 111, + "y": 248 + }, + { + "x": 111, + "y": 898 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(Office chatter.bob -- )[0]", + "src": "Office chatter.bob", + "srcArrow": "none", + "srcLabel": "", + "dst": "bob-lifeline-end-3036726343", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "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": 361, + "y": 248 + }, + { + "x": 361, + "y": 898 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/todo/sequence_diagram_edge_group_span_field/elk/sketch.exp.svg b/e2etests/testdata/todo/sequence_diagram_edge_group_span_field/elk/sketch.exp.svg new file mode 100644 index 000000000..f7cd08e57 --- /dev/null +++ b/e2etests/testdata/todo/sequence_diagram_edge_group_span_field/elk/sketch.exp.svg @@ -0,0 +1,65 @@ + +Office chatterAliceBobbyawkward small talkicebreaker attemptunfortunate outcome uhm, hioh, hellowhat did you have for lunch?that's personal + + + + + + + + + \ No newline at end of file diff --git a/e2etests/todo_test.go b/e2etests/todo_test.go index d70d98367..3fbf45e67 100644 --- a/e2etests/todo_test.go +++ b/e2etests/todo_test.go @@ -197,6 +197,28 @@ small code: |go width: 4 height: 3 } +`, + }, + { + // issue https://github.com/terrastruct/d2/issues/748 + name: "sequence_diagram_edge_group_span_field", + script: ` +Office chatter: { + shape: sequence_diagram + alice: Alice + bob: Bobby + alice.a + awkward small talk: { + alice -> bob: uhm, hi + bob -> alice: oh, hello + icebreaker attempt: { + alice -> bob: what did you have for lunch? + } + unfortunate outcome: { + bob.a -> alice.a: that's personal + } + } +} `, }, } diff --git a/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.exp.json b/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.exp.json new file mode 100644 index 000000000..f828ca6c3 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.d2,15:2:307-15:91:396", + "errmsg": "d2/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.d2:16:3: edges between edge groups are not allowed" + } + ] + } +}