block by bricedev 0a9bf537a64a55ab1fe8

Grouped Radial Bar Chart

Full Screen

A radial, fancy and almost unreadable version of the classic Grouped Bar Chart from mbostock.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.x.axis path {
  display: none;
}

</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>

var width = 960,
    height = 700,
    barHeight = height / 2 - 40;

var formatNumber = d3.format("s");

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

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

d3.json("data.json", function(error, data) {

  var statesNames = data.map(function(d) { return d.State; });
  var ageNames = data[0].ages.map(function(d) { return d.name; });

  var barScale = d3.scale.linear()
      .domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })])
      .range([0, barHeight]);

  var numBarsStates = statesNames.length ;
  var numBarsAges = ageNames.length ;

  var x = d3.scale.linear()
      .domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })])
      .range([0, -barHeight]);

  var xAxis = d3.svg.axis()
      .scale(x).orient("left")
      .ticks(5)
      .tickFormat(formatNumber);
      
  var circles = svg.selectAll("circle")
          .data(x.ticks(5))
        .enter().append("circle")
          .attr("r", function(d) {return barScale(d);})
          .style("fill", "none")
          .style("stroke", "black")
          .style("stroke-dasharray", "2,2")
          .style("stroke-width",".5px");

  var states = svg.selectAll(".state")
      .data(data)
    .enter().append("g")
      .attr("class", "state")
      .attr("transform", function(d,i) { return "rotate(" + (i * 360 / numBarsStates) + ")"; });

  var arc = d3.svg.arc()
      .startAngle(function(d,i) { return (i * 2 * Math.PI) / (numBarsAges*numBarsStates); })
      .endAngle(function(d,i) { return ((i + 1) * 2 * Math.PI) / (numBarsAges*numBarsStates); })
      .innerRadius(0);
  
  var segments = states.selectAll("path")
          .data(function(d) { return d.ages; })
        .enter().append("path")
          .each(function(d) { d.outerRadius = 0; })
          .style("fill", function (d) { return color(d.name); })
          .attr("d", arc);

  segments.transition().ease("elastic").duration(1200).delay(function(d,i,u) { return u * 200 + 400;})
          .attrTween("d", function(d,index) {
            var i = d3.interpolate(d.outerRadius, barScale(d.value));
            return function(t) { d.outerRadius = i(t); return arc(d,index); };
          });

  svg.append("circle")
      .attr("r", barHeight)
      .classed("outer", true)
      .style("fill", "none")
      .style("stroke", "black")
      .style("stroke-width","1.5px");

  states.selectAll("line")
        .data(function(d) { return d.ages; })
      .enter().append("line")
        .attr("y2", function(d,i) { return i===0 ? -barHeight - 20 : -barHeight; })
        .style("stroke", "black")
        .style("stroke-width", function(d,i) { return i===0 ? "1px" : "0.2px"; })
        .attr("transform", function(d, i) { return "rotate(" + (i * 360 / (numBarsAges*numBarsStates)) + ")"; });

  svg.append("g")
      .attr("class", "x axis")
      .call(xAxis);

  // Labels
  var labelRadius = barHeight * 1.025;

  var labels = svg.append("g")
      .classed("labels", true);

  labels.append("def")
        .append("path")
        .attr("id", "label-path")
        .attr("d", "m0 " + -labelRadius + " a" + labelRadius + " " + labelRadius + " 0 1,1 -0.01 0");

  labels.selectAll("text")
        .data(statesNames)
      .enter().append("text")
        .style("text-anchor", "middle")
        .style("font-weight","bold")
        .style("fill", function(d, i) {return "#3e3e3e";})
        .append("textPath")
        .attr("xlink:href", "#label-path")
        .attr("startOffset", function(d, i) {return i * 100 / numBarsStates + 50 / numBarsStates + '%';})
        .text(function(d) {return d.toUpperCase(); });

  // legend
  var legend = svg.selectAll(".legend")
      .data(ageNames.slice().reverse())
    .enter().append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate("+ -width/2 + "," + (-(height/2 - 20) + (i * 20)) + ")"; });

  legend.append("rect")
        .attr("x", width - 33)
        .attr("width", 18)
        .attr("height", 18)
        .style("fill", color);

  legend.append("text")
        .attr("x", width - 39)
        .attr("y", 9)
        .attr("dy", ".35em")
        .style("text-anchor", "end")
        .text(function(d) { return d; });

});

d3.select(self.frameElement).style("height", height + "px");

</script>

data.json

[
    {
        "State": "CA", 
        "ages": [
            {
                "name": "Under 5 Years", 
                "value": 2704659
            }, 
            {
                "name": "5 to 13 Years", 
                "value": 4499890
            }, 
            {
                "name": "14 to 17 Years", 
                "value": 2159981
            }, 
            {
                "name": "18 to 24 Years", 
                "value": 3853788
            }, 
            {
                "name": "25 to 44 Years", 
                "value": 10604510
            }, 
            {
                "name": "45 to 64 Years", 
                "value": 8819342
            }, 
            {
                "name": "65 Years and Over", 
                "value": 4114496
            }
        ]
    }, 
    {
        "State": "TX", 
        "ages": [
            {
                "name": "Under 5 Years", 
                "value": 2027307
            }, 
            {
                "name": "5 to 13 Years", 
                "value": 3277946
            }, 
            {
                "name": "14 to 17 Years", 
                "value": 1420518
            }, 
            {
                "name": "18 to 24 Years", 
                "value": 2454721
            }, 
            {
                "name": "25 to 44 Years", 
                "value": 7017731
            }, 
            {
                "name": "45 to 64 Years", 
                "value": 5656528
            }, 
            {
                "name": "65 Years and Over", 
                "value": 2472223
            }
        ]
    }, 
    {
        "State": "NY", 
        "ages": [
            {
                "name": "Under 5 Years", 
                "value": 1208495
            }, 
            {
                "name": "5 to 13 Years", 
                "value": 2141490
            }, 
            {
                "name": "14 to 17 Years", 
                "value": 1058031
            }, 
            {
                "name": "18 to 24 Years", 
                "value": 1999120
            }, 
            {
                "name": "25 to 44 Years", 
                "value": 5355235
            }, 
            {
                "name": "45 to 64 Years", 
                "value": 5120254
            }, 
            {
                "name": "65 Years and Over", 
                "value": 2607672
            }
        ]
    }, 
    {
        "State": "FL",  
        "ages": [
            {
                "name": "Under 5 Years", 
                "value": 1140516
            }, 
            {
                "name": "5 to 13 Years", 
                "value": 1938695
            }, 
            {
                "name": "14 to 17 Years", 
                "value": 925060
            }, 
            {
                "name": "18 to 24 Years", 
                "value": 1607297
            }, 
            {
                "name": "25 to 44 Years", 
                "value": 4782119
            }, 
            {
                "name": "45 to 64 Years", 
                "value": 4746856
            }, 
            {
                "name": "65 Years and Over", 
                "value": 3187797
            }
        ]
    }, 
    {
        "State": "IL", 
        "ages": [
            {
                "name": "Under 5 Years", 
                "value": 894368
            }, 
            {
                "name": "5 to 13 Years", 
                "value": 1558919
            }, 
            {
                "name": "14 to 17 Years", 
                "value": 725973
            }, 
            {
                "name": "18 to 24 Years", 
                "value": 1311479
            }, 
            {
                "name": "25 to 44 Years", 
                "value": 3596343
            }, 
            {
                "name": "45 to 64 Years", 
                "value": 3239173
            }, 
            {
                "name": "65 Years and Over", 
                "value": 1575308
            }
        ]
    }, 
    {
        "State": "PA",  
        "ages": [
            {
                "name": "Under 5 Years", 
                "value": 737462
            }, 
            {
                "name": "5 to 13 Years", 
                "value": 1345341
            }, 
            {
                "name": "14 to 17 Years", 
                "value": 679201
            }, 
            {
                "name": "18 to 24 Years", 
                "value": 1203944
            }, 
            {
                "name": "25 to 44 Years", 
                "value": 3157759
            }, 
            {
                "name": "45 to 64 Years", 
                "value": 3414001
            }, 
            {
                "name": "65 Years and Over", 
                "value": 1910571
            }
        ]
    }
]