So bad, even the ticks are marching...
Built with blockbuilder.org
license: apache-2.0 |
So bad, even the ticks are marching...
Built with blockbuilder.org
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
text { | |
font: 13px sans-serif; | |
} | |
</style> | |
<div id="chart"> | |
</div> | |
</head> | |
<body> | |
<script> | |
var margin = {top: 30, left: 40, bottom: 40, right: 30}; | |
var width = 960 - margin.left - margin.right; | |
var height = 500 - margin.top - margin.bottom; | |
// Assumes both axes have the same domain and same number of ticks. | |
var numTicks = 11; | |
var max = 100; | |
var x = d3.scaleLinear().domain([0, max]).range([0, width]); | |
var y = d3.scaleLinear().domain([0, max]).range([height, 0]); | |
var svg = d3.select("#chart").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var xTickLocations = x.ticks(numTicks).map(function(d) { | |
return [d, 0]; | |
}); | |
var yTickLocations = y.ticks(numTicks).map(function(d) { | |
return [0, d]; | |
}); | |
var xPoints = generateTrajectory(xTickLocations); | |
var yPoints = generateTrajectory(yTickLocations); | |
var xPaths = generatePaths(xPoints); | |
var yPaths = generatePaths(yPoints); | |
svg.append("g") | |
.attr("class", "xaxis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x).ticks(numTicks)); | |
svg.append("g") | |
.attr("class", "yaxis") | |
.call(d3.axisLeft(y).ticks(numTicks)); | |
var t = d3.transition().delay(2000).duration(10000).ease(d3.easeCubicIn); | |
d3.select(".xaxis").selectAll(".tick") | |
.transition(t) | |
.attrTween("transform", translateAlong(xPaths, height)); | |
d3.select(".yaxis").selectAll(".tick") | |
.transition(t) | |
.attrTween("transform", translateAlong(yPaths, 0)); | |
function translateAlong(nodes, yOffset) { | |
return function(d, i, a) { | |
var path = nodes[i]; | |
var l = path.getTotalLength(); | |
return function(t) { | |
var p = path.getPointAtLength(t * l); | |
return "translate(" + p.x + "," + (p.y - yOffset) + ")"; | |
}; | |
}; | |
} | |
// For each tick, generate a set of control points, representing a trajectory | |
// from the start location to somewhere off the chart, to the top right. | |
function generateTrajectory(startTicks) { | |
var trajectory = []; | |
for (var i = 0; i < numTicks; i++) { | |
var points = []; | |
var start = startTicks[i]; | |
while (start[0] < max * 1.2 || start[1] < max * 1.2) { | |
points.push([start[0], start[1]]); | |
start[0] = start[0] + Math.random() * (max/4); | |
start[1] = start[1] + Math.random() * (max/4); | |
} | |
trajectory.push(points); | |
} | |
return trajectory; | |
}; | |
// Generate a curve from each set of control points. | |
function generatePaths(points) { | |
var paths = svg.append("g").selectAll(".line") | |
.data(points) | |
.enter().append("path") | |
.attr("class", "line") | |
.style("stroke", "none") | |
.style("fill", "none") | |
.attr("d", d3.line() | |
.curve(d3.curveBasis) | |
.x(function(d) { return x(d[0]); }) | |
.y(function(d) { return y(d[1]); }) | |
); | |
return paths.nodes(); | |
}; | |
</script> | |
</body> |