Radial bar chart inspired by Peter Cook's work.
forked from bricedev's block: Radial Bar Chart
license: mit |
Radial bar chart inspired by Peter Cook's work.
forked from bricedev's block: Radial Bar Chart
name | value | |
---|---|---|
Everyday Spending | 2 | |
Savings | 1 | |
Investments | 0 | |
Pensions | 2 | |
Property | 3 |
<!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 = 500, | |
height = 500, | |
barHeight = height / 2 - 40; | |
var formatNumber = d3.format("s"); | |
var color = d3.scale.ordinal() | |
.domain([1, 2, 3]) | |
.range(["#C50000","#F9B001","#4CC500"]); | |
var svg = d3.select('body').append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
.append("g") | |
.attr("transform", "translate(" + width/2 + "," + height/2 + ")"); | |
d3.csv("data.csv", function(error, data) { | |
var extent = d3.extent(data, function(d) { return d.value; }); | |
var barScale = d3.scale.linear() | |
.domain(extent) | |
.range([0, barHeight]); | |
var keys = data.map(function(d,i) { return d.name; }); | |
var numBars = keys.length; | |
var x = d3.scale.linear() | |
.domain(extent) | |
.range([0, -barHeight]); | |
var xAxis = d3.svg.axis() | |
.scale(x).orient("left") | |
.ticks(3) | |
.tickFormat(formatNumber); | |
var circles = svg.selectAll("circle") | |
.data(x.ticks(3)) | |
.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 arc = d3.svg.arc() | |
.startAngle(function(d,i) { return (i * 2 * Math.PI) / numBars; }) | |
.endAngle(function(d,i) { return ((i + 1) * 2 * Math.PI) / numBars; }) | |
.innerRadius(0); | |
var segments = svg.selectAll("path") | |
.data(data) | |
.enter().append("path") | |
.each(function(d) { d.outerRadius = 0; }) | |
.style("fill", function (d) { return color(d.value); }) | |
.attr("d", arc); | |
segments.transition().ease("elastic").duration(800).delay(function(d,i) {return (5-i)*100;}) | |
.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"); | |
var lines = svg.selectAll("line") | |
.data(keys) | |
.enter().append("line") | |
.attr("y2", -barHeight - 20) | |
.style("stroke", "black") | |
.style("stroke-width",".5px") | |
.attr("transform", function(d, i) { return "rotate(" + (i * 360 / numBars) + ")"; }); | |
// 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(keys) | |
.enter().append("text") | |
.style("text-anchor", "middle") | |
.style("font-size","15px") | |
.style("fill", function(d, i) {return "#3e3e3e";}) | |
.append("textPath") | |
.attr("xlink:href", "#label-path") | |
.attr("startOffset", function(d, i) {return i * 100 / numBars + 50 / numBars + '%';}) | |
.text(function(d) {return d.toUpperCase(); }); | |
}); | |
</script> |