Skip to content

Instantly share code, notes, and snippets.

@karen-izuka
Created August 18, 2019 15:46
Show Gist options
  • Save karen-izuka/6b9a7ae34b4a86eceac7bfa470481572 to your computer and use it in GitHub Desktop.
Save karen-izuka/6b9a7ae34b4a86eceac7bfa470481572 to your computer and use it in GitHub Desktop.
Chord Diagram
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Chord Diagram</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Immigration Patterns</h1>
<div id="chart"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="index.js"></script>
</body>
</html>
//data
const data = [
[3.142471, 0, 2.107883, 0, 0.540887, 0.155988, 0, 0, 0, 0.673004],
[0, 1.630997, 0.601265, 0, 0.97306, 0.333608, 0, 0.380388, 0, 0.869311],
[0, 0, 2.401476, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1.762587, 0.879198, 3.627847, 0, 0, 0, 0, 0],
[0, 0, 1.215929, 0.276908, 0, 0, 0, 0, 0, 0],
[0, 0, 0.17037, 0, 0, 0.190706, 0, 0, 0, 0],
[0, 0.525881, 1.390272, 0, 1.508008, 0.34742, 1.307907, 0, 0, 4.902081],
[0, 0.145264, 0.468762, 0, 1.057904, 0.278746, 0, 0.781316, 0, 0],
[0, 0, 0.60923, 0, 0, 0, 0, 0, 1.870501, 0],
[0, 0, 0.449623, 0, 0.169274, 0, 0, 0, 0, 0.927243]
];
const labels = ["Africa","East Asia","Europe","Latin America","North America","Oceania","South Asia","South East Asia","Soviet Union","West Asia"]
//helper functions
const innerRadius = 270;
const outerRadius = 290;
const chord = d3.chord()
.padAngle(0.05)
.sortSubgroups(d3.descending);
const arc = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
const ribbon = d3.ribbon()
.radius(innerRadius);
const color = d3.scaleOrdinal()
.range(d3.schemeCategory10);
const groupTicks = (d, step) => {
const k = (d.endAngle - d.startAngle) / d.value;
return d3.range(0, d.value, step).map(value => {
return {value: value, angle: value * k + d.startAngle}
});
}
//draw
const svg = d3.select('#chart')
.append('svg')
.attr('width', 800)
.attr('height', 800)
.append('g')
.attr('transform', `translate(400, 400)`);
const chords = chord(data);
const group = svg.append('g')
.selectAll('g')
.data(chords.groups)
.join('g');
group.append('path')
.attr('d', arc)
.attr('fill', d => color(d.index))
.attr('stroke', d => d3.rgb(color(d.index)).darker())
.style('shape-rendering', 'geometricPrecision');
group.append('text')
.each(d => {d.angle = (d.startAngle + d.endAngle) / 2})
.attr('dy', '0.35em')
.attr('transform', d =>
`rotate(${(d.angle * 180 / Math.PI - 90)})
translate(${outerRadius + 30})
${d.angle > Math.PI ? 'rotate(180)' : ''}`)
.attr('text-anchor', d => d.angle > Math.PI ? 'end' : null)
.text((d, i) => labels[i])
.attr('font-family', 'Arial')
.attr('font-size', 10)
.attr('font-weight', 'bold');
svg.append('g')
.attr('fill-opacity', 0.5)
.selectAll('path')
.data(chords)
.join('path')
.attr('d', ribbon)
.attr('fill', d => color(d.source.index))
.attr('stroke', d => d3.rgb(color(d.source.index)).darker());
//ticks
const tick = group.append('g')
.selectAll('g')
.data(d => groupTicks(d, 0.5))
.join('g')
.attr('transform', d => `rotate(${d.angle * 180 / Math.PI - 90}) translate(${outerRadius}, 0)`);
tick.append('line')
.attr('stroke', '#000000')
.attr('x2', 5)
.style('shape-rendering', 'crispEdges');
tick.filter(d => d.value % 0.5 === 0)
.append('text')
.attr('x', 8)
.attr('dy', '0.35em')
.attr('transform', d => d.angle > Math.PI ? `rotate(180) translate(-16)` : null)
.attr('text-anchor', d => d.angle > Math.PI ? 'end' : null)
.text(d => d.value)
.style('font-family', 'Arial')
.style('font-size', 10);
h1 {
font-family: Arial, Helvetica, sans-serif;
font-size: 24px;
text-align: center;
}
svg {
display: block;
margin: auto;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment