Published
Edited
Jun 4, 2021
5 forks
8 stars
Insert cell
Insert cell
Insert cell
chart = {
const height = width * 0.6;
const theSvg = d3.select(DOM.svg(width, height)).attr("id", "the-chart");

const g = theSvg.append("g");

g.append("g").attr("class", "slices");
g.append("g").attr("class", "labels");
g.append("g").attr("class", "lines");

const radius = Math.min(width, height) / 2;

const pie = d3
.pie()
.sort(null)
.value(function(d) {
return d.value;
});

const arc = d3
.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);

const outerArc = d3
.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);

g.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

const key = function(d) {
return d.data.label;
};

change(randomData());

function change(data) {
console.log(data);
/* ------- PIE SLICES -------*/

const pieData = pie(data);
const slice = g
.select(".slices")
.selectAll("path.slice")
.data(pieData, key);

slice
.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice")
.merge(slice)
.transition()
.duration(1000)
.attrTween("d", function(d) {
console.log("i");
this._current = this._current || d;
const interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
});

slice.exit().remove();

/* ------- TEXT LABELS -------*/

const text = g
.select(".labels")
.selectAll("text")
.data(pie(data), key);

function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}

text
.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
})
.merge(text)
.transition()
.duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
const interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
const d2 = interpolate(t);
const pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
const interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
const d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});

text.exit().remove();

/* ------- SLICE TO TEXT POLYLINES -------*/

const polyline = g
.select(".lines")
.selectAll("polyline")
.data(pie(data), key);

polyline
.join("polyline")
.transition()
.duration(1000)
.attrTween("points", function(d) {
this._current = this._current || d;
const interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
const d2 = interpolate(t);
const pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});

polyline.exit().remove();
}

return Object.assign(theSvg.node(), {
update() {
change(randomData());
}
});
}
Insert cell
function randomData() {
const labels = color.domain();
return labels.map(function(label) {
return { label: label, value: Math.random() };
});
}
Insert cell
color = d3
.scaleOrdinal()
.domain([
"Lorem ipsum",
"dolor sit",
"amet",
"consectetur",
"adipisicing",
"elit",
"sed",
"do",
"eiusmod",
"tempor",
"incididunt"
])
.range([
"#98abc5",
"#8a89a6",
"#7b6888",
"#6b486b",
"#a05d56",
"#d0743c",
"#ff8c00"
])
Insert cell
html`<style>
#the-chart {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

path.slice{
stroke-width:2px;
}

polyline{
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
</style>`
Insert cell
d3 = require("d3@6")
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