(
inNodes: N[],
inEdges: E[],
opts: LayoutCfg
)
| 72 | // } |
| 73 | |
| 74 | export function forceLayout<N extends InputNode, E extends InputEdge>( |
| 75 | inNodes: N[], |
| 76 | inEdges: E[], |
| 77 | opts: LayoutCfg |
| 78 | ) { |
| 79 | const nodes = inNodes as LayoutNode[]; |
| 80 | const edges = inEdges as LayoutEdge[]; |
| 81 | const rect = opts.rect; |
| 82 | const width = rect.width; |
| 83 | const height = rect.height; |
| 84 | const center = [rect.x + width / 2, rect.y + height / 2]; |
| 85 | // let scale = opts.scale || 1; |
| 86 | const gravity = opts.gravity == null ? 0.1 : opts.gravity; |
| 87 | |
| 88 | // for (let i = 0; i < edges.length; i++) { |
| 89 | // let e = edges[i]; |
| 90 | // let n1 = e.n1; |
| 91 | // let n2 = e.n2; |
| 92 | // n1.edges = n1.edges || []; |
| 93 | // n2.edges = n2.edges || []; |
| 94 | // n1.edges.push(e); |
| 95 | // n2.edges.push(e); |
| 96 | // } |
| 97 | // Init position |
| 98 | for (let i = 0; i < nodes.length; i++) { |
| 99 | const n = nodes[i] as LayoutNode; |
| 100 | if (!n.p) { |
| 101 | n.p = vec2.create( |
| 102 | width * (Math.random() - 0.5) + center[0], |
| 103 | height * (Math.random() - 0.5) + center[1] |
| 104 | ); |
| 105 | } |
| 106 | n.pp = vec2.clone(n.p); |
| 107 | n.edges = null; |
| 108 | } |
| 109 | |
| 110 | // Formula in 'Graph Drawing by Force-directed Placement' |
| 111 | // let k = scale * Math.sqrt(width * height / nodes.length); |
| 112 | // let k2 = k * k; |
| 113 | |
| 114 | const initialFriction = opts.friction == null ? 0.6 : opts.friction; |
| 115 | let friction = initialFriction; |
| 116 | |
| 117 | let beforeStepCallback: (nodes: N[], edges: E[]) => void; |
| 118 | let afterStepCallback: (nodes: N[], edges: E[], finished: boolean) => void; |
| 119 | |
| 120 | return { |
| 121 | warmUp: function () { |
| 122 | friction = initialFriction * 0.8; |
| 123 | }, |
| 124 | |
| 125 | setFixed: function (idx: number) { |
| 126 | nodes[idx].fixed = true; |
| 127 | }, |
| 128 | |
| 129 | setUnfixed: function (idx: number) { |
| 130 | nodes[idx].fixed = false; |
| 131 | }, |
no test coverage detected
searching dependent graphs…