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> |