fix dagre shifting connection start past 2nd point
This commit is contained in:
parent
f6580b69df
commit
4015a48664
3 changed files with 133 additions and 2 deletions
|
|
@ -141,6 +141,118 @@ func (obj *Object) ShiftDescendants(dx, dy float64) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShiftStart moves the starting point of the route by delta either horizontally or vertically
|
||||||
|
// if subsequent points are in line with the movement, they will be removed (unless it is the last point)
|
||||||
|
// start end
|
||||||
|
// . ├────┼────┼───┼────┼───┤ before
|
||||||
|
// . ├──dx──►
|
||||||
|
// . ├──┼───┼────┼───┤ after
|
||||||
|
func (edge *Edge) ShiftStart(delta float64, isHorizontal bool) {
|
||||||
|
position := func(p *geo.Point) float64 {
|
||||||
|
if isHorizontal {
|
||||||
|
return p.X
|
||||||
|
}
|
||||||
|
return p.Y
|
||||||
|
}
|
||||||
|
|
||||||
|
start := edge.Route[0]
|
||||||
|
next := edge.Route[1]
|
||||||
|
isIncreasing := position(start) < position(next)
|
||||||
|
if isHorizontal {
|
||||||
|
start.X += delta
|
||||||
|
} else {
|
||||||
|
start.Y += delta
|
||||||
|
}
|
||||||
|
|
||||||
|
if isIncreasing == (delta < 0) {
|
||||||
|
// nothing more to do when moving away from the next point
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isAligned := func(p *geo.Point) bool {
|
||||||
|
if isHorizontal {
|
||||||
|
return p.Y == start.Y
|
||||||
|
}
|
||||||
|
return p.X == start.X
|
||||||
|
}
|
||||||
|
isPastStart := func(p *geo.Point) bool {
|
||||||
|
if delta > 0 {
|
||||||
|
return position(p) < position(start)
|
||||||
|
} else {
|
||||||
|
return position(p) > position(start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
needsRemoval := false
|
||||||
|
toRemove := make([]bool, len(edge.Route))
|
||||||
|
for i := 1; i < len(edge.Route)-1; i++ {
|
||||||
|
if !isAligned(edge.Route[i]) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if isPastStart(edge.Route[i]) {
|
||||||
|
toRemove[i] = true
|
||||||
|
needsRemoval = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if needsRemoval {
|
||||||
|
edge.Route = geo.RemovePoints(edge.Route, toRemove)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShiftEnd moves the ending point of the route by delta either horizontally or vertically
|
||||||
|
// if prior points are in line with the movement, they will be removed (unless it is the first point)
|
||||||
|
func (edge *Edge) ShiftEnd(delta float64, isHorizontal bool) {
|
||||||
|
position := func(p *geo.Point) float64 {
|
||||||
|
if isHorizontal {
|
||||||
|
return p.X
|
||||||
|
}
|
||||||
|
return p.Y
|
||||||
|
}
|
||||||
|
|
||||||
|
end := edge.Route[len(edge.Route)-1]
|
||||||
|
prev := edge.Route[len(edge.Route)-2]
|
||||||
|
isIncreasing := position(prev) < position(end)
|
||||||
|
if isHorizontal {
|
||||||
|
end.X += delta
|
||||||
|
} else {
|
||||||
|
end.Y += delta
|
||||||
|
}
|
||||||
|
|
||||||
|
if isIncreasing == (delta > 0) {
|
||||||
|
// nothing more to do when moving away from the next point
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isAligned := func(p *geo.Point) bool {
|
||||||
|
if isHorizontal {
|
||||||
|
return p.Y == end.Y
|
||||||
|
}
|
||||||
|
return p.X == end.X
|
||||||
|
}
|
||||||
|
isPastEnd := func(p *geo.Point) bool {
|
||||||
|
if delta > 0 {
|
||||||
|
return position(p) < position(end)
|
||||||
|
} else {
|
||||||
|
return position(p) > position(end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
needsRemoval := false
|
||||||
|
toRemove := make([]bool, len(edge.Route))
|
||||||
|
for i := len(edge.Route) - 2; i > 0; i-- {
|
||||||
|
if !isAligned(edge.Route[i]) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if isPastEnd(edge.Route[i]) {
|
||||||
|
toRemove[i] = true
|
||||||
|
needsRemoval = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if needsRemoval {
|
||||||
|
edge.Route = geo.RemovePoints(edge.Route, toRemove)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetModifierElementAdjustments returns width/height adjustments to account for shapes with 3d or multiple
|
// GetModifierElementAdjustments returns width/height adjustments to account for shapes with 3d or multiple
|
||||||
func (obj *Object) GetModifierElementAdjustments() (dx, dy float64) {
|
func (obj *Object) GetModifierElementAdjustments() (dx, dy float64) {
|
||||||
if obj.Is3D() {
|
if obj.Is3D() {
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
if isHorizontal && e.Src.Parent != g.Root && e.Dst.Parent != g.Root {
|
if isHorizontal && e.Src.Parent != g.Root && e.Dst.Parent != g.Root {
|
||||||
moveWholeEdge = true
|
moveWholeEdge = true
|
||||||
} else {
|
} else {
|
||||||
e.Route[0].Y += stepSize
|
e.ShiftStart(stepSize, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -393,7 +393,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
if isHorizontal && e.Dst.Parent != g.Root && e.Src.Parent != g.Root {
|
if isHorizontal && e.Dst.Parent != g.Root && e.Src.Parent != g.Root {
|
||||||
moveWholeEdge = true
|
moveWholeEdge = true
|
||||||
} else {
|
} else {
|
||||||
e.Route[len(e.Route)-1].Y += stepSize
|
e.ShiftEnd(stepSize, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -305,3 +305,22 @@ func (p *Point) TruncateDecimals() {
|
||||||
p.X = TruncateDecimals(p.X)
|
p.X = TruncateDecimals(p.X)
|
||||||
p.Y = TruncateDecimals(p.Y)
|
p.Y = TruncateDecimals(p.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemovePoints returns a new Points slice without the points in toRemove
|
||||||
|
func RemovePoints(points Points, toRemove []bool) Points {
|
||||||
|
newLen := len(points)
|
||||||
|
for _, should := range toRemove {
|
||||||
|
if should {
|
||||||
|
newLen--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
without := make([]*Point, 0, newLen)
|
||||||
|
for i := 0; i < len(points); i++ {
|
||||||
|
if toRemove[i] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
without = append(without, points[i])
|
||||||
|
}
|
||||||
|
return without
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue