Skip to content

Instantly share code, notes, and snippets.

@bricedev
Last active May 23, 2017 00:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bricedev/7952923003a8cf0ecb45 to your computer and use it in GitHub Desktop.
Save bricedev/7952923003a8cf0ecb45 to your computer and use it in GitHub Desktop.
Sortable Radial Bar Chart

This variation of the radial bar chart adds sorting. Use the checkbox in the top right to turn sorting on or off.

name value
A .08167
B .01492
C .02782
D .04253
E .12702
F .02288
G .02015
H .06094
I .06966
J .00153
K .00772
L .04025
M .02406
N .06749
O .07507
P .01929
Q .00095
R .05987
S .06327
T .09056
U .02758
V .00978
W .02360
X .00150
Y .01974
Z .00074
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
position: relative;
width: 960px;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
label {
position: absolute;
top: 10px;
right: 10px;
}
</style>
<body>
<label><input type="checkbox"> Sort values</label>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
barHeight = height / 2 - 40;
var formatNumber = d3.format("s");
var color = d3.scale.ordinal()
.range(["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"]);
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();
var segments = svg.selectAll("path")
.data(data)
.enter().append("path")
.each(function(d,i) {
d.innerRadius = 0;
d.outerRadius = barScale(+d.value);
d.startAngle = (i * 2 * Math.PI) / numBars;
d.endAngle = ((i + 1) * 2 * Math.PI) / numBars;
})
.style("fill", function (d) { return color(d.name); })
.attr("d", arc);
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(data)
.enter().append("text")
.style("text-anchor", "middle")
.style("font-weight","bold")
.style("fill", function(d, i) {return "#3e3e3e";})
.append("textPath")
.attr("class","textpath")
.attr("xlink:href", "#label-path")
.attr("startOffset", function(d,i) {return i * 100 / numBars + 50 / numBars + '%';})
.text(function(d) {return d.name.toUpperCase(); });
d3.select("input").on("change", change);
function change() {
if (this.checked) {
labels.selectAll(".textpath").sort(function(a,b) { return b.value - a.value; });
segments.sort(function(a,b) { return b.value - a.value; });
}else {
labels.selectAll(".textpath").sort(function(a,b) { return d3.ascending(a.name, b.name) });
segments.sort(function(a,b) { return d3.ascending(a.name, b.name); });
};
segments.transition().duration(2000).delay(100)
.attrTween("d", function(d,index) {
var i = d3.interpolate(d.startAngle, (index * 2 * Math.PI) / numBars );
var u = d3.interpolate(d.endAngle, ((index + 1) * 2 * Math.PI) / numBars );
return function(t) { d.endAngle = u(t); d.startAngle = i(t); return arc(d,index); };
});
labels.selectAll(".textpath").transition().duration(2000).delay(100)
.attr("startOffset", function(d,i) {return i * 100 / numBars + 50 / numBars + '%'; })
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment