Handle self edges
This commit is contained in:
parent
c4dc93faee
commit
9776d856fa
2 changed files with 58 additions and 7 deletions
|
|
@ -383,3 +383,39 @@ func TestNestedSequenceDiagrams(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ func (sd *sequenceDiagram) placeActors() {
|
|||
// │
|
||||
// │
|
||||
func (sd *sequenceDiagram) addLifelineEdges() {
|
||||
endY := sd.getMessageY(len(sd.messages))
|
||||
lastRoute := sd.messages[len(sd.messages)-1].Route
|
||||
endY := lastRoute[len(lastRoute)-1].Y + MIN_MESSAGE_DISTANCE
|
||||
for _, actor := range sd.actors {
|
||||
actorBottom := actor.Center()
|
||||
actorBottom.Y = actor.TopLeft.Y + actor.Height
|
||||
|
|
@ -241,6 +242,7 @@ func (sd *sequenceDiagram) routeMessages() {
|
|||
for rank, message := range sd.messages {
|
||||
message.ZIndex = 2
|
||||
isLeftToRight := message.Src.TopLeft.X < message.Dst.TopLeft.X
|
||||
isSelfMessage := message.Src == message.Dst
|
||||
|
||||
// finds the proper anchor point based on the message direction
|
||||
var startX, endX float64
|
||||
|
|
@ -252,7 +254,9 @@ func (sd *sequenceDiagram) routeMessages() {
|
|||
startX = message.Src.TopLeft.X
|
||||
}
|
||||
|
||||
if sd.isActor(message.Dst) {
|
||||
if isSelfMessage {
|
||||
endX = startX
|
||||
} else if sd.isActor(message.Dst) {
|
||||
endX = message.Dst.Center().X
|
||||
} else if isLeftToRight {
|
||||
endX = message.Dst.TopLeft.X
|
||||
|
|
@ -260,14 +264,25 @@ func (sd *sequenceDiagram) routeMessages() {
|
|||
endX = message.Dst.TopLeft.X + message.Dst.Width
|
||||
}
|
||||
|
||||
messageY := sd.getMessageY(rank)
|
||||
startY := sd.getMessageY(rank)
|
||||
if isSelfMessage {
|
||||
message.Route = []*geo.Point{
|
||||
geo.NewPoint(startX, messageY),
|
||||
geo.NewPoint(endX, messageY),
|
||||
geo.NewPoint(startX, startY),
|
||||
geo.NewPoint(startX+MIN_MESSAGE_DISTANCE, startY),
|
||||
geo.NewPoint(startX+MIN_MESSAGE_DISTANCE, startY+MIN_MESSAGE_DISTANCE),
|
||||
geo.NewPoint(startX, startY+MIN_MESSAGE_DISTANCE),
|
||||
}
|
||||
} else {
|
||||
message.Route = []*geo.Point{
|
||||
geo.NewPoint(startX, startY),
|
||||
geo.NewPoint(endX, startY),
|
||||
}
|
||||
}
|
||||
|
||||
if message.Attributes.Label.Value != "" {
|
||||
if isLeftToRight {
|
||||
if isSelfMessage {
|
||||
message.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
|
||||
} else if isLeftToRight {
|
||||
message.LabelPosition = go2.Pointer(string(label.OutsideTopCenter))
|
||||
} else {
|
||||
// the label will be placed above the message because the orientation is based on the edge normal vector
|
||||
|
|
|
|||
Loading…
Reference in a new issue