An example of a resuable spiral heatmap.
The data is from the Makeover Monday series, about German car and truck production.
Built with blockbuilder.org
license: mit |
An example of a resuable spiral heatmap.
The data is from the Makeover Monday series, about German car and truck production.
Built with blockbuilder.org
// A spiral heatmap | |
// The following options are available | |
// radius: radius of the overall plot, not including any labels. Default 250 | |
// holeRadiusProportion: the proportion (0 to 1) of the radius (see above) that is left as a hole. Default 0. | |
// arcsPerCoil: a 'coil' is one revolution of the spiral. This sets how many arcs (or arcs) you want per coil. Typically this would | |
// be set according to the periodicity of the data. For example, 12 for months per year, 24 for hours per day, etc | |
// coilPadding: the proportion (0 to 1) of the coil width that is used for padding between coils. Useful for making the spiral very noticeable | |
// arcLabel: the field name to use for the labels around the circumference | |
// coilLabel: the field name to use for the labels at the beginning of each coil | |
function spiralHeatmap () { | |
// constants | |
const radians = 0.0174532925 | |
// All options that are accessible to caller | |
// Default values | |
var radius = 250 | |
var holeRadiusProportion = 0.3 // proportion of radius | |
var arcsPerCoil = 12 // assuming months per year | |
var coilPadding = 0 // no padding | |
var arcLabel = '' // no labels | |
var coilLabel = '' // no labels | |
function chart (selection) { | |
selection.each(function (data) { | |
const arcAngle = 360 / arcsPerCoil | |
const labelRadius = radius + 20 | |
var arcLabelsArray = [] | |
for (var i = 0; i < arcsPerCoil; i++) { | |
arcLabelsArray.push(i) | |
} | |
// Create/update the x/y coordinates for the vertices and control points for the paths | |
// Stores the x/y coordinates on the data | |
updatePathData(data) | |
let thisSelection = d3 | |
.select(this) | |
.append('g') | |
.attr('class', 'spiral-heatmap') | |
var arcLabelsG = thisSelection | |
.selectAll('.arc-label') | |
.data(arcLabelsArray) | |
.enter() | |
.append('g') | |
.attr('class', 'arc-label') | |
arcLabelsG | |
.append('text') | |
.text(function (d) { | |
return data[d][arcLabel] | |
}) | |
.attr('x', function (d, i) { | |
let labelAngle = i * arcAngle + arcAngle / 2 | |
return x(labelAngle, labelRadius) | |
}) | |
.attr('y', function (d, i) { | |
let labelAngle = i * arcAngle + arcAngle / 2 | |
return y(labelAngle, labelRadius) | |
}) | |
.style('text-anchor', function (d, i) { | |
return i < arcLabelsArray.length / 2 ? 'start' : 'end' | |
}) | |
arcLabelsG | |
.append('line') | |
.attr('x2', function (d, i) { | |
let lineAngle = i * arcAngle | |
let lineRadius = chartRadius + 10 | |
return x(lineAngle, lineRadius) | |
}) | |
.attr('y2', function (d, i) { | |
let lineAngle = i * arcAngle | |
let lineRadius = chartRadius + 10 | |
return y(lineAngle, lineRadius) | |
}) | |
var arcs = thisSelection | |
.selectAll('.arc') | |
.data(data) | |
.enter() | |
.append('g') | |
.attr('class', 'arc') | |
arcs.append('path').attr('d', function (d) { | |
// start at vertice 1 | |
let start = 'M ' + d.x1 + ' ' + d.y1 | |
// inner curve to vertice 2 | |
let side1 = | |
' Q ' + | |
d.controlPoint1x + | |
' ' + | |
d.controlPoint1y + | |
' ' + | |
d.x2 + | |
' ' + | |
d.y2 | |
// straight line to vertice 3 | |
let side2 = 'L ' + d.x3 + ' ' + d.y3 | |
// outer curve vertice 4 | |
let side3 = | |
' Q ' + | |
d.controlPoint2x + | |
' ' + | |
d.controlPoint2y + | |
' ' + | |
d.x4 + | |
' ' + | |
d.y4 | |
// combine into string, with closure (Z) to vertice 1 | |
return start + ' ' + side1 + ' ' + side2 + ' ' + side3 + ' Z' | |
}) | |
// create coil labels on the first arc of each coil | |
coilLabels = arcs | |
.filter(function (d) { | |
return d.arcNumber == 0 | |
}) | |
.raise() | |
coilLabels | |
.append('path') | |
.attr('id', function (d) { | |
return 'path-' + d[coilLabel] | |
}) | |
.attr('d', function (d) { | |
// start at vertice 1 | |
let start = 'M ' + d.x1 + ' ' + d.y1 | |
// inner curve to vertice 2 | |
let side1 = | |
' Q ' + | |
d.controlPoint1x + | |
' ' + | |
d.controlPoint1y + | |
' ' + | |
d.x2 + | |
' ' + | |
d.y2 | |
return start + side1 | |
}) | |
.style('opacity', 0) | |
coilLabels | |
.append('text') | |
.attr('class', 'coil-label') | |
.attr('x', 3) | |
.attr('dy', -4) | |
.append('textPath') | |
.attr('xlink:href', function (d) { | |
return '#path-' + d[coilLabel] | |
}) | |
.text(function (d) { | |
return d[coilLabel] | |
}) | |
}) | |
function updatePathData (data) { | |
let holeRadius = radius * holeRadiusProportion | |
let arcAngle = 360 / arcsPerCoil | |
let dataLength = data.length | |
let coils = Math.ceil(dataLength / arcsPerCoil) // number of coils, based on data.length / arcsPerCoil | |
let coilWidth = chartRadius * (1 - holeRadiusProportion) / (coils + 1) // remaining chartRadius (after holeRadius removed), divided by coils + 1. I add 1 as the end of the coil moves out by 1 each time | |
data.forEach(function (d, i) { | |
let coil = Math.floor(i / arcsPerCoil) | |
let position = i - coil * arcsPerCoil | |
let startAngle = position * arcAngle | |
let endAngle = (position + 1) * arcAngle | |
let startInnerRadius = holeRadius + i / arcsPerCoil * coilWidth | |
let startOuterRadius = | |
holeRadius + | |
i / arcsPerCoil * coilWidth + | |
coilWidth * (1 - coilPadding) | |
let endInnerRadius = holeRadius + (i + 1) / arcsPerCoil * coilWidth | |
let endOuterRadius = | |
holeRadius + | |
(i + 1) / arcsPerCoil * coilWidth + | |
coilWidth * (1 - coilPadding) | |
// vertices of each arc | |
d.x1 = x(startAngle, startInnerRadius) | |
d.y1 = y(startAngle, startInnerRadius) | |
d.x2 = x(endAngle, endInnerRadius) | |
d.y2 = y(endAngle, endInnerRadius) | |
d.x3 = x(endAngle, endOuterRadius) | |
d.y3 = y(endAngle, endOuterRadius) | |
d.x4 = x(startAngle, startOuterRadius) | |
d.y4 = y(startAngle, startOuterRadius) | |
// CURVE CONTROL POINTS | |
let midAngle = startAngle + arcAngle / 2 | |
let midInnerRadius = | |
holeRadius + (i + 0.5) / arcsPerCoil * coilWidth | |
let midOuterRadius = | |
holeRadius + | |
(i + 0.5) / arcsPerCoil * coilWidth + | |
coilWidth * (1 - coilPadding) | |
// MID POINTS, WHERE THE CURVE WILL PASS THRU | |
d.mid1x = x(midAngle, midInnerRadius) | |
d.mid1y = y(midAngle, midInnerRadius) | |
d.mid2x = x(midAngle, midOuterRadius) | |
d.mid2y = y(midAngle, midOuterRadius) | |
d.controlPoint1x = (d.mid1x - 0.25 * d.x1 - 0.25 * d.x2) / 0.5 | |
d.controlPoint1y = (d.mid1y - 0.25 * d.y1 - 0.25 * d.y2) / 0.5 | |
d.controlPoint2x = (d.mid2x - 0.25 * d.x3 - 0.25 * d.x4) / 0.5 | |
d.controlPoint2y = (d.mid2y - 0.25 * d.y3 - 0.25 * d.y4) / 0.5 | |
d.arcNumber = position | |
d.coilNumber = coil | |
}) | |
return data | |
} | |
function x (angle, radius) { | |
// change to clockwise | |
let a = 360 - angle | |
// start from 12 o'clock | |
a = a + 180 | |
return radius * Math.sin(a * radians) | |
} | |
function y (angle, radius) { | |
// change to clockwise | |
let a = 360 - angle | |
// start from 12 o'clock | |
a = a + 180 | |
return radius * Math.cos(a * radians) | |
} | |
function chartWH (r) { | |
return r * 2 | |
} | |
} | |
chart.radius = function (value) { | |
if (!arguments.length) return radius | |
radius = value | |
return chart | |
} | |
chart.holeRadiusProportion = function (value) { | |
if (!arguments.length) return holeRadiusProportion | |
holeRadiusProportion = value | |
return chart | |
} | |
chart.arcsPerCoil = function (value) { | |
if (!arguments.length) return arcsPerCoil | |
arcsPerCoil = value | |
return chart | |
} | |
chart.coilPadding = function (value) { | |
if (!arguments.length) return coilPadding | |
coilPadding = value | |
return chart | |
} | |
chart.arcLabel = function (value) { | |
if (!arguments.length) return arcLabel | |
arcLabel = value | |
return chart | |
} | |
chart.coilLabel = function (value) { | |
if (!arguments.length) return coilLabel | |
coilLabel = value | |
return chart | |
} | |
return chart | |
} |
car_type | export_production | date | value | |
---|---|---|---|---|
Passenger cars | Production | 1/01/2008 | 475197 | |
Passenger cars | Production | 1/02/2008 | 531397 | |
Passenger cars | Production | 1/03/2008 | 492336 | |
Passenger cars | Production | 1/04/2008 | 579869 | |
Passenger cars | Production | 1/05/2008 | 444537 | |
Passenger cars | Production | 1/06/2008 | 516609 | |
Passenger cars | Production | 1/07/2008 | 434801 | |
Passenger cars | Production | 1/08/2008 | 340288 | |
Passenger cars | Production | 1/09/2008 | 535893 | |
Passenger cars | Production | 1/10/2008 | 448565 | |
Passenger cars | Production | 1/11/2008 | 452590 | |
Passenger cars | Production | 1/12/2008 | 279948 | |
Passenger cars | Production | 1/01/2009 | 310113 | |
Passenger cars | Production | 1/02/2009 | 297921 | |
Passenger cars | Production | 1/03/2009 | 435693 | |
Passenger cars | Production | 1/04/2009 | 373308 | |
Passenger cars | Production | 1/05/2009 | 427239 | |
Passenger cars | Production | 1/06/2009 | 478133 | |
Passenger cars | Production | 1/07/2009 | 410321 | |
Passenger cars | Production | 1/08/2009 | 325060 | |
Passenger cars | Production | 1/09/2009 | 553205 | |
Passenger cars | Production | 1/10/2009 | 508450 | |
Passenger cars | Production | 1/11/2009 | 493851 | |
Passenger cars | Production | 1/12/2009 | 351229 | |
Passenger cars | Production | 1/01/2010 | 376937 | |
Passenger cars | Production | 1/02/2010 | 450355 | |
Passenger cars | Production | 1/03/2010 | 560055 | |
Passenger cars | Production | 1/04/2010 | 464591 | |
Passenger cars | Production | 1/05/2010 | 470130 | |
Passenger cars | Production | 1/06/2010 | 528820 | |
Passenger cars | Production | 1/07/2010 | 392553 | |
Passenger cars | Production | 1/08/2010 | 335748 | |
Passenger cars | Production | 1/09/2010 | 536468 | |
Passenger cars | Production | 1/10/2010 | 502507 | |
Passenger cars | Production | 1/11/2010 | 519765 | |
Passenger cars | Production | 1/12/2010 | 414480 | |
Passenger cars | Production | 1/01/2011 | 398078 | |
Passenger cars | Production | 1/02/2011 | 519342 | |
Passenger cars | Production | 1/03/2011 | 583399 | |
Passenger cars | Production | 1/04/2011 | 470463 | |
Passenger cars | Production | 1/05/2011 | 563015 | |
Passenger cars | Production | 1/06/2011 | 456548 | |
Passenger cars | Production | 1/07/2011 | 462005 | |
Passenger cars | Production | 1/08/2011 | 396706 | |
Passenger cars | Production | 1/09/2011 | 562504 | |
Passenger cars | Production | 1/10/2011 | 502897 | |
Passenger cars | Production | 1/11/2011 | 546272 | |
Passenger cars | Production | 1/12/2011 | 410689 | |
Passenger cars | Production | 1/01/2012 | 443510 | |
Passenger cars | Production | 1/02/2012 | 508798 | |
Passenger cars | Production | 1/03/2012 | 546169 | |
Passenger cars | Production | 1/04/2012 | 426321 | |
Passenger cars | Production | 1/05/2012 | 448045 | |
Passenger cars | Production | 1/06/2012 | 463839 | |
Passenger cars | Production | 1/07/2012 | 460830 | |
Passenger cars | Production | 1/08/2012 | 363254 | |
Passenger cars | Production | 1/09/2012 | 450072 | |
Passenger cars | Production | 1/10/2012 | 454716 | |
Passenger cars | Production | 1/11/2012 | 482406 | |
Passenger cars | Production | 1/12/2012 | 340499 | |
Passenger cars | Production | 1/01/2013 | 397634 | |
Passenger cars | Production | 1/02/2013 | 459180 | |
Passenger cars | Production | 1/03/2013 | 474467 | |
Passenger cars | Production | 1/04/2013 | 502411 | |
Passenger cars | Production | 1/05/2013 | 428684 | |
Passenger cars | Production | 1/06/2013 | 475779 | |
Passenger cars | Production | 1/07/2013 | 444960 | |
Passenger cars | Production | 1/08/2013 | 394991 | |
Passenger cars | Production | 1/09/2013 | 514468 | |
Passenger cars | Production | 1/10/2013 | 456669 | |
Passenger cars | Production | 1/11/2013 | 537383 | |
Passenger cars | Production | 1/12/2013 | 353278 | |
Passenger cars | Production | 1/01/2014 | 442430 | |
Passenger cars | Production | 1/02/2014 | 513041 | |
Passenger cars | Production | 1/03/2014 | 522428 | |
Passenger cars | Production | 1/04/2014 | 494416 | |
Passenger cars | Production | 1/05/2014 | 482483 | |
Passenger cars | Production | 1/06/2014 | 456069 | |
Passenger cars | Production | 1/07/2014 | 535001 | |
Passenger cars | Production | 1/08/2014 | 272744 | |
Passenger cars | Production | 1/09/2014 | 524072 | |
Passenger cars | Production | 1/10/2014 | 478999 | |
Passenger cars | Production | 1/11/2014 | 515340 | |
Passenger cars | Production | 1/12/2014 | 367003 | |
Passenger cars | Production | 1/01/2015 | 421510 | |
Passenger cars | Production | 1/02/2015 | 501118 | |
Passenger cars | Production | 1/03/2015 | 556049 | |
Passenger cars | Production | 1/04/2015 | 479631 | |
Passenger cars | Production | 1/05/2015 | 447925 | |
Passenger cars | Production | 1/06/2015 | 513315 | |
Passenger cars | Production | 1/07/2015 | 533264 | |
Passenger cars | Production | 1/08/2015 | 338834 | |
Passenger cars | Production | 1/09/2015 | 538149 | |
Passenger cars | Production | 1/10/2015 | 529856 | |
Passenger cars | Production | 1/11/2015 | 518512 | |
Passenger cars | Production | 1/12/2015 | 329975 | |
Passenger cars | Production | 1/01/2016 | 416983 | |
Passenger cars | Production | 1/02/2016 | 529061 | |
Passenger cars | Production | 1/03/2016 | 523210 | |
Passenger cars | Production | 1/04/2016 | 550158 | |
Passenger cars | Production | 1/05/2016 | 445393 | |
Passenger cars | Production | 1/06/2016 | 563546 | |
Passenger cars | Production | 1/07/2016 | 410630 | |
Passenger cars | Production | 1/08/2016 | 410256 | |
Passenger cars | Production | 1/09/2016 | 529463 | |
Passenger cars | Production | 1/10/2016 | 464434 | |
Passenger cars | Production | 1/11/2016 | 535180 | |
Passenger cars | Production | 1/12/2016 | 368494 | |
Trucks | Production | 1/01/2008 | 25412 | |
Trucks | Production | 1/02/2008 | 28381 | |
Trucks | Production | 1/03/2008 | 27083 | |
Trucks | Production | 1/04/2008 | 32175 | |
Trucks | Production | 1/05/2008 | 25918 | |
Trucks | Production | 1/06/2008 | 28591 | |
Trucks | Production | 1/07/2008 | 25323 | |
Trucks | Production | 1/08/2008 | 24331 | |
Trucks | Production | 1/09/2008 | 29329 | |
Trucks | Production | 1/10/2008 | 24756 | |
Trucks | Production | 1/11/2008 | 18562 | |
Trucks | Production | 1/12/2008 | 11065 | |
Trucks | Production | 1/01/2009 | 12277 | |
Trucks | Production | 1/02/2009 | 9334 | |
Trucks | Production | 1/03/2009 | 13133 | |
Trucks | Production | 1/04/2009 | 10349 | |
Trucks | Production | 1/05/2009 | 12879 | |
Trucks | Production | 1/06/2009 | 14238 | |
Trucks | Production | 1/07/2009 | 12826 | |
Trucks | Production | 1/08/2009 | 12165 | |
Trucks | Production | 1/09/2009 | 18601 | |
Trucks | Production | 1/10/2009 | 20106 | |
Trucks | Production | 1/11/2009 | 17875 | |
Trucks | Production | 1/12/2009 | 13845 | |
Trucks | Production | 1/01/2010 | 14349 | |
Trucks | Production | 1/02/2010 | 17655 | |
Trucks | Production | 1/03/2010 | 20594 | |
Trucks | Production | 1/04/2010 | 19105 | |
Trucks | Production | 1/05/2010 | 18591 | |
Trucks | Production | 1/06/2010 | 21773 | |
Trucks | Production | 1/07/2010 | 19710 | |
Trucks | Production | 1/08/2010 | 10444 | |
Trucks | Production | 1/09/2010 | 23025 | |
Trucks | Production | 1/10/2010 | 20866 | |
Trucks | Production | 1/11/2010 | 27080 | |
Trucks | Production | 1/12/2010 | 17494 | |
Trucks | Production | 1/01/2011 | 19977 | |
Trucks | Production | 1/02/2011 | 21555 | |
Trucks | Production | 1/03/2011 | 23891 | |
Trucks | Production | 1/04/2011 | 21584 | |
Trucks | Production | 1/05/2011 | 25242 | |
Trucks | Production | 1/06/2011 | 19651 | |
Trucks | Production | 1/07/2011 | 20441 | |
Trucks | Production | 1/08/2011 | 19684 | |
Trucks | Production | 1/09/2011 | 27674 | |
Trucks | Production | 1/10/2011 | 24456 | |
Trucks | Production | 1/11/2011 | 29416 | |
Trucks | Production | 1/12/2011 | 21459 | |
Trucks | Production | 1/01/2012 | 21618 | |
Trucks | Production | 1/02/2012 | 21703 | |
Trucks | Production | 1/03/2012 | 24872 | |
Trucks | Production | 1/04/2012 | 17889 | |
Trucks | Production | 1/05/2012 | 22248 | |
Trucks | Production | 1/06/2012 | 23178 | |
Trucks | Production | 1/07/2012 | 20078 | |
Trucks | Production | 1/08/2012 | 19069 | |
Trucks | Production | 1/09/2012 | 25366 | |
Trucks | Production | 1/10/2012 | 24434 | |
Trucks | Production | 1/11/2012 | 24850 | |
Trucks | Production | 1/12/2012 | 15496 | |
Trucks | Production | 1/01/2013 | 19743 | |
Trucks | Production | 1/02/2013 | 21021 | |
Trucks | Production | 1/03/2013 | 24014 | |
Trucks | Production | 1/04/2013 | 25375 | |
Trucks | Production | 1/05/2013 | 23212 | |
Trucks | Production | 1/06/2013 | 26161 | |
Trucks | Production | 1/07/2013 | 20857 | |
Trucks | Production | 1/08/2013 | 21898 | |
Trucks | Production | 1/09/2013 | 25196 | |
Trucks | Production | 1/10/2013 | 23137 | |
Trucks | Production | 1/11/2013 | 29256 | |
Trucks | Production | 1/12/2013 | 18448 | |
Trucks | Production | 1/01/2014 | 25329 | |
Trucks | Production | 1/02/2014 | 23337 | |
Trucks | Production | 1/03/2014 | 24855 | |
Trucks | Production | 1/04/2014 | 27804 | |
Trucks | Production | 1/05/2014 | 27494 | |
Trucks | Production | 1/06/2014 | 28063 | |
Trucks | Production | 1/07/2014 | 25655 | |
Trucks | Production | 1/08/2014 | 20743 | |
Trucks | Production | 1/09/2014 | 29240 | |
Trucks | Production | 1/10/2014 | 26320 | |
Trucks | Production | 1/11/2014 | 25247 | |
Trucks | Production | 1/12/2014 | 19435 | |
Trucks | Production | 1/01/2015 | 27071 | |
Trucks | Production | 1/02/2015 | 26000 | |
Trucks | Production | 1/03/2015 | 30193 | |
Trucks | Production | 1/04/2015 | 27932 | |
Trucks | Production | 1/05/2015 | 24309 | |
Trucks | Production | 1/06/2015 | 29727 | |
Trucks | Production | 1/07/2015 | 22937 | |
Trucks | Production | 1/08/2015 | 19059 | |
Trucks | Production | 1/09/2015 | 31125 | |
Trucks | Production | 1/10/2015 | 32696 | |
Trucks | Production | 1/11/2015 | 31496 | |
Trucks | Production | 1/12/2015 | 22681 | |
Trucks | Production | 1/01/2016 | 24202 | |
Trucks | Production | 1/02/2016 | 28822 | |
Trucks | Production | 1/03/2016 | 27792 | |
Trucks | Production | 1/04/2016 | 28587 | |
Trucks | Production | 1/05/2016 | 26259 | |
Trucks | Production | 1/06/2016 | 29962 | |
Trucks | Production | 1/07/2016 | 23481 | |
Trucks | Production | 1/08/2016 | 16152 | |
Trucks | Production | 1/09/2016 | 30938 | |
Trucks | Production | 1/10/2016 | 27109 | |
Trucks | Production | 1/11/2016 | 28935 | |
Trucks | Production | 1/12/2016 | 23515 |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/d3-scale-chromatic.v0.3.min.js"></script> | |
<script src="d3-spiral-heatmap.js"></script> | |
<link href="https://fonts.googleapis.com/css?family=Catamaran" rel="stylesheet"> | |
<style> | |
body { | |
font-family: 'Catamaran', sans-serif; | |
margin: 20px; | |
top: 20px; | |
right: 20px; | |
bottom: 20px; | |
left: 20px; | |
} | |
line { | |
stroke: #E9E9E9; | |
} | |
.coil-label { | |
fill: #000; | |
font-size: 12px; | |
} | |
.arc path { | |
stroke: #FFF; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Spiral heatmap</h1> | |
<p>An example of a resuable spiral heatmap.</p> | |
<div id="charts"></div> | |
<div id="legend"></div> | |
<script> | |
//SVG dimensions | |
const chartWidth = 500 | |
const chartHeight = chartWidth | |
const chartRadius = chartWidth / 2 | |
const margin = { "top": 40, "bottom": 40, "left": 40, "right": 40 } | |
let dateParse = d3.timeParse("%d/%m/%Y") | |
let yearFormat = d3.timeFormat("%Y") | |
let monthFormat = d3.timeFormat("%b"); | |
//Colour scale | |
var colour = d3.scaleSequential(d3.interpolateRdYlGn) | |
//Load the data, nest, sort and draw charts | |
d3.csv("data.csv", convertTextToNumbers, function (error, data) { | |
if (error) { throw error; }; | |
//ENSURE THE DATA IS SORTED CORRECTLY, IN THIS CASE BY YEAR AND MONTH | |
//THE SPIRAL WILL START IN THE MIDDLE AND WORK OUTWARDS | |
var nestedData = d3.nest() | |
.key(function (d) { return d.car_type; }) | |
.sortValues(function (a, b) { return a.date - b.date; }) | |
.entries(data); | |
nestedData.forEach(function (chartData) { | |
colour.domain(d3.extent(chartData.values, function (d) { return d.value; })); | |
//set the options for the sprial heatmap | |
let heatmap = spiralHeatmap() | |
.radius(chartRadius) | |
.holeRadiusProportion(0.2) | |
.arcsPerCoil(12) | |
.coilPadding(0.1) | |
.arcLabel("month") | |
.coilLabel("year") | |
//CREATE SVG AND A G PLACED IN THE CENTRE OF THE SVG | |
const div = d3.select("#charts").append("div") | |
div.append("p") | |
.text(chartData.key) | |
const svg = div.append("svg") | |
.attr("width", chartWidth + margin.left + margin.right) | |
.attr("height", chartHeight + margin.top + margin.bottom); | |
const g = svg.append("g") | |
.attr("transform", "translate(" | |
+ (margin.left + chartRadius) | |
+ "," | |
+ (margin.top + chartRadius) + ")"); | |
g.datum(chartData.values) | |
.call(heatmap); | |
g.selectAll(".arc").selectAll("path") | |
.style("fill", function (d) { return colour(d.value); }) | |
}) | |
}) | |
function convertTextToNumbers(d) { | |
d.value = +d.value; | |
d.date = dateParse(d.date); | |
d.year = yearFormat(d.date); | |
d.month = monthFormat(d.date); | |
return d; | |
}; | |
</script> | |
</body> |