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