Published
Edited
May 23, 2021
1 star
Insert cell
Insert cell
regions = ['Northeast', 'Midwest', 'South', 'West']
Insert cell
matrix = [
// To NE To MW To S To W
[0, 79000, 412000, 104000], // From northeast
[54000, 0, 356000, 146000], // From midwest
[122000, 276000, 0, 317000], // From south
[68000, 162000, 459000, 0] // From west
]
Insert cell
Insert cell
chord = d3.chordDirected()
.sortGroups(d3.ascending)
.padAngle(0.1)
Insert cell
data = chord(matrix)
Insert cell
data.groups
Insert cell
Insert cell
outerRadius = 275
Insert cell
innerRadius = outerRadius - 10
Insert cell
nodePath = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
Insert cell
nodePath(data.groups[0])
Insert cell
Insert cell
labelArc = d3.arc()
.innerRadius(outerRadius + 20)
.outerRadius(outerRadius + 20)
Insert cell
Insert cell
edgePath = d3.ribbonArrow()
.radius(innerRadius)
Insert cell
edgePath(data[0])
Insert cell
Insert cell
regionColor = d3.scaleOrdinal()
.domain(regions)
.range(d3.schemeCategory10)
Insert cell
Insert cell
Insert cell
{
// set up
const margin = { top: 25, bottom: 25, left: 50, right : 75 };

const svg = d3.create('svg')
.attr('width', outerRadius * 2 + margin.left + margin.right)
.attr('height', outerRadius * 2 + margin.top + margin.bottom);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`)
.append('g')
// have 0,0 be at the center of the circle
.attr('transform', `translate(${outerRadius},${outerRadius})`);
// Task 1
const nodesGroup = g.append('g');
nodesGroup.selectAll('path')
.data(data.groups)
.join('path')
.attr('d', d => nodePath(d))
.attr('fill', d => regionColor(regions[d.index]));
// Task 2
const edgesGroup = g.append('g');
edgesGroup.selectAll('path')
.data(data)
.join('path')
.attr('d', d => edgePath(d))
.attr('fill', d => regionColor(regions[d.target.index]))
.attr('opacity', 0.75);
// Add labels for the nodes.
nodesGroup.selectAll('text')
.data(data.groups)
.join('text')
.attr('font-size', 11)
.attr('font-family', 'sans-serif')
.attr('transform', d => `translate(${labelArc.centroid(d)})`)
.attr('text-anchor', d => {
const [x, y] = labelArc.centroid(d);
return x > 0 ? 'start' : 'end';
})
.text(d => regions[d.index])
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
x = d3.scaleBand()
.domain(regionInitials)
.range([0, matrixWidth])
.paddingInner(0.1)
Insert cell
y = d3.scaleBand()
.domain(regionInitials)
.range([0, matrixHeight])
.paddingInner(0.1)
Insert cell
Insert cell
populationColor = d3.scaleSequential()
.domain(d3.extent(populationFlows, d => d.population))
.interpolator(d3.interpolateBlues)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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