Merge pull request #336 from ejulio-ts/sequence-diagram-self-edges
sequence diagram: self edges
This commit is contained in:
commit
b07fe2b956
12 changed files with 1630 additions and 80 deletions
|
|
@ -37,7 +37,10 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Conte
|
|||
continue
|
||||
}
|
||||
|
||||
sd := layoutSequenceDiagram(g, obj)
|
||||
sd, err := layoutSequenceDiagram(g, obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj.Children = make(map[string]*d2graph.Object)
|
||||
obj.ChildrenArray = nil
|
||||
obj.Box = geo.NewBox(nil, sd.getWidth(), sd.getHeight())
|
||||
|
|
@ -76,7 +79,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Conte
|
|||
}
|
||||
|
||||
// layoutSequenceDiagram finds the edges inside the sequence diagram and performs the layout on the object descendants
|
||||
func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) *sequenceDiagram {
|
||||
func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) (*sequenceDiagram, error) {
|
||||
var edges []*d2graph.Edge
|
||||
for _, edge := range g.Edges {
|
||||
// both Src and Dst must be inside the sequence diagram
|
||||
|
|
@ -86,8 +89,8 @@ func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) *sequenceDiagr
|
|||
}
|
||||
|
||||
sd := newSequenceDiagram(obj.ChildrenArray, edges)
|
||||
sd.layout()
|
||||
return sd
|
||||
err := sd.layout()
|
||||
return sd, err
|
||||
}
|
||||
|
||||
func getLayoutEdges(g *d2graph.Graph, toRemove map[*d2graph.Edge]struct{}) ([]*d2graph.Edge, map[string]int) {
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ func TestSpansSequenceDiagram(t *testing.T) {
|
|||
// ├┐──────────────────────►
|
||||
// t2 ││ │
|
||||
// ├┘◄─────────────────────┤
|
||||
|
||||
input := `
|
||||
shape: sequence_diagram
|
||||
a: { shape: person }
|
||||
|
|
@ -182,7 +183,6 @@ b -> a.t2`
|
|||
|
||||
a, has := g.Root.HasChild([]string{"a"})
|
||||
assert.True(t, has)
|
||||
a.Box = geo.NewBox(nil, 100, 100)
|
||||
|
||||
a_t1, has := a.HasChild([]string{"t1"})
|
||||
assert.True(t, has)
|
||||
|
|
@ -197,6 +197,12 @@ b -> a.t2`
|
|||
b_t1, has := b.HasChild([]string{"t1"})
|
||||
assert.True(t, has)
|
||||
|
||||
a.Box = geo.NewBox(nil, 100, 100)
|
||||
a_t1.Box = geo.NewBox(nil, 100, 100)
|
||||
a_t2.Box = geo.NewBox(nil, 100, 100)
|
||||
b.Box = geo.NewBox(nil, 30, 30)
|
||||
b_t1.Box = geo.NewBox(nil, 100, 100)
|
||||
|
||||
d2sequence.Layout(ctx, g, func(ctx context.Context, g *d2graph.Graph) error {
|
||||
// just set some position as if it had been properly placed
|
||||
for _, obj := range g.Objects {
|
||||
|
|
@ -304,6 +310,7 @@ container -> c: edge 1
|
|||
|
||||
a_t1, has := a.HasChild([]string{"t1"})
|
||||
assert.True(t, has)
|
||||
a_t1.Box = geo.NewBox(nil, 100, 100)
|
||||
|
||||
b, has := container.HasChild([]string{"b"})
|
||||
assert.True(t, has)
|
||||
|
|
@ -311,6 +318,7 @@ container -> c: edge 1
|
|||
|
||||
b_t1, has := b.HasChild([]string{"t1"})
|
||||
assert.True(t, has)
|
||||
b_t1.Box = geo.NewBox(nil, 100, 100)
|
||||
|
||||
c := g.Root.EnsureChild([]string{"c"})
|
||||
c.Box = geo.NewBox(nil, 100, 100)
|
||||
|
|
@ -366,3 +374,90 @@ container -> c: edge 1
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelfEdges(t *testing.T) {
|
||||
g := d2graph.NewGraph(nil)
|
||||
g.Root.Attributes.Shape = d2graph.Scalar{Value: d2target.ShapeSequenceDiagram}
|
||||
n1 := g.Root.EnsureChild([]string{"n1"})
|
||||
n1.Box = geo.NewBox(nil, 100, 100)
|
||||
|
||||
g.Edges = []*d2graph.Edge{
|
||||
{
|
||||
Src: n1,
|
||||
Dst: n1,
|
||||
Index: 0,
|
||||
Attributes: d2graph.Attributes{
|
||||
Label: d2graph.Scalar{Value: "left to right"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := log.WithTB(context.Background(), t, nil)
|
||||
Layout(ctx, g, func(ctx context.Context, g *d2graph.Graph) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
route := g.Edges[0].Route
|
||||
if len(route) != 4 {
|
||||
t.Fatalf("expected route to have 4 points, got %d", len(route))
|
||||
}
|
||||
|
||||
if route[0].X != route[3].X {
|
||||
t.Fatalf("route does not end at the same actor, start at %.5f, end at %.5f", route[0].X, route[3].X)
|
||||
}
|
||||
|
||||
if route[3].Y-route[0].Y != MIN_MESSAGE_DISTANCE {
|
||||
t.Fatalf("expected route height to be %.f5, got %.5f", MIN_MESSAGE_DISTANCE, route[3].Y-route[0].Y)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSequenceToDescendant(t *testing.T) {
|
||||
g := d2graph.NewGraph(nil)
|
||||
g.Root.Attributes.Shape = d2graph.Scalar{Value: d2target.ShapeSequenceDiagram}
|
||||
a := g.Root.EnsureChild([]string{"a"})
|
||||
a.Box = geo.NewBox(nil, 100, 100)
|
||||
a.Attributes = d2graph.Attributes{
|
||||
Shape: d2graph.Scalar{Value: shape.PERSON_TYPE},
|
||||
}
|
||||
a_t1 := a.EnsureChild([]string{"t1"})
|
||||
a_t1.Box = geo.NewBox(nil, 16, 80)
|
||||
|
||||
g.Edges = []*d2graph.Edge{
|
||||
{
|
||||
Src: a,
|
||||
Dst: a_t1,
|
||||
Index: 0,
|
||||
}, {
|
||||
Src: a_t1,
|
||||
Dst: a,
|
||||
Index: 0,
|
||||
},
|
||||
}
|
||||
|
||||
ctx := log.WithTB(context.Background(), t, nil)
|
||||
Layout(ctx, g, func(ctx context.Context, g *d2graph.Graph) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
route1 := g.Edges[0].Route
|
||||
if len(route1) != 4 {
|
||||
t.Fatal("expected route with 4 points")
|
||||
}
|
||||
if route1[0].X != a.Center().X {
|
||||
t.Fatal("expected route to start at `a` lifeline")
|
||||
}
|
||||
if route1[3].X != a_t1.TopLeft.X+a_t1.Width {
|
||||
t.Fatal("expected route to end at `a.t1` right side")
|
||||
}
|
||||
|
||||
route2 := g.Edges[1].Route
|
||||
if len(route2) != 4 {
|
||||
t.Fatal("expected route with 4 points")
|
||||
}
|
||||
if route2[0].X != a_t1.TopLeft.X+a_t1.Width {
|
||||
t.Fatal("expected route to start at `a.t1` right side")
|
||||
}
|
||||
if route2[3].X != a.Center().X {
|
||||
t.Fatal("expected route to end at `a` lifeline")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"oss.terrastruct.com/util-go/go2"
|
||||
|
||||
|
|
@ -28,9 +29,8 @@ type sequenceDiagram struct {
|
|||
objectRank map[*d2graph.Object]int
|
||||
|
||||
// keep track of the first and last message of a given actor/span
|
||||
// the message rank is the order in which it appears from top to bottom
|
||||
minMessageRank map[*d2graph.Object]int
|
||||
maxMessageRank map[*d2graph.Object]int
|
||||
firstMessage map[*d2graph.Object]*d2graph.Edge
|
||||
lastMessage map[*d2graph.Object]*d2graph.Edge
|
||||
|
||||
yStep float64
|
||||
actorXStep float64
|
||||
|
|
@ -137,8 +137,8 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
|
|||
notes: nil,
|
||||
lifelines: nil,
|
||||
objectRank: make(map[*d2graph.Object]int),
|
||||
minMessageRank: make(map[*d2graph.Object]int),
|
||||
maxMessageRank: make(map[*d2graph.Object]int),
|
||||
firstMessage: make(map[*d2graph.Object]*d2graph.Edge),
|
||||
lastMessage: make(map[*d2graph.Object]*d2graph.Edge),
|
||||
yStep: MIN_MESSAGE_DISTANCE,
|
||||
actorXStep: MIN_ACTOR_DISTANCE,
|
||||
maxActorHeight: 0.,
|
||||
|
|
@ -185,18 +185,28 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
|
|||
}
|
||||
}
|
||||
|
||||
for rank, message := range sd.messages {
|
||||
for _, message := range sd.messages {
|
||||
sd.verticalIndices[message.AbsID()] = getEdgeEarliestLineNum(message)
|
||||
sd.yStep = math.Max(sd.yStep, float64(message.LabelDimensions.Height))
|
||||
|
||||
sd.setMinMaxMessageRank(message.Src, rank)
|
||||
sd.setMinMaxMessageRank(message.Dst, rank)
|
||||
|
||||
// ensures that long labels, spanning over multiple actors, don't make for large gaps between actors
|
||||
// by distributing the label length across the actors rank difference
|
||||
rankDiff := math.Abs(float64(sd.objectRank[message.Src]) - float64(sd.objectRank[message.Dst]))
|
||||
distributedLabelWidth := float64(message.LabelDimensions.Width) / rankDiff
|
||||
sd.actorXStep = math.Max(sd.actorXStep, distributedLabelWidth+HORIZONTAL_PAD)
|
||||
if rankDiff != 0 {
|
||||
// rankDiff = 0 for self edges
|
||||
distributedLabelWidth := float64(message.LabelDimensions.Width) / rankDiff
|
||||
sd.actorXStep = math.Max(sd.actorXStep, distributedLabelWidth+HORIZONTAL_PAD)
|
||||
|
||||
}
|
||||
sd.lastMessage[message.Src] = message
|
||||
if _, exists := sd.firstMessage[message.Src]; !exists {
|
||||
sd.firstMessage[message.Src] = message
|
||||
}
|
||||
sd.lastMessage[message.Dst] = message
|
||||
if _, exists := sd.firstMessage[message.Dst]; !exists {
|
||||
sd.firstMessage[message.Dst] = message
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sd.yStep += VERTICAL_PAD
|
||||
|
|
@ -208,23 +218,17 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) *se
|
|||
return sd
|
||||
}
|
||||
|
||||
func (sd *sequenceDiagram) setMinMaxMessageRank(actor *d2graph.Object, rank int) {
|
||||
if minRank, exists := sd.minMessageRank[actor]; exists {
|
||||
sd.minMessageRank[actor] = go2.IntMin(minRank, rank)
|
||||
} else {
|
||||
sd.minMessageRank[actor] = rank
|
||||
}
|
||||
|
||||
sd.maxMessageRank[actor] = go2.IntMax(sd.maxMessageRank[actor], rank)
|
||||
}
|
||||
|
||||
func (sd *sequenceDiagram) layout() {
|
||||
func (sd *sequenceDiagram) layout() error {
|
||||
sd.placeActors()
|
||||
sd.placeSpans()
|
||||
sd.placeNotes()
|
||||
sd.routeMessages()
|
||||
if err := sd.routeMessages(); err != nil {
|
||||
return err
|
||||
}
|
||||
sd.placeSpans()
|
||||
sd.adjustRouteEndpoints()
|
||||
sd.placeGroups()
|
||||
sd.addLifelineEdges()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sd *sequenceDiagram) placeGroups() {
|
||||
|
|
@ -313,11 +317,10 @@ func (sd *sequenceDiagram) placeActors() {
|
|||
// │
|
||||
// │
|
||||
func (sd *sequenceDiagram) addLifelineEdges() {
|
||||
lastRoute := sd.messages[len(sd.messages)-1].Route
|
||||
endY := 0.
|
||||
for _, m := range sd.messages {
|
||||
for _, p := range m.Route {
|
||||
endY = math.Max(endY, p.Y)
|
||||
}
|
||||
for _, p := range lastRoute {
|
||||
endY = math.Max(endY, p.Y)
|
||||
}
|
||||
for _, note := range sd.notes {
|
||||
endY = math.Max(endY, note.TopLeft.Y+note.Height)
|
||||
|
|
@ -415,12 +418,21 @@ func (sd *sequenceDiagram) placeSpans() {
|
|||
|
||||
// finds the position if there are messages to this span
|
||||
minMessageY := math.Inf(1)
|
||||
if minRank, exists := sd.minMessageRank[span]; exists {
|
||||
minMessageY = sd.getMessageY(minRank)
|
||||
if firstMessage, exists := sd.firstMessage[span]; exists {
|
||||
// needs to check Src/Dst because of self-edges or edges to/from descendants
|
||||
if span == firstMessage.Src {
|
||||
minMessageY = firstMessage.Route[0].Y
|
||||
} else {
|
||||
minMessageY = firstMessage.Route[len(firstMessage.Route)-1].Y
|
||||
}
|
||||
}
|
||||
maxMessageY := math.Inf(-1)
|
||||
if maxRank, exists := sd.maxMessageRank[span]; exists {
|
||||
maxMessageY = sd.getMessageY(maxRank)
|
||||
if lastMessage, exists := sd.lastMessage[span]; exists {
|
||||
if span == lastMessage.Src {
|
||||
maxMessageY = lastMessage.Route[0].Y
|
||||
} else {
|
||||
maxMessageY = lastMessage.Route[len(lastMessage.Route)-1].Y
|
||||
}
|
||||
}
|
||||
|
||||
// if it is the same as the child top left, add some padding
|
||||
|
|
@ -442,52 +454,89 @@ func (sd *sequenceDiagram) placeSpans() {
|
|||
}
|
||||
}
|
||||
|
||||
// routeMessages routes horizontal edges (messages) from Src to Dst
|
||||
func (sd *sequenceDiagram) routeMessages() {
|
||||
for rank, message := range sd.messages {
|
||||
message.ZIndex = 2
|
||||
isLeftToRight := message.Src.TopLeft.X < message.Dst.TopLeft.X
|
||||
|
||||
// finds the proper anchor point based on the message direction
|
||||
var startX, endX float64
|
||||
if sd.isActor(message.Src) {
|
||||
startX = message.Src.Center().X
|
||||
} else if isLeftToRight {
|
||||
startX = message.Src.TopLeft.X + message.Src.Width
|
||||
} else {
|
||||
startX = message.Src.TopLeft.X
|
||||
}
|
||||
|
||||
if sd.isActor(message.Dst) {
|
||||
endX = message.Dst.Center().X
|
||||
} else if isLeftToRight {
|
||||
endX = message.Dst.TopLeft.X
|
||||
} else {
|
||||
endX = message.Dst.TopLeft.X + message.Dst.Width
|
||||
}
|
||||
|
||||
messageY := sd.getMessageY(rank)
|
||||
|
||||
// routeMessages routes horizontal edges (messages) from Src to Dst lifeline (actor/span center)
|
||||
// in another step, routes are adjusted to spans borders when necessary
|
||||
func (sd *sequenceDiagram) routeMessages() error {
|
||||
messageOffset := sd.maxActorHeight + sd.yStep
|
||||
for _, message := range sd.messages {
|
||||
noteOffset := 0.
|
||||
for _, note := range sd.notes {
|
||||
if sd.verticalIndices[note.AbsID()] < sd.verticalIndices[message.AbsID()] {
|
||||
messageY += note.Height + sd.yStep
|
||||
noteOffset += note.Height + sd.yStep
|
||||
}
|
||||
}
|
||||
startY := messageOffset + noteOffset
|
||||
|
||||
message.Route = []*geo.Point{
|
||||
geo.NewPoint(startX, messageY),
|
||||
geo.NewPoint(endX, messageY),
|
||||
message.ZIndex = 2
|
||||
var startX, endX float64
|
||||
if startCenter := getCenter(message.Src); startCenter != nil {
|
||||
startX = startCenter.X
|
||||
} else {
|
||||
return fmt.Errorf("could not find center of %s", message.Src.AbsID())
|
||||
}
|
||||
if endCenter := getCenter(message.Dst); endCenter != nil {
|
||||
endX = endCenter.X
|
||||
} else {
|
||||
return fmt.Errorf("could not find center of %s", message.Dst.AbsID())
|
||||
}
|
||||
isToDescendant := strings.HasPrefix(message.Dst.AbsID(), message.Src.AbsID())
|
||||
isFromDescendant := strings.HasPrefix(message.Src.AbsID(), message.Dst.AbsID())
|
||||
isSelfMessage := message.Src == message.Dst
|
||||
|
||||
if isSelfMessage || isToDescendant || isFromDescendant {
|
||||
midX := startX + MIN_MESSAGE_DISTANCE
|
||||
endY := startY + MIN_MESSAGE_DISTANCE
|
||||
message.Route = []*geo.Point{
|
||||
geo.NewPoint(startX, startY),
|
||||
geo.NewPoint(midX, startY),
|
||||
geo.NewPoint(midX, endY),
|
||||
geo.NewPoint(endX, endY),
|
||||
}
|
||||
} else {
|
||||
message.Route = []*geo.Point{
|
||||
geo.NewPoint(startX, startY),
|
||||
geo.NewPoint(endX, startY),
|
||||
}
|
||||
}
|
||||
messageOffset += sd.yStep
|
||||
|
||||
if message.Attributes.Label.Value != "" {
|
||||
message.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sd *sequenceDiagram) getMessageY(rank int) float64 {
|
||||
// +1 so that the first message has the top padding for its label
|
||||
return ((float64(rank) + 1.) * sd.yStep) + sd.maxActorHeight
|
||||
func getCenter(obj *d2graph.Object) *geo.Point {
|
||||
if obj == nil {
|
||||
return nil
|
||||
} else if obj.TopLeft != nil {
|
||||
return obj.Center()
|
||||
}
|
||||
return getCenter(obj.Parent)
|
||||
}
|
||||
|
||||
// adjustRouteEndpoints adjust the first and last points of message routes when they are spans
|
||||
// routeMessages() will route to the actor lifelife as a reference point and this function
|
||||
// adjust to span width when necessary
|
||||
func (sd *sequenceDiagram) adjustRouteEndpoints() {
|
||||
for _, message := range sd.messages {
|
||||
route := message.Route
|
||||
if !sd.isActor(message.Src) {
|
||||
if sd.objectRank[message.Src] <= sd.objectRank[message.Dst] {
|
||||
route[0].X += message.Src.Width / 2.
|
||||
} else {
|
||||
route[0].X -= message.Src.Width / 2.
|
||||
}
|
||||
}
|
||||
if !sd.isActor(message.Dst) {
|
||||
if sd.objectRank[message.Src] < sd.objectRank[message.Dst] {
|
||||
route[len(route)-1].X -= message.Dst.Width / 2.
|
||||
} else {
|
||||
route[len(route)-1].X += message.Dst.Width / 2.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *sequenceDiagram) isActor(obj *d2graph.Object) bool {
|
||||
|
|
@ -501,8 +550,7 @@ func (sd *sequenceDiagram) getWidth() float64 {
|
|||
}
|
||||
|
||||
func (sd *sequenceDiagram) getHeight() float64 {
|
||||
// the layout is always placed starting at 0, so the height is just the last message
|
||||
return sd.getMessageY(len(sd.messages))
|
||||
return sd.lifelines[0].Route[1].Y
|
||||
}
|
||||
|
||||
func (sd *sequenceDiagram) shift(tl *geo.Point) {
|
||||
|
|
|
|||
|
|
@ -1325,6 +1325,16 @@ s -> t`,
|
|||
z -> y
|
||||
z -> z: hello
|
||||
`,
|
||||
}, {
|
||||
name: "sequence_diagram_self_edges",
|
||||
script: `shape: sequence_diagram
|
||||
a -> a: a self edge here
|
||||
a -> b: between actors
|
||||
b -> b.1: to descendant
|
||||
b.1 -> b.1.2: to deeper descendant
|
||||
b.1.2 -> b: to parent
|
||||
b -> a.1.2: actor
|
||||
a.1 -> b.3`,
|
||||
},
|
||||
{
|
||||
name: "icon-label",
|
||||
|
|
|
|||
6
e2etests/testdata/stable/sequence_diagram_real/dagre/board.exp.json
generated
vendored
6
e2etests/testdata/stable/sequence_diagram_real/dagre/board.exp.json
generated
vendored
|
|
@ -9,7 +9,7 @@
|
|||
"y": 0
|
||||
},
|
||||
"width": 3633,
|
||||
"height": 2055,
|
||||
"height": 2311,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
|
|
@ -357,7 +357,7 @@
|
|||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 1304,
|
||||
"y": 869
|
||||
"y": 1125
|
||||
},
|
||||
"width": 20,
|
||||
"height": 422,
|
||||
|
|
@ -473,7 +473,7 @@
|
|||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 1727,
|
||||
"y": 1649
|
||||
"y": 1905
|
||||
},
|
||||
"width": 20,
|
||||
"height": 292,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 479 KiB After Width: | Height: | Size: 479 KiB |
6
e2etests/testdata/stable/sequence_diagram_real/elk/board.exp.json
generated
vendored
6
e2etests/testdata/stable/sequence_diagram_real/elk/board.exp.json
generated
vendored
|
|
@ -9,7 +9,7 @@
|
|||
"y": 12
|
||||
},
|
||||
"width": 3633,
|
||||
"height": 2055,
|
||||
"height": 2311,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
|
|
@ -357,7 +357,7 @@
|
|||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 1316,
|
||||
"y": 881
|
||||
"y": 1137
|
||||
},
|
||||
"width": 20,
|
||||
"height": 422,
|
||||
|
|
@ -473,7 +473,7 @@
|
|||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 1739,
|
||||
"y": 1661
|
||||
"y": 1917
|
||||
},
|
||||
"width": 20,
|
||||
"height": 292,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 479 KiB After Width: | Height: | Size: 479 KiB |
658
e2etests/testdata/stable/sequence_diagram_self_edges/dagre/board.exp.json
generated
vendored
Normal file
658
e2etests/testdata/stable/sequence_diagram_self_edges/dagre/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,658 @@
|
|||
{
|
||||
"name": "",
|
||||
"shapes": [
|
||||
{
|
||||
"id": "a",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 0,
|
||||
"y": 50
|
||||
},
|
||||
"width": 150,
|
||||
"height": 169,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#E3E9FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "a",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 12,
|
||||
"labelHeight": 26,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "b",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 400,
|
||||
"y": 52
|
||||
},
|
||||
"width": 150,
|
||||
"height": 167,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#E3E9FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "b",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "b.1",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 469,
|
||||
"y": 673
|
||||
},
|
||||
"width": 12,
|
||||
"height": 228,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#EDF0FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 15,
|
||||
"labelHeight": 36,
|
||||
"zIndex": 1,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "b.1.2",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 465,
|
||||
"y": 803
|
||||
},
|
||||
"width": 20,
|
||||
"height": 82,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#F7F8FE",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"zIndex": 1,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "a.1",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 69,
|
||||
"y": 967
|
||||
},
|
||||
"width": 12,
|
||||
"height": 178,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#EDF0FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 15,
|
||||
"labelHeight": 36,
|
||||
"zIndex": 1,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "a.1.2",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 65,
|
||||
"y": 983
|
||||
},
|
||||
"width": 20,
|
||||
"height": 80,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#F7F8FE",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"zIndex": 1,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "b.3",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 469,
|
||||
"y": 1113
|
||||
},
|
||||
"width": 12,
|
||||
"height": 80,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#EDF0FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"zIndex": 1,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "(a -> a)[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "a self edge here",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 103,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 75,
|
||||
"y": 349
|
||||
},
|
||||
{
|
||||
"x": 155,
|
||||
"y": 349
|
||||
},
|
||||
{
|
||||
"x": 155,
|
||||
"y": 429
|
||||
},
|
||||
{
|
||||
"x": 75,
|
||||
"y": 429
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(a -> b)[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "between actors",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 102,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 75,
|
||||
"y": 479
|
||||
},
|
||||
{
|
||||
"x": 475,
|
||||
"y": 479
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(b -> b.1)[0]",
|
||||
"src": "b",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b.1",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "to descendant",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 94,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 475,
|
||||
"y": 609
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 609
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 689
|
||||
},
|
||||
{
|
||||
"x": 481,
|
||||
"y": 689
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "b.(1 -> 1.2)[0]",
|
||||
"src": "b.1",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b.1.2",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "to deeper descendant",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 143,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 481,
|
||||
"y": 739
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 739
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 819
|
||||
},
|
||||
{
|
||||
"x": 485,
|
||||
"y": 819
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(b.1.2 -> b)[0]",
|
||||
"src": "b.1.2",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "to parent",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 62,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 485,
|
||||
"y": 869
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 869
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 949
|
||||
},
|
||||
{
|
||||
"x": 475,
|
||||
"y": 949
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(b -> a.1.2)[0]",
|
||||
"src": "b",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a.1.2",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "actor",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 36,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 475,
|
||||
"y": 999
|
||||
},
|
||||
{
|
||||
"x": 85,
|
||||
"y": 999
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(a.1 -> b.3)[0]",
|
||||
"src": "a.1",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b.3",
|
||||
"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": 81,
|
||||
"y": 1129
|
||||
},
|
||||
{
|
||||
"x": 469,
|
||||
"y": 1129
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(a -- )[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a-lifeline-end-2251863791",
|
||||
"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": 75,
|
||||
"y": 219
|
||||
},
|
||||
{
|
||||
"x": 75,
|
||||
"y": 1259
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(b -- )[0]",
|
||||
"src": "b",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b-lifeline-end-668380428",
|
||||
"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": 475,
|
||||
"y": 219
|
||||
},
|
||||
{
|
||||
"x": 475,
|
||||
"y": 1259
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
39
e2etests/testdata/stable/sequence_diagram_self_edges/dagre/sketch.exp.svg
vendored
Normal file
39
e2etests/testdata/stable/sequence_diagram_self_edges/dagre/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 472 KiB |
658
e2etests/testdata/stable/sequence_diagram_self_edges/elk/board.exp.json
generated
vendored
Normal file
658
e2etests/testdata/stable/sequence_diagram_self_edges/elk/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,658 @@
|
|||
{
|
||||
"name": "",
|
||||
"shapes": [
|
||||
{
|
||||
"id": "a",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 0,
|
||||
"y": 50
|
||||
},
|
||||
"width": 150,
|
||||
"height": 169,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#E3E9FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "a",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 12,
|
||||
"labelHeight": 26,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "b",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 400,
|
||||
"y": 52
|
||||
},
|
||||
"width": 150,
|
||||
"height": 167,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#E3E9FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "b",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "b.1",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 469,
|
||||
"y": 673
|
||||
},
|
||||
"width": 12,
|
||||
"height": 228,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#EDF0FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 15,
|
||||
"labelHeight": 36,
|
||||
"zIndex": 1,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "b.1.2",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 465,
|
||||
"y": 803
|
||||
},
|
||||
"width": 20,
|
||||
"height": 82,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#F7F8FE",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"zIndex": 1,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "a.1",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 69,
|
||||
"y": 967
|
||||
},
|
||||
"width": 12,
|
||||
"height": 178,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#EDF0FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 15,
|
||||
"labelHeight": 36,
|
||||
"zIndex": 1,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "a.1.2",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 65,
|
||||
"y": 983
|
||||
},
|
||||
"width": 20,
|
||||
"height": 80,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#F7F8FE",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"zIndex": 1,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "b.3",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 469,
|
||||
"y": 1113
|
||||
},
|
||||
"width": 12,
|
||||
"height": 80,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "#EDF0FD",
|
||||
"stroke": "#0D32B2",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#0A0F25",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 13,
|
||||
"labelHeight": 26,
|
||||
"zIndex": 1,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "(a -> a)[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "a self edge here",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 103,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 75,
|
||||
"y": 349
|
||||
},
|
||||
{
|
||||
"x": 155,
|
||||
"y": 349
|
||||
},
|
||||
{
|
||||
"x": 155,
|
||||
"y": 429
|
||||
},
|
||||
{
|
||||
"x": 75,
|
||||
"y": 429
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(a -> b)[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "between actors",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 102,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 75,
|
||||
"y": 479
|
||||
},
|
||||
{
|
||||
"x": 475,
|
||||
"y": 479
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(b -> b.1)[0]",
|
||||
"src": "b",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b.1",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "to descendant",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 94,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 475,
|
||||
"y": 609
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 609
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 689
|
||||
},
|
||||
{
|
||||
"x": 481,
|
||||
"y": 689
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "b.(1 -> 1.2)[0]",
|
||||
"src": "b.1",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b.1.2",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "to deeper descendant",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 143,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 481,
|
||||
"y": 739
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 739
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 819
|
||||
},
|
||||
{
|
||||
"x": 485,
|
||||
"y": 819
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(b.1.2 -> b)[0]",
|
||||
"src": "b.1.2",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "to parent",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 62,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 485,
|
||||
"y": 869
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 869
|
||||
},
|
||||
{
|
||||
"x": 555,
|
||||
"y": 949
|
||||
},
|
||||
{
|
||||
"x": 475,
|
||||
"y": 949
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(b -> a.1.2)[0]",
|
||||
"src": "b",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a.1.2",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "#0D32B2",
|
||||
"label": "actor",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "#676C7E",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 36,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 475,
|
||||
"y": 999
|
||||
},
|
||||
{
|
||||
"x": 85,
|
||||
"y": 999
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(a.1 -> b.3)[0]",
|
||||
"src": "a.1",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b.3",
|
||||
"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": 81,
|
||||
"y": 1129
|
||||
},
|
||||
{
|
||||
"x": 469,
|
||||
"y": 1129
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 2
|
||||
},
|
||||
{
|
||||
"id": "(a -- )[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a-lifeline-end-2251863791",
|
||||
"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": 75,
|
||||
"y": 219
|
||||
},
|
||||
{
|
||||
"x": 75,
|
||||
"y": 1259
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(b -- )[0]",
|
||||
"src": "b",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "b-lifeline-end-668380428",
|
||||
"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": 475,
|
||||
"y": 219
|
||||
},
|
||||
{
|
||||
"x": 475,
|
||||
"y": 1259
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
39
e2etests/testdata/stable/sequence_diagram_self_edges/elk/sketch.exp.svg
vendored
Normal file
39
e2etests/testdata/stable/sequence_diagram_self_edges/elk/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 472 KiB |
Loading…
Reference in a new issue