Skip to content

Commit

Permalink
add mutation warnings (#3755)
Browse files Browse the repository at this point in the history
* docs: warn about impure fn in `simulation.md`

* mutation warnings

---------

Co-authored-by: Hamir Mahal <hamirmahal@gmail.com>
  • Loading branch information
mbostock and hamirmahal committed Aug 21, 2023
1 parent fa4553c commit af562ed
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
10 changes: 9 additions & 1 deletion docs/d3-force/link.md
Expand Up @@ -14,6 +14,10 @@ The link force pushes linked nodes together or apart according to the desired [l

[Source](https://github.com/d3/d3-force/blob/main/src/link.js) · Creates a new link force with the specified *links* and default parameters. If *links* is not specified, it defaults to the empty array.

:::warning
This function is impure; it may mutate the passed-in *links*. See [*link*.links](#link_links).
:::

```js
const link = d3.forceLink(links).id((d) => d.id);
```
Expand All @@ -28,7 +32,11 @@ Each link is an object with the following properties:
* `target` - the link’s target node; see [*simulation*.nodes](./simulation.md#simulation_nodes)
* `index` - the zero-based index into *links*, assigned by this method

For convenience, a link’s source and target properties may be initialized using numeric or string identifiers rather than object references; see [*link*.id](#link_id). When the link force is [initialized](./simulation.md#force_initialize) (or re-initialized, as when the nodes or links change), any *link*.source or *link*.target property which is *not* an object is replaced by an object reference to the corresponding *node* with the given identifier.
For convenience, a link’s source and target properties may be initialized using numeric or string identifiers rather than object references; see [*link*.id](#link_id).

:::warning
This function is impure; it may mutate the passed-in *links* when the link force is [initialized](./simulation.md#force_initialize) (or re-initialized, as when the nodes or links change). Any *link*.source or *link*.target property which is not an object is replaced by an object reference to the corresponding *node* with the given identifier.
:::

If the specified array of *links* is modified, such as when links are added to or removed from the simulation, this method must be called again with the new (or changed) array to notify the force of the change; the force does not make a defensive copy of the specified array.

Expand Down
12 changes: 11 additions & 1 deletion docs/d3-force/simulation.md
Expand Up @@ -4,12 +4,18 @@ A force simulation implements a [velocity Verlet](https://en.wikipedia.org/wiki/

## forceSimulation(*nodes*) {#forceSimulation}

[Source](https://github.com/d3/d3-force/blob/main/src/simulation.js) · Creates a new simulation with the specified array of [*nodes*](#simulation_nodes) and no [forces](#simulation_force). If *nodes* is not specified, it defaults to the empty array. The simulator [starts](#simulation_restart) automatically; use [*simulation*.on](#simulation_on) to listen for tick events as the simulation runs. If you wish to run the simulation manually instead, call [*simulation*.stop](#simulation_stop), and then call [*simulation*.tick](#simulation_tick) as desired.
[Source](https://github.com/d3/d3-force/blob/main/src/simulation.js) · Creates a new simulation with the specified array of [*nodes*](#simulation_nodes) and no [forces](#simulation_force). If *nodes* is not specified, it defaults to the empty array.

:::warning
This function is impure; it mutates the passed-in *nodes*. See [*simulation*.nodes](#simulation_nodes).
:::

```js
const simulation = d3.forceSimulation(nodes);
```

The simulator [starts](#simulation_restart) automatically; use [*simulation*.on](#simulation_on) to listen for tick events as the simulation runs. If you wish to run the simulation manually instead, call [*simulation*.stop](#simulation_stop), and then call [*simulation*.tick](#simulation_tick) as desired.

## *simulation*.restart() {#simulation_restart}

[Source](https://github.com/d3/d3-force/blob/main/src/simulation.js) · Restarts the simulation’s internal timer and returns the simulation. In conjunction with [*simulation*.alphaTarget](#simulation_alphaTarget) or [*simulation*.alpha](#simulation_alpha), this method can be used to “reheat” the simulation during interaction, such as when dragging a node, or to resume the simulation after temporarily pausing it with [*simulation*.stop](#simulation_stop).
Expand All @@ -32,6 +38,10 @@ This method can be used in conjunction with [*simulation*.stop](#simulation_stop

[Source](https://github.com/d3/d3-force/blob/main/src/simulation.js) · If *nodes* is specified, sets the simulation’s nodes to the specified array of objects, initializing their positions and velocities if necessary, and then [re-initializes](#force_initialize) any bound [forces](#simulation_force); returns the simulation. If *nodes* is not specified, returns the simulation’s array of nodes as specified to the [constructor](#forceSimulation).

:::warning
This function is impure; it mutates the passed-in *nodes* to assign the index *node*.index, the position *node*.x & *node*.y, and the velocity *node*.vx & *node*.vy. The position and velocity are further updated as the simulation runs by [*simulation*.tick](#simulation_tick).
:::

Each *node* must be an object. The following properties are assigned by the simulation:

* `index` - the node’s zero-based index into *nodes*
Expand Down

0 comments on commit af562ed

Please sign in to comment.