fix tracing edge to label with multiple intersections

This commit is contained in:
Gavin Nishizawa 2023-07-12 14:45:59 -07:00
parent 2c5c395315
commit e52f0bb8ba
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD

View file

@ -1,6 +1,7 @@
package d2graph
import (
"sort"
"strings"
"oss.terrastruct.com/d2/d2target"
@ -337,9 +338,13 @@ func (edge *Edge) TraceToShape(points []*geo.Point, startIndex, endIndex int) (n
labelBox.Width += 2 * label.PADDING
if intersections := labelBox.Intersections(startingSegment); len(intersections) > 0 {
overlapsOutsideLabel = true
p := intersections[0]
if len(intersections) > 1 {
p = findOuterIntersection(labelPosition, intersections)
}
// move starting segment to label intersection point
points[startIndex] = intersections[0]
startingSegment.End = intersections[0]
points[startIndex] = p
startingSegment.End = p
// if the segment becomes too short, just merge it with the next segment
if startIndex+1 < len(points)-1 && startingSegment.Length() < MIN_SEGMENT_LEN {
points[startIndex+1] = points[startIndex]
@ -378,9 +383,13 @@ func (edge *Edge) TraceToShape(points []*geo.Point, startIndex, endIndex int) (n
labelBox.Width += 2 * label.PADDING
if intersections := labelBox.Intersections(endingSegment); len(intersections) > 0 {
overlapsOutsideLabel = true
p := intersections[0]
if len(intersections) > 1 {
p = findOuterIntersection(labelPosition, intersections)
}
// move ending segment to label intersection point
points[endIndex] = intersections[0]
endingSegment.End = intersections[0]
points[endIndex] = p
endingSegment.End = p
// if the segment becomes too short, just merge it with the previous segment
if endIndex-1 > 0 && endingSegment.Length() < MIN_SEGMENT_LEN {
points[endIndex-1] = points[endIndex]
@ -404,3 +413,25 @@ func (edge *Edge) TraceToShape(points []*geo.Point, startIndex, endIndex int) (n
}
return startIndex, endIndex
}
func findOuterIntersection(labelPosition label.Position, intersections []*geo.Point) *geo.Point {
switch labelPosition {
case label.OutsideTopLeft, label.OutsideTopRight, label.OutsideTopCenter:
sort.Slice(intersections, func(i, j int) bool {
return intersections[i].Y < intersections[j].Y
})
case label.OutsideBottomLeft, label.OutsideBottomRight, label.OutsideBottomCenter:
sort.Slice(intersections, func(i, j int) bool {
return intersections[i].Y > intersections[j].Y
})
case label.OutsideLeftTop, label.OutsideLeftMiddle, label.OutsideLeftBottom:
sort.Slice(intersections, func(i, j int) bool {
return intersections[i].X < intersections[j].X
})
case label.OutsideRightTop, label.OutsideRightMiddle, label.OutsideRightBottom:
sort.Slice(intersections, func(i, j int) bool {
return intersections[i].X > intersections[j].X
})
}
return intersections[0]
}