diff --git a/README.md b/README.md
index ffcc00a..04a57f2 100644
--- a/README.md
+++ b/README.md
@@ -457,8 +457,25 @@ The *radius* accessor is invoked for each [node](#simulation_nodes) in the simul
# radial.x([x]) [<>](https://github.com/d3/d3-force/blob/master/src/radial.js "Source")
-If *x* is specified, sets the *x*-coordinate of the circle center to the specified number and returns this force. If *x* is not specified, returns the current *x*-coordinate of the center, which defaults to zero.
+If *x* is specified, sets the *x*-coordinate accessor to the specified number or function, re-evaluates the *x*-accessor for each node, and returns this force. If *x* is not specified, returns the current *x*-accessor, which defaults to:
+
+```js
+function x() {
+ return 0;
+}
+```
+
+The *x*-accessor is invoked for each [node](#simulation_nodes) in the simulation, being passed the *node* and its zero-based *index*. The resulting number is then stored internally, such that the target *x*-coordinate of each node is only recomputed when the force is initialized or when this method is called with a new *x*, and not on every application of the force.
# radial.y([y]) [<>](https://github.com/d3/d3-force/blob/master/src/radial.js "Source")
-If *y* is specified, sets the *y*-coordinate of the circle center to the specified number and returns this force. If *y* is not specified, returns the current *y*-coordinate of the center, which defaults to zero.
+If *y* is specified, sets the *y*-coordinate accessor to the specified number or function, re-evaluates the *y*-accessor for each node, and returns this force. If *y* is not specified, returns the current *y*-accessor, which defaults to:
+
+```js
+function y() {
+ return 0;
+}
+```
+
+The *y*-accessor is invoked for each [node](#simulation_nodes) in the simulation, being passed the *node* and its zero-based *index*. The resulting number is then stored internally, such that the target *y*-coordinate of each node is only recomputed when the force is initialized or when this method is called with a new *y*, and not on every application of the force.
+
diff --git a/src/radial.js b/src/radial.js
index 609516b..dbf2661 100644
--- a/src/radial.js
+++ b/src/radial.js
@@ -4,17 +4,19 @@ export default function(radius, x, y) {
var nodes,
strength = constant(0.1),
strengths,
- radiuses;
+ radiuses,
+ xs,
+ ys;
if (typeof radius !== "function") radius = constant(+radius);
- if (x == null) x = 0;
- if (y == null) y = 0;
+ if (typeof x !== "function") x = constant(x == null ? 0 : +x);
+ if (typeof y !== "function") y = constant(y == null ? 0 : +y);
function force(alpha) {
for (var i = 0, n = nodes.length; i < n; ++i) {
var node = nodes[i],
- dx = node.x - x || 1e-6,
- dy = node.y - y || 1e-6,
+ dx = node.x - xs[i] || 1e-6,
+ dy = node.y - ys[i] || 1e-6,
r = Math.sqrt(dx * dx + dy * dy),
k = (radiuses[i] - r) * strengths[i] * alpha / r;
node.vx += dx * k;
@@ -27,8 +29,12 @@ export default function(radius, x, y) {
var i, n = nodes.length;
strengths = new Array(n);
radiuses = new Array(n);
+ xs = new Array(n);
+ ys = new Array(n);
for (i = 0; i < n; ++i) {
radiuses[i] = +radius(nodes[i], i, nodes);
+ xs[i] = +x(nodes[i], i, nodes);
+ ys[i] = +y(nodes[i], i, nodes);
strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);
}
}
@@ -46,11 +52,11 @@ export default function(radius, x, y) {
};
force.x = function(_) {
- return arguments.length ? (x = +_, force) : x;
+ return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), initialize(), force) : x;
};
force.y = function(_) {
- return arguments.length ? (y = +_, force) : y;
+ return arguments.length ? (y = typeof _ === "function" ? _ : constant(+_), initialize(), force) : y;
};
return force;