@graphty/layout 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -1
- package/dist/layout.js +1762 -0
- package/dist/layout.js.map +1 -0
- package/package.json +7 -4
- package/src/layouts/force-directed/forceatlas2.ts +23 -4
- package/src/utils/rescale.ts +90 -15
- package/dist/src/algorithms/index.d.ts +0 -5
- package/dist/src/algorithms/index.js +0 -6
- package/dist/src/algorithms/index.js.map +0 -1
- package/dist/src/algorithms/optimization/index.d.ts +0 -7
- package/dist/src/algorithms/optimization/index.js +0 -7
- package/dist/src/algorithms/optimization/index.js.map +0 -1
- package/dist/src/algorithms/optimization/kamada-kawai-solver.d.ts +0 -32
- package/dist/src/algorithms/optimization/kamada-kawai-solver.js +0 -176
- package/dist/src/algorithms/optimization/kamada-kawai-solver.js.map +0 -1
- package/dist/src/algorithms/optimization/lbfgs.d.ts +0 -13
- package/dist/src/algorithms/optimization/lbfgs.js +0 -56
- package/dist/src/algorithms/optimization/lbfgs.js.map +0 -1
- package/dist/src/algorithms/optimization/line-search.d.ts +0 -15
- package/dist/src/algorithms/optimization/line-search.js +0 -37
- package/dist/src/algorithms/optimization/line-search.js.map +0 -1
- package/dist/src/algorithms/optimization/types.d.ts +0 -5
- package/dist/src/algorithms/optimization/types.js +0 -5
- package/dist/src/algorithms/optimization/types.js.map +0 -1
- package/dist/src/algorithms/planarity/check.d.ts +0 -17
- package/dist/src/algorithms/planarity/check.js +0 -30
- package/dist/src/algorithms/planarity/check.js.map +0 -1
- package/dist/src/algorithms/planarity/embedding.d.ts +0 -29
- package/dist/src/algorithms/planarity/embedding.js +0 -179
- package/dist/src/algorithms/planarity/embedding.js.map +0 -1
- package/dist/src/algorithms/planarity/index.d.ts +0 -7
- package/dist/src/algorithms/planarity/index.js +0 -8
- package/dist/src/algorithms/planarity/index.js.map +0 -1
- package/dist/src/algorithms/planarity/lr-test.d.ts +0 -15
- package/dist/src/algorithms/planarity/lr-test.js +0 -54
- package/dist/src/algorithms/planarity/lr-test.js.map +0 -1
- package/dist/src/algorithms/planarity/special-graphs.d.ts +0 -28
- package/dist/src/algorithms/planarity/special-graphs.js +0 -108
- package/dist/src/algorithms/planarity/special-graphs.js.map +0 -1
- package/dist/src/generators/basic.d.ts +0 -28
- package/dist/src/generators/basic.js +0 -79
- package/dist/src/generators/basic.js.map +0 -1
- package/dist/src/generators/bipartite.d.ts +0 -16
- package/dist/src/generators/bipartite.js +0 -40
- package/dist/src/generators/bipartite.js.map +0 -1
- package/dist/src/generators/grid.d.ts +0 -11
- package/dist/src/generators/grid.js +0 -37
- package/dist/src/generators/grid.js.map +0 -1
- package/dist/src/generators/index.d.ts +0 -8
- package/dist/src/generators/index.js +0 -9
- package/dist/src/generators/index.js.map +0 -1
- package/dist/src/generators/random.d.ts +0 -12
- package/dist/src/generators/random.js +0 -34
- package/dist/src/generators/random.js.map +0 -1
- package/dist/src/generators/scale-free.d.ts +0 -12
- package/dist/src/generators/scale-free.js +0 -62
- package/dist/src/generators/scale-free.js.map +0 -1
- package/dist/src/index.d.ts +0 -10
- package/dist/src/index.js +0 -15
- package/dist/src/index.js.map +0 -1
- package/dist/src/layouts/basic/index.d.ts +0 -4
- package/dist/src/layouts/basic/index.js +0 -5
- package/dist/src/layouts/basic/index.js.map +0 -1
- package/dist/src/layouts/basic/random.d.ts +0 -14
- package/dist/src/layouts/basic/random.js +0 -27
- package/dist/src/layouts/basic/random.js.map +0 -1
- package/dist/src/layouts/force-directed/arf.d.ts +0 -13
- package/dist/src/layouts/force-directed/arf.js +0 -103
- package/dist/src/layouts/force-directed/arf.js.map +0 -1
- package/dist/src/layouts/force-directed/forceatlas2.d.ts +0 -22
- package/dist/src/layouts/force-directed/forceatlas2.js +0 -322
- package/dist/src/layouts/force-directed/forceatlas2.js.map +0 -1
- package/dist/src/layouts/force-directed/fruchterman-reingold.d.ts +0 -19
- package/dist/src/layouts/force-directed/fruchterman-reingold.js +0 -131
- package/dist/src/layouts/force-directed/fruchterman-reingold.js.map +0 -1
- package/dist/src/layouts/force-directed/index.d.ts +0 -8
- package/dist/src/layouts/force-directed/index.js +0 -9
- package/dist/src/layouts/force-directed/index.js.map +0 -1
- package/dist/src/layouts/force-directed/kamada-kawai.d.ts +0 -15
- package/dist/src/layouts/force-directed/kamada-kawai.js +0 -87
- package/dist/src/layouts/force-directed/kamada-kawai.js.map +0 -1
- package/dist/src/layouts/force-directed/spring.d.ts +0 -19
- package/dist/src/layouts/force-directed/spring.js +0 -23
- package/dist/src/layouts/force-directed/spring.js.map +0 -1
- package/dist/src/layouts/geometric/circular.d.ts +0 -14
- package/dist/src/layouts/geometric/circular.js +0 -67
- package/dist/src/layouts/geometric/circular.js.map +0 -1
- package/dist/src/layouts/geometric/index.d.ts +0 -6
- package/dist/src/layouts/geometric/index.js +0 -7
- package/dist/src/layouts/geometric/index.js.map +0 -1
- package/dist/src/layouts/geometric/shell.d.ts +0 -15
- package/dist/src/layouts/geometric/shell.js +0 -67
- package/dist/src/layouts/geometric/shell.js.map +0 -1
- package/dist/src/layouts/geometric/spiral.d.ts +0 -16
- package/dist/src/layouts/geometric/spiral.js +0 -73
- package/dist/src/layouts/geometric/spiral.js.map +0 -1
- package/dist/src/layouts/hierarchical/bfs.d.ts +0 -12
- package/dist/src/layouts/hierarchical/bfs.js +0 -62
- package/dist/src/layouts/hierarchical/bfs.js.map +0 -1
- package/dist/src/layouts/hierarchical/bipartite.d.ts +0 -16
- package/dist/src/layouts/hierarchical/bipartite.js +0 -72
- package/dist/src/layouts/hierarchical/bipartite.js.map +0 -1
- package/dist/src/layouts/hierarchical/index.d.ts +0 -6
- package/dist/src/layouts/hierarchical/index.js +0 -7
- package/dist/src/layouts/hierarchical/index.js.map +0 -1
- package/dist/src/layouts/hierarchical/multipartite.d.ts +0 -12
- package/dist/src/layouts/hierarchical/multipartite.js +0 -73
- package/dist/src/layouts/hierarchical/multipartite.js.map +0 -1
- package/dist/src/layouts/index.d.ts +0 -8
- package/dist/src/layouts/index.js +0 -9
- package/dist/src/layouts/index.js.map +0 -1
- package/dist/src/layouts/specialized/index.d.ts +0 -5
- package/dist/src/layouts/specialized/index.js +0 -6
- package/dist/src/layouts/specialized/index.js.map +0 -1
- package/dist/src/layouts/specialized/planar.d.ts +0 -14
- package/dist/src/layouts/specialized/planar.js +0 -47
- package/dist/src/layouts/specialized/planar.js.map +0 -1
- package/dist/src/layouts/specialized/spectral.d.ts +0 -14
- package/dist/src/layouts/specialized/spectral.js +0 -106
- package/dist/src/layouts/specialized/spectral.js.map +0 -1
- package/dist/src/types/embedding.d.ts +0 -9
- package/dist/src/types/embedding.js +0 -5
- package/dist/src/types/embedding.js.map +0 -1
- package/dist/src/types/graph.d.ts +0 -10
- package/dist/src/types/graph.js +0 -5
- package/dist/src/types/graph.js.map +0 -1
- package/dist/src/types/index.d.ts +0 -6
- package/dist/src/types/index.js +0 -7
- package/dist/src/types/index.js.map +0 -1
- package/dist/src/types/layout.d.ts +0 -6
- package/dist/src/types/layout.js +0 -5
- package/dist/src/types/layout.js.map +0 -1
- package/dist/src/utils/graph.d.ts +0 -34
- package/dist/src/utils/graph.js +0 -69
- package/dist/src/utils/graph.js.map +0 -1
- package/dist/src/utils/index.d.ts +0 -8
- package/dist/src/utils/index.js +0 -9
- package/dist/src/utils/index.js.map +0 -1
- package/dist/src/utils/numpy.d.ts +0 -17
- package/dist/src/utils/numpy.js +0 -101
- package/dist/src/utils/numpy.js.map +0 -1
- package/dist/src/utils/params.d.ts +0 -17
- package/dist/src/utils/params.js +0 -22
- package/dist/src/utils/params.js.map +0 -1
- package/dist/src/utils/random.d.ts +0 -14
- package/dist/src/utils/random.js +0 -42
- package/dist/src/utils/random.js.map +0 -1
- package/dist/src/utils/rescale.d.ts +0 -21
- package/dist/src/utils/rescale.js +0 -119
- package/dist/src/utils/rescale.js.map +0 -1
- package/dist/vitest.config.d.ts +0 -2
- package/dist/vitest.config.js +0 -30
- package/dist/vitest.config.js.map +0 -1
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fruchterman-Reingold force-directed layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { _processParams } from '../../utils/params';
|
|
5
|
-
import { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';
|
|
6
|
-
import { RandomNumberGenerator } from '../../utils/random';
|
|
7
|
-
import { rescaleLayout } from '../../utils/rescale';
|
|
8
|
-
/**
|
|
9
|
-
* Position nodes using Fruchterman-Reingold force-directed algorithm.
|
|
10
|
-
*
|
|
11
|
-
* @param {Object} G - Graph or list of nodes
|
|
12
|
-
* @param {number} k - Optimal distance between nodes
|
|
13
|
-
* @param {Object} pos - Initial positions for nodes
|
|
14
|
-
* @param {Array} fixed - Nodes to keep fixed at initial position
|
|
15
|
-
* @param {number} iterations - Maximum number of iterations
|
|
16
|
-
* @param {number} scale - Scale factor for positions
|
|
17
|
-
* @param {Array|null} center - Coordinate pair around which to center the layout
|
|
18
|
-
* @param {number} dim - Dimension of layout
|
|
19
|
-
* @param {number} seed - Random seed for initial positions
|
|
20
|
-
* @returns {Object} Positions dictionary keyed by node
|
|
21
|
-
*/
|
|
22
|
-
export function fruchtermanReingoldLayout(G, k = null, pos = null, fixed = null, iterations = 50, scale = 1, center = null, dim = 2, seed = null) {
|
|
23
|
-
const processed = _processParams(G, center, dim);
|
|
24
|
-
let graph = processed.G;
|
|
25
|
-
center = processed.center;
|
|
26
|
-
const nodes = getNodesFromGraph(graph);
|
|
27
|
-
const edges = getEdgesFromGraph(graph);
|
|
28
|
-
if (nodes.length === 0) {
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
if (nodes.length === 1) {
|
|
32
|
-
const singlePos = {};
|
|
33
|
-
singlePos[nodes[0]] = center;
|
|
34
|
-
return singlePos;
|
|
35
|
-
}
|
|
36
|
-
// Set up initial positions
|
|
37
|
-
let positions = {};
|
|
38
|
-
if (pos) {
|
|
39
|
-
// Use provided positions
|
|
40
|
-
for (const node of nodes) {
|
|
41
|
-
if (pos[node]) {
|
|
42
|
-
positions[node] = [...pos[node]];
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
const rng = new RandomNumberGenerator(seed ?? undefined);
|
|
46
|
-
positions[node] = rng.rand(dim);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// Random initial positions
|
|
52
|
-
const rng = new RandomNumberGenerator(seed ?? undefined);
|
|
53
|
-
for (const node of nodes) {
|
|
54
|
-
positions[node] = rng.rand(dim);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
// Set up fixed nodes
|
|
58
|
-
const fixedNodes = new Set(fixed || []);
|
|
59
|
-
// Optimal distance between nodes
|
|
60
|
-
if (!k) {
|
|
61
|
-
k = 1.0 / Math.sqrt(nodes.length);
|
|
62
|
-
}
|
|
63
|
-
// Initialize temperature
|
|
64
|
-
let t = 0.1;
|
|
65
|
-
// Calculate temperature reduction
|
|
66
|
-
const dt = t / (iterations + 1);
|
|
67
|
-
// Simple cooling schedule
|
|
68
|
-
for (let i = 0; i < iterations; i++) {
|
|
69
|
-
// Calculate repulsive forces
|
|
70
|
-
const displacement = {};
|
|
71
|
-
for (const node of nodes) {
|
|
72
|
-
displacement[node] = Array(dim).fill(0);
|
|
73
|
-
}
|
|
74
|
-
// Repulsive forces between nodes
|
|
75
|
-
for (let v1i = 0; v1i < nodes.length; v1i++) {
|
|
76
|
-
const v1 = nodes[v1i];
|
|
77
|
-
for (let v2i = v1i + 1; v2i < nodes.length; v2i++) {
|
|
78
|
-
const v2 = nodes[v2i];
|
|
79
|
-
// Difference vector
|
|
80
|
-
const delta = positions[v1].map((p, i) => p - positions[v2][i]);
|
|
81
|
-
// Distance
|
|
82
|
-
const distance = Math.sqrt(delta.reduce((sum, d) => sum + d * d, 0)) || 0.1;
|
|
83
|
-
// Force
|
|
84
|
-
const force = (k * k) / distance;
|
|
85
|
-
// Add force to displacement
|
|
86
|
-
for (let j = 0; j < dim; j++) {
|
|
87
|
-
const direction = delta[j] / distance;
|
|
88
|
-
displacement[v1][j] += direction * force;
|
|
89
|
-
displacement[v2][j] -= direction * force;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// Attractive forces between connected nodes
|
|
94
|
-
for (const [source, target] of edges) {
|
|
95
|
-
// Difference vector
|
|
96
|
-
const delta = positions[source].map((p, i) => p - positions[target][i]);
|
|
97
|
-
// Distance
|
|
98
|
-
const distance = Math.sqrt(delta.reduce((sum, d) => sum + d * d, 0)) || 0.1;
|
|
99
|
-
// Force
|
|
100
|
-
const force = (distance * distance) / k;
|
|
101
|
-
// Add force to displacement
|
|
102
|
-
for (let j = 0; j < dim; j++) {
|
|
103
|
-
const direction = delta[j] / distance;
|
|
104
|
-
displacement[source][j] -= direction * force;
|
|
105
|
-
displacement[target][j] += direction * force;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// Update positions
|
|
109
|
-
for (const node of nodes) {
|
|
110
|
-
if (fixedNodes.has(node))
|
|
111
|
-
continue;
|
|
112
|
-
// Calculate displacement magnitude
|
|
113
|
-
const magnitude = Math.sqrt(displacement[node].reduce((sum, d) => sum + d * d, 0));
|
|
114
|
-
// Limit maximum displacement by temperature
|
|
115
|
-
const limitedMagnitude = Math.min(magnitude, t);
|
|
116
|
-
// Update position
|
|
117
|
-
for (let j = 0; j < dim; j++) {
|
|
118
|
-
const direction = magnitude === 0 ? 0 : displacement[node][j] / magnitude;
|
|
119
|
-
positions[node][j] += direction * limitedMagnitude;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Cool temperature
|
|
123
|
-
t -= dt;
|
|
124
|
-
}
|
|
125
|
-
// Rescale positions
|
|
126
|
-
if (!fixed) {
|
|
127
|
-
positions = rescaleLayout(positions, scale, center);
|
|
128
|
-
}
|
|
129
|
-
return positions;
|
|
130
|
-
}
|
|
131
|
-
//# sourceMappingURL=fruchterman-reingold.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fruchterman-reingold.js","sourceRoot":"","sources":["../../../../src/layouts/force-directed/fruchterman-reingold.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Force-directed layout algorithms
|
|
3
|
-
*/
|
|
4
|
-
export { springLayout } from './spring';
|
|
5
|
-
export { fruchtermanReingoldLayout } from './fruchterman-reingold';
|
|
6
|
-
export { kamadaKawaiLayout } from './kamada-kawai';
|
|
7
|
-
export { forceatlas2Layout } from './forceatlas2';
|
|
8
|
-
export { arfLayout } from './arf';
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Force-directed layout algorithms
|
|
3
|
-
*/
|
|
4
|
-
export { springLayout } from './spring';
|
|
5
|
-
export { fruchtermanReingoldLayout } from './fruchterman-reingold';
|
|
6
|
-
export { kamadaKawaiLayout } from './kamada-kawai';
|
|
7
|
-
export { forceatlas2Layout } from './forceatlas2';
|
|
8
|
-
export { arfLayout } from './arf';
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/layouts/force-directed/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Graph, PositionMap } from '../../types';
|
|
2
|
-
import type { DistanceMap } from '../../algorithms/optimization';
|
|
3
|
-
/**
|
|
4
|
-
* Position nodes using Kamada-Kawai path-length cost-function.
|
|
5
|
-
*
|
|
6
|
-
* @param G - NetworkX graph or list of nodes
|
|
7
|
-
* @param dist - A two-level dictionary of optimal distances between nodes
|
|
8
|
-
* @param pos - Initial positions for nodes
|
|
9
|
-
* @param weight - The edge attribute used for edge weights
|
|
10
|
-
* @param scale - Scale factor for positions
|
|
11
|
-
* @param center - Coordinate pair around which to center the layout
|
|
12
|
-
* @param dim - Dimension of layout
|
|
13
|
-
* @returns Positions dictionary keyed by node
|
|
14
|
-
*/
|
|
15
|
-
export declare function kamadaKawaiLayout(G: Graph, dist?: DistanceMap | null, pos?: PositionMap | null, weight?: string, scale?: number, center?: number[] | null, dim?: number): PositionMap;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { getNodesFromGraph } from '../../utils/graph';
|
|
2
|
-
import { _processParams } from '../../utils/params';
|
|
3
|
-
import { rescaleLayout } from '../../utils/rescale';
|
|
4
|
-
import { circularLayout } from '../geometric/circular';
|
|
5
|
-
import { _computeShortestPathDistances, _kamadaKawaiSolve } from '../../algorithms/optimization';
|
|
6
|
-
/**
|
|
7
|
-
* Position nodes using Kamada-Kawai path-length cost-function.
|
|
8
|
-
*
|
|
9
|
-
* @param G - NetworkX graph or list of nodes
|
|
10
|
-
* @param dist - A two-level dictionary of optimal distances between nodes
|
|
11
|
-
* @param pos - Initial positions for nodes
|
|
12
|
-
* @param weight - The edge attribute used for edge weights
|
|
13
|
-
* @param scale - Scale factor for positions
|
|
14
|
-
* @param center - Coordinate pair around which to center the layout
|
|
15
|
-
* @param dim - Dimension of layout
|
|
16
|
-
* @returns Positions dictionary keyed by node
|
|
17
|
-
*/
|
|
18
|
-
export function kamadaKawaiLayout(G, dist = null, pos = null, weight = 'weight', scale = 1, center = null, dim = 2) {
|
|
19
|
-
const processed = _processParams(G, center, dim);
|
|
20
|
-
const graph = processed.G;
|
|
21
|
-
center = processed.center;
|
|
22
|
-
const nodes = getNodesFromGraph(graph);
|
|
23
|
-
if (nodes.length === 0) {
|
|
24
|
-
return {};
|
|
25
|
-
}
|
|
26
|
-
if (nodes.length === 1) {
|
|
27
|
-
return { [nodes[0]]: center };
|
|
28
|
-
}
|
|
29
|
-
// Initialize distance matrix
|
|
30
|
-
if (!dist) {
|
|
31
|
-
// Kamada-Kawai requires a proper Graph, not just a list of nodes
|
|
32
|
-
if (Array.isArray(graph)) {
|
|
33
|
-
throw new Error('Kamada-Kawai layout requires a Graph with edges, not just a list of nodes');
|
|
34
|
-
}
|
|
35
|
-
dist = _computeShortestPathDistances(graph, weight);
|
|
36
|
-
}
|
|
37
|
-
// Convert distances to a matrix
|
|
38
|
-
const nodesArray = Array.from(nodes);
|
|
39
|
-
const nNodes = nodesArray.length;
|
|
40
|
-
const distMatrix = Array(nNodes).fill(0).map(() => Array(nNodes).fill(1e6));
|
|
41
|
-
for (let i = 0; i < nNodes; i++) {
|
|
42
|
-
const nodeI = nodesArray[i];
|
|
43
|
-
distMatrix[i][i] = 0;
|
|
44
|
-
if (!dist[nodeI])
|
|
45
|
-
continue;
|
|
46
|
-
for (let j = 0; j < nNodes; j++) {
|
|
47
|
-
const nodeJ = nodesArray[j];
|
|
48
|
-
if (dist[nodeI][nodeJ] !== undefined) {
|
|
49
|
-
distMatrix[i][j] = dist[nodeI][nodeJ];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// Initialize positions if not provided
|
|
54
|
-
if (!pos) {
|
|
55
|
-
if (dim >= 2) {
|
|
56
|
-
// Use circular/spherical layout for 2D and 3D
|
|
57
|
-
pos = circularLayout(G, 1, center, dim);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
// For 1D, use a linear layout
|
|
61
|
-
const posArray = {};
|
|
62
|
-
nodesArray.forEach((node, i) => {
|
|
63
|
-
posArray[node] = [i / (nNodes - 1 || 1)];
|
|
64
|
-
});
|
|
65
|
-
pos = posArray;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// Convert positions to array for computation
|
|
69
|
-
const posArray = new Array(nNodes);
|
|
70
|
-
for (let i = 0; i < nNodes; i++) {
|
|
71
|
-
const node = nodesArray[i];
|
|
72
|
-
posArray[i] = pos[node] ? [...pos[node]] : Array(dim).fill(0);
|
|
73
|
-
// Ensure correct dimensionality
|
|
74
|
-
while (posArray[i].length < dim) {
|
|
75
|
-
posArray[i].push(0);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// Run the Kamada-Kawai algorithm
|
|
79
|
-
const newPositions = _kamadaKawaiSolve(distMatrix, posArray, dim);
|
|
80
|
-
// Convert positions array back to dictionary and rescale
|
|
81
|
-
const finalPos = {};
|
|
82
|
-
for (let i = 0; i < nNodes; i++) {
|
|
83
|
-
finalPos[nodesArray[i]] = newPositions[i];
|
|
84
|
-
}
|
|
85
|
-
return rescaleLayout(finalPos, scale, center);
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=kamada-kawai.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kamada-kawai.js","sourceRoot":"","sources":["../../../../src/layouts/force-directed/kamada-kawai.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spring layout algorithm (Fruchterman-Reingold variant)
|
|
3
|
-
*/
|
|
4
|
-
import { Graph, Node, PositionMap } from '../../types';
|
|
5
|
-
/**
|
|
6
|
-
* Position nodes using Fruchterman-Reingold force-directed algorithm.
|
|
7
|
-
*
|
|
8
|
-
* @param {Object} G - Graph or list of nodes
|
|
9
|
-
* @param {number} k - Optimal distance between nodes
|
|
10
|
-
* @param {Object} pos - Initial positions for nodes
|
|
11
|
-
* @param {Array} fixed - Nodes to keep fixed at initial position
|
|
12
|
-
* @param {number} iterations - Maximum number of iterations
|
|
13
|
-
* @param {number} scale - Scale factor for positions
|
|
14
|
-
* @param {Array|null} center - Coordinate pair around which to center the layout
|
|
15
|
-
* @param {number} dim - Dimension of layout
|
|
16
|
-
* @param {number} seed - Random seed for initial positions
|
|
17
|
-
* @returns {Object} Positions dictionary keyed by node
|
|
18
|
-
*/
|
|
19
|
-
export declare function springLayout(G: Graph, k?: number | null, pos?: PositionMap | null, fixed?: Node[] | null, iterations?: number, scale?: number, center?: number[] | null, dim?: number, seed?: number | null): PositionMap;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spring layout algorithm (Fruchterman-Reingold variant)
|
|
3
|
-
*/
|
|
4
|
-
import { fruchtermanReingoldLayout } from './fruchterman-reingold';
|
|
5
|
-
/**
|
|
6
|
-
* Position nodes using Fruchterman-Reingold force-directed algorithm.
|
|
7
|
-
*
|
|
8
|
-
* @param {Object} G - Graph or list of nodes
|
|
9
|
-
* @param {number} k - Optimal distance between nodes
|
|
10
|
-
* @param {Object} pos - Initial positions for nodes
|
|
11
|
-
* @param {Array} fixed - Nodes to keep fixed at initial position
|
|
12
|
-
* @param {number} iterations - Maximum number of iterations
|
|
13
|
-
* @param {number} scale - Scale factor for positions
|
|
14
|
-
* @param {Array|null} center - Coordinate pair around which to center the layout
|
|
15
|
-
* @param {number} dim - Dimension of layout
|
|
16
|
-
* @param {number} seed - Random seed for initial positions
|
|
17
|
-
* @returns {Object} Positions dictionary keyed by node
|
|
18
|
-
*/
|
|
19
|
-
export function springLayout(G, k = null, pos = null, fixed = null, iterations = 50, scale = 1, center = null, dim = 2, seed = null) {
|
|
20
|
-
// Legacy compatibility alias
|
|
21
|
-
return fruchtermanReingoldLayout(G, k, pos, fixed, iterations, scale, center, dim, seed);
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=spring.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spring.js","sourceRoot":"","sources":["../../../../src/layouts/force-directed/spring.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAC1B,CAAQ,EACR,IAAmB,IAAI,EACvB,MAA0B,IAAI,EAC9B,QAAuB,IAAI,EAC3B,aAAqB,EAAE,EACvB,QAAgB,CAAC,EACjB,SAA0B,IAAI,EAC9B,MAAc,CAAC,EACf,OAAsB,IAAI;IAE1B,6BAA6B;IAC7B,OAAO,yBAAyB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAC3F,CAAC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Circular layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { Graph, PositionMap } from '../../types';
|
|
5
|
-
/**
|
|
6
|
-
* Position nodes on a circle (2D) or sphere (3D).
|
|
7
|
-
*
|
|
8
|
-
* @param G - Graph or list of nodes
|
|
9
|
-
* @param scale - Scale factor for positions
|
|
10
|
-
* @param center - Coordinate pair around which to center the layout
|
|
11
|
-
* @param dim - Dimension of layout (supports 2D circle or 3D sphere)
|
|
12
|
-
* @returns Positions dictionary keyed by node
|
|
13
|
-
*/
|
|
14
|
-
export declare function circularLayout(G: Graph, scale?: number, center?: number[] | null, dim?: number): PositionMap;
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Circular layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { _processParams } from '../../utils/params';
|
|
5
|
-
import { getNodesFromGraph } from '../../utils/graph';
|
|
6
|
-
import { RandomNumberGenerator } from '../../utils/random';
|
|
7
|
-
import { np } from '../../utils/numpy';
|
|
8
|
-
/**
|
|
9
|
-
* Position nodes on a circle (2D) or sphere (3D).
|
|
10
|
-
*
|
|
11
|
-
* @param G - Graph or list of nodes
|
|
12
|
-
* @param scale - Scale factor for positions
|
|
13
|
-
* @param center - Coordinate pair around which to center the layout
|
|
14
|
-
* @param dim - Dimension of layout (supports 2D circle or 3D sphere)
|
|
15
|
-
* @returns Positions dictionary keyed by node
|
|
16
|
-
*/
|
|
17
|
-
export function circularLayout(G, scale = 1, center = null, dim = 2) {
|
|
18
|
-
if (dim < 2) {
|
|
19
|
-
throw new Error("cannot handle dimensions < 2");
|
|
20
|
-
}
|
|
21
|
-
const processed = _processParams(G, center, dim);
|
|
22
|
-
const nodes = getNodesFromGraph(processed.G);
|
|
23
|
-
center = processed.center;
|
|
24
|
-
const pos = {};
|
|
25
|
-
if (nodes.length === 0) {
|
|
26
|
-
return pos;
|
|
27
|
-
}
|
|
28
|
-
if (nodes.length === 1) {
|
|
29
|
-
pos[nodes[0]] = center;
|
|
30
|
-
return pos;
|
|
31
|
-
}
|
|
32
|
-
if (dim === 2) {
|
|
33
|
-
// 2D circle layout
|
|
34
|
-
const theta = np.linspace(0, 2 * Math.PI, nodes.length + 1).slice(0, -1);
|
|
35
|
-
nodes.forEach((node, i) => {
|
|
36
|
-
const x = Math.cos(theta[i]) * scale + center[0];
|
|
37
|
-
const y = Math.sin(theta[i]) * scale + center[1];
|
|
38
|
-
pos[node] = [x, y];
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
else if (dim === 3) {
|
|
42
|
-
// 3D sphere layout using Fibonacci spiral
|
|
43
|
-
const n = nodes.length;
|
|
44
|
-
const goldenRatio = (1 + Math.sqrt(5)) / 2;
|
|
45
|
-
nodes.forEach((node, i) => {
|
|
46
|
-
// Use Fibonacci spiral for even distribution on sphere
|
|
47
|
-
const theta = 2 * Math.PI * i / goldenRatio;
|
|
48
|
-
const phi = Math.acos(1 - 2 * (i + 0.5) / n);
|
|
49
|
-
const x = Math.sin(phi) * Math.cos(theta) * scale + center[0];
|
|
50
|
-
const y = Math.sin(phi) * Math.sin(theta) * scale + center[1];
|
|
51
|
-
const z = Math.cos(phi) * scale + center[2];
|
|
52
|
-
pos[node] = [x, y, z];
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
// For higher dimensions, fall back to random on hypersphere
|
|
57
|
-
const rng = new RandomNumberGenerator();
|
|
58
|
-
nodes.forEach((node) => {
|
|
59
|
-
// Generate random point on unit hypersphere
|
|
60
|
-
const coords = Array(dim).fill(0).map(() => rng.rand() * 2 - 1);
|
|
61
|
-
const norm = Math.sqrt(coords.reduce((sum, c) => sum + c * c, 0));
|
|
62
|
-
pos[node] = coords.map((c, j) => c / norm * scale + center[j]);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return pos;
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=circular.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"circular.js","sourceRoot":"","sources":["../../../../src/layouts/geometric/circular.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/layouts/geometric/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shell layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { Graph, Node, PositionMap } from '../../types';
|
|
5
|
-
/**
|
|
6
|
-
* Position nodes in concentric circles.
|
|
7
|
-
*
|
|
8
|
-
* @param G - Graph or list of nodes
|
|
9
|
-
* @param nlist - List of node lists for each shell
|
|
10
|
-
* @param scale - Scale factor for positions
|
|
11
|
-
* @param center - Coordinate pair around which to center the layout
|
|
12
|
-
* @param dim - Dimension of layout (currently only supports dim=2)
|
|
13
|
-
* @returns Positions dictionary keyed by node
|
|
14
|
-
*/
|
|
15
|
-
export declare function shellLayout(G: Graph, nlist?: Node[][] | null, scale?: number, center?: number[] | null, dim?: number): PositionMap;
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shell layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { _processParams } from '../../utils/params';
|
|
5
|
-
import { getNodesFromGraph } from '../../utils/graph';
|
|
6
|
-
import { np } from '../../utils/numpy';
|
|
7
|
-
/**
|
|
8
|
-
* Position nodes in concentric circles.
|
|
9
|
-
*
|
|
10
|
-
* @param G - Graph or list of nodes
|
|
11
|
-
* @param nlist - List of node lists for each shell
|
|
12
|
-
* @param scale - Scale factor for positions
|
|
13
|
-
* @param center - Coordinate pair around which to center the layout
|
|
14
|
-
* @param dim - Dimension of layout (currently only supports dim=2)
|
|
15
|
-
* @returns Positions dictionary keyed by node
|
|
16
|
-
*/
|
|
17
|
-
export function shellLayout(G, nlist = null, scale = 1, center = null, dim = 2) {
|
|
18
|
-
if (dim !== 2) {
|
|
19
|
-
throw new Error("can only handle 2 dimensions");
|
|
20
|
-
}
|
|
21
|
-
const processed = _processParams(G, center, dim);
|
|
22
|
-
const nodes = getNodesFromGraph(processed.G);
|
|
23
|
-
center = processed.center;
|
|
24
|
-
const pos = {};
|
|
25
|
-
if (nodes.length === 0) {
|
|
26
|
-
return pos;
|
|
27
|
-
}
|
|
28
|
-
if (nodes.length === 1) {
|
|
29
|
-
pos[nodes[0]] = center;
|
|
30
|
-
return pos;
|
|
31
|
-
}
|
|
32
|
-
// If no nlist is specified, put all nodes in a single shell
|
|
33
|
-
if (!nlist) {
|
|
34
|
-
nlist = [nodes];
|
|
35
|
-
}
|
|
36
|
-
const radiusBump = scale / nlist.length;
|
|
37
|
-
let radius;
|
|
38
|
-
if (nlist[0].length === 1) {
|
|
39
|
-
// Single node at center
|
|
40
|
-
radius = 0;
|
|
41
|
-
pos[nlist[0][0]] = [...center];
|
|
42
|
-
radius += radiusBump;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
// Start at radius 1
|
|
46
|
-
radius = radiusBump;
|
|
47
|
-
}
|
|
48
|
-
for (let i = 0; i < nlist.length; i++) {
|
|
49
|
-
const shell = nlist[i];
|
|
50
|
-
if (shell.length === 0)
|
|
51
|
-
continue;
|
|
52
|
-
if (shell.length === 1 && i === 0) {
|
|
53
|
-
// Already handled the case of a single center node
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
// Calculate positions on a circle
|
|
57
|
-
const theta = np.linspace(0, 2 * Math.PI, shell.length + 1).slice(0, -1);
|
|
58
|
-
shell.forEach((node, j) => {
|
|
59
|
-
const x = Math.cos(theta[j]) * radius + center[0];
|
|
60
|
-
const y = Math.sin(theta[j]) * radius + center[1];
|
|
61
|
-
pos[node] = [x, y];
|
|
62
|
-
});
|
|
63
|
-
radius += radiusBump;
|
|
64
|
-
}
|
|
65
|
-
return pos;
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=shell.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../../src/layouts/geometric/shell.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spiral layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { Graph, PositionMap } from '../../types';
|
|
5
|
-
/**
|
|
6
|
-
* Position nodes in a spiral layout.
|
|
7
|
-
*
|
|
8
|
-
* @param G - Graph or list of nodes
|
|
9
|
-
* @param scale - Scale factor for positions
|
|
10
|
-
* @param center - Coordinate pair around which to center the layout
|
|
11
|
-
* @param dim - Dimension of layout
|
|
12
|
-
* @param resolution - Controls the spacing between spiral elements
|
|
13
|
-
* @param equidistant - Whether to place nodes equidistant from each other
|
|
14
|
-
* @returns Positions dictionary keyed by node
|
|
15
|
-
*/
|
|
16
|
-
export declare function spiralLayout(G: Graph, scale?: number, center?: number[] | null, dim?: number, resolution?: number, equidistant?: boolean): PositionMap;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spiral layout algorithm
|
|
3
|
-
*/
|
|
4
|
-
import { _processParams } from '../../utils/params';
|
|
5
|
-
import { getNodesFromGraph } from '../../utils/graph';
|
|
6
|
-
import { rescaleLayout } from '../../utils/rescale';
|
|
7
|
-
/**
|
|
8
|
-
* Position nodes in a spiral layout.
|
|
9
|
-
*
|
|
10
|
-
* @param G - Graph or list of nodes
|
|
11
|
-
* @param scale - Scale factor for positions
|
|
12
|
-
* @param center - Coordinate pair around which to center the layout
|
|
13
|
-
* @param dim - Dimension of layout
|
|
14
|
-
* @param resolution - Controls the spacing between spiral elements
|
|
15
|
-
* @param equidistant - Whether to place nodes equidistant from each other
|
|
16
|
-
* @returns Positions dictionary keyed by node
|
|
17
|
-
*/
|
|
18
|
-
export function spiralLayout(G, scale = 1, center = null, dim = 2, resolution = 0.35, equidistant = false) {
|
|
19
|
-
if (dim !== 2) {
|
|
20
|
-
throw new Error("can only handle 2 dimensions");
|
|
21
|
-
}
|
|
22
|
-
const processed = _processParams(G, center || [0, 0], dim);
|
|
23
|
-
const nodes = getNodesFromGraph(processed.G);
|
|
24
|
-
center = processed.center;
|
|
25
|
-
const pos = {};
|
|
26
|
-
if (nodes.length === 0) {
|
|
27
|
-
return pos;
|
|
28
|
-
}
|
|
29
|
-
if (nodes.length === 1) {
|
|
30
|
-
pos[nodes[0]] = [...center];
|
|
31
|
-
return pos;
|
|
32
|
-
}
|
|
33
|
-
let positions = [];
|
|
34
|
-
if (equidistant) {
|
|
35
|
-
// Create equidistant points along the spiral
|
|
36
|
-
// This matches the Python implementation logic
|
|
37
|
-
const chord = 1;
|
|
38
|
-
const step = 0.5;
|
|
39
|
-
let theta = resolution;
|
|
40
|
-
theta += chord / (step * theta);
|
|
41
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
42
|
-
const r = step * theta;
|
|
43
|
-
theta += chord / r;
|
|
44
|
-
positions.push([Math.cos(theta) * r, Math.sin(theta) * r]);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
// Create points with equal angle but increasing distance
|
|
49
|
-
const dist = Array.from({ length: nodes.length }, (_, i) => parseFloat(String(i)));
|
|
50
|
-
const angle = dist.map(d => resolution * d);
|
|
51
|
-
positions = dist.map((d, i) => [
|
|
52
|
-
Math.cos(angle[i]) * d,
|
|
53
|
-
Math.sin(angle[i]) * d
|
|
54
|
-
]);
|
|
55
|
-
}
|
|
56
|
-
// Convert position array to position matrix for rescaling
|
|
57
|
-
const posArray = [];
|
|
58
|
-
for (let i = 0; i < positions.length; i++) {
|
|
59
|
-
posArray.push(positions[i]);
|
|
60
|
-
}
|
|
61
|
-
// Rescale positions and add center offset
|
|
62
|
-
const scaledPositions = rescaleLayout(posArray, scale);
|
|
63
|
-
for (let i = 0; i < scaledPositions.length; i++) {
|
|
64
|
-
scaledPositions[i][0] += center[0];
|
|
65
|
-
scaledPositions[i][1] += center[1];
|
|
66
|
-
}
|
|
67
|
-
// Create position dictionary
|
|
68
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
69
|
-
pos[nodes[i]] = scaledPositions[i];
|
|
70
|
-
}
|
|
71
|
-
return pos;
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=spiral.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spiral.js","sourceRoot":"","sources":["../../../../src/layouts/geometric/spiral.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Graph, Node, PositionMap } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Position nodes according to breadth-first search algorithm.
|
|
4
|
-
*
|
|
5
|
-
* @param G - Graph
|
|
6
|
-
* @param start - Starting node for bfs
|
|
7
|
-
* @param align - The alignment of layers: 'vertical' or 'horizontal'
|
|
8
|
-
* @param scale - Scale factor for positions
|
|
9
|
-
* @param center - Coordinate pair around which to center the layout
|
|
10
|
-
* @returns Positions dictionary keyed by node
|
|
11
|
-
*/
|
|
12
|
-
export declare function bfsLayout(G: Graph, start: Node, align?: 'vertical' | 'horizontal', scale?: number, center?: number[] | null): PositionMap;
|