D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
jadiehm
Full window
Github gist
Horizontal bar chart with button scale transition
<!doctype html> <html lang='en-GB'> <head></head> <style> p { font-family: sans-serif; font-size: 14px; } /*template styles*/ .gia-chart-wrapper { max-width: 620px; margin: 0 auto; } /*chart styles*/ .x.axis line { fill: none; stroke: #dcdcdc; stroke-dasharray: 1px 1px; shape-rendering: crispEdges; stroke-width: 1px; } .y.axis line { display: none; } .tick.g-baseline line { display: none; } .x.axis text { font-family: sans-serif; text-anchor: middle !important; font-size: 12px; pointer-events: none; fill: #bdbdbd; } .y.axis text { display: none; } .g-axis-text { font-family: sans-serif; text-anchor: start !important; font-size:13px; fill: #333333; font-weight: 700; } .domain { display: none; } .bar-positive { fill: #dcdcdc; } .bar-negative { fill: #d61d00; } .g-labels { font-family: sans-serif; font-size: 14px; fill: #767676; text-anchor: start !important; } button { background-color: #ffffff; border: 1px solid #dcdcdc; border-radius: 15px; color: #333333; padding: 5px 8px; cursor: pointer; display: inline-block; margin-right: 10px; text-align: center; text-decoration: none; font-size: 12px; line-height: 20px; font-family: sans-serif; } button:focus { outline: 0; } .active { background-color: #333333; color: #ffffff; border: 1px solid #333333; } .gia-key { margin-bottom: 15px; } </style> <body> <main> <div class='gia-chart-wrapper'> <div class='gia-key'></div> <div class='gia-chart'></div> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> <script> //Margin conventions var margin = {top: 0, right: 6, bottom:30, left: 170}; var widther = d3.select(".gia-chart").node().clientWidth; var width = widther - margin.left - margin.right, height = 500 - margin.top - margin.bottom; //Appends the svg to the chart-container div var svg = d3.select(".gia-chart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //Format comma var format = d3.format("0,000") //Creates the xScale var xScale = d3.scale.linear() .range([0,width]); //Creates the yScale var y0 = d3.scale.ordinal() .rangeRoundBands([height, 0], 0.1); //Defines the y axis styles var yAxis = d3.svg.axis() .scale(y0) .tickSize(-width) .tickPadding(6) .ticks(4) .orient("left"); //Defines the y axis styles var xAxis = d3.svg.axis() .scale(xScale) .tickSize(-height) .tickPadding(6) .orient("bottom") .ticks(6); //Loads the data d3.csv("budget.csv", ready); function ready(err, data) { if (err) throw "error loading data"; //FORMAT data data.forEach(function(d) { d.amount = +d.amount; d.percentChange = +d.percentChange; d.dollarChange = +d.dollarChange; }); //Sets the max for the xScale var maxX = d3.max(data, function(d) { return d.amount; }); var minX = d3.min(data, function(d) { return d.amount; }); //Filters the data initialType = data.filter(function(d) { return d.type === "Billions of $";}); //Defines the domains xScale.domain(d3.extent(initialType, function(d) { return d.amount; })).nice(); y0.domain(data.map(function(d) { return d.agency; })); //Organizes buttons data var types = data.map(function(d) { return d.type;}); var uniq = d3.set(types).values(); //Buttons var button = d3.select(".gia-key").selectAll("button") .data(uniq) .enter() .append("button") .attr("class", function (d) { if ( d === "Billions of $" ) { return 'active'; } else { return 'not-active'; } }) .text(function(d) {return d;}) .on("click", function(d) { updateChartForType(d); d3.select(".active").classed("active", false); d3.select(this).classed("active", true); }); var xAxisGroup = svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); xAxisGroup .selectAll("g") .classed("g-baseline", function(d) {return d == 0}); var yAxisGroup = svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + xScale(0) + ",0)") .call(yAxis); var bars = svg.selectAll(".bar") .data(initialType) .enter().append("rect") .attr("class", function(d) { return "bar-" + (d.amount < 0 ? "negative" : "positive"); }) .attr("x", function(d) { return xScale(Math.min(0, d.amount)); }) .attr("y", function(d) { return y0(d.agency); }) .attr("width", function(d) { return Math.abs(xScale(d.amount) - xScale(0)); }) .attr("height", y0.rangeBand()); //Append baseline var baseline = svg.append("line") .attr("y2", function(d) { return height; }) .attr("class", "added-baseline") .attr("x1", xScale(0)) .attr("x2", xScale(0)) .attr("stroke-width", 1) .attr("stroke", "#333333"); //Binds data to axis text var axisLabelGroup = svg.selectAll("g-axis-text") .data(initialType) .enter() .append("g") .attr("class", "g-axis-text") .attr("x", function(d) { return xScale(Math.min(0, d.amount)); }) .attr("y", function(d) { return y0(d.agency); }) .attr("width", function(d) { return Math.abs(xScale(d.amount) - xScale(0)); }) .attr("height", y0.rangeBand()); //Append axis labels var axisLabels = axisLabelGroup.append("text") .text(function(d) { return d.agency; }) .attr("x", function(d) { return xScale(0); }) .attr("y", function(d) { return y0(d.agency) + 17; }); d3.selectAll(".g-axis-text") .attr("transform", "translate(-265,0)"); //Update chart on click function updateChartForType(typeId) { //Filters to the new data var typeData = data.filter(function(d) { return d.type === typeId;}); //Updates domains xScale.domain(d3.extent(typeData, function(d) { return d.amount; })).nice(); y0.domain(data.map(function(d) { return d.agency; })); bars .data(typeData) .transition().duration(1000) .attr("x", function(d) { return xScale(Math.min(0, d.amount)); }) .attr("width", function(d) { return Math.abs(xScale(d.amount) - xScale(0)); }); xAxisGroup .transition().duration(1000) .call(xAxis); yAxisGroup .transition().duration(1000) .call(yAxis); baseline .transition().duration(1000) .attr("x1", xScale(0)) .attr("x2", xScale(0)) } //RESPONSIVENESS d3.select(window).on("resize", resized); function resized() { //new margin var newMargin = {top: 0, right: 6, bottom:30, left: 170}; var newWidther = d3.select(".gia-chart").node().clientWidth; var newWidth = newWidther - newMargin.left - newMargin.right; //Change the width of the svg d3.select("svg") .attr("width", newWidth + newMargin.left + newMargin.right); //Change the xScale xScale .range([0, newWidth]); //Update the bars bars .attr("width", function(d) { return Math.abs(xScale(d.amount) - xScale(0)); }) .attr("x", function(d) { return xScale(Math.min(0, d.amount)); }) //Updates xAxis d3.selectAll(".x.axis") .call(xAxis); //Updates ticks xAxis .scale(xScale); //Updates yAxis d3.selectAll(".y.axis") .attr("transform", "translate(" + xScale(0) + ",0)") .call(yAxis); yAxis .tickSize(-newWidth); baseline .attr("x1", xScale(0)) .attr("x2", xScale(0)); }; } </script> </body> </html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js