-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.html
448 lines (376 loc) · 28.2 KB
/
index.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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Montreal 311 Service Requests, an Analysis</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.14.0/pivot.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.14.0/pivot.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.14.0/c3_renderers.min.js"></script>
<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-46914903-1', 'kruchten.com'); ga('send', 'pageview');</script>
</head>
<style>
@import url('http://fonts.googleapis.com/css?family=Open+Sans:400');
@font-face {
font-family: 'Museo Slab 700';
src: url('http://nicolas.kruchten.com/font/Museo_Slab_700-webfont.eot');
src: url('http://nicolas.kruchten.com/font/Museo_Slab_700-webfont.eot?#iefix') format('embedded-opentype'),
url('http://nicolas.kruchten.com/font/Museo_Slab_700-webfont.woff') format('woff'),
url('http://nicolas.kruchten.com/font/Museo_Slab_700-webfont.ttf') format('truetype'),
url('http://nicolas.kruchten.com/font/Museo_Slab_700-webfont.svg#MuseoSlab700Regular') format('svg');
font-weight: bold;
font-style: normal;
}
h1, h2, h3, h4, h5, h6, .brand {font-family: 'Museo Slab 700';}
body {
font-family: 'Open Sans';
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
color: #333;
}
.c3-line, .c3-focused {stroke-width: 3px !important;}
.c3-bar {stroke: white !important; stroke-width: 1;}
.c3 text { font-size: 12px; color: grey;}
.tick line {stroke: white;}
.c3-axis path {stroke: grey;}
.chapter {display: none;}
p, li {
font-size: 18px;
line-height: 1.5;
}
li {margin-top: 5px;}
</style>
<body>
<script type="text/javascript">
var tpl = $.pivotUtilities.aggregatorTemplates;
var intfmt = $.pivotUtilities.numberFormat({digitsAfterDecimal: 0});
var num_requests = function() { return tpl.sum(intfmt)(["Requests"]) };
var common_params = {
aggregators: {
"Requests": num_requests,
"Request %": tpl.fractionOf(num_requests, "total"),
"Requests row %": tpl.fractionOf(num_requests, "row"),
"Requests col %": tpl.fractionOf(num_requests, "col"),
},
hiddenAttributes: ["Requests"],
renderers: {
"Table": $.pivotUtilities.renderers["Table"],
"Heatmap": $.pivotUtilities.renderers["Heatmap"],
"Line Chart": $.pivotUtilities.c3_renderers["Line Chart"],
"Bar Chart": $.pivotUtilities.c3_renderers["Stacked Bar Chart"],
},
sorters: function(attr) {
if(attr == "Month") {
return $.pivotUtilities.sortAs(
["Jan","Feb","Mar",
"Apr","May","Jun",
"Jul","Aug","Sep",
"Oct","Nov","Dec"]);
}
if(attr == "Borough") {
return $.pivotUtilities.sortAs(
["Côte-des-Neiges–Notre-Dame-de-Grâce",
"Villeray–Saint-Michel–Parc-Extension",
"Rosemont–La Petite-Patrie",
"Mercier–Hochelaga-Maisonneuve",
"Ahuntsic-Cartierville",
"Rivière-des-Prairies–Pointe-aux-Trembles",
"Le Plateau-Mont-Royal",
"Saint-Laurent",
"Ville-Marie",
"Montréal-Nord",
"Saint-Léonard",
"LaSalle",
"Le Sud-Ouest",
"Pierrefonds-Roxboro",
"Verdun",
"Anjou",
"Lachine",
"Outremont",
"L’Île-Bizard–Sainte-Geneviève"]);
}
if(attr == "Category") {
return $.pivotUtilities.sortAs(
["Selective Collection", "Roads", "Garbage Collection", "Water", "Other", "Trees", "Signage", "Dogs", "Environment", "Bulky Collection", "Lighting", "Parking", "Snow", "Permits", "Sewers", "Security", "Taxes", "Parks"]);
}
},
rendererOptions: {
c3: {
color: {
pattern:
[ "#3366cc", "#dc3912", "#ff9900", "#109618",
"#990099", "#0099c6", "#dd4477", "#66aa00",
"#b82e2e", "#316395", "#994499", "#22aa99",
"#aaaa11", "#6633cc", "#e67300", "#8b0707",
"#651067", "#329262", "#5574a6", "#3b3eac" ]
}
}
}
};
$(function(){
$.get("311_pivot.csv", function(csvData) {
var data = $.csv.toArrays(csvData);
function showChapter(chapterNumber, changeState) {
$(".chapter").hide();
var chapter = $("#chapter"+chapterNumber);
chapter.show();
var chapter_params = {
rows: chapter.data("rows").split(","),
cols: chapter.data("cols").split(","),
aggregatorName: chapter.data("agg"),
rendererName: chapter.data("view")
}
var catFilter = chapter.data("catfilter")
if(catFilter != null && catFilter.length >0 )
chapter_params["inclusions"] = {Category: catFilter.split(",")}
$.extend(chapter_params, common_params);
$("#output").pivotUI(data, chapter_params, true);
if(changeState && history.pushState) {
history.pushState(null, null,'#'+chapterNumber,"");
}
$("#chapter_links a").hide()
if(chapterNumber > 1) {
$("#prevlink").data("chapter", chapterNumber-1).show()
}
if(chapterNumber < numChapters){
$("#nextlink").data("chapter", chapterNumber+1).show()
}
$("#chapter_list").val("jump");
window.scrollTo(0,0)
}
function showChapterClickHandler(e) {
e.preventDefault();
showChapter($(this).data("chapter"), true);
return false;
}
var chapterDivs = $(".chapter")
var numChapters = chapterDivs.size()
$("#chapter_links a").click(showChapterClickHandler);
chapterDivs.each(function(i){
var chapterNumber = i+1;
var title = $(this).data("title")
$(this)
.attr("id", "chapter"+chapterNumber)
.prepend($("<h2>").text(""+chapterNumber+" - " +title));
$("#chapter_list")
.append($("<option>", {value: chapterNumber})
.text(""+chapterNumber+" - " +title))
})
function showChapterFromUrlBar() {
var dest = parseInt(window.location.hash.slice(1));
if(isNaN(dest)) { dest = 1; }
showChapter(dest, false);
}
showChapterFromUrlBar();
$(window).bind('popstate', showChapterFromUrlBar);
$("#chapter_links").show()
$("#chapter_list").change(function(e){
if($(this).val() != "jump"){
showChapter(parseInt($(this).val()), true);
}
})
});
});
</script>
<div id="chapters" style="width: 800px; margin: 0 auto;">
<h1 align="center">Montreal 311 Service Requests, an Analysis</h1>
<div class="chapter"
data-rows="" data-cols=""
data-agg="Requests"
data-view="Table"
data-catFilter=""
data-title="Introduction">
<p>In early 2015, <a href="http://nicolas.kruchten.com">Nicolas Kruchten</a> collaborated with a reporter from the Montreal Gazette, Roberto Rocha, to analyze a dataset containing information about 1.4 million service requests received by the City of Montreal from its citizens. The resulting article was entitled "<a href="http://montrealgazette.com/news/local-news/311-calls-whats-bugging-montreal" target="_blank">Montreal's 311 records shed light on residents' concerns — to a point</a>" and credits Nicolas at the bottom. The dataset, obtained from the city's Gestion des demandes clients (GDC) system via an Access to Information request and also worked on by Stéphane Guidoin, covered the five years from 2008 to 2012 and contained only the date and a very short description for each request, and in most cases, an address. Notably missing was any indication of resolution time or correspondance with the originating citizen. The service requests were received by the city through its 311 phone line or at service counters throughout the city.</p>
<p>In these pages, you will be able to walk through the process of analyzing the 1.2 million requests which were linked to a specific borough through an interactive pivot table such as the one you see below. As you advance through the steps of the analysis, the table will reconfigure itself to show you different views of the data. You can interact with the pivot table at any time by dragging the fields around to modify the tables and graphs, or by hiding/showing information by clicking on the little triangles.</p>
<p>Let's get started!</p>
</div>
<div class="chapter"
data-rows="" data-cols="Category"
data-agg="Requests"
data-view="Bar Chart"
data-catFilter=""
data-title="Requests by Category" >
<p>The original dataset contained more than 4,000 unique request descriptions. The pivot table below is loaded with a partially-processed dataset: the requests have been grouped into 18 broad categories. You can find examples of the various descriptions, as well as a detailed explanation of the categorization process <a href="http://nicolas.kruchten.com/content/2015/06/montreal-311/" target="_blank">here</a>. The chart below shows the distribution of requests by category; the categories are ordered by overall request volume.</p>
<h3>Observations</h3>
<ul>
<li>These categories span essentially all the non-emergency services the city manages, and can be compared to the city's <a href="http://www1.ville.montreal.qc.ca/banque311/" target="_blank">311 knowledge bank</a> categories.
<li>Waste collection spans 3 categories: Selective Collection, Bulky Collection and Garbage Collection. Garbage Collection covers standard household waste; Selective Collection covers recycling and green waste; and Bulky Collection covers bulky items such as furniture and appliances.
</ul>
</div>
<div class="chapter"
data-rows="Category" data-cols="Borough"
data-agg="Requests"
data-view="Bar Chart"
data-catFilter=""
data-title="Requests by Category and Borough">
<a href="http://www.ville.montreal.qc.ca/pls/portal/docs/page/prt_vdm_fr/media/documents/CARTE_ILEMONTREALARRON.pdf" target="_blank" style="float: right; margin-left: 20px;" alt="click for map" title="click for map"><img src="map.png" /></a>
<p>On an administrative level, Montreal is divided up into <a href="https://en.wikipedia.org/wiki/Boroughs_of_Montreal" target="_blank">19 boroughs</a>, some of which were <a href="https://en.wikipedia.org/wiki/2002%E2%80%9306_municipal_reorganization_of_Montreal" target="_blank">merged into the city in 2002 and then reorganized in 2006</a>. Below is the distribution of requests by borough and category. The boroughs are ordered by population. You can mouse over the bars to see which category is which and how many requests it represents within each borough. Click on the <a href="http://www.ville.montreal.qc.ca/pls/portal/docs/page/prt_vdm_fr/media/documents/CARTE_ILEMONTREALARRON.pdf" target="_blank">map</a> for a handy reference.</p>
<h3>Observations</h3>
<ul>
<li>Saint-Laurent has the most requests, even though it's only the 8th most populous.
<li>At a high-level, it looks like there are notable differences in the distribution of categories among the boroughs.
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Category"
data-agg="Requests row %"
data-view="Heatmap"
data-catFilter=""
data-title="Requests by Category and Borough II" >
<p>In the table below, we are looking at the percentage of requests that each category represents within each borough. The redder the cell, the more that category preoccupied that borough.</p>
<h3>Observations</h3>
<ul>
<li>Bulky Collection is big in Rivière-des-Prairies–Pointe-aux-Trembles (see <a href="#10">section 10</a>).
<li>Security lights up for Saint-Laurent and L’Île-Bizard–Sainte-Geneviève (see <a href="#7">section 7</a>).
<li>Selective Collection lights up for Saint-Laurent (see <a href="#9">section 9</a>).
<li>Taxes light up in LaSalle and Saint-Léonard (see <a href="#11">section 11</a>).
<li>The fact that Other lights up in Montréal-Nord and Saint-Laurent suggests maybe the categorization scheme is missing important request types in those areas.
</ul>
</div>
<div class="chapter"
data-rows="Category" data-cols="Year"
data-agg="Requests row %"
data-view="Heatmap"
data-catFilter=""
data-title="Requests over Time" >
<p>In the table below, we are looking at the percentage of requests that each year represented within a category. The redder the cell, the more requests in that category occurred in that year.</p>
<h3>Observations</h3>
<ul>
<li>Overall request volumes were relatively constant year over year.
<li>Security exhibits a steep decline during 2010 (see <a href="#7">section 7</a>).
<li>Parking also exhibits a steep decline during 2010 (see <a href="#8">section 8</a>).
<li>Selective Collection has a spike in 2012 (see <a href="#9">section 9</a>).
<li>Bulky Collection has a spike in in 2008 (see <a href="#10">section 10</a>).
<li>Snow also has a spike in in 2008, likely because Montreal saw 342 cm of snow that year, compared to roughly 200 cm per year over 2009-2012.
</ul>
</div>
<div class="chapter"
data-rows="Category" data-cols="Month"
data-agg="Requests row %"
data-view="Heatmap"
data-catFilter=""
data-title="Requests over Time II" >
<p>In the table below, we are looking at the percentage of requests that each month represented within a category. The redder the cell, the more requests in that category occurred in that month.</p>
<h3>Observations</h3>
<ul>
<li>Overall request volume is high in summer, low in winter.
<li>Snow is big in winter and absent in summer, unsurprisingly.
<li>Taxes spikes in February (see <a href="#11">section 11</a>).
<li>Environment spikes in May (see <a href="#12">section 12</a>).
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Year,Month"
data-agg="Requests"
data-view="Line Chart"
data-catFilter="Security"
data-title="Security Requests over Time" >
<p>The Security category stood out in both time and space (a <a href="#4">large percentage of the requests in Saint-Laurent and L’Île-Bizard–Sainte-Geneviève</a>, and as <a href="#5">being much higher in 2008/2009 than in 2011/2012</a>), so let's take a closer look. In the graph below we have Security requests by borough over time by month. We see a dramatic pattern: almost the entire change in request volume over the years is due to Saint-Laurent. Looking closely, L’Île-Bizard–Sainte-Geneviève also displays a cyclical pattern with more requests in summer. You can click on Saint-Laurent in the legend to hide that borough's line and see the others more clearly.</p>
<h3>Analysis</h3>
<ul>
<li>Most of the requests which comprise the anomalous line in 2008-2010 in Saint-Laurent have the same description ("20 - Surveillance particulière") and many are about a handful of addresses, usually of parks. As mentioned in the <a href="http://montrealgazette.com/news/local-news/311-calls-whats-bugging-montreal" target="_blank">Gazette article</a>, Saint-Laurent has a private security force which uses the 311 system to record some of its activities. Perhaps this practice stopped in April 2010.
<li>We have no clear explanation for the cyclical pattern in L’Île-Bizard–Sainte-Geneviève but the requests all have the same description: "Surveillance et sécurité publique".
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Year,Month"
data-agg="Requests"
data-view="Line Chart"
data-catFilter="Parking"
data-title="Parking Requests over Time" >
<p>The Parking category stood out as <a href="#5">being much higher in 2008/2009 than in 2011/2012</a>. Taking a closer look at just that category we can pin-point the change in May/June 2010, and we can see that unlike the Security category, it is not a case of a single anomalous borough, but rather spread out across many boroughs.</p>
<h3>Analysis</h3>
<ul>
<li>In the underlying dataset, the description of the requests which stopped appearing in June 2010 was "Intervention stationnement", suggesting a change in city policy at that time.
<li>Interestingly, in this case the Saint-Laurent borough again stands out as having more requests in this category than others in 2010-2012 but no requests from that borough had the "Intervention stationnement" description.
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Year,Month"
data-agg="Requests"
data-view="Line Chart"
data-catFilter="Selective Collection"
data-title="Selective Collection Requests over Time" >
<p>The Selective Collection category stood out as <a href="#5">spiking up in 2012</a> and being <a href="#4">a big percentage of the requests in Saint-Laurent</a>. Taking a closer look, we can see that Saint-Laurent figures prominently, but in small spikes throughout the period. Additionally, we see that the rise in 2012 occurs across all boroughs starting in April/May.</p>
<h3>Analysis</h3>
<ul>
<li>The 2012 jump in this category is entirely due to requests described as "Environnement - Collecte de branches d'arbre", likely due to a change in city policy regarding tree branches as a result of the emerald ash borer infestation.
<li>Saint-Laurent spikes occur in October/November and are related to green waste bags, which are perhaps distributed to citizens at the same time each year. Interestingly, there is no such spike in 2009 or 2010.
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Year,Month"
data-agg="Requests"
data-view="Line Chart"
data-catFilter="Bulky Collection"
data-title="Bulky Collection over Time" >
<p>The Bulky Collection category stood out as being <a href="#4">a huge percentage of the requests in Rivière-des-Prairies–Pointe-aux-Trembles</a> and as <a href="#5">spiking in 2008</a>. Taking a closer look, RDP-PAT dominates throughout the 5-year period, but we also see the smaller pattern of every borough having more requests about this in 2008. If you look closely, you will see that there are also regular spikes in this category of requests in May and September in Lachine</p>
<h3>Analysis</h3>
<ul>
<li>As mentioned in the <a href="http://montrealgazette.com/news/local-news/311-calls-whats-bugging-montreal" target="_blank">Gazette article</a>, in some boroughs such as Rivière-des-Prairies–Pointe-aux-Trembles, bulky waste is not collected unless a specific request is made, so perhaps this borough is much stricter about this policy and the result is a higher volume of requests.
<li>Perhaps more boroughs had such a policy up until 2009, which might explain why many of them had more Bulky Collection requests in 2008 than in other years.
<li>The periodic Lachine spikes are also likely due to a specific policy in that borough.
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Year,Month"
data-agg="Requests"
data-view="Line Chart"
data-catFilter="Taxes"
data-title="Taxes Requests over Time" >
<p>The Taxes category stood out as <a href="#6">spiking in February</a>, and as being <a href="#4">a big deal in LaSalle and Saint-Léonard</a>. Taking a closer look, we see that most boroughs have a spike in February, but that Saint-Laurent, Saint-Léonard and LaSalle have a different pattern that spikes in April and tails off more slowly.</p>
<h3>Analysis</h3>
<ul>
<li>The punctual spikes in this category are due to the timing of city correspondance about municipal taxes, and it's likely that the three anomalous boroughs just have a different schedule for these things. The three outliers were independent municipalities until 2002, and they share a request description not found in the other boroughs: "Changement d'adresse - Taxes eau et déchets".
</ul>
</div>
<div class="chapter"
data-rows="Borough" data-cols="Year,Month"
data-agg="Requests"
data-view="Line Chart"
data-catFilter="Environment"
data-title="Environment Requests over Time" >
<p>The Environment category stood out as <a href="#6">spiking in the month of May</a>. Taking a closer look, we can immediately see that the May spike is solely due to Saint-Laurent. There is also a smaller pattern of spikes in March in Le Sud-Ouest, and some spikes in Ville-Marie, Rosemont–La Petite-Patrie and Pierrefonds-Roxboro.</p>
<h3>Analysis</h3>
<ul>
<li>All of the May spikes in Saint-Laurent can be explained by one request description: "Maisons fleuries". This relates to a contest held yearly in Saint-Laurent.
<li>The spikes in Le Sud-Ouest are all described as "Jardins - Renouvellement", which makes sense as a seasonal event.
<li>The increase in requests in 2012 (and the spike in November 2011) in Ville-Marie is entirely accounted for by requests related to graffiti.
<li>The spike in Pierrefonds-Roxboro in late 2012 is entirely accounted for by requests related to (presumably temporary) car shelters.
<li>The spike in Rosemont–La Petite-Patrie is related to the Eco-quartier program.
</ul>
</div>
<div class="chapter"
data-rows="" data-cols="Category"
data-agg="Requests"
data-view="Bar Chart"
data-catFilter=""
data-title="Conclusions" >
<p>This analysis began with an overview chart of requests volumes by category (replicated below) and then proceeded to look at places and time periods where request volumes deviated from this overall pattern. Most of the deviations turned out to be attributable to seasonal effects or borough-specific policies or differences in the way in which different boroughs use the Gestion des demandes clients (GDC) system. In the aggregate, however, most of the time and in most places, the distribution of requests does follow the overall pattern, so we can look at the chart below and conclude that it more or less sums up the bulk of the service requests in the GDC system. That said, there may be more subtle patterns and stories of interest in the "Other" category, which represents 6.5% of the requests.</p>
<p>Beyond looking at types of requests over time and space, it would certainly be interesting to examine the outcomes of service requests, for example what was done in response to a request and how long it took or how much it cost, but unfortunately this information was not present in the dataset obtained by the Gazette.</p>
<p>Questions, feedback or comments on this analysis are welcome by email at <a href="mailto:[email protected]">[email protected]</a>!</p>
</div>
</div>
<br />
<div id="chapter_links" style="text-align: center; display: none;">
<a href="#" id="prevlink">« Previous</a>
<select id="chapter_list">
<option selected disabled value="jump">Jump to section...</option>
</select>
<a href="#" id="nextlink">Next »</a>
</div>
<br />
<div align="center">
<div id="output" style="margin: 30px;"></div>
</div>
<p align="center">This is a data story by <a href="http://nicolas.kruchten.com" target="_blank">Nicolas Kruchten</a> using <a href="http://nicolas.kruchten.com/pivottable" target="_blank">PivotTable.js</a></p>
</body>
</html>