forked from openoakland/openbudgetoakland-staging
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnew.html
231 lines (231 loc) · 8.7 KB
/
new.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width"><link rel="stylesheet" href="/css/main.css"><title></title><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-35908939-3', 'openbudgetoakland.org');
ga('send', 'pageview');
</script><script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script><script src="http://code.jquery.com/jquery-migrate-1.2.1.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/js/bootstrap.min.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.5/d3.min.js"></script></head><body><nav class="main-nav"><div class="navbar navbar-default navbar-fixed-top"><div class="container"><div class="navbar-header"><button type="button" data-toggle="collapse" data-target=".nav-collapse" class="navbar-toggle"><span class="sr-only">Toggle navigation<span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></span></button><a href="/" class="navbar-brand">Open Budget: Oakland</a></div><div class="navbar-collapse collapse"><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a href="#" data-toggle="dropdown" class="dropdown-toggle">About<b class="caret"></b></a><ul class="dropdown-menu"><li><a href="what-we-do.html">What and How</a></li><li><a href="who-we-are.html">Who We Are</a></li><li><a href="news.html">News</a></li><li><a href="contact.html">Contact Us</a></li></ul></li><li class="dropdown"><a href="#" data-toggle="dropdown" class="dropdown-toggle">Visuals<b class="caret"></b></a><ul class="dropdown-menu"><li><a href="mayor_13-15_proposed.html">2013-15 Mayor's Proposed Spending (Treemap)</a></li><li><a href="2012-2013-sankey.html">2012-13 Adopted Revenues & Spending (Sankey)</a></li><li><a href="oak11-13adopted.html">2011-13 Adopted Spending (Treemap)</a></li></ul></li><li><a href="http://data.openoakland.org/dataset/city-of-oakland-budget" target="_blank">Data</a></li><li class="dropdown"><a href="#" data-toggle="dropdown" class="dropdown-toggle">Resources<b class="caret"></b></a><ul class="dropdown-menu"><li><a href="oakland-budget-101.html">Oakland Budget 101</a></li><li><a href="tools-projects.html">Tools and Projects</a></li></ul><li><a href="feedback.html">Feedback</a></li></li></ul></div></div></div></nav><!DOCTYPE html><html><meta charset="utf-8"><head><title>Zoomable Treemap</title><style>#treemap{
display: block;
width: 800px;
margin: auto;
}
#table {
display: block;
width: 800px;
margin: auto;
}
#tooltip p {
margin: 0px;
padding: 0px;
}
.amount {
padding: 0px;
margin: 0px;
font-size: medium;
font-family: "Open Sans", Helvetica, Arial, sans-serif;
}
.name {
padding: 0px;
margin: 0px;
font-size: small ;
font-family: "Open Sans", Helvetica, Arial, sans-serif;
}
#spacer {
height: 30px;
}</style></head><body><div id="treemap"></div><div id="chart"></div><div id="spacer"></div><div id="table"></div><script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script><script src="/js/source.js" charset="utf-8"></script><script src="/js/data.js" charset="utf-8"></script><script src="/js/treemap.js" charset="utf-8"></script><script src="/js/spreadsheet.js" charset="utf-8"></script><script src="/js/tooltip.js" charset="utf-8"></script><script>var treemap = null;
var spreadsheet = null;
/* The 'cruncher' reorganizes the budget data into a hierarchy
* and offers some other functionality into managing the data */
var cruncher = ob.data.hierarchy();
/* Budget data is stored in google's fusion tables. Here we store
* specific data to acess the api, and table were interested in.
* The hierarchy is used in the SQL query to the fusion table as well
* as in the data crunching portion */
var fusion = {
api_key: 'AIzaSyCnWo1USrkSKnN6oy02tNeWfg6aFSg0OI8',
table: '1V2R7lsdg-GTbGOZ_h_DrGOa-Gfqk1PGA9h_n5zwU',
hierarchy: [
'Fund Description',
'Department',
'Division',
'Account Category'
]
};
var value_selector = 'balance';
var max_rects = 40;
var min_area_for_text = 0.0125;
/* layout settings */
var layout = {
width: 800,
height: 500,
};
var colors = {
_stack: [],
current: function() {
if (this._stack.length > 0) {
return this._stack[0];
}
return null;
},
shift: function() {
this._stack.shift();
},
unshift: function (color, count) {
color = d3.rgb(color);
this._stack.unshift(d3.scale.linear()
.domain([0, count])
.range([color, color.darker(2.0)]));
},
init: function(node) {
var self = this;
this._stack = [];
cruncher.path(node).forEach(function(d) {
if (d.parent) {
var i = d.parent.values.indexOf(d);
self.unshift(
self._stack[0](i),
Math.min(d.values.length, max_rects));
}
else {
self._stack.unshift(
d3.scale.category10()
.domain(d3.range(0, max_rects)));
}
});
}
};
/* create and configure the tooltip */
var tooltip = ob.display.tooltip()
.html(function(d, i) {
/* this creates the html content that is displayed within
* the tooltip */
var display = '<p class="treemap_tooltip title">' + d.key + '</p>';
display += '<p class="treemap_tooltip amount">' + format.number(d[value_selector]) + '</p>';
var percent = 1.0;
if (d.parent) {
percent = d[value_selector] / d.parent[value_selector];
}
display += '<p class="treemap_tooltip percentage">' + format.percent(percent) + '</p>';
return display;
});
/* determine current view in hierarchy based on url hash */
var hash = {
get: function(root) {
if (window.location.hash.length < 2) {
return root;
}
return cruncher.spelunk(
root,
window.location.hash.replace("#", "").split(".")
);
},
set: function(node) {
var hash = cruncher.path(node)
.slice(1)
.map(function(d) { return d.key; })
.join('.');
window.location.hash = hash;
}
};
/* used to convert numerical data into text data */
var format = {
number: d3.format("$,d"),
percent: d3.format(".2%")
};
/* create the url into the fusion table api to load the budget
* data */
url = ob.fusion(fusion.api_key, fusion.table)
.url(fusion.hierarchy, 'Amount');
/* call d3 to load the budget data, and then display the data
* after it has loaded */
d3.json(url, function(data) {
var root = cruncher.crunch(data.rows, fusion.hierarchy);
/* caculate data percentages */
cruncher.apply(root, function(node) {
if (node.parent) {
node.precentage = node.value / node.parent.value;
}
else {
node.percentage = 1.0;
}
});
var node = hash.get(root);
colors.init(node);
spreadsheet = ob.display.spreadsheet()
.element(d3.select("#table"))
.width(layout.width)
.value(function(d) {
/* have to make sure values are greater than zero, otherwise
* treemap layout breaks */
return d[value_selector] <= 0 ? 0.001 : d[value_selector];
});
/* create treemap using current color scheme */
treemap = ob.display.treemap().colors(colors.current());
/* configure treemap and display */
treemap.width(layout.width)
.height(layout.height)
.value(function(d) {
/* have to make sure values are greater than zero, otherwise
* treemap layout breaks */
return d[value_selector] <= 0 ? 0.001 : d[value_selector];
})
.rects(max_rects)
.rect_text(function(d, i) {
/* this controls the text that is displayed in the
* rectangles */
var text_width = layout.width * d.dx;
var text_height = layout.height * d.dy;
if (text_width < 100 || text_height < 40) {
return "";
}
var html = '<div class="amount">';
html += format.number(d[value_selector]);
html += '</div><div class="name">';
html += d.key;
html += '</div>';
return html;
})
.on("mouseover", function(d, i) {
/* when a mouse is over of rectangle, show the
* tooltip for that rectangle */
tooltip.show(d,i);
})
.on("mousemove", function(d, i) {
/* when a mouse is moving have the tooltip follow along */
tooltip.track();
})
.on("mouseout", function(d, i) {
/* when a mouse leaves a rectangle, hide the tooltip */
tooltip.hide();
})
.on("display", function(d) {
/* This is called when a new budget view is being
* displayed. It updates the hash in the URL, as well
* as the spreadsheet data */
hash.set(d);
spreadsheet.data(d.values)
.colors(treemap.colors())
.display();
})
.on("transition", function(d, i, direction) {
/* This is called right before a transition from one
* budget view to the next happens. */
if (direction) {
/* add in a new set of colors */
colors.unshift(
treemap.colors()(i),
d.children.length);
}
else {
/* pop off the last used color */
colors.shift();
}
/* set the colors for the treemap */
treemap.colors(colors.current());
})
.data(root)
.display(d3.select("#treemap"), node);
/* when the spreadsheet is clicked, tell the treemap to
* transition */
spreadsheet.on("click", treemap.transition);
});</script></body></html></body><footer><link href="http://fonts.googleapis.com/css?family=Arvo:400,700" rel="stylesheet" type="text/css"></footer></html>