ext(`${newNodes.length} / ${nodes.length}`)

  // Make a shallow copy to protect against mutation, while
  // recycling old nodes to preserve position and velocity.
  const old = new Map(node.data().map(d => [d.id, d]))
  newNodes = newNodes.map(d => Object.assign(old.get(d.id) || {}, d))
  newLinks = newLinks.map(d => Object.assign({}, d))

  node = node.data(newNodes, d => d.id)
    .join(enter => {
      const g = enter.append('g')
        .attr('opacity', 0)

      g.transition().duration(1000).attr('op