implement s-shape
This commit is contained in:
parent
e4b82c1708
commit
73c35bb14b
8 changed files with 2457 additions and 2 deletions
|
|
@ -96,6 +96,7 @@ var DefaultOpts = ConfigurableOpts{
|
|||
}
|
||||
|
||||
var port_spacing = 40.
|
||||
var edge_node_spacing = 40
|
||||
|
||||
type elkOpts struct {
|
||||
EdgeNode int `json:"elk.spacing.edgeNode,omitempty"`
|
||||
|
|
@ -143,7 +144,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
|||
LayoutOptions: &elkOpts{
|
||||
Thoroughness: 8,
|
||||
EdgeEdgeBetweenLayersSpacing: 50,
|
||||
EdgeNode: 40,
|
||||
EdgeNode: edge_node_spacing,
|
||||
HierarchyHandling: "INCLUDE_CHILDREN",
|
||||
FixedAlignment: "BALANCED",
|
||||
ConsiderModelOrder: "NODES_AND_EDGES",
|
||||
|
|
@ -224,7 +225,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
|||
EdgeEdgeBetweenLayersSpacing: 50,
|
||||
HierarchyHandling: "INCLUDE_CHILDREN",
|
||||
FixedAlignment: "BALANCED",
|
||||
EdgeNode: 40,
|
||||
EdgeNode: edge_node_spacing,
|
||||
ConsiderModelOrder: "NODES_AND_EDGES",
|
||||
// Why is it (height, width)? I have no clue, but it works.
|
||||
NodeSizeMinimum: fmt.Sprintf("(%d, %d)", int(math.Ceil(height)), int(math.Ceil(width))),
|
||||
|
|
@ -442,5 +443,131 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
|||
edge.Route = points
|
||||
}
|
||||
|
||||
deleteBends(g)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteBends is a shim for ELK to delete unnecessary bends
|
||||
// see https://github.com/terrastruct/d2/issues/1030
|
||||
func deleteBends(g *d2graph.Graph) {
|
||||
// Get rid of S-shapes at the source and the target
|
||||
for _, isSource := range []bool{true, false} {
|
||||
for ei, e := range g.Edges {
|
||||
if len(e.Route) < 4 {
|
||||
continue
|
||||
}
|
||||
var endpoint *d2graph.Object
|
||||
var start *geo.Point
|
||||
var corner *geo.Point
|
||||
var end *geo.Point
|
||||
|
||||
if isSource {
|
||||
start = e.Route[0]
|
||||
corner = e.Route[1]
|
||||
end = e.Route[2]
|
||||
endpoint = e.Src
|
||||
} else {
|
||||
start = e.Route[len(e.Route)-1]
|
||||
corner = e.Route[len(e.Route)-2]
|
||||
end = e.Route[len(e.Route)-3]
|
||||
endpoint = e.Dst
|
||||
}
|
||||
|
||||
isHorizontal := start.Y == corner.Y
|
||||
|
||||
// Make sure it's still attached
|
||||
if isHorizontal {
|
||||
if end.Y <= endpoint.TopLeft.Y+10 {
|
||||
continue
|
||||
}
|
||||
if end.Y >= endpoint.TopLeft.Y+endpoint.Height-10 {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if end.X <= endpoint.TopLeft.X+10 {
|
||||
continue
|
||||
}
|
||||
if end.X >= endpoint.TopLeft.X+endpoint.Width-10 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var newStart *geo.Point
|
||||
if isHorizontal {
|
||||
newStart = geo.NewPoint(start.X, end.Y)
|
||||
} else {
|
||||
newStart = geo.NewPoint(end.X, start.Y)
|
||||
}
|
||||
|
||||
// Check that the new segment doesn't collide with anything new
|
||||
|
||||
oldSegment := geo.NewSegment(start, corner)
|
||||
newSegment := geo.NewSegment(newStart, end)
|
||||
|
||||
oldIntersects := countObjectIntersects(g, *oldSegment)
|
||||
newIntersects := countObjectIntersects(g, *newSegment)
|
||||
|
||||
if newIntersects > oldIntersects {
|
||||
continue
|
||||
}
|
||||
|
||||
oldIntersects = countEdgeIntersects(g, g.Edges[ei], *oldSegment)
|
||||
newIntersects = countEdgeIntersects(g, g.Edges[ei], *newSegment)
|
||||
|
||||
if newIntersects > oldIntersects {
|
||||
continue
|
||||
}
|
||||
|
||||
// commit
|
||||
if isSource {
|
||||
g.Edges[ei].Route = append(
|
||||
[]*geo.Point{newStart},
|
||||
e.Route[3:]...,
|
||||
)
|
||||
} else {
|
||||
g.Edges[ei].Route = append(
|
||||
e.Route[:len(e.Route)-3],
|
||||
newStart,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func countObjectIntersects(g *d2graph.Graph, s geo.Segment) int {
|
||||
count := 0
|
||||
for _, o := range g.Objects {
|
||||
if o.Intersects(s, float64(edge_node_spacing)) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// countEdgeIntersects counts both crossings AND getting too close to a parallel segment
|
||||
func countEdgeIntersects(g *d2graph.Graph, sEdge *d2graph.Edge, s geo.Segment) int {
|
||||
isHorizontal := s.Start.Y == s.End.Y
|
||||
count := 0
|
||||
for _, e := range g.Edges {
|
||||
if e == sEdge {
|
||||
continue
|
||||
}
|
||||
|
||||
for i := 0; i < len(e.Route)-1; i++ {
|
||||
otherS := geo.NewSegment(e.Route[i], e.Route[i+1])
|
||||
otherIsHorizontal := otherS.Start.Y == otherS.End.Y
|
||||
if isHorizontal == otherIsHorizontal {
|
||||
if s.Overlaps(*otherS, isHorizontal, float64(edge_node_spacing)) {
|
||||
count++
|
||||
}
|
||||
} else {
|
||||
if s.Intersects(*otherS) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,59 @@ func testStable(t *testing.T) {
|
|||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "elk_shim",
|
||||
script: `network: {
|
||||
cell tower: {
|
||||
satellites: {
|
||||
shape: stored_data
|
||||
style.multiple: true
|
||||
width: 140
|
||||
}
|
||||
|
||||
transmitter: {
|
||||
width: 140
|
||||
}
|
||||
|
||||
satellites -> transmitter: send {
|
||||
}
|
||||
satellites -> transmitter: send {
|
||||
}
|
||||
satellites -> transmitter: send {
|
||||
}
|
||||
}
|
||||
|
||||
online portal: {
|
||||
ui: { shape: hexagon }
|
||||
}
|
||||
|
||||
data processor: {
|
||||
storage: {
|
||||
shape: cylinder
|
||||
style.multiple: true
|
||||
}
|
||||
}
|
||||
|
||||
cell tower.transmitter -> data processor.storage: phone logs
|
||||
}
|
||||
|
||||
user: {
|
||||
shape: person
|
||||
width: 130
|
||||
}
|
||||
|
||||
user -> network.cell tower: make call
|
||||
user -> network.online portal.ui: access {
|
||||
style.stroke-dash: 3
|
||||
}
|
||||
|
||||
api server -> network.online portal.ui: display
|
||||
api server -> logs: persist
|
||||
logs: { shape: page; style.multiple: true }
|
||||
|
||||
network.data processor -> api server
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "mono-font",
|
||||
script: `satellites: SATELLITES {
|
||||
|
|
|
|||
1109
e2etests/testdata/stable/elk_shim/dagre/board.exp.json
generated
vendored
Normal file
1109
e2etests/testdata/stable/elk_shim/dagre/board.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
116
e2etests/testdata/stable/elk_shim/dagre/sketch.exp.svg
vendored
Normal file
116
e2etests/testdata/stable/elk_shim/dagre/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 806 KiB |
908
e2etests/testdata/stable/elk_shim/elk/board.exp.json
generated
vendored
Normal file
908
e2etests/testdata/stable/elk_shim/elk/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,908 @@
|
|||
{
|
||||
"name": "",
|
||||
"isFolderOnly": false,
|
||||
"fontFamily": "SourceSansPro",
|
||||
"shapes": [
|
||||
{
|
||||
"id": "network",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 12,
|
||||
"y": 311
|
||||
},
|
||||
"width": 540,
|
||||
"height": 892,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B4",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "network",
|
||||
"fontSize": 28,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 96,
|
||||
"labelHeight": 36,
|
||||
"labelPosition": "INSIDE_TOP_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "network.cell tower",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 62,
|
||||
"y": 361
|
||||
},
|
||||
"width": 240,
|
||||
"height": 403,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "cell tower",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 99,
|
||||
"labelHeight": 31,
|
||||
"labelPosition": "INSIDE_TOP_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "network.cell tower.satellites",
|
||||
"type": "stored_data",
|
||||
"pos": {
|
||||
"x": 112,
|
||||
"y": 411
|
||||
},
|
||||
"width": 140,
|
||||
"height": 61,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "AA5",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": true,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "satellites",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 65,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "network.cell tower.transmitter",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 112,
|
||||
"y": 653
|
||||
},
|
||||
"width": 140,
|
||||
"height": 61,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B6",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "transmitter",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 83,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "network.online portal",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 322,
|
||||
"y": 366
|
||||
},
|
||||
"width": 180,
|
||||
"height": 169,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "online portal",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 128,
|
||||
"labelHeight": 31,
|
||||
"labelPosition": "INSIDE_TOP_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "network.online portal.ui",
|
||||
"type": "hexagon",
|
||||
"pos": {
|
||||
"x": 372,
|
||||
"y": 416
|
||||
},
|
||||
"width": 80,
|
||||
"height": 69,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "N5",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "ui",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 14,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "network.data processor",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 82,
|
||||
"y": 935
|
||||
},
|
||||
"width": 199,
|
||||
"height": 218,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "data processor",
|
||||
"fontSize": 24,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 150,
|
||||
"labelHeight": 31,
|
||||
"labelPosition": "INSIDE_TOP_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "network.data processor.storage",
|
||||
"type": "cylinder",
|
||||
"pos": {
|
||||
"x": 132,
|
||||
"y": 985
|
||||
},
|
||||
"width": 99,
|
||||
"height": 118,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "AA5",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": true,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "storage",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 54,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "user",
|
||||
"type": "person",
|
||||
"pos": {
|
||||
"x": 286,
|
||||
"y": 12
|
||||
},
|
||||
"width": 130,
|
||||
"height": 87,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B3",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "user",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 32,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "OUTSIDE_BOTTOM_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "api server",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 534,
|
||||
"y": 59
|
||||
},
|
||||
"width": 116,
|
||||
"height": 66,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B6",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "api server",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 71,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "logs",
|
||||
"type": "page",
|
||||
"pos": {
|
||||
"x": 632,
|
||||
"y": 311
|
||||
},
|
||||
"width": 73,
|
||||
"height": 87,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "AB4",
|
||||
"stroke": "B1",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": true,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "logs",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 28,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "network.cell tower.(satellites -> transmitter)[0]",
|
||||
"src": "network.cell tower.satellites",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.cell tower.transmitter",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "send",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 33,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 138,
|
||||
"y": 472
|
||||
},
|
||||
{
|
||||
"x": 138,
|
||||
"y": 653
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "network.cell tower.(satellites -> transmitter)[1]",
|
||||
"src": "network.cell tower.satellites",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.cell tower.transmitter",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "send",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 33,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 182,
|
||||
"y": 472
|
||||
},
|
||||
{
|
||||
"x": 182,
|
||||
"y": 653
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "network.cell tower.(satellites -> transmitter)[2]",
|
||||
"src": "network.cell tower.satellites",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.cell tower.transmitter",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "send",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 33,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 226,
|
||||
"y": 472
|
||||
},
|
||||
{
|
||||
"x": 226,
|
||||
"y": 653
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "network.(cell tower.transmitter -> data processor.storage)[0]",
|
||||
"src": "network.cell tower.transmitter",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.data processor.storage",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "phone logs",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 74,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 182,
|
||||
"y": 714
|
||||
},
|
||||
{
|
||||
"x": 182,
|
||||
"y": 985
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(user -> network.cell tower)[0]",
|
||||
"src": "user",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.cell tower",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "make call",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 64,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 329,
|
||||
"y": 99
|
||||
},
|
||||
{
|
||||
"x": 329.33333333333337,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 222.83333333333334,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 222.83333333333334,
|
||||
"y": 361
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(user -> network.online portal.ui)[0]",
|
||||
"src": "user",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.online portal.ui",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 3,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B2",
|
||||
"borderRadius": 10,
|
||||
"label": "access",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 44,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 373,
|
||||
"y": 99
|
||||
},
|
||||
{
|
||||
"x": 372.6666666666667,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 398.6666666666667,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 399,
|
||||
"y": 416
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(api server -> network.online portal.ui)[0]",
|
||||
"src": "api server",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "network.online portal.ui",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "display",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 48,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 563,
|
||||
"y": 125
|
||||
},
|
||||
{
|
||||
"x": 563,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 462.5,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 462.5,
|
||||
"y": 266
|
||||
},
|
||||
{
|
||||
"x": 425.33333333333337,
|
||||
"y": 266
|
||||
},
|
||||
{
|
||||
"x": 425,
|
||||
"y": 416
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(api server -> logs)[0]",
|
||||
"src": "api server",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "logs",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "persist",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 46,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 621,
|
||||
"y": 125
|
||||
},
|
||||
{
|
||||
"x": 621,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 668.5,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 669,
|
||||
"y": 311
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(network.data processor -> api server)[0]",
|
||||
"src": "network.data processor",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "api server",
|
||||
"dstArrow": "triangle",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 0,
|
||||
"labelHeight": 0,
|
||||
"labelPosition": "",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 132.5,
|
||||
"y": 1153
|
||||
},
|
||||
{
|
||||
"x": 132.5,
|
||||
"y": 1248
|
||||
},
|
||||
{
|
||||
"x": 592,
|
||||
"y": 1248
|
||||
},
|
||||
{
|
||||
"x": 592,
|
||||
"y": 125
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
}
|
||||
],
|
||||
"root": {
|
||||
"id": "",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"opacity": 0,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 0,
|
||||
"borderRadius": 0,
|
||||
"fill": "N7",
|
||||
"stroke": "",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
"multiple": false,
|
||||
"double-border": false,
|
||||
"tooltip": "",
|
||||
"link": "",
|
||||
"icon": null,
|
||||
"iconPosition": "",
|
||||
"blend": false,
|
||||
"fields": null,
|
||||
"methods": null,
|
||||
"columns": null,
|
||||
"label": "",
|
||||
"fontSize": 0,
|
||||
"fontFamily": "",
|
||||
"language": "",
|
||||
"color": "",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 0,
|
||||
"labelHeight": 0,
|
||||
"zIndex": 0,
|
||||
"level": 0
|
||||
}
|
||||
}
|
||||
116
e2etests/testdata/stable/elk_shim/elk/sketch.exp.svg
vendored
Normal file
116
e2etests/testdata/stable/elk_shim/elk/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 806 KiB |
|
|
@ -27,6 +27,28 @@ func (b *Box) Center() *Point {
|
|||
return NewPoint(b.TopLeft.X+b.Width/2, b.TopLeft.Y+b.Height/2)
|
||||
}
|
||||
|
||||
// Intersects returns true if the segment comes within buffer of the box
|
||||
func (b *Box) Intersects(s Segment, buffer float64) bool {
|
||||
tl := NewPoint(b.TopLeft.X-buffer, b.TopLeft.Y-buffer)
|
||||
tr := NewPoint(tl.X+b.Width+buffer*2, tl.Y)
|
||||
br := NewPoint(tr.X, tr.Y+b.Height+buffer*2)
|
||||
bl := NewPoint(tl.X, br.Y)
|
||||
|
||||
if p := IntersectionPoint(s.Start, s.End, tl, tr); p != nil {
|
||||
return true
|
||||
}
|
||||
if p := IntersectionPoint(s.Start, s.End, tr, br); p != nil {
|
||||
return true
|
||||
}
|
||||
if p := IntersectionPoint(s.Start, s.End, br, bl); p != nil {
|
||||
return true
|
||||
}
|
||||
if p := IntersectionPoint(s.Start, s.End, bl, tl); p != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Box) Intersections(s Segment) []*Point {
|
||||
pts := []*Point{}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ func (s Segment) Overlaps(otherS Segment, isHorizontal bool, buffer float64) boo
|
|||
}
|
||||
}
|
||||
|
||||
func (segment Segment) Intersects(otherSegment Segment) bool {
|
||||
return IntersectionPoint(segment.Start, segment.End, otherSegment.Start, otherSegment.End) != nil
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func (s Segment) ToString() string {
|
||||
return fmt.Sprintf("%v -> %v", s.Start.ToString(), s.End.ToString())
|
||||
|
|
|
|||
Loading…
Reference in a new issue