Skip to content

Instantly share code, notes, and snippets.

@jwilber
Last active October 13, 2018 23:14
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 jwilber/91d19a05e4909e6d525c7b600655b052 to your computer and use it in GitHub Desktop.
Save jwilber/91d19a05e4909e6d525c7b600655b052 to your computer and use it in GitHub Desktop.
(Radial) bar chart
license: mit
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