extend previous segment to target if last segment is very short
This commit is contained in:
parent
25e37fd0c4
commit
54f34d72ad
4 changed files with 55 additions and 4 deletions
|
|
@ -30,6 +30,8 @@ var setupJS string
|
|||
//go:embed dagre.js
|
||||
var dagreJS string
|
||||
|
||||
const MIN_SEGMENT_LEN = 10
|
||||
|
||||
type ConfigurableOpts struct {
|
||||
NodeSep int `json:"nodesep"`
|
||||
EdgeSep int `json:"edgesep"`
|
||||
|
|
@ -247,6 +249,47 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
|||
}
|
||||
}
|
||||
|
||||
// arrowheads can appear broken if segments are very short from dagre routing a point just outside the shape
|
||||
// to fix this, we try extending the previous segment into the shape instead of having a very short segment
|
||||
if !start.Equals(points[0]) && startIndex+2 < len(points) {
|
||||
newStartingSegment := *geo.NewSegment(start, points[startIndex+1])
|
||||
if newStartingSegment.Length() < MIN_SEGMENT_LEN {
|
||||
// we don't want a very short segment right next to the source because it will mess up the arrowhead
|
||||
// instead we want to extend the next segment into the shape border if possible
|
||||
nextStart := points[startIndex+1]
|
||||
nextEnd := points[startIndex+2]
|
||||
|
||||
// Note: in other direction to extend towards source
|
||||
nextSegment := *geo.NewSegment(nextStart, nextEnd)
|
||||
v := nextSegment.ToVector()
|
||||
extendedStart := nextEnd.ToVector().Add(v.AddLength(MIN_SEGMENT_LEN)).ToPoint()
|
||||
extended := *geo.NewSegment(nextEnd, extendedStart)
|
||||
|
||||
if intersections := edge.Src.Box.Intersections(extended); len(intersections) > 0 {
|
||||
start = intersections[0]
|
||||
startIndex += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if !end.Equals(points[len(points)-1]) && endIndex-2 >= 0 {
|
||||
newEndingSegment := *geo.NewSegment(end, points[endIndex-1])
|
||||
if newEndingSegment.Length() < MIN_SEGMENT_LEN {
|
||||
// extend the prev segment into the shape border if possible
|
||||
prevStart := points[endIndex-2]
|
||||
prevEnd := points[endIndex-1]
|
||||
|
||||
prevSegment := *geo.NewSegment(prevStart, prevEnd)
|
||||
v := prevSegment.ToVector()
|
||||
extendedEnd := prevStart.ToVector().Add(v.AddLength(MIN_SEGMENT_LEN)).ToPoint()
|
||||
extended := *geo.NewSegment(prevStart, extendedEnd)
|
||||
|
||||
if intersections := edge.Dst.Box.Intersections(extended); len(intersections) > 0 {
|
||||
end = intersections[0]
|
||||
endIndex -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srcShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Src.Attributes.Shape.Value)], edge.Src.Box)
|
||||
dstShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Dst.Attributes.Shape.Value)], edge.Dst.Box)
|
||||
|
||||
|
|
|
|||
|
|
@ -187,12 +187,12 @@ func (p *Point) DistanceToLine(p1, p2 *Point) float64 {
|
|||
|
||||
// Moves the given point by Vector
|
||||
func (start *Point) AddVector(v Vector) *Point {
|
||||
return start.toVector().Add(v).ToPoint()
|
||||
return start.ToVector().Add(v).ToPoint()
|
||||
}
|
||||
|
||||
// Creates a Vector of the size between start and endpoint, pointing to endpoint
|
||||
func (start *Point) VectorTo(endpoint *Point) Vector {
|
||||
return endpoint.toVector().Minus(start.toVector())
|
||||
return endpoint.ToVector().Minus(start.ToVector())
|
||||
}
|
||||
|
||||
func (p *Point) FormattedCoordinates() string {
|
||||
|
|
@ -205,7 +205,7 @@ func (q *Point) OnSegment(p, r *Point) bool {
|
|||
}
|
||||
|
||||
// Creates a Vector pointing to point
|
||||
func (endpoint *Point) toVector() Vector {
|
||||
func (endpoint *Point) ToVector() Vector {
|
||||
return []float64{endpoint.X, endpoint.Y}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func TestAddVector(t *testing.T) {
|
|||
|
||||
func TestToVector(t *testing.T) {
|
||||
p := &Point{3.5, 6.7}
|
||||
v := p.toVector()
|
||||
v := p.ToVector()
|
||||
|
||||
if v[0] != p.X || v[1] != p.Y {
|
||||
t.Fatalf("Expected Vector (%v) coordinates to match the point (%v)", p, v)
|
||||
|
|
|
|||
|
|
@ -114,3 +114,11 @@ func (segment *Segment) GetBounds(segments []*Segment, buffer float64) (float64,
|
|||
}
|
||||
return floor, ceil
|
||||
}
|
||||
|
||||
func (segment Segment) Length() float64 {
|
||||
return EuclideanDistance(segment.Start.X, segment.Start.Y, segment.End.X, segment.End.Y)
|
||||
}
|
||||
|
||||
func (segment Segment) ToVector() Vector {
|
||||
return NewVector(segment.End.X-segment.Start.X, segment.End.Y-segment.Start.Y)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue