Skip to content

Instantly share code, notes, and snippets.

@areologist
Last active January 12, 2018 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save areologist/77caab43cd91988a5fbf2d5ab9408d0d to your computer and use it in GitHub Desktop.
Save areologist/77caab43cd91988a5fbf2d5ab9408d0d to your computer and use it in GitHub Desktop.
demonstrates path interpolation caveat
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
button {
font-size: 16px;
margin: 15px;
padding: 10px;
}
svg {
border: 1px solid gray;
}
</style>
</head>
<body>
<button id="update">Press Me</button>
<script>
const margin = {left: 15, top: 15, right: 15, bottom: 40};
const width = 960 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);
const data = Array(4).fill(0).map(generateData.bind(null, 10));
const xMax = Math.max(...data.reduce((acc, x) => acc.concat([x.length - 1]), []));
const xScale = d3.scaleLinear()
.domain([0, xMax])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain(d3.extent(data.reduce((acc, x) => acc.concat(x), [])))
.range([height, 0]);
const container = svg
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const line = d3.line()
.x((d, i) => xScale(i))
.y(d => yScale(d))
.curve(d3.curveCatmullRom);
const color = (i) =>
`hsl(${Math.floor(240/data.length) * i}, 80%, 50%)`;
container
.selectAll('path')
.data(data, (d, i) => i)
.enter()
.append('path')
.attr('d', line)
.attr('fill', 'transparent')
.attr('stroke', (d, i) => color(i))
.attr('stroke-width', 2);
const xAxis = d3.axisBottom(xScale);
container
.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0, ${height + 16})`)
.call(xAxis);
function update() {
const x = Math.floor(Math.random() * 20) + 2;
data.forEach((d, i) => data[i] = generateData(x));
const y = data.reduce((acc, x) => acc.concat(x), []);
xScale.domain([0, x - 1]);
yScale.domain(d3.extent(y));
container
.selectAll('path')
.data(data, (d, i) => i)
.transition()
.duration(500)
.attr('d', line);
container
.select('.x-axis')
.transition()
.duration(500)
.call(d3.axisBottom(xScale));
}
function generateData(size = 0) {
return Array(size).fill(0).map(() => Math.random());
}
window.addEventListener('load', () => {
document.querySelector('#update')
.addEventListener('click', update);
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment