D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
john-guerra
Full window
Github gist
2017 US Federal Budget
Built with
blockbuilder.org
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>US Federal Budget</title> <style> body { font-family: sans-serif; } </style> </head> <body> <input type="checkbox" id="chkBEA"><label for="chkBEA">Group by BEA Category</label> <input type="checkbox" id="chkGrant"><label for="chkGrant">Group by Grant</label> <div id="budget"></div> <script src="//d3js.org/d3.v4.min.js"></script> <script> /* global d3 */ var width = 900, height = 400, svg = d3.select("#budget") .append("svg") .attr("width", width) .attr("height", height), rScale = d3.scalePow().exponent(0.5) // A scale for areas Pi*r^2 .range([1, 50]), cScale = d3.scaleOrdinal(d3.schemeCategory10), yScale = d3.scaleBand() .range([50, height]), xScale = d3.scaleBand() .range([70, width]); function preprocess(row) { if (row["2017"]==="0") return null; row["2017"] = +(row["2017"].replace(new RegExp(",", "g"), "")); return row; } d3.csv("outlays.csv", preprocess, function (err, data) { if (err) throw err; var nestedData = d3.nest() .key(function (d) { return d["Grant/non-grant split"]; }) .key(function (d) { return d["BEA Category"]; }) .key(function (d) { return d["Agency Name"]; }) // .key(function (d) { return d["Bureau Name"]; }) .rollup(function(leaves) { return { "length": leaves.length, "budget": d3.sum(leaves, function(d) { return +d["2017"]; }) }; }) .entries(data); var flatAgencies = []; nestedData.forEach(function (g) { g.values.forEach(function (bea) { bea.values.forEach(function (a) { a.bea = bea.key; a.grant = g.key; flatAgencies.push(a); }); }); }); xScale.domain(nestedData[0].values.map(function (d) { return d.key; })); yScale.domain(nestedData.map(function (d) { return d.key; })); rScale.domain([0, d3.max(flatAgencies, function (d) { return d.value.budget; })]); var simulation = d3.forceSimulation(flatAgencies) .force("collide", d3.forceCollide().radius(function (d) { return rScale(d.value.budget)+1; })) .force("x", d3.forceX(width/2)) // .force("y", ) .force("y", d3.forceY(height/2)) .on("tick", ticked); var cs = svg.selectAll("circle") .data(flatAgencies); var csEnter = cs.enter() .append("circle") .style("fill", function (d) { return cScale(d.bea); }) .attr("r", function (d) { return rScale(d.value.budget); }); csEnter.append("title") .text(function (d) { return d.key + " $" + d.value.budget/1000000 + "M"; }); svg.append("g") .attr("class", "axis y") .style("display", "none") .call(d3.axisLeft(yScale)) .attr("transform", "translate(70,0)"); svg.append("g") .attr("class", "axis x") .style("display", "none") .call(d3.axisTop(xScale)) .attr("transform", "translate(0,50)"); d3.select("#chkBEA").on("change", function () { simulation.force("x", d3.event.target.checked ? d3.forceX(function (d) { return xScale(d.bea) + xScale.bandwidth()/2; }).strength(0.3) : d3.forceX(width/2) ); svg.select(".x.axis").style("display", d3.event.target.checked ? "block" : "none"); simulation.alpha(0.3).restart(); }); d3.select("#chkGrant").on("change", function () { simulation.force("y", d3.event.target.checked ? d3.forceY(function (d) { return yScale(d.grant) + yScale.bandwidth()/2; }).strength(0.3) : d3.forceY(height/2) ); svg.select(".y.axis").style("display", d3.event.target.checked ? "block" : "none"); simulation.alpha(0.3).restart(); }); function ticked() { csEnter.merge(cs) .attr("cx", function (d) { return d.x; }) .attr("cy", function (d) { return d.y; }); } }); </script> </body> </html>
https://d3js.org/d3.v4.min.js