chart = {
let width = 500,
height = 500,
start = 0,
end = 2.25,
numSpirals = 4;
var theta = function(r) {return numSpirals * Math.PI * r;};
var r = d3.min([width, height]) / 2 - 40;
var radius = d3.scaleLinear()
.domain([start, end])
.range([40, r]);
var svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
let wrapper = svg.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 = wrapper.append("path")
.datum(points)
.attr("id", "spiral")
.attr("d", spiral)
.style("fill", "none")
.style("stroke", "steelblue");
var spiralLength = path.node().getTotalLength(),
N = 730,
barWidth = (spiralLength / N) - 1;
let year = d => d.year
let Total = d => d.Total
var timeScale = d3.scaleTime()
.domain(d3.extent(data, function(d){
return d.year;
}))
.range([0, spiralLength]);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d){
return d.Total
})])
.range([0, (r/numSpirals) - 30]);
wrapper.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", function(d,i){
var linePer = timeScale(d.year),
posOnLine = path.node().getPointAtLength(linePer),
angleOnLine = path.node().getPointAtLength(linePer - barWidth);
d.linePer = linePer;
d.x = posOnLine.x;
d.y = posOnLine.y;
d.a = (Math.atan2(angleOnLine.y, angleOnLine.x) * 180 / Math.PI) - 90;
return d.x;
})
.attr("y", function(d){
return d.y;
})
.attr("width", function(d){
return barWidth;
})
.attr("height", function(d){
return yScale(d.Total);
})
.style("fill", "steelblue")
.style("stroke", "none")
.attr("transform", function(d){
return "rotate(" + d.a + "," + d.x + "," + d.y + ")";
});
return svg.node()
}