double line animation

by nancynancy

HTML

<pre id="data">
step,guy,x,y,speed
1,A,1.0,1.0,0
2,A,2.0,2.0,1000
3,A,4.0,1.0,2000
4,A,7.0,2.0,3000
1,B,1.0,4.0,0
2,B,2.1,3.0,4000
3,B,3.4,3.0,5000
4,B,5.0,4.0,4000
</pre>

CSS

path {
    fill: none;
    stroke: black;
    stroke-width: 2px;
  }
  
circle {
    stroke: #fff;
    stroke-width: 1px;
  }
pre {
  display:none;
  }

JavaScript

var margin = { top: 40, bottom: 40, left: 40, right: 40 };
var width = 300;
var height = 300;
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var colors = ["red", "blue", "green", "orange"];
var data = d3.csvParse(d3.select("pre#data").text());

var svg = d3.selectAll("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("transform", "translate(" + margin.right + "," + margin.top + ")")
    
var panel = svg.append("g");
var dotPanel = svg.append("g");

var line = d3.line()
    .x(function (d) { return x(d.x); })
    .y(function (d) { return y(d.y); })
    .curve(d3.curveCardinal.tension(0));
    
data.forEach(function (d) {
  d.guy = d.guy;
  d.step = +d.step;
  d.x = +d.x;
  d.y = +d.y;
  d.speed = +d.speed;
});

var pathData = d3.nest()
  .key(function (d) { return d.guy; })
  .entries(data);

x.domain([d3.min(data, function (d) { return d.x }) - 1,
          d3.max(data, function (d) { return d.x }) + 1]);
y.domain([d3.min(data, function (d) { return d.y }) - 1,
          d3.max(data, function (d) { return d.y }) + 1]);

dotPanel.selectAll(".dot")
  .data(data)
  .enter().append("circle")
  .attr("cx", function (d) { return x(d.x); })
  .attr("cy", function (d) { return y(d.y + 0.5); })
  .transition()
  .ease(d3.easeElastic)
  .duration(2000)
  .attr("cy", function (d) { return y(d.y); })
  .attr("r", 6)
  .style("fill", "pink")

//////////////////////////////////////////////////////////////////
var totalLengths = [];
pathData.forEach(function (d) {
  eachGuy = d.values; 
  circle = panel.append("circle")
    .attr("transform", `translate(${x(eachGuy[0].x)}, ${y(eachGuy[0].y)})`)
    .attr("r", 20)
    .style("fill", 'black')
    .style("opacity", 0.3)
    
 ///////// Annotate the groups and speeds /////////////////////////
for (i = 0; i < 3; i++) {
    panel.append("text")
      .attr("x", function () { return x(eachGuy[i].x + 0.5) })
      .attr("y", function () { return...