Two bar charts, side-by-side.
xxxxxxxxxx
<html>
<meta charset="utf-8">
<style>
h1, h2, h3 {
font-family: "Lato", "Open Sans", "sans-serif";
margin: 0px;
padding: 0px;
}
text {
font-family: "Lato", "Open Sans", "sans-serif";
font-size: 22px;
margin-top: 15px;
margin-bottom: 0px;
border: 0px;
padding: 0px;
}
.bar--positive {
fill: steelblue;
}
.bar--negative {
fill: brown;
}
.value {
font-size: 10px;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<div class="text-things">
<h1>US Weekly Oil and Gas Rig Count</h1>
<h2>Week of December 8, 2017</h2>
</div>
<svg width="1200" height="350">
<g id="first" transform="translate(0, 30)">
<text>Weekly net change</text>
</g>
<g id="second" transform="translate(560, 30)">
<text>Yearly net change</text>
</g>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<!--<script src="weekly-net-change.js"></script>
<script src="yearly-net-change.js"></script>-->
<script>
var svg = d3.select("svg"),
margin = {top: 30, right: 10, bottom: 60, left: 10},
width = (+svg.attr("width") / 2.25) - margin.left - margin.right,
height = (+svg.attr("height") / 1) - margin.top - margin.bottom;
var x = d3.scaleLinear()
.range([0, width]);
var y = d3.scaleBand()
.rangeRound([0, height])
.padding(0.1);
var gContainer = svg.append("g")
.attr("transform", "translate(0, 30)")
.classed("weekly-container", true);
var g = gContainer.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("rc-weekly-net-change.csv", type, function(error, data) {
if (error) throw errror;
x.domain(d3.extent(data, function(d) { return d.change; })).nice();
y.domain(data.map(function(d) { return d.formation;}));
g.append("g")
.attr("class", "axis axis-x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(6));
var tickNegative = g.append("g")
.attr("class", "axis axis--y")
.attr("transform", "translate(" + x(0) + ",0)")
.call(d3.axisLeft(y))
.selectAll(".tick")
.filter(function(d, i) { return data[i].change < 0; });
tickNegative.select("line")
.attr("x2", 6);
tickNegative.select("text")
.attr("x", 9)
.style("text-anchor", "start");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", function(d) { return "bar bar--" + (d.change < 0 ? "negative" : "positive"); })
.attr("x", function(d) { return x(Math.min(0, d.change)); })
.attr("y", function(d) { return y(d.formation); })
.attr("width", function(d) { return Math.abs(x(d.change) - x(0)); })
.attr("height", y.bandwidth());
g.selectAll(".value")
.data(data)
.enter().append("text")
.attr("class", "value")
.attr("x", function(d){
if (d.change < 0){
return (x(d.change * -1) - x(0)) > 20 ? x(d.change) + 2 : x(d.change) - 1;
} else {
return (x(d.change) - x(0)) > 20 ? x(d.change) - 2 : x(d.change) + 1;
}})
.attr("y", function(d){ return y(d.formation); })
.attr("dy", y.bandwidth() - 8)
.attr("text-anchor", function(d){
if (d.change < 0){
return (x(d.change * -1) - x(0)) > 20 ? "start" : "end";
} else {
return (x(d.change) - x(0)) > 20 ? "end" : "start";
}})
.style("fill", function(d){
if (d.change < 0){
return (x(d.change * -1) - x(0)) > 20 ? "#fff" : "#3a403d";
} else {
return (x(d.change) - x(0)) > 20 ? "#fff" : "#3a403d";
}})
.text(function(d){ return d.change; });
})
function type(d) {
d.change = +d.change;
return d;
}
var margin2 = {top: 30, right: 60, bottom: 60, left: 20},
width2 = (+svg.attr("width") / 1.75) - margin2.left - margin2.right,
height2 = (+svg.attr("height") / 1) - margin2.top - margin2.bottom;
var x2 = d3.scaleLinear()
.range([0, width2]);
var y2 = d3.scaleBand()
.rangeRound([0, height2])
.padding(0.1);
var gContainer2 = svg.append("g")
.attr("transform", "translate(560, 30)")
.classed("yearly-container", true);
var g2 = gContainer2.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
d3.csv("rc-yearly-net-change.csv", type, function(error, data) {
if (error) throw errror;
x2.domain(d3.extent(data, function(d) { return d.change; })).nice();
y2.domain(data.map(function(d) { return d.formation;}));
g2.append("g")
.attr("class", "axis axis-x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x2).ticks(6));
var tickNegative = g2.append("g")
.attr("class", "axis axis--y")
.attr("transform", "translate(" + x2(0) + ",0)")
.call(d3.axisLeft(y2))
.selectAll(".tick")
.filter(function(d, i) { return data[i].change < 0; });
tickNegative.select("line")
.attr("x2", 6);
tickNegative.select("text")
.attr("x", 9)
.style("text-anchor", "start");
g2.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", function(d) { return "bar bar--" + (d.change < 0 ? "negative" : "positive"); })
.attr("x", function(d) { return x2(Math.min(0, d.change)); })
.attr("y", function(d) { return y2(d.formation); })
.attr("width", function(d) { return Math.abs(x2(d.change) - x2(0)); })
.attr("height", y2.bandwidth());
g2.selectAll(".value")
.data(data)
.enter().append("text")
.attr("class", "value")
.attr("x", function(d){
if (d.change < 0){
return (x2(d.change * -1) - x2(0)) > 20 ? x2(d.change) + 2 : x2(d.change) - 1;
} else {
return (x2(d.change) - x2(0)) > 20 ? x2(d.change) - 2 : x2(d.change) + 1;
}})
.attr("y", function(d){ return y2(d.formation); })
.attr("dy", y2.bandwidth() - 4)
.attr("text-anchor", function(d){
if (d.change < 0){
return (x2(d.change * -1) - x2(0)) > 20 ? "start" : "end";
} else {
return (x2(d.change) - x2(0)) > 20 ? "end" : "start";
}})
.style("fill", function(d){
if (d.change < 0){
return (x2(d.change * -1) - x2(0)) > 20 ? "#fff" : "#3a403d";
} else {
return (x2(d.change) - x2(0)) > 20 ? "#fff" : "#3a403d";
}})
.text(function(d){ return d.change; });
})
function type(d) {
d.change = +d.change;
return d;
}
</script>
</html>
https://d3js.org/d3.v4.min.js