'use strict'; var w = 960, h = 600, r = 80, // radius rings = 15; // level of brightness var svg = d3.select('#vis').append('svg').attr({ width: w, height: h }); // use some colours (the scale) as 'data' var colours = d3.scale.category20b(); var angle = d3.scale.linear().domain([0, 20]).range([0, 2 * Math.PI]); // arc generator var arc = d3.svg.arc().innerRadius(function (d) { return d * r / rings; }).outerRadius(function (d) { return r + d * r / rings; }).startAngle(function (d, i, j) { return angle(j); }).endAngle(function (d, i, j) { return angle(j + 1); }); // two data accessors to set ring shades // https://github.com/mbostock/d3/wiki/Colors#rgb_brighter var shade = { darker: function darker(d, j) { return d3.rgb(colours(j)).darker(d / rings); }, brighter: function brighter(d, j) { return d3.rgb(colours(j)).brighter(d / rings); }, normal: function normal(d, j) { return d3.rgb(colours(j)); } }; // use array of triplets, each defining colour wheel's position // and which shader to apply [[r * 2, r * 2, shade.darker], [r * 6, r * 2, shade.normal], [r * 10, r * 2, shade.brighter]].forEach(function (conf) { svg.append('g').attr('transform', 'translate(' + conf[0] + ', ' + conf[1] + ')').selectAll('g').data(colours.range()).enter().append('g').selectAll('path').data(function (d) { return d3.range(0, rings); }).enter().append('path').attr('d', arc).attr('fill', function (d, i, j) { return conf[2](d, j); }); // make the circles into donuts! svg.append('circle').attr({ transform: 'translate(' + conf[0] + ', ' + conf[1] + ')', r: r, fill: '#eee' }); });