Published
Edited
Nov 10, 2019
1 fork
Importers
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
forceAngular = function(angle, x, y) {
var nodes,
strength = constant(0.1),
strengths,
angles;

if (typeof angle !== "function") angle = constant(+angle);
if (x == null) x = 0;
if (y == null) y = 0;

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,
a = Math.atan2(dy, dx),
r = Math.hypot(dy, dx),
diff = angles[i] - a,
k = r * Math.sin(diff) * (strengths[i] * alpha);

// the factor below augments the "unease" for points that are opposite the correct direction:
// in that case, though sin(diff) is small, tan(diff/2) is very high
k *= Math.hypot(1, Math.tan(diff / 2));

node.vx += -k * Math.sin(a);
node.vy += k * Math.cos(a);
}
}

function initialize() {
if (!nodes) return;
var i,
n = nodes.length;
strengths = new Array(n);
angles = new Array(n);
for (i = 0; i < n; ++i) {
angles[i] = +angle(nodes[i], i, nodes) * (Math.PI / 180);
strengths[i] = isNaN(angles[i]) ? 0 : +strength(nodes[i], i, nodes);
}
}

force.initialize = function(_) {
(nodes = _), initialize();
};

force.strength = function(_) {
return arguments.length
? ((strength = typeof _ === "function" ? _ : constant(+_)),
initialize(),
force)
: strength;
};

force.angle = function(_) {
return arguments.length
? ((angle = typeof _ === "function" ? _ : constant(+_)),
initialize(),
force)
: angle;
};

force.x = function(_) {
return arguments.length ? ((x = +_), force) : x;
};

force.y = function(_) {
return arguments.length ? ((y = +_), force) : y;
};

return force;
}
Insert cell
Insert cell
nodes = {
replay;

const angle = d3.randomUniform(0, 360),
radius = d3.randomUniform(1, 10);

return Array.from({ length: 400 }, () => ({
angle: angle(),
r: radius()
}));
}
Insert cell
constant = x => _ => x
Insert cell
height = Math.min(500, width * 0.7)
Insert cell
d3 = require("d3@5")
Insert cell
import { slider } from "@jashkenas/inputs"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more