also trace in elk
This commit is contained in:
parent
8d2636a147
commit
07390c7ae0
3 changed files with 86 additions and 84 deletions
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"oss.terrastruct.com/d2/lib/shape"
|
"oss.terrastruct.com/d2/lib/shape"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MIN_SEGMENT_LEN = 10
|
||||||
|
|
||||||
func (obj *Object) MoveWithDescendants(dx, dy float64) {
|
func (obj *Object) MoveWithDescendants(dx, dy float64) {
|
||||||
obj.TopLeft.X += dx
|
obj.TopLeft.X += dx
|
||||||
obj.TopLeft.Y += dy
|
obj.TopLeft.Y += dy
|
||||||
|
|
@ -313,3 +315,72 @@ func (obj *Object) GetLabelTopLeft() *geo.Point {
|
||||||
)
|
)
|
||||||
return labelTL
|
return labelTL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (edge *Edge) TraceToShape(points []*geo.Point, startIndex, endIndex int) (newStart, newEnd int) {
|
||||||
|
srcShape := edge.Src.ToShape()
|
||||||
|
dstShape := edge.Dst.ToShape()
|
||||||
|
|
||||||
|
// if an edge runs into an outside label, stop the edge at the label instead
|
||||||
|
overlapsOutsideLabel := false
|
||||||
|
if edge.Src.HasLabel() {
|
||||||
|
// assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label
|
||||||
|
labelPosition := label.Position(*edge.Src.LabelPosition)
|
||||||
|
if labelPosition.IsOutside() {
|
||||||
|
labelWidth := float64(edge.Src.LabelDimensions.Width)
|
||||||
|
labelHeight := float64(edge.Src.LabelDimensions.Height)
|
||||||
|
labelTL := labelPosition.GetPointOnBox(edge.Src.Box, label.PADDING, labelWidth, labelHeight)
|
||||||
|
|
||||||
|
startingSegment := geo.Segment{Start: points[startIndex+1], End: points[startIndex]}
|
||||||
|
labelBox := geo.NewBox(labelTL, labelWidth, labelHeight)
|
||||||
|
// add left/right padding to box
|
||||||
|
labelBox.TopLeft.X -= label.PADDING
|
||||||
|
labelBox.Width += 2 * label.PADDING
|
||||||
|
if intersections := labelBox.Intersections(startingSegment); len(intersections) > 0 {
|
||||||
|
overlapsOutsideLabel = true
|
||||||
|
// move starting segment to label intersection point
|
||||||
|
points[startIndex] = intersections[0]
|
||||||
|
startingSegment.End = intersections[0]
|
||||||
|
// if the segment becomes too short, just merge it with the next segment
|
||||||
|
if startIndex < len(points) && startingSegment.Length() < MIN_SEGMENT_LEN {
|
||||||
|
points[startIndex+1] = points[startIndex]
|
||||||
|
startIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !overlapsOutsideLabel {
|
||||||
|
// trace the edge to the specific shape's border
|
||||||
|
points[startIndex] = shape.TraceToShapeBorder(srcShape, points[startIndex], points[startIndex+1])
|
||||||
|
}
|
||||||
|
overlapsOutsideLabel = false
|
||||||
|
if edge.Dst.HasLabel() {
|
||||||
|
// assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label
|
||||||
|
labelPosition := label.Position(*edge.Dst.LabelPosition)
|
||||||
|
if labelPosition.IsOutside() {
|
||||||
|
labelWidth := float64(edge.Dst.LabelDimensions.Width)
|
||||||
|
labelHeight := float64(edge.Dst.LabelDimensions.Height)
|
||||||
|
labelTL := labelPosition.GetPointOnBox(edge.Dst.Box, label.PADDING, labelWidth, labelHeight)
|
||||||
|
|
||||||
|
endingSegment := geo.Segment{Start: points[endIndex-1], End: points[endIndex]}
|
||||||
|
labelBox := geo.NewBox(labelTL, labelWidth, labelHeight)
|
||||||
|
// add left/right padding to box
|
||||||
|
labelBox.TopLeft.X -= label.PADDING
|
||||||
|
labelBox.Width += 2 * label.PADDING
|
||||||
|
if intersections := labelBox.Intersections(endingSegment); len(intersections) > 0 {
|
||||||
|
overlapsOutsideLabel = true
|
||||||
|
// move ending segment to label intersection point
|
||||||
|
points[endIndex] = intersections[0]
|
||||||
|
endingSegment.End = intersections[0]
|
||||||
|
// 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]
|
||||||
|
endIndex--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !overlapsOutsideLabel {
|
||||||
|
points[endIndex] = shape.TraceToShapeBorder(dstShape, points[endIndex], points[endIndex-1])
|
||||||
|
}
|
||||||
|
return startIndex, endIndex
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/label"
|
"oss.terrastruct.com/d2/lib/label"
|
||||||
"oss.terrastruct.com/d2/lib/log"
|
"oss.terrastruct.com/d2/lib/log"
|
||||||
"oss.terrastruct.com/d2/lib/shape"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed setup.js
|
//go:embed setup.js
|
||||||
|
|
@ -31,9 +30,8 @@ var setupJS string
|
||||||
var dagreJS string
|
var dagreJS string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MIN_SEGMENT_LEN = 10
|
MIN_RANK_SEP = 60
|
||||||
MIN_RANK_SEP = 60
|
EDGE_LABEL_GAP = 20
|
||||||
EDGE_LABEL_GAP = 20
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfigurableOpts struct {
|
type ConfigurableOpts struct {
|
||||||
|
|
@ -433,7 +431,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
// to fix this, we try extending the previous segment into the shape instead of having a very short segment
|
// 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) {
|
if !start.Equals(points[0]) && startIndex+2 < len(points) {
|
||||||
newStartingSegment := *geo.NewSegment(start, points[startIndex+1])
|
newStartingSegment := *geo.NewSegment(start, points[startIndex+1])
|
||||||
if newStartingSegment.Length() < MIN_SEGMENT_LEN {
|
if newStartingSegment.Length() < d2graph.MIN_SEGMENT_LEN {
|
||||||
// we don't want a very short segment right next to the source because it will mess up the arrowhead
|
// 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
|
// instead we want to extend the next segment into the shape border if possible
|
||||||
nextStart := points[startIndex+1]
|
nextStart := points[startIndex+1]
|
||||||
|
|
@ -442,30 +440,32 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
// Note: in other direction to extend towards source
|
// Note: in other direction to extend towards source
|
||||||
nextSegment := *geo.NewSegment(nextStart, nextEnd)
|
nextSegment := *geo.NewSegment(nextStart, nextEnd)
|
||||||
v := nextSegment.ToVector()
|
v := nextSegment.ToVector()
|
||||||
extendedStart := nextEnd.ToVector().Add(v.AddLength(MIN_SEGMENT_LEN)).ToPoint()
|
extendedStart := nextEnd.ToVector().Add(v.AddLength(d2graph.MIN_SEGMENT_LEN)).ToPoint()
|
||||||
extended := *geo.NewSegment(nextEnd, extendedStart)
|
extended := *geo.NewSegment(nextEnd, extendedStart)
|
||||||
|
|
||||||
if intersections := edge.Src.Box.Intersections(extended); len(intersections) > 0 {
|
if intersections := edge.Src.Box.Intersections(extended); len(intersections) > 0 {
|
||||||
start = intersections[0]
|
startIndex++
|
||||||
startIndex += 1
|
points[startIndex] = intersections[0]
|
||||||
|
start = points[startIndex]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !end.Equals(points[len(points)-1]) && endIndex-2 >= 0 {
|
if !end.Equals(points[len(points)-1]) && endIndex-2 >= 0 {
|
||||||
newEndingSegment := *geo.NewSegment(end, points[endIndex-1])
|
newEndingSegment := *geo.NewSegment(end, points[endIndex-1])
|
||||||
if newEndingSegment.Length() < MIN_SEGMENT_LEN {
|
if newEndingSegment.Length() < d2graph.MIN_SEGMENT_LEN {
|
||||||
// extend the prev segment into the shape border if possible
|
// extend the prev segment into the shape border if possible
|
||||||
prevStart := points[endIndex-2]
|
prevStart := points[endIndex-2]
|
||||||
prevEnd := points[endIndex-1]
|
prevEnd := points[endIndex-1]
|
||||||
|
|
||||||
prevSegment := *geo.NewSegment(prevStart, prevEnd)
|
prevSegment := *geo.NewSegment(prevStart, prevEnd)
|
||||||
v := prevSegment.ToVector()
|
v := prevSegment.ToVector()
|
||||||
extendedEnd := prevStart.ToVector().Add(v.AddLength(MIN_SEGMENT_LEN)).ToPoint()
|
extendedEnd := prevStart.ToVector().Add(v.AddLength(d2graph.MIN_SEGMENT_LEN)).ToPoint()
|
||||||
extended := *geo.NewSegment(prevStart, extendedEnd)
|
extended := *geo.NewSegment(prevStart, extendedEnd)
|
||||||
|
|
||||||
if intersections := edge.Dst.Box.Intersections(extended); len(intersections) > 0 {
|
if intersections := edge.Dst.Box.Intersections(extended); len(intersections) > 0 {
|
||||||
end = intersections[0]
|
endIndex--
|
||||||
endIndex -= 1
|
points[endIndex] = intersections[0]
|
||||||
|
end = points[endIndex]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -489,72 +489,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srcShape := edge.Src.ToShape()
|
startIndex, endIndex = edge.TraceToShape(points, startIndex, endIndex)
|
||||||
dstShape := edge.Dst.ToShape()
|
|
||||||
|
|
||||||
// if an edge runs into an outside label, stop the edge at the label instead
|
|
||||||
overlapsOutsideLabel := false
|
|
||||||
if edge.Src.HasLabel() {
|
|
||||||
// assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label
|
|
||||||
labelPosition := label.Position(*edge.Src.LabelPosition)
|
|
||||||
if labelPosition.IsOutside() {
|
|
||||||
labelWidth := float64(edge.Src.LabelDimensions.Width)
|
|
||||||
labelHeight := float64(edge.Src.LabelDimensions.Height)
|
|
||||||
labelTL := labelPosition.GetPointOnBox(edge.Src.Box, label.PADDING, labelWidth, labelHeight)
|
|
||||||
|
|
||||||
startingSegment := geo.Segment{Start: points[startIndex+1], End: points[startIndex]}
|
|
||||||
labelBox := geo.NewBox(labelTL, labelWidth, labelHeight)
|
|
||||||
// add left/right padding to box
|
|
||||||
labelBox.TopLeft.X -= label.PADDING
|
|
||||||
labelBox.Width += 2 * label.PADDING
|
|
||||||
if intersections := labelBox.Intersections(startingSegment); len(intersections) > 0 {
|
|
||||||
overlapsOutsideLabel = true
|
|
||||||
// move starting segment to label intersection point
|
|
||||||
points[startIndex] = intersections[0]
|
|
||||||
startingSegment.End = intersections[0]
|
|
||||||
// if the segment becomes too short, just merge it with the next segment
|
|
||||||
if startIndex < len(points) && startingSegment.Length() < MIN_SEGMENT_LEN {
|
|
||||||
points[startIndex+1] = points[startIndex]
|
|
||||||
startIndex++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !overlapsOutsideLabel {
|
|
||||||
// trace the edge to the specific shape's border
|
|
||||||
points[startIndex] = shape.TraceToShapeBorder(srcShape, start, points[startIndex+1])
|
|
||||||
}
|
|
||||||
|
|
||||||
overlapsOutsideLabel = false
|
|
||||||
if edge.Dst.HasLabel() {
|
|
||||||
// assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label
|
|
||||||
labelPosition := label.Position(*edge.Dst.LabelPosition)
|
|
||||||
if labelPosition.IsOutside() {
|
|
||||||
labelWidth := float64(edge.Dst.LabelDimensions.Width)
|
|
||||||
labelHeight := float64(edge.Dst.LabelDimensions.Height)
|
|
||||||
labelTL := labelPosition.GetPointOnBox(edge.Dst.Box, label.PADDING, labelWidth, labelHeight)
|
|
||||||
|
|
||||||
endingSegment := geo.Segment{Start: points[endIndex-1], End: points[endIndex]}
|
|
||||||
labelBox := geo.NewBox(labelTL, labelWidth, labelHeight)
|
|
||||||
// add left/right padding to box
|
|
||||||
labelBox.TopLeft.X -= label.PADDING
|
|
||||||
labelBox.Width += 2 * label.PADDING
|
|
||||||
if intersections := labelBox.Intersections(endingSegment); len(intersections) > 0 {
|
|
||||||
overlapsOutsideLabel = true
|
|
||||||
// move ending segment to label intersection point
|
|
||||||
points[endIndex] = intersections[0]
|
|
||||||
endingSegment.End = intersections[0]
|
|
||||||
// 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]
|
|
||||||
endIndex--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !overlapsOutsideLabel {
|
|
||||||
points[endIndex] = shape.TraceToShapeBorder(dstShape, end, points[endIndex-1])
|
|
||||||
}
|
|
||||||
points = points[startIndex : endIndex+1]
|
points = points[startIndex : endIndex+1]
|
||||||
|
|
||||||
// build a curved path from the dagre route
|
// build a curved path from the dagre route
|
||||||
|
|
|
||||||
|
|
@ -501,12 +501,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srcShape := edge.Src.ToShape()
|
startIndex, endIndex = edge.TraceToShape(points, startIndex, endIndex)
|
||||||
dstShape := edge.Dst.ToShape()
|
points = points[startIndex : endIndex+1]
|
||||||
|
|
||||||
// trace the edge to the specific shape's border
|
|
||||||
points[startIndex] = shape.TraceToShapeBorder(srcShape, points[startIndex], points[startIndex+1])
|
|
||||||
points[endIndex] = shape.TraceToShapeBorder(dstShape, points[endIndex], points[endIndex-1])
|
|
||||||
|
|
||||||
if edge.Label.Value != "" {
|
if edge.Label.Value != "" {
|
||||||
edge.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
|
edge.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue