Public
Edited
Jul 5, 2023
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
redraw()
Insert cell
rings
Insert cell
/**
* Perform shift animation,
* the sequence is the name of the rings in the loop.
*
* The plot will be drawn in the div with the id of '#' + divId
*/
function* shiftAnimation(sequence, divId = "div-1") {
var { length } = sequence,
data = [],
thetaScales = [],
radiusScales = [],
t = 0,
dom = document.getElementById(divId);

for (let i = 0; i < length; ++i) {
data.push(rings.filter((d) => d.name === sequence[i])[0]);
}

console.log("data", data);

for (let i = 0; i < length - 1; ++i) {
data[i].name = sequence[i + 1];

thetaScales.push(
d3
.scaleLinear()
.domain([0, 1])
.range([data[i].theta, data[i + 1].theta])
);

radiusScales.push(
d3
.scaleLinear()
.domain([0, 1])
.range([data[i].radius, data[i + 1].radius])
);
}

while (t < 1) {
t += 0.01;

for (let i = 0; i < length - 1; ++i) {
data[i].theta = thetaScales[i](t);
data[i].radius = radiusScales[i](t);
}
dom.innerHTML = "";
yield dom.appendChild(redraw());
}
}
Insert cell
function* exchange(name1, name2) {
const a = rings.filter((d) => d.name === name1)[0],
b = rings.filter((d) => d.name === name2)[0],
{ theta: theta1, radius: radius1 } = a,
{ theta: theta2, radius: radius2 } = b,
thetaScale = d3.scaleLinear().domain([0, 1]).range([theta1, theta2]),
radiusScale = d3.scaleLinear().domain([0, 1]).range([radius1, radius2]),
dom = document.getElementById("div-1");

a.name = name2;
b.name = name1;

var t = 0;

while (t < 1) {
t += 0.01;

a.theta = thetaScale(t);
b.theta = thetaScale(1 - t);

a.radius = radiusScale(t);
b.radius = radiusScale(1 - t);

dom.innerHTML = "";
yield dom.appendChild(redraw());

// yield redraw();
}
}
Insert cell
redraw = () => {
computeRings(rings);

return Plot.plot({
aspectRatio: 1.0,
width: 600,
grid: true,

x: { nice: true },
y: { nice: true },
r: { domain: [1, 1.5], range: [150, 180] },
marks: [
Plot.dot(rings, {
x: "x",
y: "y",
r: "radius",
fill: undefined,
stroke: (d) => d.color,
strokeWidth: 10
}),
Plot.ruleX([-5, 5]),
Plot.ruleY([-5, 5])
]
});
}
Insert cell
computeRings = (rings) => {
rings.map((ring) => {
const x = constant.r0 * constant.cos(ring.theta),
y = constant.r0 * constant.sin(ring.theta);
Object.assign(ring, { x, y });
});
}
Insert cell
rings = {
refreshEverything;
const rings = [
{
name: "xAxis-1",
radius: constant.r1,
theta: 0,
color: colorScheme[0] + "80"
},
{
name: "xAxis-2",
radius: constant.r2,
theta: 0,
color: colorScheme[0] + "ff"
},
{
name: "yAxis-1",
radius: constant.r1,
theta: 120,
color: colorScheme[1] + "80"
},
{
name: "yAxis-2",
radius: constant.r2,
theta: 120,
color: colorScheme[1] + "ff"
},
{
name: "zAxis-1",
radius: constant.r1,
theta: 240,
color: colorScheme[2] + "80"
},
{
name: "zAxis-2",
radius: constant.r2,
theta: 240,
color: colorScheme[2] + "ff"
}
];

computeRings(rings);

return rings;
}
Insert cell
colorScheme = d3.schemeTableau10
Insert cell
constant = {
const r0 = 1.8,
r1 = 1,
r2 = 1.5,
pi = Math.PI,
cos = (angle) => Math.cos((angle / 180) * pi),
sin = (angle) => Math.sin((angle / 180) * pi),
__ = 0;

return { r0, r1, r2, pi, cos, sin };
}
Insert cell
d3 = require("d3")
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