Skip to content

Instantly share code, notes, and snippets.

Created November 14, 2017 15:50
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 anonymous/8d9d0500a5f9639c755d10d4d1dbf1bc to your computer and use it in GitHub Desktop.
Save anonymous/8d9d0500a5f9639c755d10d4d1dbf1bc to your computer and use it in GitHub Desktop.
Reading - Grouped Bar Chart D3 V4
license: gpl-3.0

This grouped bar chart is constructed from a CSV file storing the populations of different states by age group. The chart employs conventional margins and a number of D3 features:

forked from mbostock's block: Grouped Bar Chart

forked from alandunning's block: Reading - Grouped Bar Chart D3 V4

State Pre-treatment Post Treatment Post Treatment2
Seperation Anxiety 80 73 71
Generalised Anxiety 77 75 73
Panic 75 73 79
Socail pHOBIA 81 70 70
OCD 66 65 68
Depression 75 74 79
0 0 0
Total Anxiety 77 73 70
Total Anxiety & Depression 81 69 77
<!DOCTYPE html>
<style>
.axis .domain {
display: none;
}
body {
font-family: 'Droid Sans', sans-serif;
}
.axis {
font-size: 14px;
font-weight: bold;
}
text {
fill: #727075;
stroke: none;
}
.axis path,
.axis line {
fill: none;
stroke: none;
stroke-width: 2px;
shape-rendering: crispEdges;
}
.grid path {
stroke: none;
}
.grid line {
stroke: #E0E0E0;
shape-rendering: crispEdges;
}
.data-line {
fill: none;
stroke: #3C92BA;
stroke-width: 4px;
}
.data-circle {
fill: #3C92BA;
}
.axis-title {
text-anchor: end;
fill: #5D6971;
font-weight: normal;
}
.axis-tspan {
font-size: 12px;
}
.clinical-cut-off-line {
fill: none;
stroke: #333333;
stroke-dasharray: 8,8;
stroke-width: 4px;
}
.clinical-cut-off-text {
text-transform: uppercase;
text-anchor: start;
font-size: 12px;
font-weight: bold;
fill: #333333;
stroke: none
}
@-webkit-keyframes pulse
{
0% {opacity: 1;}
50% {opacity: 0.3;}
100% {opacity: 1;}
}
.bars-container-middle {
fill: none
}
.blah {
fill: pink;
/* Giving Animation Function */
-webkit-animation: pulse 1.5s ease infinite;
}
</style>
<link href="https://fonts.googleapis.com/css?family=Droid+Sans:400,700" rel="stylesheet">
<svg width="730" height="375"></svg>
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <pattern id="diagonal-stripe-1" patternUnits="userSpaceOnUse" width="10" height="10"> <image xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSd3aGl0ZScvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J2JsYWNrJyBzdHJva2Utd2lkdGg9JzEnLz4KPC9zdmc+Cg==" x="0" y="0" width="10" height="10"> </image> </pattern> </defs> </svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x0 = d3.scaleBand()
.rangeRound([0, width])
.paddingInner(0.2);
var x1 = d3.scaleBand()
.padding(0.1);
var y = d3.scaleLinear()
.rangeRound([(height / 1.4), 0]);
var z = d3.scaleOrdinal()
.range(["#37A3D6", "#FF9400", "#ff0000"]);
var clinicalCutOffValue = 65;
d3.csv("data.csv", function(d, i, columns) {
for (var i = 1, n = columns.length; i < n; ++i) d[columns[i]] = +d[columns[i]];
return d;
}, function(error, data) {
if (error) throw error;
var keys = data.columns.slice(1);
x0.domain(data.map(function(d) { return d.State; }));
x1.domain(keys).rangeRound([0, x0.bandwidth()]);
y.domain([
(Math.floor(d3.min(data, function(d) { return d3.max(keys, function(key) { return d[key]; }); }) / 10) * 10),
(Math.ceil(d3.max(data, function(d) { return d3.max(keys, function(key) { return d[key]; }); }) / 10) * 10)
]);
// add the Y gridlines
g.append("g")
.attr("class", "grid")
.call(d3.axisLeft(y)
.tickSize(-width)
.tickFormat("")
.ticks(6)
);
var barG = g.append("g")
.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; });
// barG.selectAll(".bars-container-back")
// .data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })
// .enter()
// .append("rect")
// .attr("class", "bars-container-back")
// .attr("x", function(d) { return x1(d.key) - 4; })
// .attr("y", function(d) { return y(d.value) - 4; })
// .attr("width", x1.bandwidth() + 8)
// .attr("height", function(d) { return (height / 1.4) - y(d.value) + 3; })
// .attr("fill", "white")
// .attr("stroke-width", "2px")
// .attr("stroke", "transparent")
// .attr("stroke-dasharray", "6,4")
// .attr("shape-rendering", "crispEdges")
// .transition()
// .delay(500)
// .duration(150)
// .attr("stroke", "#727075");
barG.selectAll(".bars-container-middle")
.data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })
.enter()
.append("rect")
.attr("class", function(d) {
if (d.value > 75) return 'bars-container-middle blah';
else return 'bars-container-middle';
})
.attr("x", function(d) { return x1(d.key); })
.attr("y", function(d) { return 0; })
.attr("width", x1.bandwidth())
.attr("stroke", "none")
.transition()
.delay(function (d,i){ return 750;}) // this is to do left then right bars
.duration(250)
.attr('height', function( d ) { return ((height / 1.4));});;
barG.selectAll(".bars")
.data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })
.enter()
.append("rect")
.attr("class", "bars")
.attr("x", function(d) { return x1(d.key); })
.attr("width", x1.bandwidth())
.attr("fill", function(d) { return z(d.key); })
.attr("y", (height / 1.4))
.transition()
.delay(function (d,i){ return i * 250;}) // this is to do left then right bars
.duration(250)
.attr("y", function(d) { return y(d.value); })
.attr('height', function( d ) { return ((height / 1.4)) - y( d.value );});
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (height / 1.4) + ")")
.call(d3.axisBottom(x0))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)")
.text(function (d) {
if(d.length > 14) { return d.substring(0,14)+'...'; }
else { return d; }
});
g.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(6));
var legend = g.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.selectAll("g")
.data(keys.slice().reverse())
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", z);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9.5)
.attr("dy", "0.32em")
.text(function(d) { return d; });
// Clinicial cut off line and text group
var clinicalCutOffLineAndText = g.append("g")
.attr("class", "clinical-cut-off-line-and-text")
// Clinicial cut off line
clinicalCutOffLineAndText.append("line")
.attr("class", "clinical-cut-off-line")
.attr("x1", 0)
.attr("y1", y(clinicalCutOffValue))
.attr("x2", width)
.attr("y2", y(clinicalCutOffValue));
// Clinicial cut off text
clinicalCutOffLineAndText.append("text")
.attr("class", "clinical-cut-off-text")
.attr("y", y(clinicalCutOffValue))
.attr("dy","20px")
.text("Clinical Cut-off");
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment