Skip to content

Instantly share code, notes, and snippets.

@ilanman
Last active January 2, 2016 21:59
Show Gist options
  • Save ilanman/8366624 to your computer and use it in GitHub Desktop.
Save ilanman/8366624 to your computer and use it in GitHub Desktop.
Congressional Bills

This chart compares congressional workload over the years to the appropriations they are given. There is also the option of looking at the U.S. CPI over the same time to highlight the discrepancy. I am using d3-tip for my tooltips. More context around this chart can be found on my blog post.

congress enact senateDem senateRep appropriation houseDem houseRep CPI CPIgrowth Appgrowth CPIrel propDem propRep
80 906 47 53 1.01 43 57 65.2 0 0 1.01 45 55
81 921 56 44 1.12 61 39 72.6 11 11 1.12 59 42
82 594 51 49 1.2 54 46 82.4 26 19 1.27 53 48
83 781 49 51 1.29 49 51 90.9 39 28 1.4 49 51
84 1028 51 49 1.37 53 47 96.5 48 36 1.49 52 48
85 936 51 49 1.47 54 46 99.6 53 46 1.55 53 48
86 800 65 35 1.64 65 35 103.9 59 62 1.61 65 35
87 885 64 36 1.6 60 40 107.6 65 58 1.67 62 38
88 666 67 33 1.78 59 41 109.6 68 76 1.7 63 37
89 810 68 32 1.64 68 32 113.6 74 62 1.76 68 32
90 640 64 36 1.75 57 43 118.3 81 73 1.83 61 40
91 695 58 42 1.8 56 44 124 90 78 1.92 57 43
92 607 55 45 1.97 59 41 130.7 100 95 2.02 57 43
93 649 57 43 2.16 56 44 136.2 109 114 2.11 57 44
94 588 62 38 2.3 67 33 140.3 115 128 2.17 65 36
95 634 62 38 2.3 67 33 144.5 122 128 2.24 65 36
96 613 59 41 2.27 64 36 148.2 127 125 2.29 62 39
97 473 46 54 2.39 56 44 152.4 134 137 2.36 51 49
98 623 46 54 2.13 62 38 156.9 141 111 2.43 54 46
99 664 47 53 2.17 58 42 160.5 146 115 2.48 53 48
100 713 55 45 2.29 59 41 163 150 127 2.53 57 43
101 650 55 45 2.58 60 40 166.6 156 155 2.59 58 43
102 590 56 44 2.49 62 38 172.2 164 147 2.67 59 41
103 465 57 43 2.73 59 41 177.1 172 170 2.75 58 42
104 333 48 52 3.23 47 53 179.9 176 220 2.79 48 53
105 394 45 55 3.46 48 52 184 182 243 2.85 47 54
106 580 45 55 3.57 49 51 189 190 253 2.93 47 53
107 377 50 50 3.64 49 51 195.3 200 260 3.03 50 51
108 498 48 52 3.77 47 53 201.6 209 273 3.12 48 53
109 482 44 56 3.85 47 53 207.3 218 281 3.21 46 55
110 460 50 50 3.97 54 46 215.3 230 293 3.33 52 48
111 383 58 42 4.4 59 41 214.5 229 336 3.32 59 42
112 283 52 48 4.66 44 56 218.1 235 361 3.38 48 52
113 116 55 45 4.54 46 54 224.9 245 350 3.48 51 50
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis2 line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
path {
stroke: black;
stroke-width: 1;
fill: none;
}
.line {
fill: none;
stroke-width: 5px;
opacity: 0.5;
}
.line:hover {
opacity: 1;
}
.line2 {
fill: none;
stroke-width: 5px;
opacity: 0.5;
}
.line2:hover {
opacity: 1;
}
.bar {
opacity: 0.7;
}
.bar:hover {
opacity: 1 ;
}
.x.axis path {
display: none
stroke: #000;
}
.d3-tip {
font-weight: bold;
background: rgba(0, 0, 0, 0.8);
padding: 12px;
color: #fff;
z-index: 5070;
}
</style>
<body>
<div class="filter_options">
<input class="filter_button"
id="button"
type="checkbox"> Show CPI
</input></div><br>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>
var margin = {top: 40, right: 40, bottom: 30, left: 70},
width = 710 - margin.left - margin.right,
height = 420 - margin.top - margin.bottom;
var formatPercent = d3.format("f");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var y2 = d3.scale.linear().domain([0,6])
.range([height,0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(formatPercent);
var yAxisRight = d3.svg.axis()
.scale(y2)
.orient("right");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d){ return x(d.congress); })
.y(function(d){ return y2(d.appropriation); });
var CPI = d3.svg.line()
.interpolate("basis")
.x(function(d){ return x(d.congress); })
.y(function(d){ return y2(d.CPIrel); });
var tip = d3.tip()
.attr('class', 'd3-tip')
.style("visibility","visible")
.offset([-20, 0])
.html(function(d) {
return "Bills Enacted: " + d.enact + "<br> <span style='color:lightskyblue'>"
"Democrats: " + d.propDem + " %</span><span style='color:red'><br>"
"Republicans : " + d.propRep + "%</span>" ;
});
var tip2 = d3.tip()
.attr('class', 'd3-tip')
.html("Appropriations growth")
var tip3 = d3.tip()
.attr('class', 'd3-tip')
.html("Consumer Price Index growth");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right-10)
.attr("height", height + margin.top + margin.bottom+15)
.append("g")
.attr("transform", "translate(" +(-10+ margin.left) + ","
+ margin.top + ")");
// read in all the data, but no need to use it all
d3.csv("congress/data.csv", function(error, data) {
data.forEach(function(d) {
d.congress = d.congress;
d.enact = +d.enact;
d.senateDem = +d.senateDem;
d.senateRep = +d.senateRep;
d.appropriation = +d.appropriation;
d.houseDem = +d.houseDem;
d.houseRep = +d.houseRep;
d.CPI = +d.CPI;
d.CPIgrowth = +d.CPIgrowth;
d.Appgrowth = +d.Appgrowth;
d.CPIrel = +d.CPIrel;
d.propDem = +d.propDem;
d.propRep = +d.propRep;
});
x.domain(data.map(function(d) { return d.congress; }));
y.domain([0, d3.max(data, function(d) { return d.enact; })]);
svg.append("g")
.attr("class", "x axis")
.style("font-size","0.7em")
.style("font-family","sans-serif")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
svg.append("text")
.attr("x", width / 2 )
.attr("y", height + margin.bottom + 10)
.style("text-anchor", "middle")
.style("font-size","0.8em")
.style("font-family","sans-serif")
.text("Congress");
svg.append("g")
.attr("class", "y axis")
.style("font-size","0.7em")
.style("font-family","sans-serif")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 3)
.attr("dy", ".71em")
.style("font-size","0.8em")
.style("font-family","sans-serif")
.style("text-anchor", "end")
.text("# Bills Enacted");
svg.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("font-weight", "bold")
.style("font-family", "sans-serif")
.text("Congressional Workload");
svg.append("g")
.attr("class", "y axis2")
.style("font-size","0.7em")
.style("font-family","sans-serif")
.attr("transform", "translate(" + (width) + ",0)")
.call(yAxisRight)
.append("text")
.attr("transform", "rotate(-90)")
.style("font-size","0.8em")
.style("font-family","sans-serif")
.attr("y", -10)
.attr("dy", ".1em")
.style("text-anchor", "end")
.text("$ Million Appropriations");;
// ideally this would be a gradient with darker red representing more Republicans
// and darker blue representing more Democrats. I haven't yet figured out how to make
// it a gradient.
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.congress); })
.attr("fill",function(d) {
var diff = d.propDem - d.propRep;
switch (true)
{
case (diff > 0):
return "Blue";
break;
case (diff < 0):
return "Red";
break;
}
})
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.enact); })
.attr("height", function(d) { return height - 2 - y(d.enact); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
svg.call(tip);
svg.call(tip2);
svg.call(tip3);
svg.append("path")
.datum(data)
.attr("class","line")
.style("stroke", "grey")
.attr("d",line)
.on('mouseover', tip2.show)
.on("mousemove", function(){return tip2.style("top", (event.pageY-10)+"px").
style("left",(event.pageX+10)+"px");})
.on('mouseout', tip2.hide);
svg.append("path")
.datum(data)
.attr("class","line2")
.style("stroke", "black")
.style("stroke-dasharray", 10)
.attr("display","none")
.attr("d",CPI)
.on('mouseover',tip3.show)
.on("mousemove", function(){ return tip3.style("top", (event.pageY-10)+"px")
.style("left",(event.pageX+10)+"px");})
.on('mouseout', tip3.hide);
// display CPI line when checkbox clicked
d3.selectAll(".filter_button").on("change", function() {
display = this.checked ? "inline" : "none";
svg.selectAll(".line2")
.attr("display", display);
});
});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment