UNPKG

47.6 kBTypeScriptView Raw
1// Last module patch version validated against: 3.0.0
2
3// -----------------------------------------------------------------------
4// Force Simulation
5// -----------------------------------------------------------------------
6
7/**
8 * The base data structure for the datum of a Simulation Node.
9 * The optional properties contained in this data structure are internally assigned
10 * by the Simulation upon (re-)initialization.
11 *
12 * When defining a data type to use for node data, it should be an extension of this interface
13 * and respect the already "earmarked" properties used by the simulation.
14 *
15 * IMPORTANT: Prior to initialization, the following properties are optional: index, x, y, vx, and vy.
16 * After initialization they will be defined. The optional properties fx and fy are ONLY defined,
17 * if the node's position has been fixed.
18 */
19export interface SimulationNodeDatum {
20 /**
21 * Node’s zero-based index into nodes array. This property is set during the initialization process of a simulation.
22 */
23 index?: number | undefined;
24 /**
25 * Node’s current x-position
26 */
27 x?: number | undefined;
28 /**
29 * Node’s current y-position
30 */
31 y?: number | undefined;
32 /**
33 * Node’s current x-velocity
34 */
35 vx?: number | undefined;
36 /**
37 * Node’s current y-velocity
38 */
39 vy?: number | undefined;
40 /**
41 * Node’s fixed x-position (if position was fixed)
42 */
43 fx?: number | null | undefined;
44 /**
45 * Node’s fixed y-position (if position was fixed)
46 */
47 fy?: number | null | undefined;
48}
49
50/**
51 * The base data structure for the datum of a Simulation Link, as used by ForceLink.
52 * The optional properties contained in this data structure are internally assigned
53 * by when initializing with ForceLink.links(...)
54 *
55 * IMPORTANT: The source and target properties may be internally mutated in type during the
56 * ForceLink initialization process (possibly being changed from a node index in the nodes array,
57 * or a node id string to the simulation node object which was mapped in using the current
58 * ForceLink.id(...) accessor function.)
59 */
60export interface SimulationLinkDatum<NodeDatum extends SimulationNodeDatum> {
61 /**
62 * Link’s source node.
63 * For convenience, a link’s source and target properties may be initialized using numeric or string identifiers rather than object references; see link.id.
64 * When the link force is initialized (or re-initialized, as when the nodes or links change), any link.source or link.target property which is not an object
65 * is replaced by an object reference to the corresponding node with the given identifier.
66 * After initialization, the source property represents the source node object.
67 */
68 source: NodeDatum | string | number;
69 /**
70 * Link’s source link
71 * For convenience, a link’s source and target properties may be initialized using numeric or string identifiers rather than object references; see link.id.
72 * When the link force is initialized (or re-initialized, as when the nodes or links change), any link.source or link.target property which is not an object
73 * is replaced by an object reference to the corresponding node with the given identifier.
74 * After initialization, the target property represents the target node object.
75 */
76 target: NodeDatum | string | number;
77 /**
78 * The zero-based index into the links array. Internally generated when calling ForceLink.links(...)
79 */
80 index?: number | undefined;
81}
82
83/**
84 * A Force Simulation
85 *
86 * The first generic refers to the type of the datum associated with a node in the simulation.
87 * The second generic refers to the type of the datum associated with a link in the simulation, if applicable.
88 */
89export interface Simulation<
90 NodeDatum extends SimulationNodeDatum,
91 LinkDatum extends SimulationLinkDatum<NodeDatum> | undefined,
92> {
93 /**
94 * Restart the simulation’s internal timer and return the simulation.
95 * In conjunction with simulation.alphaTarget or simulation.alpha, this method can be used to “reheat” the simulation during interaction,
96 * such as when dragging a node, or to resume the simulation after temporarily pausing it with simulation.stop.
97 */
98 restart(): this;
99
100 /**
101 * Stop the simulation’s internal timer, if it is running, and return the simulation. If the timer is already stopped, this method does nothing.
102 * This method is useful for running the simulation manually; see simulation.tick.
103 */
104 stop(): this;
105
106 /**
107 * Manually steps the simulation by the specified number of *iterations*, and returns the simulation. If *iterations* is not specified, it defaults to 1 (single step).
108 *
109 * For each iteration, it increments the current alpha by (alphaTarget - alpha) × alphaDecay; then invokes each registered force, passing the new alpha;
110 * then decrements each node’s velocity by velocity × velocityDecay; lastly increments each node’s position by velocity.
111 *
112 * This method does not dispatch events; events are only dispatched by the internal timer when the simulation is started automatically upon
113 * creation or by calling simulation.restart. The natural number of ticks when the simulation is started is
114 * ⌈log(alphaMin) / log(1 - alphaDecay)⌉; by default, this is 300.
115 */
116 tick(iterations?: number): this;
117
118 /**
119 * Returns the simulation’s array of nodes as specified to the constructor.
120 */
121 nodes(): NodeDatum[];
122 /**
123 * Set the simulation’s nodes to the specified array of objects, initialize their positions and velocities if necessary,
124 * and then re-initialize any bound forces; Returns the simulation.
125 *
126 * Each node must be an object. The following properties are assigned by the simulation:
127 * - index (the node’s zero-based index into nodes)
128 * - x (the node’s current x-position)
129 * - y (the node’s current y-position)
130 * - vx (the node’s current x-velocity)
131 * - vy (the node’s current y-velocity)
132 *
133 * The position [x,y] and velocity [vx,vy] may be subsequently modified by forces and by the simulation.
134 * If either vx or vy is NaN, the velocity is initialized to [0,0]. If either x or y is NaN, the position is initialized in a phyllotaxis arrangement,
135 * so chosen to ensure a deterministic, uniform distribution.
136 *
137 * To fix a node in a given position, you may specify two additional properties:
138 * - fx (the node’s fixed x-position)
139 * - fy (the node’s fixed y-position)
140 *
141 * At the end of each tick, after the application of any forces, a node with a defined node.fx has node.x reset to this value and node.vx set to zero;
142 * likewise, a node with a defined node.fy has node.y reset to this value and node.vy set to zero.
143 * To unfix a node that was previously fixed, set node.fx and node.fy to null, or delete these properties.
144 *
145 * If the specified array of nodes is modified, such as when nodes are added to or removed from the simulation,
146 * this method must be called again with the new (or changed) array to notify the simulation and bound forces of the change;
147 * the simulation does not make a defensive copy of the specified array.
148 */
149 nodes(nodesData: NodeDatum[]): this;
150
151 /**
152 * Return the current alpha of the simulation, which defaults to 1.
153 *
154 * alpha is roughly analogous to temperature in simulated annealing.
155 * It decreases over time as the simulation “cools down”.
156 * When alpha reaches alphaMin, the simulation stops; see simulation.restart.
157 */
158 alpha(): number;
159 /**
160 * Set the current alpha to the specified number in the range [0,1] and return this simulation.
161 * The default is 1.
162 *
163 * alpha is roughly analogous to temperature in simulated annealing.
164 * It decreases over time as the simulation “cools down”.
165 * When alpha reaches alphaMin, the simulation stops; see simulation.restart.
166 *
167 * @param alpha Current alpha of simulation.
168 */
169 alpha(alpha: number): this;
170
171 /**
172 * Return the current minimum alpha value, which defaults to 0.001.
173 */
174 alphaMin(): number;
175 /**
176 * Set the minimum alpha to the specified number in the range [0,1] and return this simulation.
177 * The default is 0.001. The simulation’s internal timer stops when the current alpha is less than the minimum alpha.
178 * The default alpha decay rate of ~0.0228 corresponds to 300 iterations.
179 *
180 * @param min Minimum alpha of simulation.
181 */
182 alphaMin(min: number): this;
183
184 /**
185 * Return the current alpha decay rate, which defaults to 0.0228… = 1 - pow(0.001, 1 / 300) where 0.001 is the default minimum alpha.
186 */
187 alphaDecay(): number;
188 /**
189 * Set the alpha decay rate to the specified number in the range [0,1] and return this simulation.
190 * The default is 0.0228… = 1 - pow(0.001, 1 / 300) where 0.001 is the default minimum alpha.
191 *
192 * The alpha decay rate determines how quickly the current alpha interpolates towards the desired target alpha;
193 * since the default target alpha is zero, by default this controls how quickly the simulation cools.
194 * Higher decay rates cause the simulation to stabilize more quickly, but risk getting stuck in a local minimum;
195 * lower values cause the simulation to take longer to run, but typically converge on a better layout.
196 * To have the simulation run forever at the current alpha, set the decay rate to zero;
197 * alternatively, set a target alpha greater than the minimum alpha.
198 *
199 * @param decay Alpha decay rate.
200 */
201 alphaDecay(decay: number): this;
202
203 /**
204 * Returns the current target alpha value, which defaults to 0.
205 */
206 alphaTarget(): number;
207 /**
208 * Set the current target alpha to the specified number in the range [0,1] and return this simulation.
209 * The default is 0.
210 *
211 * @param target Alpha target value.
212 */
213 alphaTarget(target: number): this;
214
215 /**
216 * Return the current target alpha value, which defaults to 0.4.
217 */
218 velocityDecay(): number;
219 /**
220 * Set the velocity decay factor to the specified number in the range [0,1] and return this simulation.
221 * The default is 0.4.
222 *
223 * The decay factor is akin to atmospheric friction; after the application of any forces during a tick,
224 * each node’s velocity is multiplied by 1 - decay. As with lowering the alpha decay rate,
225 * less velocity decay may converge on a better solution, but risks numerical instabilities and oscillation.
226 *
227 * @param decay Velocity Decay.
228 */
229 velocityDecay(decay: number): this;
230
231 /**
232 * Return the force with the specified name, or undefined if there is no such force.
233 * (By default, new simulations have no forces.)
234 *
235 * Given that it is in general not known, what type of force has been registered under
236 * a specified name, use the generic to cast the result to the appropriate type, if known.
237 *
238 * @param name Name of the registered force.
239 */
240 // eslint-disable-next-line @definitelytyped/no-unnecessary-generics
241 force<F extends Force<NodeDatum, LinkDatum>>(name: string): F | undefined;
242 /**
243 * If force is specified, assigns the force for the specified name and returns this simulation.
244 * To remove the force with the given name, pass null as the force.
245 */
246 force(name: string, force: null | Force<NodeDatum, LinkDatum>): this;
247
248 /**
249 * Return the node closest to the position [x,y] with the given search radius.
250 * If radius is not specified, it defaults to infinity.
251 * If there is no node within the search area, returns undefined.
252 *
253 * @param x x-coordinate
254 * @param y y-coordinate
255 * @param radius Optional search radius. Defaults to infinity.
256 */
257 find(x: number, y: number, radius?: number): NodeDatum | undefined;
258
259 /**
260 * Returns this simulation’s current random source which defaults to a fixed-seed linear congruential generator.
261 * See also random.source.
262 */
263 randomSource(): () => number;
264 /**
265 * Sets the function used to generate random numbers; this should be a function that returns a number between 0 (inclusive) and 1 (exclusive).
266 *
267 * @param source The function used to generate random numbers.
268 */
269 randomSource(source: () => number): this;
270
271 /**
272 * Return the first currently-assigned listener matching the specified typenames, if any.
273 *
274 * @param typenames The typenames is a string containing one or more typename separated by whitespace. Each typename is a type,
275 * optionally followed by a period (.) and a name, such as "tick.foo" and "tick.bar"; the name allows multiple listeners to be registered for the same type.
276 * The type must be one of the following: "tick" (after each tick of the simulation’s internal timer) or
277 * "end" (after the simulation’s timer stops when alpha < alphaMin).
278 */
279 on(typenames: "tick" | "end" | string): ((this: Simulation<NodeDatum, LinkDatum>) => void) | undefined;
280 /**
281 * Sets the event listener for the specified typenames and returns this simulation.
282 * If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added.
283 * If listener is null, removes the current event listeners for the specified typenames, if any.
284 * When a specified event is dispatched, each listener will be invoked with the this context as the simulation.
285 */
286 on(typenames: "tick" | "end" | string, listener: null | ((this: this) => void)): this;
287}
288
289/**
290 * Create a new simulation with the specified array of nodes and no forces.
291 * If nodes is not specified, it defaults to the empty array.
292 * The simulator starts automatically; use simulation.on to listen for tick events as the simulation runs.
293 * If you wish to run the simulation manually instead, call simulation.stop, and then call simulation.tick as desired.
294 *
295 * Use this signature, when creating a simulation WITHOUT link force(s).
296 *
297 * The generic refers to the type of the data for a node.
298 *
299 * @param nodesData Optional array of nodes data, defaults to empty array.
300 */
301export function forceSimulation<NodeDatum extends SimulationNodeDatum>(
302 nodesData?: NodeDatum[],
303): Simulation<NodeDatum, undefined>;
304/**
305 * Create a new simulation with the specified array of nodes and no forces.
306 * If nodes is not specified, it defaults to the empty array.
307 * The simulator starts automatically; use simulation.on to listen for tick events as the simulation runs.
308 * If you wish to run the simulation manually instead, call simulation.stop, and then call simulation.tick as desired.
309 *
310 * Use this signature, when creating a simulation WITH link force(s).
311 *
312 * The first generic refers to the type of data for a node.
313 * The second generic refers to the type of data for a link.
314 *
315 * @param nodesData Optional array of nodes data, defaults to empty array.
316 */
317export function forceSimulation<
318 NodeDatum extends SimulationNodeDatum,
319 // eslint-disable-next-line @definitelytyped/no-unnecessary-generics
320 LinkDatum extends SimulationLinkDatum<NodeDatum>,
321>(nodesData?: NodeDatum[]): Simulation<NodeDatum, LinkDatum>;
322
323// ----------------------------------------------------------------------
324// Forces
325// ----------------------------------------------------------------------
326
327/**
328 * A force is simply a function that modifies nodespositions or velocities; in this context, a force can apply a classical physical force such as electrical charge or gravity,
329 * or it can resolve a geometric constraint, such as keeping nodes within a bounding box or keeping linked nodes a fixed distance apart.
330 *
331 * Forces typically read the nodes current position [x,y] and then add to (or subtract from) the nodes velocity [vx,vy].
332 * However, forces may alsopeek aheadto the anticipated next position of the node, [x + vx,y + vy]; this is necessary for resolving geometric constraints through iterative relaxation.
333 * Forces may also modify the position directly, which is sometimes useful to avoid adding energy to the simulation, such as when recentering the simulation in the viewport.
334 *
335 * Forces may optionally implement force.initialize to receive the simulations array of nodes.
336 */
337export interface Force<
338 NodeDatum extends SimulationNodeDatum,
339 LinkDatum extends SimulationLinkDatum<NodeDatum> | undefined,
340> {
341 /**
342 * Apply this force, optionally observing the specified alpha.
343 * Typically, the force is applied to the array of nodes previously passed to force.initialize,
344 * however, some forces may apply to a subset of nodes, or behave differently.
345 * For example, d3.forceLink applies to the source and target of each link.
346 */
347 (alpha: number): void;
348 /**
349 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
350 * and when the simulations nodes change via simulation.nodes.
351 *
352 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
353 */
354 initialize?(nodes: NodeDatum[], random: () => number): void;
355}
356
357// Centering ------------------------------------------------------------
358
359/**
360 * The centering force translates nodes uniformly so that the mean position of all nodes
361 * (the center of mass if all nodes have equal weight) is at the given position [x,y].
362 * This force modifies the positions of nodes on each application; it does not modify velocities,
363 * as doing so would typically cause the nodes to overshoot and oscillate around the desired center.
364 * This force helps keeps nodes in the center of the viewport, and unlike the positioning force,
365 * it does not distort their relative positions.
366 *
367 * The generic refers to the type of data for a node.
368 */
369export interface ForceCenter<NodeDatum extends SimulationNodeDatum> extends Force<NodeDatum, any> {
370 /**
371 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
372 * and when the simulations nodes change via simulation.nodes.
373 *
374 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
375 */
376 initialize(nodes: NodeDatum[], random: () => number): void;
377
378 /**
379 * Return the current x-coordinate of the centering position, which defaults to zero.
380 */
381 x(): number;
382 /**
383 * Set the x-coordinate of the centering position.
384 *
385 * @param x x-coordinate.
386 */
387 x(x: number): this;
388
389 /**
390 * Return the current y-coordinate of the centering position, which defaults to zero.
391 */
392 y(): number;
393 /**
394 * Set the y-coordinate of the centering position.
395 *
396 * @param y y-coordinate.
397 */
398 y(y: number): this;
399
400 /**
401 * Returns the forces current strength, which defaults to 1.
402 */
403 strength(): number;
404
405 /**
406 * Sets the centering forces strength.
407 * A reduced strength of e.g. 0.05 softens the movements on interactive graphs in which new nodes enter or exit the graph.
408 * @param strength The centering force's strength.
409 */
410 strength(strength: number): this;
411}
412
413/**
414 * Create a new centering force with the specified x- and y- coordinates.
415 * If x and y are not specified, they default to [0,0].
416 *
417 * The centering force translates nodes uniformly so that the mean position of all nodes
418 * (the center of mass if all nodes have equal weight) is at the given position [x,y].
419 * This force modifies the positions of nodes on each application; it does not modify velocities,
420 * as doing so would typically cause the nodes to overshoot and oscillate around the desired center.
421 * This force helps keeps nodes in the center of the viewport, and unlike the positioning force,
422 * it does not distort their relative positions.
423 *
424 * The generic refers to the type of data for a node.
425 *
426 * @param x An optional x-coordinate for the centering position, defaults to 0.
427 * @param y An optional y-coordinate for the centering position, defaults to 0.
428 */
429// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
430export function forceCenter<NodeDatum extends SimulationNodeDatum>(x?: number, y?: number): ForceCenter<NodeDatum>;
431
432// Collision ------------------------------------------------------------
433
434/**
435 * The collision force treats nodes as circles with a given radius, rather than points, and prevents nodes from overlapping.
436 * More formally, two nodes a and b are separated so that the distance between a and b is at least radius(a) + radius(b).
437 * To reduce jitter, this is by default asoftconstraint with a configurable strength and iteration count.
438 *
439 * The generic refers to the type of data for a node.
440 */
441export interface ForceCollide<NodeDatum extends SimulationNodeDatum> extends Force<NodeDatum, any> {
442 /**
443 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
444 * and when the simulations nodes change via simulation.nodes.
445 *
446 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
447 */
448 initialize(nodes: NodeDatum[], random: () => number): void;
449
450 /**
451 * Returns the current radius accessor function.
452 */
453 radius(): (node: NodeDatum, i: number, nodes: NodeDatum[]) => number;
454 /**
455 * Sets the radius accessor to the specified number or function, re-evaluates the radius accessor for each node, and returns this force.
456 * The radius accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
457 * The resulting number is then stored internally, such that the radius of each node is only recomputed when the
458 * force is initialized or when this method is called with a new radius, and not on every application of the force.
459 */
460 radius(radius: number | ((node: NodeDatum, i: number, nodes: NodeDatum[]) => number)): this;
461
462 /**
463 * Return the current strength, which defaults to 1.
464 */
465 strength(): number;
466 /**
467 * Set the force strength to the specified number in the range [0,1] and return this force.
468 * The default strength is 0.7.
469 *
470 * Overlapping nodes are resolved through iterative relaxation.
471 * For each node, the other nodes that are anticipated to overlap at the next tick (using the anticipated positions [x + vx,y + vy]) are determined;
472 * the nodes velocity is then modified to push the node out of each overlapping node.
473 * The change in velocity is dampened by the forces strength such that the resolution of simultaneous overlaps can be blended together to find a stable solution.
474 *
475 * @param strength Strength.
476 */
477 strength(strength: number): this;
478
479 /**
480 * Return the current iteration count which defaults to 1.
481 */
482 iterations(): number;
483 /**
484 * Sets the number of iterations per application to the specified number and return this force.
485 *
486 * Increasing the number of iterations greatly increases the rigidity of the constraint and avoids partial overlap of nodes,
487 * but also increases the runtime cost to evaluate the force.
488 *
489 * @param iterations Number of iterations.
490 */
491 iterations(iterations: number): this;
492}
493
494/**
495 * Creates a new circle collision force with the specified radius.
496 * If radius is not specified, it defaults to the constant one for all nodes.
497 */
498export function forceCollide<NodeDatum extends SimulationNodeDatum>(
499 radius?: number | ((node: NodeDatum, i: number, nodes: NodeDatum[]) => number),
500): ForceCollide<NodeDatum>;
501
502// Link ----------------------------------------------------------------
503
504/**
505 * The link force pushes linked nodes together or apart according to the desired link distance.
506 * The strength of the force is proportional to the difference between the linked nodesdistance and the target distance, similar to a spring force.
507 *
508 * The first generic refers to the type of data for a node.
509 * The second generic refers to the type of data for a link.
510 */
511export interface ForceLink<NodeDatum extends SimulationNodeDatum, LinkDatum extends SimulationLinkDatum<NodeDatum>>
512 extends Force<NodeDatum, LinkDatum>
513{
514 /**
515 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
516 * and when the simulations nodes change via simulation.nodes.
517 *
518 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
519 */
520 initialize(nodes: NodeDatum[], random: () => number): void;
521
522 /**
523 * Return the current array of links, which defaults to the empty array.
524 */
525 links(): LinkDatum[];
526 /**
527 * Set the array of links associated with this force, recompute the distance and strength parameters for each link, and return this force.
528 *
529 * Each link is an object with the following properties:
530 * * source - the links source node; see simulation.nodes
531 * * target - the links target node; see simulation.nodes
532 * * index - the zero-based index into links, assigned by this method
533 *
534 * For convenience, a links source and target properties may be initialized using numeric or string identifiers rather than object references; see link.id.
535 * When the link force is initialized (or re-initialized, as when the nodes or links change), any link.source or link.target property which is not an object
536 * is replaced by an object reference to the corresponding node with the given identifier.
537 * If the specified array of links is modified, such as when links are added to or removed from the simulation,
538 * this method must be called again with the new (or changed) array to notify the force of the change;
539 * the force does not make a defensive copy of the specified array.
540 *
541 * @param links An array of link data.
542 */
543 links(links: LinkDatum[]): this;
544
545 /**
546 * Return the current node id accessor, which defaults to the numeric node.index.
547 */
548 id(): (node: NodeDatum, i: number, nodesData: NodeDatum[]) => string | number;
549 /**
550 * Set the node id accessor to the specified function and return this force.
551 *
552 * The default id accessor allows each link’s source and target to be specified as a zero-based index
553 * into the nodes array.
554 *
555 * The id accessor is invoked for each node whenever the force is initialized,
556 * as when the nodes or links change, being passed the node, the zero-based index of the node in the node array, and the node array.
557 *
558 * @param id A node id accessor function which is invoked for each node in the simulation,
559 * being passed the node, the zero-based index of the node in the node array, and the node array. It returns a string or number to represent the node id which can be used
560 * for matching link source and link target strings during the ForceLink initialization.
561 */
562 id(id: (node: NodeDatum, i: number, nodesData: NodeDatum[]) => string | number): this;
563
564 /**
565 * Return the current distance accessor, which defaults to implying a default distance of 30.
566 */
567 distance(): (link: LinkDatum, i: number, links: LinkDatum[]) => number;
568 /**
569 * Sets the distance accessor to the specified number or function, re-evaluates the distance accessor for each link, and returns this force.
570 * The distance accessor is invoked for each link, being passed the link and its zero-based index.
571 * The resulting number is then stored internally, such that the distance of each link is only recomputed when the
572 * force is initialized or when this method is called with a new distance, and not on every application of the force.
573 */
574 distance(distance: number | ((link: LinkDatum, i: number, links: LinkDatum[]) => number)): this;
575
576 /**
577 * Return the current strength accessor.
578 * For details regarding the default behavior see: {@link https://github.com/d3/d3-force#link_strength}
579 */
580 strength(): (link: LinkDatum, i: number, links: LinkDatum[]) => number;
581 /**
582 * Sets the strength accessor to the specified number or function, re-evaluates the strength accessor for each link, and returns this force.
583 * The strength accessor is invoked for each link, being passed the link and its zero-based index.
584 * The resulting number is then stored internally, such that the strength of each link is only recomputed when the
585 * force is initialized or when this method is called with a new strength, and not on every application of the force.
586 */
587 strength(strength: number | ((link: LinkDatum, i: number, links: LinkDatum[]) => number)): this;
588
589 /**
590 * Return the current iteration count which defaults to 1.
591 */
592 iterations(): number;
593 /**
594 * Sets the number of iterations per application to the specified number and return this force.
595 *
596 * Increasing the number of iterations greatly increases the rigidity of the constraint and is useful for complex structures such as lattices,
597 * but also increases the runtime cost to evaluate the force.
598 *
599 * @param iterations Number of iterations.
600 */
601 iterations(iterations: number): this;
602}
603
604/**
605 * Creates a new link force with the specified links and default parameters.
606 * If links is not specified, it defaults to the empty array.
607 */
608export function forceLink<NodeDatum extends SimulationNodeDatum, LinksDatum extends SimulationLinkDatum<NodeDatum>>(
609 links?: LinksDatum[],
610): ForceLink<NodeDatum, LinksDatum>;
611
612// Many Body ----------------------------------------------------------------
613
614/**
615 * The many-body (or n-body) force applies mutually amongst all nodes. It can be used to simulate gravity (attraction) if the strength is positive,
616 * or electrostatic charge (repulsion) if the strength is negative. This implementation uses quadtrees and the BarnesHut approximation to greatly
617 * improve performance; the accuracy can be customized using the theta parameter.
618 *
619 * Unlike links, which only affect two linked nodes, the charge force is global: every node affects every other node, even if they are on disconnected subgraphs.
620 *
621 * The generic refers to the type of data for a node.
622 */
623export interface ForceManyBody<NodeDatum extends SimulationNodeDatum> extends Force<NodeDatum, any> {
624 /**
625 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
626 * and when the simulations nodes change via simulation.nodes.
627 *
628 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
629 */
630 initialize(nodes: NodeDatum[], random: () => number): void;
631
632 /**
633 * Return the current strength accessor.
634 *
635 * For details regarding the default behavior see: {@link https://github.com/d3/d3-force#manyBody_strength}
636 */
637 strength(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
638 /**
639 * sets the strength accessor to the specified number or function, re-evaluates the strength accessor for each node, and returns this force.
640 * A positive value causes nodes to attract each other, similar to gravity, while a negative value causes nodes to repel each other, similar to electrostatic charge.
641 * The strength accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
642 * The resulting number is then stored internally, such that the strength of each node is only recomputed when the
643 * force is initialized or when this method is called with a new strength, and not on every application of the force.
644 */
645 strength(strength: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
646
647 /**
648 * Return the current value of the BarnesHut approximation criterion , which defaults to 0.9
649 */
650 theta(): number;
651 /**
652 * Set the BarnesHut approximation criterion to the specified number and returns this force.
653 *
654 * To accelerate computation, this force implements the BarnesHut approximation which takes O(n log n) per application
655 * where n is the number of nodes. For each application, a quadtree stores the current node positions;
656 * then for each node, the combined force of all other nodes on the given node is computed.
657 * For a cluster of nodes that is far away, the charge force can be approximated by treating the cluster as a single, larger node.
658 * The theta parameter determines the accuracy of the approximation:
659 * if the ratio w / l of the width w of the quadtree cell to the distance l from the node to the cells center of mass is less than theta,
660 * all nodes in the given cell are treated as a single node rather than individually.
661 *
662 * The default value is 0.9.
663 *
664 * @param theta Value for the theta parameter.
665 */
666 theta(theta: number): this;
667
668 /**
669 * Returns the current minimum distance over which this force is considered, which defaults to 1.
670 */
671 distanceMin(): number;
672 /**
673 * Sets the minimum distance between nodes over which this force is considered.
674 *
675 * A minimum distance establishes an upper bound on the strength of the force between two nearby nodes, avoiding instability.
676 * In particular, it avoids an infinitely-strong force if two nodes are exactly coincident; in this case, the direction of the force is random.
677 *
678 * The default value is 1.
679 *
680 * @param distance The minimum distance between nodes over which this force is considered.
681 */
682 distanceMin(distance: number): this;
683
684 /**
685 * Returns the current maximum distance over which this force is considered, which defaults to infinity.
686 */
687 distanceMax(): number;
688 /**
689 * Sets the maximum distance between nodes over which this force is considered.
690 *
691 * Specifying a finite maximum distance improves performance and produces a more localized layout.
692 *
693 * The default value is infinity.
694 *
695 * @param distance The maximum distance between nodes over which this force is considered.
696 */
697 distanceMax(distance: number): this;
698}
699
700/**
701 * Creates a new many-body force with the default parameters.
702 *
703 * The many-body (or n-body) force applies mutually amongst all nodes. It can be used to simulate gravity (attraction) if the strength is positive,
704 * or electrostatic charge (repulsion) if the strength is negative. This implementation uses quadtrees and the BarnesHut approximation to greatly
705 * improve performance; the accuracy can be customized using the theta parameter.
706 *
707 * Unlike links, which only affect two linked nodes, the charge force is global: every node affects every other node, even if they are on disconnected subgraphs.
708 *
709 * The generic refers to the type of data for a node.
710 */
711// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
712export function forceManyBody<NodeDatum extends SimulationNodeDatum>(): ForceManyBody<NodeDatum>;
713
714// Positioning ----------------------------------------------------------------
715
716/**
717 * The x-positioning force pushes nodes towards a desired position along the given dimension with a configurable strength.
718 * The strength of the force is proportional to the one-dimensional distance between the nodes position and the target position.
719 * While this force can be used to position individual nodes, it is intended primarily for global forces that apply to all (or most) nodes.
720 *
721 * The generic refers to the type of data for a node.
722 */
723export interface ForceX<NodeDatum extends SimulationNodeDatum> extends Force<NodeDatum, any> {
724 /**
725 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
726 * and when the simulations nodes change via simulation.nodes.
727 *
728 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
729 */
730 initialize(nodes: NodeDatum[], random: () => number): void;
731
732 /**
733 * Returns the current strength accessor, which defaults to a constant strength for all nodes of 0.1.
734 */
735 strength(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
736 /**
737 * Sets the strength accessor to the specified number or function, re-evaluates the strength accessor for each node, and returns this force.
738 * The strength determines how much to increment the node’s x-velocity: (x - node.x) × strength.
739 * For example, a value of 0.1 indicates that the node should move a tenth of the way from its current x-position to the target x-position with each application.
740 * Higher values moves nodes more quickly to the target position, often at the expense of other forces or constraints.
741 * A value outside the range [0,1] is not recommended.
742 * The strength accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
743 * The resulting number is then stored internally, such that the strength of each node is only recomputed when the
744 * force is initialized or when this method is called with a new strength, and not on every application of the force.
745 */
746 strength(strength: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
747
748 /**
749 * Return the current x-accessor, which defaults to a function returning 0 for all nodes.
750 */
751 x(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
752 /**
753 * Sets the x-coordinate accessor to the specified number or function, re-evaluates the x-accessor for each node, and returns this force.
754 * The x-accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
755 * The resulting number is then stored internally, such that the target x-coordinate of each node is only recomputed
756 * when the force is initialized or when this method is called with a new x, and not on every application of the force.
757 */
758 x(x: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
759}
760
761/**
762 * Creates a new positioning force along the x-axis towards the given position x.
763 * If x is not specified, it defaults to 0.
764 */
765export function forceX<NodeDatum extends SimulationNodeDatum>(
766 x?: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number),
767): ForceX<NodeDatum>;
768
769/**
770 * The y-positioning force pushes nodes towards a desired position along the given dimension with a configurable strength.
771 * The strength of the force is proportional to the one-dimensional distance between the nodes position and the target position.
772 * While this force can be used to position individual nodes, it is intended primarily for global forces that apply to all (or most) nodes.
773 *
774 * The generic refers to the type of data for a node.
775 */
776export interface ForceY<NodeDatum extends SimulationNodeDatum> extends Force<NodeDatum, any> {
777 /**
778 * Supplies the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
779 * and when the simulations nodes change via simulation.nodes.
780 *
781 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
782 */
783 initialize(nodes: NodeDatum[], random: () => number): void;
784
785 /**
786 * Returns the current strength accessor, which defaults to a constant strength for all nodes of 0.1.
787 */
788 strength(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
789 /**
790 * Sets the strength accessor to the specified number or function, re-evaluates the strength accessor for each node, and returns this force.
791 * The strength determines how much to increment the node’s y-velocity: (y - node.y) × strength.
792 * For example, a value of 0.1 indicates that the node should move a tenth of the way from its current y-position to the target y-position with each application.
793 * Higher values moves nodes more quickly to the target position, often at the expense of other forces or constraints.
794 * A value outside the range [0,1] is not recommended.
795 * The strength accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
796 * The resulting number is then stored internally, such that the strength of each node is only recomputed when the
797 * force is initialized or when this method is called with a new strength, and not on every application of the force.
798 */
799 strength(strength: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
800
801 /**
802 * Return the current y-accessor, which defaults to a function returning 0 for all nodes.
803 */
804 y(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
805 /**
806 * Sets the y-coordinate accessor to the specified number or function, re-evaluates the y-accessor for each node, and returns this force.
807 * The y-accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
808 * The resulting number is then stored internally, such that the target y-coordinate of each node is only recomputed
809 * when the force is initialized or when this method is called with a new y, and not on every application of the force.
810 */
811 y(y: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
812}
813
814/**
815 * Creates a new positioning force along the y-axis towards the given position y.
816 * If y is not specified, it defaults to 0.
817 */
818export function forceY<NodeDatum extends SimulationNodeDatum>(
819 y?: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number),
820): ForceY<NodeDatum>;
821
822/**
823 * The radial force is similar to the x- and y-positioning forces, except it pushes nodes towards the closest point on a given circle.
824 * The circle is of the specified radius centered atx,y⟩. If x and y are not specified, they default to ⟨0,0⟩.
825 * The strength of the force is proportional to the one-dimensional distance between the nodes position and the target position.
826 * While this force can be used to position individual nodes, it is intended primarily for global forces that apply to all (or most) nodes.
827 *
828 * The generic refers to the type of data for a node.
829 */
830export interface ForceRadial<NodeDatum extends SimulationNodeDatum> extends Force<NodeDatum, any> {
831 /**
832 * Assigns the array of nodes and random source to this force. This method is called when a force is bound to a simulation via simulation.force
833 * and when the simulations nodes change via simulation.nodes.
834 *
835 * A force may perform necessary work during initialization, such as evaluating per-node parameters, to avoid repeatedly performing work during each application of the force.
836 */
837 initialize(nodes: NodeDatum[], random: () => number): void;
838
839 /**
840 * Returns the current strength accessor, which defaults to a constant strength for all nodes of 0.1.
841 */
842 strength(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
843 /**
844 * Sets the strength accessor to the specified number or function, re-evaluates the strength accessor for each node, and returns this force.
845 * The strength determines how much to increment the node’s x- and y-velocity.
846 * For example, a value of 0.1 indicates that the node should move a tenth of the way from its current position to the closest point on the circle with each application.
847 * Higher values moves nodes more quickly to the target position, often at the expense of other forces or constraints.
848 * A value outside the range [0,1] is not recommended.
849 * The strength accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
850 * The resulting number is then stored internally, such that the strength of each node is only recomputed when the
851 * force is initialized or when this method is called with a new strength, and not on every application of the force.
852 */
853 strength(strength: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
854
855 /**
856 * Return the current radius accessor for the circle.
857 */
858 radius(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
859 /**
860 * Sets the circle radius to the specified number or function, re-evaluates the radius accessor for each node, and returns this force.
861 * The radius accessor is invoked for each node in the simulation, being passed the node and its zero-based index.
862 * The resulting number is then stored internally, such that the target radius of each node is only recomputed when
863 * the force is initialized or when this method is called with a new radius, and not on every application of the force.
864 */
865 radius(radius: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
866
867 /**
868 * Return the current x-accessor for the circle center, which defaults to a function returning 0 for all nodes.
869 */
870 x(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
871 /**
872 * Sets the x-coordinate of the circle center to the specified number and returns this force.
873 */
874 x(x: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
875
876 /**
877 * Return the current y-accessor for the circle center, which defaults to a function returning 0 for all nodes.
878 */
879 y(): (d: NodeDatum, i: number, data: NodeDatum[]) => number;
880 /**
881 * Sets the y-coordinate of the circle center to the specified number and returns this force.
882 */
883 y(y: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number)): this;
884}
885
886/**
887 * Create a new radial positioning force towards a circle of the specified radius centered atx,y⟩.
888 * If x and y are not specified, they default to ⟨0,0⟩.
889 *
890 * The strength of the force is proportional to the one-dimensional distance between the nodes position and the target position.
891 * While this force can be used to position individual nodes, it is intended primarily for global forces that apply to all (or most) nodes.
892 *
893 * The generic refers to the type of data for a node.
894 */
895export function forceRadial<NodeDatum extends SimulationNodeDatum>(
896 radius: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number),
897 x?: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number),
898 y?: number | ((d: NodeDatum, i: number, data: NodeDatum[]) => number),
899): ForceRadial<NodeDatum>;
900
\No newline at end of file