@graphty/layout 1.1.0 → 1.1.1

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.
Files changed (43) hide show
  1. package/.github/workflows/ci.yml +89 -14
  2. package/.releaserc.json +22 -0
  3. package/CHANGELOG.md +24 -0
  4. package/CLAUDE.md +104 -0
  5. package/CONTRIBUTING.md +1 -0
  6. package/README.md +609 -93
  7. package/dist/layout-helpers.d.ts +123 -0
  8. package/dist/layout-helpers.js +457 -0
  9. package/dist/layout-helpers.js.map +1 -0
  10. package/dist/layout.d.ts +275 -0
  11. package/dist/layout.js +2280 -0
  12. package/dist/layout.js.map +1 -0
  13. package/dist/vitest.config.d.ts +2 -0
  14. package/dist/vitest.config.js +30 -0
  15. package/dist/vitest.config.js.map +1 -0
  16. package/examples/bfs-layout.html +37 -39
  17. package/examples/bipartite-layout.html +77 -69
  18. package/examples/circular-layout.html +13 -34
  19. package/examples/forceatlas2-layout.html +122 -28
  20. package/examples/multipartite-layout.html +64 -51
  21. package/examples/shell-layout.html +53 -34
  22. package/examples/spring-layout.html +11 -1
  23. package/layout-helpers.ts +559 -0
  24. package/layout.ts +277 -1
  25. package/package.json +17 -6
  26. package/test/arf-layout.test.ts +443 -0
  27. package/test/bfs-layout.test.ts +427 -0
  28. package/test/bipartite-layout.test.ts +344 -0
  29. package/test/circular-layout.test.ts +300 -0
  30. package/test/forceatlas2-layout.test.ts +405 -0
  31. package/test/fruchterman-reingold-layout.test.ts +477 -0
  32. package/test/graph-generators.test.ts +450 -0
  33. package/test/kamada-kawai-layout.test.ts +351 -0
  34. package/test/multipartite-layout.test.ts +404 -0
  35. package/test/planar-layout.test.ts +266 -0
  36. package/test/random-layout.test.ts +254 -0
  37. package/test/rescale-layout.test.ts +373 -0
  38. package/test/shell-layout.test.ts +347 -0
  39. package/test/spectral-layout.test.ts +378 -0
  40. package/test/spiral-layout.test.ts +338 -0
  41. package/test/spring-layout.test.ts +241 -0
  42. package/vitest.config.ts +30 -0
  43. package/.releaserc +0 -3
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Layout
3
+ * ======
4
+ *
5
+ * Node positioning algorithms for graph drawing in TypeScript.
6
+ *
7
+ * For `randomLayout()` the possible resulting shape
8
+ * is a square of side [0, scale] (default: [0, 1])
9
+ * Changing `center` shifts the layout by that amount.
10
+ *
11
+ * For the other layout routines, the extent is
12
+ * [center - scale, center + scale] (default: [-1, 1]).
13
+ *
14
+ * Ported from NetworkX Python library.
15
+ */
16
+ export type Node = string | number;
17
+ export type Edge = [Node, Node];
18
+ export type Graph = {
19
+ nodes?: () => Node[];
20
+ edges?: () => Edge[];
21
+ getEdgeData?: (source: Node, target: Node, attr: string) => any;
22
+ };
23
+ type Position = number[];
24
+ type PositionMap = Record<Node, Position>;
25
+ /**
26
+ * Position nodes uniformly at random in the unit square.
27
+ *
28
+ * @param G - Graph or list of nodes
29
+ * @param center - Coordinate pair around which to center the layout
30
+ * @param dim - Dimension of layout
31
+ * @param seed - Random seed for reproducible layouts
32
+ * @returns Positions dictionary keyed by node
33
+ */
34
+ declare function randomLayout(G: Graph, center?: number[] | null, dim?: number, seed?: number | null): PositionMap;
35
+ /**
36
+ * Position nodes on a circle.
37
+ *
38
+ * @param G - Graph or list of nodes
39
+ * @param scale - Scale factor for positions
40
+ * @param center - Coordinate pair around which to center the layout
41
+ * @param dim - Dimension of layout (currently only supports dim=2)
42
+ * @returns Positions dictionary keyed by node
43
+ */
44
+ declare function circularLayout(G: Graph, scale?: number, center?: number[] | null, dim?: number): PositionMap;
45
+ /**
46
+ * Position nodes in concentric circles.
47
+ *
48
+ * @param G - Graph or list of nodes
49
+ * @param nlist - List of node lists for each shell
50
+ * @param scale - Scale factor for positions
51
+ * @param center - Coordinate pair around which to center the layout
52
+ * @param dim - Dimension of layout (currently only supports dim=2)
53
+ * @returns Positions dictionary keyed by node
54
+ */
55
+ declare function shellLayout(G: Graph, nlist?: Node[][] | null, scale?: number, center?: number[] | null, dim?: number): PositionMap;
56
+ /**
57
+ * Position nodes using Fruchterman-Reingold force-directed algorithm.
58
+ *
59
+ * @param {Object} G - Graph or list of nodes
60
+ * @param {number} k - Optimal distance between nodes
61
+ * @param {Object} pos - Initial positions for nodes
62
+ * @param {Array} fixed - Nodes to keep fixed at initial position
63
+ * @param {number} iterations - Maximum number of iterations
64
+ * @param {number} scale - Scale factor for positions
65
+ * @param {Array|null} center - Coordinate pair around which to center the layout
66
+ * @param {number} dim - Dimension of layout
67
+ * @param {number} seed - Random seed for initial positions
68
+ * @returns {Object} Positions dictionary keyed by node
69
+ */
70
+ 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;
71
+ /**
72
+ * Position nodes using Fruchterman-Reingold force-directed algorithm.
73
+ *
74
+ * @param {Object} G - Graph or list of nodes
75
+ * @param {number} k - Optimal distance between nodes
76
+ * @param {Object} pos - Initial positions for nodes
77
+ * @param {Array} fixed - Nodes to keep fixed at initial position
78
+ * @param {number} iterations - Maximum number of iterations
79
+ * @param {number} scale - Scale factor for positions
80
+ * @param {Array|null} center - Coordinate pair around which to center the layout
81
+ * @param {number} dim - Dimension of layout
82
+ * @param {number} seed - Random seed for initial positions
83
+ * @returns {Object} Positions dictionary keyed by node
84
+ */
85
+ declare function fruchtermanReingoldLayout(G: Graph, k?: number | null, pos?: PositionMap | null, fixed?: Node[] | null, iterations?: number, scale?: number, center?: number[] | null, dim?: number, seed?: number | null): PositionMap;
86
+ /**
87
+ * Position nodes in a spectral layout using eigenvectors of the graph Laplacian.
88
+ *
89
+ * @param G - Graph
90
+ * @param scale - Scale factor for positions
91
+ * @param center - Coordinate pair around which to center the layout
92
+ * @param dim - Dimension of layout
93
+ * @returns Positions dictionary keyed by node
94
+ */
95
+ declare function spectralLayout(G: Graph, scale?: number, center?: number[] | null, dim?: number): PositionMap;
96
+ /**
97
+ * Position nodes in a spiral layout.
98
+ *
99
+ * @param G - Graph or list of nodes
100
+ * @param scale - Scale factor for positions
101
+ * @param center - Coordinate pair around which to center the layout
102
+ * @param dim - Dimension of layout
103
+ * @param resolution - Controls the spacing between spiral elements
104
+ * @param equidistant - Whether to place nodes equidistant from each other
105
+ * @returns Positions dictionary keyed by node
106
+ */
107
+ declare function spiralLayout(G: Graph, scale?: number, center?: number[] | null, dim?: number, resolution?: number, equidistant?: boolean): PositionMap;
108
+ /**
109
+ * Rescale node positions to fit in the specified scale and center.
110
+ *
111
+ * @param pos - Dictionary or array of positions
112
+ * @param scale - Scale factor for positions
113
+ * @param center - Coordinate pair around which to center the layout
114
+ * @returns Rescaled positions dictionary
115
+ */
116
+ declare function rescaleLayout(pos: PositionMap | number[][], scale?: number, center?: number[]): PositionMap | number[][];
117
+ /**
118
+ * Position nodes in two straight lines (bipartite layout).
119
+ *
120
+ * @param G - Graph or list of nodes
121
+ * @param nodes - Nodes in one node set of the graph
122
+ * @param align - The alignment of nodes: 'vertical' or 'horizontal'
123
+ * @param scale - Scale factor for positions
124
+ * @param center - Coordinate pair around which to center the layout
125
+ * @param aspectRatio - The ratio of the width to the height of the layout
126
+ * @returns Positions dictionary keyed by node
127
+ */
128
+ declare function bipartiteLayout(G: Graph, nodes?: Node[] | null, align?: 'vertical' | 'horizontal', scale?: number, center?: number[] | null, aspectRatio?: number): PositionMap;
129
+ /**
130
+ * Position nodes in layers of straight lines (multipartite layout).
131
+ *
132
+ * @param G - Graph or list of nodes
133
+ * @param subsetKey - Object mapping layers to node sets, or node attribute name
134
+ * @param align - The alignment of nodes: 'vertical' or 'horizontal'
135
+ * @param scale - Scale factor for positions
136
+ * @param center - Coordinate pair around which to center the layout
137
+ * @returns Positions dictionary keyed by node
138
+ */
139
+ declare function multipartiteLayout(G: Graph, subsetKey?: Record<number | string, Node | Node[]> | string, align?: 'vertical' | 'horizontal', scale?: number, center?: number[] | null): PositionMap;
140
+ /**
141
+ * Position nodes according to breadth-first search algorithm.
142
+ *
143
+ * @param G - Graph
144
+ * @param start - Starting node for bfs
145
+ * @param align - The alignment of layers: 'vertical' or 'horizontal'
146
+ * @param scale - Scale factor for positions
147
+ * @param center - Coordinate pair around which to center the layout
148
+ * @returns Positions dictionary keyed by node
149
+ */
150
+ declare function bfsLayout(G: Graph, start: Node, align?: 'vertical' | 'horizontal', scale?: number, center?: number[] | null): PositionMap;
151
+ /**
152
+ * Position nodes without edge intersections (planar layout).
153
+ *
154
+ * @param G - Graph
155
+ * @param scale - Scale factor for positions
156
+ * @param center - Coordinate pair around which to center the layout
157
+ * @param dim - Dimension of layout (must be 2)
158
+ * @returns Positions dictionary keyed by node
159
+ */
160
+ declare function planarLayout(G: Graph, scale?: number, center?: number[] | null, dim?: number): PositionMap;
161
+ type DistanceMap = Record<Node, Record<Node, number>>;
162
+ /**
163
+ * Position nodes using Kamada-Kawai path-length cost-function.
164
+ *
165
+ * @param G - NetworkX graph or list of nodes
166
+ * @param dist - A two-level dictionary of optimal distances between nodes
167
+ * @param pos - Initial positions for nodes
168
+ * @param weight - The edge attribute used for edge weights
169
+ * @param scale - Scale factor for positions
170
+ * @param center - Coordinate pair around which to center the layout
171
+ * @param dim - Dimension of layout
172
+ * @returns Positions dictionary keyed by node
173
+ */
174
+ declare function kamadaKawaiLayout(G: Graph, dist?: DistanceMap | null, pos?: PositionMap | null, weight?: string, scale?: number, center?: number[] | null, dim?: number): PositionMap;
175
+ /**
176
+ * Position nodes using the ForceAtlas2 force-directed algorithm.
177
+ *
178
+ * @param G - Graph
179
+ * @param pos - Initial positions for nodes
180
+ * @param maxIter - Maximum number of iterations
181
+ * @param jitterTolerance - Controls tolerance for node speed adjustments
182
+ * @param scalingRatio - Scaling of attraction and repulsion forces
183
+ * @param gravity - Attraction to center to prevent disconnected components from drifting
184
+ * @param distributedAction - Distributes attraction force among nodes
185
+ * @param strongGravity - Uses a stronger gravity model
186
+ * @param nodeMass - Dictionary mapping nodes to their masses
187
+ * @param nodeSize - Dictionary mapping nodes to their sizes
188
+ * @param weight - Edge attribute for weight
189
+ * @param dissuadeHubs - Whether to prevent hub nodes from clustering
190
+ * @param linlog - Whether to use logarithmic attraction
191
+ * @param seed - Random seed for initial positions
192
+ * @param dim - Dimension of layout
193
+ * @returns Positions dictionary keyed by node
194
+ */
195
+ declare function forceatlas2Layout(G: Graph, pos?: PositionMap | null, maxIter?: number, jitterTolerance?: number, scalingRatio?: number, gravity?: number, distributedAction?: boolean, strongGravity?: boolean, nodeMass?: Record<Node, number> | null, nodeSize?: Record<Node, number> | null, weight?: string | null, dissuadeHubs?: boolean, linlog?: boolean, seed?: number | null, dim?: number): PositionMap;
196
+ /**
197
+ * Layout algorithm with attractive and repulsive forces (ARF).
198
+ *
199
+ * @param G - Graph
200
+ * @param pos - Initial positions for nodes
201
+ * @param scaling - Scale factor for positions
202
+ * @param a - Strength of springs between connected nodes (should be > 1)
203
+ * @param maxIter - Maximum number of iterations
204
+ * @param seed - Random seed for initial positions
205
+ * @returns Positions dictionary keyed by node
206
+ */
207
+ declare function arfLayout(G: Graph, pos?: PositionMap | null, scaling?: number, a?: number, maxIter?: number, seed?: number | null): PositionMap;
208
+ /**
209
+ * Return a dictionary of scaled positions keyed by node.
210
+ *
211
+ * @param pos - Dictionary of positions keyed by node
212
+ * @param scale - Scale factor for positions
213
+ * @returns Dictionary of scaled positions
214
+ */
215
+ declare function rescaleLayoutDict(pos: PositionMap, scale?: number): PositionMap;
216
+ /**
217
+ * Create a complete graph with n nodes
218
+ * @param n - Number of nodes
219
+ * @returns Graph object with all nodes connected to all other nodes
220
+ */
221
+ declare function completeGraph(n: number): Graph;
222
+ /**
223
+ * Create a cycle graph with n nodes
224
+ * @param n - Number of nodes
225
+ * @returns Graph object with nodes connected in a cycle
226
+ */
227
+ declare function cycleGraph(n: number): Graph;
228
+ /**
229
+ * Create a star graph with n nodes (1 center + n-1 leaves)
230
+ * @param n - Total number of nodes
231
+ * @returns Graph object with star topology
232
+ */
233
+ declare function starGraph(n: number): Graph;
234
+ /**
235
+ * Create a wheel graph with n nodes (1 center + n-1 rim nodes)
236
+ * @param n - Total number of nodes
237
+ * @returns Graph object with wheel topology
238
+ */
239
+ declare function wheelGraph(n: number): Graph;
240
+ /**
241
+ * Create a grid graph with rows x cols nodes
242
+ * @param rows - Number of rows
243
+ * @param cols - Number of columns
244
+ * @returns Graph object with grid topology
245
+ */
246
+ declare function gridGraph(rows: number, cols: number): Graph;
247
+ /**
248
+ * Create a random graph with n nodes and given edge probability
249
+ * @param n - Number of nodes
250
+ * @param p - Probability of edge between any two nodes (0-1)
251
+ * @param seed - Random seed for reproducibility
252
+ * @returns Graph object with random edges
253
+ */
254
+ declare function randomGraph(n: number, p: number, seed?: number): Graph;
255
+ /**
256
+ * Create a bipartite graph with two sets of nodes
257
+ * @param n1 - Number of nodes in first set
258
+ * @param n2 - Number of nodes in second set
259
+ * @param p - Probability of edge between nodes in different sets
260
+ * @param seed - Random seed for reproducibility
261
+ * @returns Graph object with bipartite structure and setA/setB properties
262
+ */
263
+ declare function bipartiteGraph(n1: number, n2: number, p: number, seed?: number): Graph & {
264
+ setA: Node[];
265
+ setB: Node[];
266
+ };
267
+ /**
268
+ * Create a scale-free graph using Barabási-Albert model
269
+ * @param n - Total number of nodes
270
+ * @param m - Number of edges to attach from new node
271
+ * @param seed - Random seed for reproducibility
272
+ * @returns Graph object with scale-free properties
273
+ */
274
+ declare function scaleFreeGraph(n: number, m: number, seed?: number): Graph;
275
+ export { randomLayout, circularLayout, shellLayout, springLayout, fruchtermanReingoldLayout, spectralLayout, spiralLayout, bipartiteLayout, multipartiteLayout, bfsLayout, planarLayout, kamadaKawaiLayout, forceatlas2Layout, arfLayout, rescaleLayout, rescaleLayoutDict, completeGraph, cycleGraph, starGraph, wheelGraph, gridGraph, randomGraph, bipartiteGraph, scaleFreeGraph };