D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
seasmith
Full window
Github gist
Side-by-side bar charts
Two bar charts, side-by-side.
<!DOCTYPE html> <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