-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbar.html
171 lines (150 loc) · 4.88 KB
/
bar.html
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
rect {
fill: teal;
fill-opacity: .8;
}
text {
font: 10px sans-serif;
}
</style>
</head>
<body>
<div style="position:absolute; left:50px; top:50px; font-size:16pt; color:maroon; font-family:arial;">
<label><input type="radio" name="order" value="state" > State</label><br />
<label><input type="radio" name="order" value="rate" checked> Rate</label>
</div>
<script type="text/javascript">
/*
##########################
## SET PAGE VARIABLES
##########################
*/
var margin = {top: 50, bottom: 10, left:300, right: 40};
var width = 900 - margin.left - margin.right;
var height = 900 - margin.top - margin.bottom;
var xScale = d3.scale.linear().range([0, width]);
var yScale = d3.scale.ordinal().rangeRoundBands([0, height], .8, 0);
var bar_height = 15;
var toggle = {'rate':false,'state':false}
d3.tsv("unemp_states_us_nov_2013.tsv", function(data) {
/* ##########################
## FUNCTIONS
##########################
*/
// state name mapping function
var state = function(d) { return d.State; };
// reorder() solved with help from: http://bl.ocks.org/mbostock/3885705
reorder = function() {
// flip toggle
toggle[this.value] = toggle[this.value] ? false : true;
// nickname var
tog = toggle[this.value]
// set which column to sort by with boolean
is_rate = (this.value=='rate') ? true : false;
// resort data, redefine Y ordinal domain with newly mapped state names
yScale
.domain(data.sort(function(a, b) {
var a_val = is_rate ? a.Rate : a.State;
var b_val = is_rate ? b.Rate : b.State;
if (is_rate) {
a_val = parseFloat(a.Rate);
b_val = parseFloat(b.Rate);
// if two values are equal, then change sort index to 1 (ie. States)
// see table.html for discussion of float equality comparison
if (Math.abs(a_val - b_val) < .001) { a_val = a.State; b_val = b.State; }
}
return (tog)
? d3.ascending(a_val, b_val)
: d3.descending(a_val, b_val)
})
.map(state))
groups
.transition()
.duration(750)
.delay(function(d, i) { return i * 10; })
.attr("transform", function(d, i) {
return "translate(0, "+ yScale(d.State)+")";
})
}
/*
##########################
## SET TSV VARIABLES
##########################
*/
var max = d3.max(data, function(d) { return d.Rate; } );
var min = 0;
var rate_max = max;
var rate_min = d3.min(data, function(d) { return d.Rate } );
xScale.domain([min, max]);
yScale.domain(data.map(state));
// linear color gradient scale
var color = d3.scale.linear()
.domain([rate_min, rate_max])
.interpolate(d3.interpolateRgb)
.range(["orangered", "silver"]);
/*
##########################
## RENDER CHART
##########################
*/
var svg = d3.select("body").append("svg")
.attr("width", width+margin.left+margin.right)
.attr("height", height+margin.top+margin.bottom);
var g = svg.append("g")
.attr("transform", "translate("+margin.left+","+margin.top+")");
var title = g
.append("text")
.style("fill", "black")
.style("font-size", "18pt")
.style("font-weight", "900")
.style("font-family", "arial")
.attr("text-anchor", "start")
.text("Unemployment Rates for States")
var groups = g
.append("g")
.selectAll("text")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0, " + yScale(d.State) +")"; });
var bars = groups
.append("rect")
.attr("width", function(d) { return xScale(d.Rate); })
.attr("height", bar_height)
d3.selectAll("rect")
.style("fill", function(d) { return color(d.Rate); });
// In the text settings that follow, I went with relative % to specify font-size
// and x/y positioning. Generally I'd prefer to assign values with some firmer metric,
// but this is the best way I can think of to make them as generalizable as possible.
var rate_values = groups
.append("text")
.attr("x", function(d) { return xScale(d.Rate); })
.attr("y", function(d) { bar_height/2; })
.attr("dx", function(d) {return "-.5%"; })
.attr("dy", function(d) { return "1.3%"; })
.attr("text-anchor", "end")
.style("fill", "rgb(255,254,224)")
.style("font-size", "90%")
.style("font-weight", "bold")
.text(function(d,i) { return data[i].Rate; })
var state_names = groups
.append("g")
.attr("text-anchor", "start")
.append("text")
.attr("text-anchor", "end")
.attr("dx", function(d) { return "-.5%"; })
.attr("dy", function(d) { return "1.4%"; })
.style("fill", "teal")
.style("font-size", "90%")
.style("font-weight", "bold")
.text(function(d,i) { return data[i].State; })
d3.selectAll("input")
.on("click", reorder);
});
</script>
</body>
</html>