Public
Edited
Apr 11
Insert cell
Insert cell
Insert cell
directedMatrix = [
[10, 5, 20],
[35, 50, 10],
[45, 60, 100]
]

Insert cell
{
const width = 600;
const height =600;
const radius = Math.min(width, height) / 3 - 30;
const names = ["A", "B", "C"];
const color = d3.schemeCategory10;

const chord = d3.chord().padAngle(0.05)(directedMatrix);
const arc = d3.arc().innerRadius(radius).outerRadius(radius + 10);
const ribbon = d3.ribbon().radius(radius);

const svg = d3.create("svg")
.attr("viewBox", [-width/2, -height/2, width, height]);

svg.append("g")
.selectAll("path")
.data(chord.groups)
.join("path")
.attr("fill", d => color[d.index])
.attr("stroke", "#000")
.attr("d", arc);

svg.append("g")
.selectAll("text")
.data(chord.groups)
.join("text")
.attr("dy", ".35em")
.attr("transform", d => {
const angle = (d.startAngle + d.endAngle) / 2;
const rotate = (angle * 180 / Math.PI) - 90;
const x = Math.cos(angle) * (radius + 20);
const y = Math.sin(angle) * (radius + 20);
return `translate(${x}, ${y}) rotate(${rotate})`;
})
.attr("text-anchor", "middle")
.text(d => names[d.index]);

svg.append("g")
.attr("fill-opacity", 0.7)
.selectAll("path")
.data(chord)
.join("path")
.attr("d", ribbon)
.attr("fill", d => color[d.target.index])
.attr("stroke", "#111");

return svg.node();
}

Insert cell
Insert cell
undirectedMatrix = [
[5, 15, 20, 30],
[45, 50, 60, 65],
[70, 40, 55, 80],
[95, 25, 100, 90]
]

Insert cell
{
const width = 400;
const height = 400;
const radius = Math.min(width, height) / 3 - 30;
const names = ["A", "B", "C", "D", "E"];
const color = d3.schemeCategory10;

const chord = d3.chord().padAngle(0.05)(undirectedMatrix);
const arc = d3.arc().innerRadius(radius).outerRadius(radius + 10);
const ribbon = d3.ribbon().radius(radius);

const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);


svg.append("g")
.selectAll("path")
.data(chord.groups.filter(d => d.index < 4))
.join("path")
.attr("fill", d => color[d.index])
.attr("stroke", "#000")
.attr("d", arc);

svg.append("g")
.selectAll("text")
.data(chord.groups.filter(d => d.index < 4))
.join("text")
.attr("dy", ".35em")
.attr("transform", d => {
const angle = (d.startAngle + d.endAngle) / 2;
const rotate = (angle * 180 / Math.PI) - 90;
const x = Math.cos(angle) * (radius + 20);
const y = Math.sin(angle) * (radius + 20);
return `translate(${x}, ${y}) rotate(${rotate})`;
})
.attr("text-anchor", "middle")
.text(d => names[d.index]);

svg.append("g")
.attr("fill-opacity", 0.7)
.selectAll("path")
.data(chord)
.join("path")
.attr("d", ribbon)
.attr("fill", d => color[d.source.index < 4 ? d.source.index : d.target.index])
.attr("stroke", "#111");

return svg.node();
}

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