score:3

Accepted answer

here's a quick implementation which replicates your diagram. it essentially builds concentric donut charts based on weight and then colors the slices based on points:

<!doctype html>
<meta charset="utf-8">
<style> 
  .arc path {
    stroke: #fff;
  }
</style>

<body>
  <script src="//d3js.org/d3.v3.min.js"></script>
  <script>
    var testdata = {
      maxpoints: 10,
      color: '#bababa',
      border: {
        width: 1,
        color: '#ffffff'
      },
      items: [{
        name: 'looks',
        color: '#2976dd',
        weight: 0.37,
        points: 8
      }, {
        name: 'charm',
        color: '#87bd24',
        weight: 0.03,
        points: 5
      }, {
        name: 'honesty',
        color: '#406900',
        weight: 0.16,
        points: 7
      }, {
        name: 'humour',
        color: '#ffb200',
        weight: 0.31,
        points: 9
      }, {
        name: 'intelligence',
        color: '#f78200',
        weight: 0.12,
        points: 0
      }]
    };

    var width = 500,
      height = 500;
      color = d3.scale.category20();
    
    // inner radius
    var ir = 75,
    // radius of each concentric arc
        r = ((math.min(width, height) / 2) - ir)  / testdata.maxpoints;
        
    var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d.weight;
      })
      .padangle(.01);

  var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var g = svg.selectall(".arc")
      .data(pie(testdata.items))
      .enter().append("g")
      .attr("class", "arc");

    // iterate our number of rings
    d3.range(testdata.maxpoints)
      .foreach(function(i){
        
        // generate an arc
        var arc = d3.svg.arc()
            .outerradius(r * (i + 1) + ir)
            .innerradius(r * i + ir);
        
        // fill it, if appropriate
        g.append("path")
          .attr("d", arc)
          .style("fill", function(d) {
            if (i < d.data.points)
              return color(d.data.name);
            else
              return "#eee"
          });
    });

  </script>


Related Query

More Query from same tag