Public
Edited
Aug 20, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const htmlContent = html`
<style type="text/css">
.circle {
opacity: 0.7;
fill: steelblue;
}
</style>
<div><svg width="800" height="100"></svg></div>
<button>Update data</button>
`
const container = d3.select(htmlContent);
const svg = container.select("svg");
const button = container.select("button");
update();
button.on("click", update);
function update() {
let data = [];
for (let i = 0; i < 5; ++i) {
data.push(Math.random() * 800);
}
svg.selectAll("circle")
.data(data)
.join("circle")
.attr("cy", 50)
.attr("r", 40)
.attr("class", "circle")
.attr("cx", d => d);
}

return htmlContent;
}
Insert cell
Insert cell
chart2 = {
const htmlContent = html`
<style type="text/css">
.circle {
opacity: 0.7;
fill: steelblue;
}
</style>
<div><svg width="800" height="100"></svg></div>
<button>Update data</button>
`
const container = d3.select(htmlContent);
const svg = container.select("svg");
const button = container.select("button");
update();
button.on("click", update);
function update() {
let data = [];
for (let i = 0; i < 5; ++i) {
data.push(Math.random() * 800);
}
svg.selectAll("circle")
.data(data)
.join("circle")
.attr("cy", 50)
.attr("r", 40)
.attr("class", "circle")
.transition()
.attr("cx", d => d);
}

return htmlContent;
}
Insert cell
Insert cell
chart3 = {
const htmlContent = html`
<style type="text/css">
.circle {
opacity: 0.7;
fill: steelblue;
}
</style>
<div><svg width="800" height="100"></svg></div>
<button>Update data</button>
`
const container = d3.select(htmlContent);
const svg = container.select("svg");
const button = container.select("button");
const height = svg.attr("height");
update();
button.on("click", update);
function update() {
let data = [];
// We need different number of data for removing existent data fields or introducing new data fields
let numItems = Math.ceil(Math.random() * 10);
for (let i = 0; i < numItems; ++i) {
data.push(Math.random() * 800);
}
const r = 40;
svg.selectAll("circle")
.data(data)
.join(enter => enter.append("circle")
.attr("cx", d => d)
.attr("cy", 50)
,
update => update,
exit => exit.transition()
.duration(2500)
.attr("cy", height+r)
.remove()
)
.transition()
.duration(2000)
.attr("cx", d => d)
.attr("r", r)
.attr("class", "circle");
}

return htmlContent;
}
Insert cell
Insert cell
{
const htmlContent = html`
<style type="text/css">
.circle {
opacity: 0.7;
fill: steelblue;
}
</style>
<div><svg width="800" height="300">
<circle cx="150" cy="150" r="100" style="fill: none; stroke: grey; stroke-dasharray: 1,3"/>
<g transform="translate(150, 150)"></g>
</svg></div>
<button>Update data</button>
`
const container = d3.select(htmlContent);
const svg = container.select("svg");
const button = container.select("button");
const r = svg.select("circle").attr("r");
update();
button.on("click", update);

function update() {
let data = [];
for (let i = 0; i < 3; ++i) {
data.push(Math.random() * 2 * Math.PI);
}
svg.select("g")
.selectAll("circle")
.data(data)
.join("circle")
.attr("r", 7)
.attr("class", "circle")
.transition()
.attr("cx", d => r * Math.cos(d))
.attr("cy", d => r * Math.sin(d));
}

return htmlContent;
}
Insert cell
{
const htmlContent = html`
<style type="text/css">
.dot {
opacity: 0.7;
fill: steelblue;
}
</style>
<div><svg width="800" height="300">
<circle cx="150" cy="150" r="100" style="fill: none; stroke: grey; stroke-dasharray: 1,3"/>
<g transform="translate(150, 150)"></g>
</svg></div>
<button>Update data</button>
`
const container = d3.select(htmlContent);
const svg = container.select("svg");
const button = container.select("button");
const r = svg.select("circle").attr("r");
let data = [0, 0, 0];
update();
button.on("click", update);

function getAngle(circ) {
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
return Math.atan2(circ.attr("cy"), circ.attr("cx"));
}

function getInterpolator(cur, d) {
let currentAngle = getAngle(cur);
if (d - currentAngle > Math.PI) { d -= 2 * Math.PI; }
else if (currentAngle - d > Math.PI) { d += 2 * Math.PI; }
return d3.interpolate(currentAngle, d);
}

//
function getCurrentAngle(el) {
let x = d3.select(el).attr('cx');
let y = d3.select(el).attr('cy');
return Math.atan2(y, x);
}

function update() {
for (let i = 0; i < 3; ++i) {
data[i] = Math.random() * 2 * Math.PI;
}
svg.select("g")
.selectAll("circle")
.data(data)
.join("circle")
.attr("r", 7)
.attr("class", "dot")
.transition()
.duration(1000)
.tween("circumference", function(d) { // Need to use function not arrow function here
const cur = d3.select(this);
const currentAngle = getAngle(cur);
let interpolator = getInterpolator(cur, d);
return (t) => {
const angle = interpolator(t);
cur.attr("cx", r * Math.cos(angle));
cur.attr("cy", r * Math.sin(angle));
};
})
}

return htmlContent;
}
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