diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go
index 961ab0bcb..d9a96d83a 100644
--- a/d2graph/d2graph.go
+++ b/d2graph/d2graph.go
@@ -331,6 +331,20 @@ func (l ContainerLevel) LabelSize() int {
func (obj *Object) GetFill(theme *d2themes.Theme) string {
level := int(obj.Level())
+ if obj.Parent.IsSequenceDiagram() {
+ return theme.Colors.B5
+ } else if obj.IsSequenceDiagramNote() {
+ return theme.Colors.Neutrals.N7
+ } else if obj.IsSequenceDiagramGroup() {
+ sd := obj.outerSequenceDiagram()
+ // Alternate
+ if (level-int(sd.Level()))%2 == 0 {
+ return theme.Colors.Neutrals.N7
+ } else {
+ return theme.Colors.Neutrals.N6
+ }
+ }
+
shape := obj.Attributes.Shape.Value
if shape == "" || strings.EqualFold(shape, d2target.ShapeSquare) || strings.EqualFold(shape, d2target.ShapeCircle) || strings.EqualFold(shape, d2target.ShapeOval) || strings.EqualFold(shape, d2target.ShapeRectangle) {
@@ -399,10 +413,6 @@ func (obj *Object) IsContainer() bool {
return len(obj.Children) > 0
}
-func (obj *Object) IsSequenceDiagram() bool {
- return obj != nil && obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram
-}
-
func (obj *Object) AbsID() string {
if obj.Parent != nil && obj.Parent.ID != "" {
return obj.Parent.AbsID() + "." + obj.ID
@@ -711,16 +721,6 @@ func (e *Edge) AbsID() string {
return fmt.Sprintf("%s(%s %s %s)[%d]", commonKey, strings.Join(srcIDA, "."), e.ArrowString(), strings.Join(dstIDA, "."), e.Index)
}
-func (obj *Object) outerSequenceDiagram() *Object {
- for obj != nil {
- obj = obj.Parent
- if obj.IsSequenceDiagram() {
- return obj
- }
- }
- return nil
-}
-
func (obj *Object) Connect(srcID, dstID []string, srcArrow, dstArrow bool, label string) (*Edge, error) {
srcObj, srcID, err := ResolveUnderscoreKey(srcID, obj)
if err != nil {
diff --git a/d2graph/seqdiagram.go b/d2graph/seqdiagram.go
new file mode 100644
index 000000000..fbd4d4bb6
--- /dev/null
+++ b/d2graph/seqdiagram.go
@@ -0,0 +1,77 @@
+package d2graph
+
+import "oss.terrastruct.com/d2/d2target"
+
+func (obj *Object) IsSequenceDiagram() bool {
+ return obj != nil && obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram
+}
+
+func (obj *Object) outerSequenceDiagram() *Object {
+ for obj != nil {
+ obj = obj.Parent
+ if obj.IsSequenceDiagram() {
+ return obj
+ }
+ }
+ return nil
+}
+
+// groups are objects in sequence diagrams that have no messages connected
+// and does not have a note as a child (a note can appear within a group, but it's a child of an actor)
+func (obj *Object) IsSequenceDiagramGroup() bool {
+ if obj.outerSequenceDiagram() == nil {
+ return false
+ }
+ for _, e := range obj.Graph.Edges {
+ if e.Src == obj || e.Dst == obj {
+ return false
+ }
+ }
+ for _, ch := range obj.ChildrenArray {
+ // if the child contains a message, it's a span, not a note
+ if !ch.ContainsAnyEdge(obj.Graph.Edges) {
+ return false
+ }
+ }
+ return true
+}
+
+// notes are descendant of actors with no edges and no children
+func (obj *Object) IsSequenceDiagramNote() bool {
+ if obj.outerSequenceDiagram() == nil {
+ return false
+ }
+ return !obj.hasEdgeRef() && !obj.ContainsAnyEdge(obj.Graph.Edges) && len(obj.ChildrenArray) == 0
+}
+
+func (obj *Object) hasEdgeRef() bool {
+ for _, ref := range obj.References {
+ if ref.MapKey != nil && len(ref.MapKey.Edges) > 0 {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (obj *Object) ContainsAnyEdge(edges []*Edge) bool {
+ for _, e := range edges {
+ if e.ContainedBy(obj) {
+ return true
+ }
+ }
+ return false
+}
+
+func (e *Edge) ContainedBy(obj *Object) bool {
+ for _, ref := range e.References {
+ curr := ref.ScopeObj
+ for curr != nil {
+ if curr == obj {
+ return true
+ }
+ curr = curr.Parent
+ }
+ }
+ return false
+}
diff --git a/d2layouts/d2sequence/constants.go b/d2layouts/d2sequence/constants.go
index 676eb3d73..78ff0ce16 100644
--- a/d2layouts/d2sequence/constants.go
+++ b/d2layouts/d2sequence/constants.go
@@ -6,10 +6,14 @@ const HORIZONTAL_PAD = 50.
// leaves at least 25 units of space on the top/bottom when computing the space required between messages
const VERTICAL_PAD = 50.
-const MIN_ACTOR_DISTANCE = 250.
+const MIN_ACTOR_DISTANCE = 70.
const MIN_ACTOR_WIDTH = 150.
+const SELF_MESSAGE_HORIZONTAL_TRAVEL = 100.
+
+const GROUP_CONTAINER_PADDING = 24.
+
// min vertical distance between messages
const MIN_MESSAGE_DISTANCE = 80.
@@ -30,3 +34,11 @@ const LIFELINE_STROKE_DASH int = 6
// pad when the actor has the label placed OutsideMiddleBottom so that the lifeline is not so close to the text
const LIFELINE_LABEL_PAD = 5.
+
+const (
+ GROUP_Z_INDEX = 1
+ LIFELINE_Z_INDEX = 2
+ SPAN_Z_INDEX = 3
+ MESSAGE_Z_INDEX = 4
+ NOTE_Z_INDEX = 5
+)
diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go
index 3f8650259..33e82a0a4 100644
--- a/d2layouts/d2sequence/layout.go
+++ b/d2layouts/d2sequence/layout.go
@@ -56,6 +56,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Conte
for _, obj := range sd.notes {
objectsToRemove[obj] = struct{}{}
}
+ for _, obj := range sd.groups {
+ objectsToRemove[obj] = struct{}{}
+ }
for _, obj := range sd.spans {
objectsToRemove[obj] = struct{}{}
}
@@ -151,6 +154,7 @@ func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, obj
g.Edges = append(g.Edges, sequenceDiagrams[obj.AbsID()].lifelines...)
g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].actors...)
g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].notes...)
+ g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].groups...)
g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].spans...)
}
diff --git a/d2layouts/d2sequence/layout_test.go b/d2layouts/d2sequence/layout_test.go
index dc4e6d07c..1e3dbfd60 100644
--- a/d2layouts/d2sequence/layout_test.go
+++ b/d2layouts/d2sequence/layout_test.go
@@ -231,8 +231,8 @@ b -> a.t2`
}
for _, span := range []*d2graph.Object{a_t1, a_t2, b_t1} {
- if span.ZIndex != 1 {
- t.Fatalf("expected span ZIndex=1, got %d", span.ZIndex)
+ if span.ZIndex != d2sequence.SPAN_Z_INDEX {
+ t.Fatalf("expected span ZIndex=%d, got %d", d2sequence.SPAN_Z_INDEX, span.ZIndex)
}
}
diff --git a/d2layouts/d2sequence/sequence_diagram.go b/d2layouts/d2sequence/sequence_diagram.go
index 11df81b59..fdf214eff 100644
--- a/d2layouts/d2sequence/sequence_diagram.go
+++ b/d2layouts/d2sequence/sequence_diagram.go
@@ -64,61 +64,12 @@ func getEdgeEarliestLineNum(e *d2graph.Edge) int {
return min
}
-func hasEdge(o *d2graph.Object) bool {
- for _, ref := range o.References {
- if ref.MapKey != nil && len(ref.MapKey.Edges) > 0 {
- return true
- }
- }
-
- return false
-}
-
-func containsAnyMessage(o *d2graph.Object, messages []*d2graph.Edge) bool {
- for _, m := range messages {
- if containsMessage(o, m) {
- return true
- }
- }
- return false
-}
-
-func containsMessage(o *d2graph.Object, m *d2graph.Edge) bool {
- for _, ref := range m.References {
- curr := ref.ScopeObj
- for curr != nil {
- if curr == o {
- return true
- }
- curr = curr.Parent
- }
- }
- return false
-}
-
func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *sequenceDiagram {
var actors []*d2graph.Object
var groups []*d2graph.Object
for _, obj := range objects {
- messageRecipient := false
- for _, m := range messages {
- if m.Src == obj || m.Dst == obj {
- messageRecipient = true
- break
- }
- }
- hasNote := false
- for _, ch := range obj.ChildrenArray {
- // if the child contains a message, it's a span, not a note
- if !containsAnyMessage(ch, messages) {
- hasNote = true
- break
- }
- }
- if messageRecipient || hasNote {
- actors = append(actors, obj)
- } else {
+ if obj.IsSequenceDiagramGroup() {
queue := []*d2graph.Object{obj}
// Groups may have more nested groups
for len(queue) > 0 {
@@ -129,6 +80,8 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
queue = append(queue, c)
}
}
+ } else {
+ actors = append(actors, obj)
}
}
@@ -153,9 +106,7 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
sd.objectRank[actor] = rank
if actor.Width < MIN_ACTOR_WIDTH {
- aspectRatio := actor.Height / actor.Width
actor.Width = MIN_ACTOR_WIDTH
- actor.Height = math.Round(aspectRatio * actor.Width)
}
sd.maxActorHeight = math.Max(sd.maxActorHeight, actor.Height)
@@ -166,22 +117,21 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
queue = queue[1:]
// spans are children of actors that have edges
- // notes are children of actors with no edges and no children
// edge groups are children of actors with no edges and children edges
- if hasEdge(child) && !containsAnyMessage(child, sd.messages) {
- // spans have no labels
- // TODO why not? Spans should be able to
- child.Attributes.Label = d2graph.Scalar{Value: ""}
- child.Attributes.Shape = d2graph.Scalar{Value: shape.SQUARE_TYPE}
- sd.spans = append(sd.spans, child)
- sd.objectRank[child] = rank
- } else {
+ if child.IsSequenceDiagramNote() {
sd.verticalIndices[child.AbsID()] = getObjEarliestLineNum(child)
// TODO change to page type when it doesn't look deformed
child.Attributes.Shape = d2graph.Scalar{Value: shape.SQUARE_TYPE}
sd.notes = append(sd.notes, child)
sd.objectRank[child] = rank
child.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
+ } else {
+ // spans have no labels
+ // TODO why not? Spans should be able to
+ child.Attributes.Label = d2graph.Scalar{Value: ""}
+ child.Attributes.Shape = d2graph.Scalar{Value: shape.SQUARE_TYPE}
+ sd.spans = append(sd.spans, child)
+ sd.objectRank[child] = rank
}
queue = append(queue, child.ChildrenArray...)
@@ -240,7 +190,11 @@ func (sd *sequenceDiagram) layout() error {
}
func (sd *sequenceDiagram) placeGroups() {
+ sort.SliceStable(sd.groups, func(i, j int) bool {
+ return sd.groups[i].Level() > sd.groups[j].Level()
+ })
for _, group := range sd.groups {
+ group.ZIndex = GROUP_Z_INDEX
sd.placeGroup(group)
}
}
@@ -252,12 +206,12 @@ func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
maxY := math.Inf(-1)
for _, m := range sd.messages {
- if containsMessage(group, m) {
+ if m.ContainedBy(group) {
for _, p := range m.Route {
- minX = math.Min(minX, p.X)
- minY = math.Min(minY, p.Y)
- maxX = math.Max(maxX, p.X)
- maxY = math.Max(maxY, p.Y)
+ minX = math.Min(minX, p.X-HORIZONTAL_PAD)
+ minY = math.Min(minY, p.Y-MIN_MESSAGE_DISTANCE/2.)
+ maxX = math.Max(maxX, p.X+HORIZONTAL_PAD)
+ maxY = math.Max(maxY, p.Y+MIN_MESSAGE_DISTANCE/2.)
}
}
}
@@ -278,20 +232,32 @@ func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
}
}
if inGroup {
- minY = math.Min(minY, n.TopLeft.Y)
- maxY = math.Max(maxY, n.TopLeft.Y+n.Height)
- minX = math.Min(minX, n.TopLeft.X)
- maxX = math.Max(maxX, n.TopLeft.X+n.Width)
+ minX = math.Min(minX, n.TopLeft.X-HORIZONTAL_PAD)
+ minY = math.Min(minY, n.TopLeft.Y-MIN_MESSAGE_DISTANCE/2.)
+ maxY = math.Max(maxY, n.TopLeft.Y+n.Height+HORIZONTAL_PAD)
+ maxX = math.Max(maxX, n.TopLeft.X+n.Width+MIN_MESSAGE_DISTANCE/2.)
+ }
+ }
+
+ for _, ch := range group.ChildrenArray {
+ for _, g := range sd.groups {
+ if ch == g {
+ minX = math.Min(minX, ch.TopLeft.X-GROUP_CONTAINER_PADDING)
+ minY = math.Min(minY, ch.TopLeft.Y-GROUP_CONTAINER_PADDING)
+ maxX = math.Max(maxX, ch.TopLeft.X+ch.Width+GROUP_CONTAINER_PADDING)
+ maxY = math.Max(maxY, ch.TopLeft.Y+ch.Height+GROUP_CONTAINER_PADDING)
+ break
+ }
}
}
group.Box = geo.NewBox(
geo.NewPoint(
- minX-HORIZONTAL_PAD,
- minY-(MIN_MESSAGE_DISTANCE/2.),
+ minX,
+ minY,
),
- maxX-minX+HORIZONTAL_PAD*2,
- maxY-minY+MIN_MESSAGE_DISTANCE,
+ maxX-minX,
+ maxY-minY,
)
}
@@ -360,6 +326,7 @@ func (sd *sequenceDiagram) addLifelineEdges() {
},
DstArrow: false,
Route: []*geo.Point{actorBottom, actorLifelineEnd},
+ ZIndex: LIFELINE_Z_INDEX,
})
}
}
@@ -385,7 +352,7 @@ func (sd *sequenceDiagram) placeNotes() {
x := rankToX[sd.objectRank[note]] - (note.Width / 2.)
note.Box.TopLeft = geo.NewPoint(x, y)
- note.ZIndex = 1
+ note.ZIndex = NOTE_Z_INDEX
}
}
@@ -457,11 +424,11 @@ func (sd *sequenceDiagram) placeSpans() {
}
height := math.Max(maxY-minY, MIN_SPAN_HEIGHT)
- // -2 because the actors count as level 1 making the first level span getting 2*SPAN_DEPTH_GROW_FACTOR
- width := SPAN_BASE_WIDTH + (float64(span.Level()-2) * SPAN_DEPTH_GROWTH_FACTOR)
+ // -1 because the actors count as 1 level
+ width := SPAN_BASE_WIDTH + (float64(span.Level()-sd.root.Level()-2) * SPAN_DEPTH_GROWTH_FACTOR)
x := rankToX[sd.objectRank[span]] - (width / 2.)
span.Box = geo.NewBox(geo.NewPoint(x, minY), width, height)
- span.ZIndex = 1
+ span.ZIndex = SPAN_Z_INDEX
}
}
@@ -470,6 +437,7 @@ func (sd *sequenceDiagram) placeSpans() {
func (sd *sequenceDiagram) routeMessages() error {
messageOffset := sd.maxActorHeight + sd.yStep
for _, message := range sd.messages {
+ message.ZIndex = MESSAGE_Z_INDEX
noteOffset := 0.
for _, note := range sd.notes {
if sd.verticalIndices[note.AbsID()] < sd.verticalIndices[message.AbsID()] {
@@ -478,7 +446,6 @@ func (sd *sequenceDiagram) routeMessages() error {
}
startY := messageOffset + noteOffset
- message.ZIndex = 2
var startX, endX float64
if startCenter := getCenter(message.Src); startCenter != nil {
startX = startCenter.X
@@ -495,7 +462,7 @@ func (sd *sequenceDiagram) routeMessages() error {
isSelfMessage := message.Src == message.Dst
if isSelfMessage || isToDescendant || isFromDescendant {
- midX := startX + MIN_MESSAGE_DISTANCE
+ midX := startX + SELF_MESSAGE_HORIZONTAL_TRAVEL
endY := startY + MIN_MESSAGE_DISTANCE
message.Route = []*geo.Point{
geo.NewPoint(startX, startY),
diff --git a/d2lib/d2.go b/d2lib/d2.go
index 182dd0ae3..6ab141d95 100644
--- a/d2lib/d2.go
+++ b/d2lib/d2.go
@@ -35,15 +35,17 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target
return nil, nil, err
}
- err = g.SetDimensions(opts.MeasuredTexts, opts.Ruler)
- if err != nil {
- return nil, nil, err
- }
+ if len(g.Objects) > 0 {
+ err = g.SetDimensions(opts.MeasuredTexts, opts.Ruler)
+ if err != nil {
+ return nil, nil, err
+ }
- if layout, err := getLayout(opts); err != nil {
- return nil, nil, err
- } else if err := d2sequence.Layout(ctx, g, layout); err != nil {
- return nil, nil, err
+ if layout, err := getLayout(opts); err != nil {
+ return nil, nil, err
+ } else if err := d2sequence.Layout(ctx, g, layout); err != nil {
+ return nil, nil, err
+ }
}
diagram, err := d2exporter.Export(ctx, g, opts.ThemeID)
diff --git a/d2themes/d2themes.go b/d2themes/d2themes.go
index c5217c592..64510eb2f 100644
--- a/d2themes/d2themes.go
+++ b/d2themes/d2themes.go
@@ -14,6 +14,7 @@ type Neutral struct {
N3 string `json:"n3"`
N4 string `json:"n4"`
N5 string `json:"n5"`
+ N6 string `json:"n6"`
N7 string `json:"n7"`
}
@@ -44,6 +45,7 @@ var CoolNeutral = Neutral{
N3: "#9499AB",
N4: "#CFD2DD",
N5: "#F0F3F9",
+ N6: "#EEF1F8",
N7: "#FFFFFF",
}
@@ -53,5 +55,6 @@ var WarmNeutral = Neutral{
N3: "#787777",
N4: "#CCCACA",
N5: "#DFDCDC",
+ N6: "#ECEBEB",
N7: "#FFFFFF",
}
diff --git a/e2etests/e2e_test.go b/e2etests/e2e_test.go
index fa3e07ba8..b77a4cc59 100644
--- a/e2etests/e2e_test.go
+++ b/e2etests/e2e_test.go
@@ -38,6 +38,10 @@ func TestE2E(t *testing.T) {
func testSanity(t *testing.T) {
tcs := []testCase{
+ {
+ name: "empty",
+ script: ``,
+ },
{
name: "basic",
script: `a -> b
diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go
index 526d22aca..3596355f2 100644
--- a/e2etests/stable_test.go
+++ b/e2etests/stable_test.go
@@ -1399,7 +1399,9 @@ choo: {
d2compiler -> CLI: objects and edges
CLI -> d2layout.layout: run layout engines
d2layout.layout -> d2sequencelayout: run engine on shape: sequence_diagram, temporarily remove
- d2layout.layout -> d2dagrelayout: run core engine on rest
+ only if root is not sequence: {
+ _.d2layout.layout -> _.d2dagrelayout: run core engine on rest
+ }
d2layout.layout <- d2sequencelayout: add back in sequence diagrams
d2layout -> CLI: diagram with correct positions and dimensions
CLI -> d2exporter: export diagram with chosen theme and renderer
diff --git a/e2etests/testdata/sanity/empty/dagre/board.exp.json b/e2etests/testdata/sanity/empty/dagre/board.exp.json
new file mode 100644
index 000000000..8591adc9e
--- /dev/null
+++ b/e2etests/testdata/sanity/empty/dagre/board.exp.json
@@ -0,0 +1,5 @@
+{
+ "name": "",
+ "shapes": [],
+ "connections": []
+}
diff --git a/e2etests/testdata/sanity/empty/dagre/sketch.exp.svg b/e2etests/testdata/sanity/empty/dagre/sketch.exp.svg
new file mode 100644
index 000000000..5c521366b
--- /dev/null
+++ b/e2etests/testdata/sanity/empty/dagre/sketch.exp.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/sanity/empty/elk/board.exp.json b/e2etests/testdata/sanity/empty/elk/board.exp.json
new file mode 100644
index 000000000..8591adc9e
--- /dev/null
+++ b/e2etests/testdata/sanity/empty/elk/board.exp.json
@@ -0,0 +1,5 @@
+{
+ "name": "",
+ "shapes": [],
+ "connections": []
+}
diff --git a/e2etests/testdata/sanity/empty/elk/sketch.exp.svg b/e2etests/testdata/sanity/empty/elk/sketch.exp.svg
new file mode 100644
index 000000000..5c521366b
--- /dev/null
+++ b/e2etests/testdata/sanity/empty/elk/sketch.exp.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/board.exp.json b/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/board.exp.json
index 4c42ba6d9..73b2fad99 100644
--- a/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/board.exp.json
+++ b/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/board.exp.json
@@ -14,7 +14,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#FFFFFF",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -44,16 +44,16 @@
"id": "b",
"type": "oval",
"pos": {
- "x": 259,
- "y": 84
+ "x": 223,
+ "y": 87
},
"width": 150,
- "height": 150,
+ "height": 147,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#F7F8FE",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -83,7 +83,7 @@
"id": "c",
"type": "class",
"pos": {
- "x": 463,
+ "x": 443,
"y": 50
},
"width": 241,
@@ -92,7 +92,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#FFFFFF",
+ "fill": "#EDF0FD",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
@@ -133,7 +133,7 @@
"id": "d",
"type": "cloud",
"pos": {
- "x": 744,
+ "x": 754,
"y": 108
},
"width": 179,
@@ -142,7 +142,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#FFFFFF",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -172,7 +172,7 @@
"id": "e",
"type": "code",
"pos": {
- "x": 986,
+ "x": 1003,
"y": 164
},
"width": 196,
@@ -181,7 +181,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#FFFFFF",
+ "fill": "#EDF0FD",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
@@ -211,11 +211,11 @@
"id": "f",
"type": "cylinder",
"pos": {
- "x": 1259,
- "y": 84
+ "x": 1269,
+ "y": 108
},
"width": 150,
- "height": 150,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -250,16 +250,16 @@
"id": "g",
"type": "diamond",
"pos": {
- "x": 1509,
- "y": 85
+ "x": 1489,
+ "y": 108
},
"width": 150,
- "height": 149,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#CFD2DD",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -289,11 +289,11 @@
"id": "h",
"type": "document",
"pos": {
- "x": 1759,
- "y": 97
+ "x": 1709,
+ "y": 108
},
"width": 150,
- "height": 137,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -328,7 +328,7 @@
"id": "i",
"type": "hexagon",
"pos": {
- "x": 1993,
+ "x": 1929,
"y": 108
},
"width": 182,
@@ -337,7 +337,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#F0F3F9",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -367,16 +367,16 @@
"id": "j",
"type": "image",
"pos": {
- "x": 2259,
- "y": 63
+ "x": 2181,
+ "y": 85
},
"width": 150,
- "height": 150,
+ "height": 128,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#FFFFFF",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -417,16 +417,16 @@
"id": "k",
"type": "oval",
"pos": {
- "x": 2509,
- "y": 97
+ "x": 2401,
+ "y": 108
},
"width": 150,
- "height": 137,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#F7F8FE",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -456,11 +456,11 @@
"id": "l",
"type": "package",
"pos": {
- "x": 2759,
- "y": 98
+ "x": 2621,
+ "y": 108
},
"width": 150,
- "height": 136,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -495,7 +495,7 @@
"id": "m",
"type": "page",
"pos": {
- "x": 2996,
+ "x": 2841,
"y": 108
},
"width": 175,
@@ -534,7 +534,7 @@
"id": "n",
"type": "parallelogram",
"pos": {
- "x": 3242,
+ "x": 3086,
"y": 92
},
"width": 183,
@@ -543,7 +543,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#F0F3F9",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -573,7 +573,7 @@
"id": "o",
"type": "person",
"pos": {
- "x": 3507,
+ "x": 3339,
"y": 55
},
"width": 154,
@@ -582,7 +582,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#E3E9FD",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -612,7 +612,7 @@
"id": "p",
"type": "queue",
"pos": {
- "x": 3753,
+ "x": 3563,
"y": 108
},
"width": 161,
@@ -621,7 +621,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#F0F3F9",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -651,7 +651,7 @@
"id": "q",
"type": "rectangle",
"pos": {
- "x": 4001,
+ "x": 3794,
"y": 69
},
"width": 165,
@@ -660,7 +660,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#F7F8FE",
+ "fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
@@ -690,7 +690,7 @@
"id": "r",
"type": "step",
"pos": {
- "x": 4227,
+ "x": 4029,
"y": 108
},
"width": 213,
@@ -729,11 +729,11 @@
"id": "s",
"type": "stored_data",
"pos": {
- "x": 4509,
- "y": 96
+ "x": 4312,
+ "y": 108
},
"width": 150,
- "height": 138,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -768,7 +768,7 @@
"id": "t",
"type": "sql_table",
"pos": {
- "x": 4729,
+ "x": 4532,
"y": 126
},
"width": 210,
@@ -777,7 +777,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "#FFFFFF",
+ "fill": "#EDF0FD",
"stroke": "#0A0F25",
"shadow": false,
"3d": false,
@@ -848,14 +848,14 @@
"y": 364
},
{
- "x": 334,
+ "x": 298,
"y": 364
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(b <-> c)[0]",
@@ -883,18 +883,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 334,
+ "x": 298,
"y": 494
},
{
- "x": 583.5,
+ "x": 563.5,
"y": 494
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(c -> d)[0]",
@@ -922,18 +922,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 583.5,
+ "x": 563.5,
"y": 624
},
{
- "x": 833.5,
+ "x": 843.5,
"y": 624
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(d -> e)[0]",
@@ -961,18 +961,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 833.5,
+ "x": 843.5,
"y": 754
},
{
- "x": 1084,
+ "x": 1101,
"y": 754
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(e -> f)[0]",
@@ -1000,18 +1000,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1084,
+ "x": 1101,
"y": 884
},
{
- "x": 1334,
+ "x": 1344,
"y": 884
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(f -> g)[0]",
@@ -1039,18 +1039,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1334,
+ "x": 1344,
"y": 1014
},
{
- "x": 1584,
+ "x": 1564,
"y": 1014
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(g -> h)[0]",
@@ -1078,18 +1078,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1584,
+ "x": 1564,
"y": 1144
},
{
- "x": 1834,
+ "x": 1784,
"y": 1144
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(h -> i)[0]",
@@ -1117,18 +1117,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1834,
+ "x": 1784,
"y": 1274
},
{
- "x": 2084,
+ "x": 2020,
"y": 1274
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(i -> j)[0]",
@@ -1156,18 +1156,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2084,
+ "x": 2020,
"y": 1404
},
{
- "x": 2334,
+ "x": 2256,
"y": 1404
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(j -> k)[0]",
@@ -1195,18 +1195,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2334,
+ "x": 2256,
"y": 1534
},
{
- "x": 2584,
+ "x": 2476,
"y": 1534
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(k -> l)[0]",
@@ -1234,18 +1234,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2584,
+ "x": 2476,
"y": 1664
},
{
- "x": 2834,
+ "x": 2696,
"y": 1664
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(l -> m)[0]",
@@ -1273,18 +1273,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2834,
+ "x": 2696,
"y": 1794
},
{
- "x": 3083.5,
+ "x": 2928.5,
"y": 1794
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(m -> n)[0]",
@@ -1312,18 +1312,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3083.5,
+ "x": 2928.5,
"y": 1924
},
{
- "x": 3333.5,
+ "x": 3177.5,
"y": 1924
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(n -> o)[0]",
@@ -1351,18 +1351,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3333.5,
+ "x": 3177.5,
"y": 2054
},
{
- "x": 3584,
+ "x": 3416,
"y": 2054
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(o -> p)[0]",
@@ -1390,18 +1390,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3584,
+ "x": 3416,
"y": 2184
},
{
- "x": 3833.5,
+ "x": 3643.5,
"y": 2184
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(p -> q)[0]",
@@ -1429,18 +1429,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3833.5,
+ "x": 3643.5,
"y": 2314
},
{
- "x": 4083.5,
+ "x": 3876.5,
"y": 2314
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(q -> r)[0]",
@@ -1468,18 +1468,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4083.5,
+ "x": 3876.5,
"y": 2444
},
{
- "x": 4333.5,
+ "x": 4135.5,
"y": 2444
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(r -> s)[0]",
@@ -1507,18 +1507,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4333.5,
+ "x": 4135.5,
"y": 2574
},
{
- "x": 4584,
+ "x": 4387,
"y": 2574
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(s -> t)[0]",
@@ -1546,18 +1546,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4584,
+ "x": 4387,
"y": 2704
},
{
- "x": 4834,
+ "x": 4637,
"y": 2704
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 2
+ "zIndex": 4
},
{
"id": "(a -- )[0]",
@@ -1596,7 +1596,7 @@
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(b -- )[0]",
@@ -1624,18 +1624,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 334,
+ "x": 298,
"y": 234
},
{
- "x": 334,
+ "x": 298,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(c -- )[0]",
@@ -1663,18 +1663,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 583.5,
+ "x": 563.5,
"y": 234
},
{
- "x": 583.5,
+ "x": 563.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(d -- )[0]",
@@ -1702,18 +1702,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 833.5,
+ "x": 843.5,
"y": 234
},
{
- "x": 833.5,
+ "x": 843.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(e -- )[0]",
@@ -1741,18 +1741,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1084,
+ "x": 1101,
"y": 234
},
{
- "x": 1084,
+ "x": 1101,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(f -- )[0]",
@@ -1780,18 +1780,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1334,
+ "x": 1344,
"y": 234
},
{
- "x": 1334,
+ "x": 1344,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(g -- )[0]",
@@ -1819,18 +1819,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1584,
+ "x": 1564,
"y": 234
},
{
- "x": 1584,
+ "x": 1564,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(h -- )[0]",
@@ -1858,18 +1858,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 1834,
+ "x": 1784,
"y": 234
},
{
- "x": 1834,
+ "x": 1784,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(i -- )[0]",
@@ -1897,18 +1897,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2084,
+ "x": 2020,
"y": 234
},
{
- "x": 2084,
+ "x": 2020,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(j -- )[0]",
@@ -1936,18 +1936,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2334,
+ "x": 2256,
"y": 239
},
{
- "x": 2334,
+ "x": 2256,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(k -- )[0]",
@@ -1975,18 +1975,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2584,
+ "x": 2476,
"y": 234
},
{
- "x": 2584,
+ "x": 2476,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(l -- )[0]",
@@ -2014,18 +2014,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 2834,
+ "x": 2696,
"y": 234
},
{
- "x": 2834,
+ "x": 2696,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(m -- )[0]",
@@ -2053,18 +2053,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3083.5,
+ "x": 2928.5,
"y": 234
},
{
- "x": 3083.5,
+ "x": 2928.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(n -- )[0]",
@@ -2092,18 +2092,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3333.5,
+ "x": 3177.5,
"y": 234
},
{
- "x": 3333.5,
+ "x": 3177.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(o -- )[0]",
@@ -2131,18 +2131,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3584,
+ "x": 3416,
"y": 239
},
{
- "x": 3584,
+ "x": 3416,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(p -- )[0]",
@@ -2170,18 +2170,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 3833.5,
+ "x": 3643.5,
"y": 234
},
{
- "x": 3833.5,
+ "x": 3643.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(q -- )[0]",
@@ -2209,18 +2209,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4083.5,
+ "x": 3876.5,
"y": 234
},
{
- "x": 4083.5,
+ "x": 3876.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(r -- )[0]",
@@ -2248,18 +2248,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4333.5,
+ "x": 4135.5,
"y": 234
},
{
- "x": 4333.5,
+ "x": 4135.5,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(s -- )[0]",
@@ -2287,18 +2287,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4584,
+ "x": 4387,
"y": 234
},
{
- "x": 4584,
+ "x": 4387,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
},
{
"id": "(t -- )[0]",
@@ -2326,18 +2326,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 4834,
+ "x": 4637,
"y": 234
},
{
- "x": 4834,
+ "x": 4637,
"y": 2834
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 0
+ "zIndex": 2
}
]
}
diff --git a/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg
index 2d74a90f0..7e13b2b3a 100644
--- a/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg
+++ b/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg
@@ -2,7 +2,7 @@