Built with blockbuilder.org
forked from john-guerra's block: 2017 US Federal Budget
forked from john-guerra's block: 2017 US Federal Budget Template
xxxxxxxxxx
<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[0].values.map(function (d) { return d.grant; }));
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 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(width/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