D3 Condegram Spiral Animation

by Sandeep Desai

HTML

<head>
  <title>Condegram Spiral Plot</title>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.js"></script>
</head>

<body>
  <div id="chart" style="height: 500px"></div>
  <script type="text/javascript" src="main.js"></script>
</body>

CSS

body {
  font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif;
  margin: 40px;
}

.axis path {
  fill: none;
  stroke: #999;
  stroke-dasharray: 2 3;
}

.axis text {
  font-size: 13px;
  stroke: #222;
}

text.title {
  font-size: 24px;
}

circle.tick {
  fill: #f3f3f3;
  stroke: #999;
  stroke-dasharray: 2 3;
}

path.spiral {
  fill: none;
  stroke: #ee8d18;
  stroke-width: 3px;
}

.tooltip {
  background: #eee;
  box-shadow: 0 0 5px #999999;
  color: #333;
  font-size: 12px;
  left: 130px;
  padding: 10px;
  position: absolute;
  text-align: center;
  top: 95px;
  z-index: 10;
  display: block;
  opacity: 0;
}

JavaScript

var width = 500,
  height = 500,
  start = 0,
  end = 2.25,
  numSpirals = 3
margin = {
  top: 50,
  bottom: 50,
  left: 50,
  right: 50
};

var theta = function(r) {
  return numSpirals * Math.PI * r;
};

// used to assign nodes color by group
var color = d3.scaleOrdinal(d3.schemeCategory10);

var r = d3.min([width, height]) / 2 - 40;

var radius = d3.scaleLinear()
  .domain([start, end])
  .range([40, r]);

N = 0;
var FULLN = 730;
var f = function() {
  $('#chart').empty();
  var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.left + margin.right)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var points = d3.range(start, end + 0.001, (end - start) / 1000);

  var spiral = d3.radialLine()
    .curve(d3.curveCardinal)
    .angle(theta)
    .radius(radius);

  var path = svg.append("path")
    .datum(points)
    .attr("id", "spiral")
    .attr("d", spiral)
    .style("fill", "none")
    .style("stroke", "steelblue");


  N += 7;
  if (N > FULLN)
    clearInterval(t);
  var spiralLength = path.node().getTotalLength(),
    barWidth = (spiralLength / FULLN) - 1;
  var someData = [];
  for (var i = 0; i < N && i < FULLN; i++) {
    var currentDate = new Date();
    currentDate.setDate(currentDate.getDate() + i);
    someData.push({
      date: currentDate,
      value: Math.random(),
      group: currentDate.getMonth()
    });
  }
  for (var i = N + 1; i < FULLN; i++) {
    var currentDate = new Date();
    currentDate.setDate(currentDate.getDate() + i);
    someData.push({
      date: currentDate,
      value: 0,
      group: currentDate.getMonth()
    });
  }


  var timeScale = d3.scaleTime()
    .domain(d3.extent(someData, function(d) {
      return d.date;
    }))
    .range([0, spiralLength]);

  // yScale for the bar height
  var yScale = d3.scaleLinear()
    .domain([0, d3.max(someData, function(d) {
      return d.value;
   ...