Handle self edges

This commit is contained in:
Júlio César Batista 2022-12-02 21:49:51 -08:00
parent c4dc93faee
commit 9776d856fa
No known key found for this signature in database
GPG key ID: 10C4B861BF314878
2 changed files with 58 additions and 7 deletions

View file

@ -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)
}
}

View file

@ -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)
message.Route = []*geo.Point{
geo.NewPoint(startX, messageY),
geo.NewPoint(endX, messageY),
startY := sd.getMessageY(rank)
if isSelfMessage {
message.Route = []*geo.Point{
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