D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
abrown004
Full window
Github gist
Diverging Bar Chart
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600" rel="stylesheet" type="text/css"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { font-family: 'Open Sans'; color: #333333; } .axis { font-family: 'Open Sans'; color: #333333; font-weight: bold; font-size: 15px; } div.tooltip { position: absolute; text-align: left; max-width: 300px; /*height: 100px;*/ padding: 8px; font-size: 14px; font-family: 'Open Sans'; color: white; font-weight: 500; background: #123D4B; border: 1px solid black; border-radius: 4px; pointer-events: none; } </style> </head> <body> <script> // Define the variables var margin = {top:20, left:50, bottom:50, right:20}; var h = 500 - margin.top - margin.bottom; var w = 860 - margin.left - margin.right; var barPadding = 0.25; // Calculate the percent the sample exceeded the limit/benchmark/NAL var exceedance = function(value,limit) { return ((value - limit)/limit); } // Tooltip div var tooltip = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0); // Import the data d3.csv("data.csv",function(d) { d.parameter = d.parameter; d.percentExceeded = exceedance(+d.value,+d.limit); debugger; return d; }, function(error,inputData) { if (error) throw error; // Calculate the average percentExceeded for each parameter key function formatData(inputData){ var dictionary = d3.nest() .key(function(d){return d.parameter}) .rollup(function(v) {return d3.mean(v, function(d) {return d.percentExceeded; }); }) .entries(inputData.filter(x=>{return x.parameter && x.percentExceeded !== undefined && !isNaN(x.percentExceeded);})); return dictionary; } var dataset = formatData(inputData); // console.log(dataset // .sort(function(a,b) {return d3.descending(a.value,b.value);}) // .map(function(d){ return d.key;})); // debugger; // Create the SVG element a surrounding margin and make 0,0 past the margin var svg = d3.select("body") .append("svg") .attr("height", h + margin.top + margin.bottom) .attr("width", w + margin.left + margin.right) .append("g") .attr("transform","translate(" + margin.left + "," + margin.top + ")"); //sorting function: .sort(function(a,b) {return d3.descending(a.value,b.value);}) // // Define the y-axis (categorical) scale var yScale = d3.scaleBand() .domain(dataset.sort(function(a,b) { return d3.descending(a.value,b.value);}) .map(function(d){ return d.key;})) .rangeRound([h,0]) .padding(barPadding); var yAxis = d3.axisLeft() .scale(yScale); //Define the x-axis (continuous) scale var xScale = d3.scaleLinear() .domain(d3.extent(dataset.map(function(d){return d.value;}))) .rangeRound([0, w]); var xAxis = d3.axisBottom() .scale(xScale) .tickFormat(d3.format(".0%")); // Add rectangles (bars) where percentExceeded > 0 svg.append("g") .attr("class", "bars") .selectAll("rect") .data(dataset) .enter().append("rect") .filter(function(d) { return (d.value > 0); }) .attr("y",function(d) {return yScale(d.key); }) .attr("x",function(d){ return xScale(Math.min(0,d.value)); }) .attr("height", yScale.bandwidth()) .attr("width",function(d) {return Math.abs(xScale(d.value)-xScale(0)); }) .attr("fill","#e6550d") .on("mouseover", function(d) { tooltip.transition() .duration(200) .style("opacity", .9); tooltip.html("Average Percent Exceeding Limit: " + Math.abs(d.value*100).toFixed(1) + "%") .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY) + "px"); }) .on('mouseout', function (d) { tooltip.style("opacity", 0); }); // Add rectangles (bars) where percentExceeded <= 0 svg.append("g") .attr("class", "bars") .selectAll("rect") .data(dataset) .enter().append("rect") .filter(function(d) { return d.value <= 0 }) .attr("y",function(d) {return yScale(d.key); }) .attr("x",function(d){return xScale(Math.min(0, d.value)); }) .attr("height", yScale.bandwidth()) .attr("width",function(d) {return Math.abs(xScale(d.value)-xScale(0)); }) .attr("fill","#9ecae1") .on("mouseover", function(d) { tooltip.transition() .duration(200) .style("opacity", .9); tooltip.html("Average Percent Below Limit: " + Math.abs(d.value*100).toFixed(1) + "%") .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY) + "px"); }) .on('mouseout', function (d) { tooltip.style("opacity", 0); }); // Add the y-axis svg.append("g") .attr("class","axis") .attr("transform", "translate(" + xScale(0) + ",0)") .call(yAxis); // Number of keys where percentExceeded <= 0 var n = dataset.map(function(d) {return d.value;}).filter( function(d) { return d <= 0; }).length // Add the x-axis svg.append("g") .attr("class","axis") .attr("transform", "translate(0," + h/dataset.map(function(d) {return d.key;}).length*n + ")") .call(xAxis); }); </script> </body>
https://d3js.org/d3.v4.min.js