Public
Edited
Jan 5
5 forks
1 star
Insert cell
Insert cell
Insert cell
Insert cell
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
Insert cell
data = chord(matrix)
Insert cell
Insert cell
regions[data[0].source.index]
Insert cell
regions[data[0].target.index]
Insert cell
Insert cell
data.groups
Insert cell
Insert cell
regions[data.groups[0].index]
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');

// Task 2
const edgesGroup = g.append('g');


// 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
regionInitials = ['NE', 'MW', 'S', 'W']
Insert cell
populationFlows = {
const data = [];
for (let i = 0; i < regionInitials.length; i++) {
for (let j = 0; j < regionInitials.length; j++) {
const source = regionInitials[i];
const target = regionInitials[j];
const population = matrix[i][j] || null;
data.push({ source, target, population });
}
}
return data;
}
Insert cell
Insert cell
margin = ({top: 40, right: 0, bottom: 0, left: 60})
Insert cell
matrixWidth = 150 + margin.left + margin.right
Insert cell
matrixHeight = 150 + margin.top + margin.bottom
Insert cell
Insert cell
x = d3.scaleBand()
.domain()
.range()
.paddingInner(0.1)
Insert cell
y = d3.scaleBand()
.domain()
.range()
.paddingInner(0.1)
Insert cell
Insert cell
minMaxPopulationFlow = null
Insert cell
populationColor = d3.scaleSequential()
.domain(minMaxPopulationFlow)
.interpolator(d3.interpolateBlues)
.unknown('#eee')
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', matrixWidth)
.attr('height', matrixHeight);

// create and add axes
const xAxis = d3.axisTop(x).tickSize(0);
svg.append("g")
.attr('transform', `translate(0,${margin.top})`)
.call(xAxis)
.call(g => g.selectAll(".domain").remove())
.append("text")
.attr("x", margin.left + (matrixWidth - margin.left - margin.right) / 2)
.attr("y", -margin.top + 5)
.attr("fill", "black")
.attr("text-anchor", "middle")
.attr("dominant-baseline", "hanging")
.text("Target");
const yAxis = d3.axisLeft(y).tickSize(0);
svg.append("g")
.attr('transform', `translate(${margin.left})`)
.call(yAxis)
.call(g => g.selectAll(".domain").remove())
.append("text")
.attr("x", -margin.left)
.attr("y", margin.top + (matrixHeight - margin.top - margin.bottom) / 2)
.attr("fill", "black")
.attr("dominant-baseline", "middle")
.attr("text-anchor", "start")
.text("Source");
// Create one rect for each element in populationFlows
// Set the x attribute according to the link's target
// Set the y attribute according to the link's source
// Set the width, height, and fill properties as well.
return svg.node();
}
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