-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlegislation.js
149 lines (124 loc) · 4.88 KB
/
legislation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 20, left: 50},
width = 700 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("#leg_container")
.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 + ")");
d3.csv("https://raw.githubusercontent.com/6859-sp21/final-project-police-brutality/main/data/billData2.csv").then((lawData) => {
cleanLawData = lawData.filter(d => d.status !== "");
let statesData = {};
const mySet = new Set();
cleanLawData.forEach((element) => {
if (!(element.state in statesData)){
statesData[element.state] = {"Enacted": 0, "Pending": 0, "Failed": 0, "To Governor": 0,
"Adopted": 0, "Vetoed": 0, "To Mayor": 0, "To Congress": 0, "Total": 0};
}
let status = element.status.split("-")[0].trim();
mySet.add(status);
if (status in statesData[element.state]){
statesData[element.state][status] += 1;
statesData[element.state]["Total"] += 1;
}
});
let statesArray = []
for (const state in statesData){
statesArray.push({"state": state,...statesData[state]});
}
statesArray.sort(function(a, b) { return b.Total - a.Total; });
let subgroups = Object.keys(statesData["CA"]).filter((key)=> key!=="Total");
let smallerStatesArray = statesArray.slice(0,20);
let groups = smallerStatesArray.map((entry) => entry.state);
// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.2])
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSizeOuter(0));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, 500])
.range([ height, 0 ]);
svg.append("g")
.call(d3.axisLeft(y));
// color palette = one color per subgroup
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(["#33a02c","#a6cee3","#e15759","#76b7b2","#59a14f","#edc949","#af7aa1","#ff9da7","#9c755f","#bab0ab"])
// tooltip
var tooltip = d3.select("div#leg_container").append("div")
.attr("class", "tooltip")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background", "white")
.style("padding", "10px")
.style("border-radius", "5px")
.style("width", "200px")
//stack the data? --> stack per subgroup
var stackedData = d3.stack()
.keys(subgroups)
.order(d3.stackOrderDescending)
(smallerStatesArray)
// ----------------
// Highlight a specific subgroup when hovered
// ----------------
// What happens when user hover a bar
var mouseover = function(d) {
console.log("over")
// what subgroup are we hovering?
var subgroupName = d3.select(this.parentNode).datum().key; // This was the tricky part
// Reduce opacity of all rect to 0.2
d3.selectAll(".myRect").style("opacity", 0.2)
// Highlight all rects of this subgroup with opacity 0.8. It is possible to select them since they have a specific class = their name.
d3.selectAll("."+subgroupName.split(" ")[0])
.style("opacity", 1)
}
tooltip.transition()
.duration(200)
.style("opacity", 0.9)
.style("visibility", "visible")
// When user do not hover anymore
var mouseleave = function(d) {
console.log("leave")
// Back to normal opacity: 0.8
d3.selectAll(".myRect")
.style("opacity",0.8)
tooltip.transition()
.duration(50)
.style("opacity", 0)
.style("visiblity", 'hidden')
}
var mousemove = function(d) {
var subgroupName = d3.select(this.parentNode).datum().key; // This was the tricky part
tooltip.html("<b>Status:</b> " + subgroupName )
.style("top",(event.pageY-10)+"px").style("left",(event.pageX+10)+"px").style("opacity", 0.9)
}
// Show the bars
svg.append("g")
.selectAll("g")
// Enter in the stack data = loop key per key = group per group
.data(stackedData)
.enter().append("g")
.attr("fill", function(d) { return color(d.key); })
.attr("class", function(d){ return "myRect " + d.key }) // Add a class to each subgroup: their name
.selectAll("rect")
// enter a second time = loop subgroup per subgroup to add all rectangles
.data(function(d) { return d; })
.enter().append("rect")
.attr("x", function(d) { return x(d.data.state); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width",x.bandwidth())
// .attr("stroke", "grey")
.on("mouseover", mouseover)
.on("mouseleave", mouseleave)
.on("mousemove", mousemove)
});