-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathproposal.html
379 lines (347 loc) · 14.5 KB
/
proposal.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
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta content="initial-scale=1, shrink-to-fit=no, width=device-width" name="viewport">
<!-- CSS -->
<link href="dist/css/main.css" rel="stylesheet">
<style>
main {
font-size:1.3em;
}
.navbar-brand svg {
width:2em;
fill:white;
animation: pulse 3s 9s;
}
@keyframes pulse {
0% {
fill: #9c27b0;
}
50% {
fill: white;
}
100% {
fill: #9c27b0;
}
}
</style>
</head>
<body>
<header>
<div class="collapse bg-primary-light" id="navbarHeader">
<div class="container">
<div class="row">
<div class="col-sm-8 col-md-7 py-4">
<h4 class="">About</h4>
<p class="">
</p>
</div>
<div class="col-sm-4 offset-md-1 py-4">
<h4 class="">Contact</h4>
<ul class="list-unstyled">
<li><a href="https://twitter.com/eucampaign" class="">Follow on Twitter</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="navbar navbar-dark bg-primary box-shadow">
<div class="container d-flex justify-content-between">
<a href="#" class="navbar-brand d-flex align-items-center">
<svg><use href="#logo" /></svg>MEP Watch
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
</header>
<main role="main">
<section class="jumbotron text-center">
<div class="container">
<h1 class="jumbotron-heading">About</h1>
<h3>
We transform data into actionable knowledge
</h3>
</div>
</section>
<div class="py-5">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<p>With the European elections approaching fast, CSOs across Europe are preparing their campaigns to encourage Europeans to vote.</p>
<p>However, many CSOs have struggles with finding the right data to support fact-based political campaigning. Gathering the roll calls and presenting the voting patterns of MEPs requires more capacity and know-how than that routinely held by NGOs across Europe. </p>
<p>That’s even more true for regular citizens -- finding out who is the person representing my interests in the EP, and how that person tends to vote on an issue that I care about, presents too many barriers and challenges for engagement. This leads to a feeling of disconnect - and most likely contributes to the low voter turnout across the EU for the European elections. </p>
<p><strong>The MEPwatch.eu tool is going to close that knowledge gap, and build a solid foundation for fact-based campaigning for CSOs around the upcoming European elections. </strong></p>
<p>By engaging with a simple user interface, and choosing a small number of relevant votes with roll calls, CSOs will be able to generate “scorecards” to assess the voting behaviour of the politicians currently sitting in the European Parliament, many of whom will be running for reelection in the 2019 voting.</p>
<p>The tool will make it possible for CSOs to present to citizens in any EU country the information most relevant in their area, based on a voter’s postal code. It will help bridge the gap between citizens and their representatives in the European Parliament, and ultimately help improve the quality of the European democracy. The app will address and remove the barriers using opendata:</p>
<ul>
<li>Finding the relevant votes and aggregating them to build the scorecards is time consuming and needed expert resources, unaccessible for most CSOs. We will provide all the roll calls and let the CSOs easily compose the relevant scorecards. </li>
<li>Citizens often have difficulty finding out who is their representative in the EP. By using national geographic opendata and data on postal codes, we will make it much simpler to find your MEP, how they voted on an issue you care about, and how their voting behaviour compares to the other representatives at the Parliament.</li>
<li>By using data about the MEPs’ social media accounts, we will provide a simple way for EU citizens to directly engage with their representatives on issues they care about.</li>
</ul>
<p>Some European NGOs have already expressed their interest in beta-testing the MEPwatch.eu tool for the purpose of launching election-related campaigns: on the issue of the copyright reform, and on the revision of the ECI regulation. </p>
<p>To make sure that solid data is available to support fact-based campaigning, we are going to provide the software under an open source license.</p>
<p>According to the Eurobarometer 373, EU citizen think that NGOs can influence EU-level decision making less than that at the national or local level. We think that this is partly because of the difficulty faced by CSOs in the EP elections. We want to change that.</p>
<p>Beside providing a simple to use tool for both citizen and NGOs, the challenge of this project is to aggregate the 28 national datasets on postcodes and geodata/constituencies. We might have to supplement the data available at the European data portal, e.g. with openstreetmap.</p>
</div>
</div>
</main>
<footer class="text-muted">
<div class="container">
<p class="float-right">
<a href="#">Back to top</a>
</p>
</div>
</footer>
<!-- Optional JavaScript -->
<script src="dist/js/main.js"></script>
<script src="dist/js/dcbundle.js"></script>
<script>
'use strict';
var ndx=null;
var graphs={};
var q=d3.queue();
var docs = {};
docs.get=function(reference){
docs[reference] ? docs[reference] : "";
};
var dateParse = d3.timeParse("%Y-%m-%d");
var dateTimeParse = d3.timeParse("%Y-%m-%dT%H:%M:%S");
var dayFormat = d3.timeFormat("%Y-%m-%d");
var dateFormat = d3.timeFormat("%Y-%m-%d %H:%M:%S");
var week = d3.timeFormat("%V");
//d3.csv('data/ep_votes.csv',function(d){
q
.defer(dl_votes)
.defer(dl_doc)
.awaitAll(function(error,results){
draw();
});
function dl_doc (callback){
d3.csv('data/text_tabled.csv',function(d){
docs[d.reference]=d;
}).then(function(d){
callback();
});
};
function dl_votes (callback){
d3.csv('data/item_rollcall.csv',function(d){
d.date=dateParse(d.date.substring(0,10));
if (!d.date) {console.log(d)};
d.day=d.date.getDay();
d.week=+week(d.date);
d.year=d.date.getYear();
["for","against","abstention","identifier"].forEach(function(i) {
d[i]= +d[i] || "";
});
return d;
})
.then(function(d){
ndx = crossfilter(d);
// draw();
callback();
});
};
function draw(){
graphs.date=drawDate('#date div.graph');
graphs.report=drawReport('#report div.graph');
graphs.table=drawTable('table.table');
graphs.search=drawSearch("form#search");
dc.renderAll();
}
function drawReport(dom){
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([0, 10])
.direction("e")
.html(function(d) {
console.log(docs[d.key]);
return docs[d.key]? "<h3>"+docs[d.key].rapporteur+"</h3>"+docs[d.key].title +":"+ d.value: d.value;
// return abbr(d.key) + "<br><b>" + d.value + " MEPs</b> <i>" + formatPercent(d.value/summary.total) +"</i>";
});
//var dim = ndx.dimension(function(d) {return d.report?d.report:"?";}, true);
var dim = ndx.dimension(function(d) {return d.report? d.report : "?";});
var group = dim.group().reduceSum(function(d) {
return 1;
});
var graph = dc.rowChart(dom)
.width(0)
.height(300)
// .rowsCap(18)
// .ordering(function(d) { return -d.key })
.cap(10)
.label (function(d){return docs[d.key]? docs[d.key].rapporteur : d.key})
.renderTitle(false)
.margins({
top: 0,
right: 0,
bottom: 20,
left: 0
})
// .ordinalColors([committee_color])
.gap(0)
.elasticX(true)
.dimension(dim)
.group(group)
.on("renderlet.top", function(c) {
c.selectAll("g.row")
.call(tip)
.on("mouseover.tip", tip.show)
.on("mouseout.tip", tip.hide);
});
graph.xAxis().ticks(3);
return graph;
}
function drawDate(dom){ // not working for now....
//var dim=ndx.dimension(function(d){return [d.year,d.week,d.day]});
var col=d3.timeFormat("%y-%m-%w");
var coltick=d3.timeFormat("%b");
var lasttick="";
var dim=ndx.dimension(function(d){return d.date});
var group=dim.group().reduceSum(function(d){return 1});
var day=["Sun","Mon","Tue","Wed","Thu","Fri"];
var color = d3.scaleLinear()
.domain([0,1, 300])
.range(["white","lightgrey","#7b2253"]);
var graph=dc.heatMap(dom)
.dimension(dim)
.group(group)
.width(0)
.height(150)
.rowsLabel(function(d){
return day[d];
})
.colsLabel(function(d){
var t=Math.floor(d /100000);
if(lasttick !==t){
lasttick=t;
return t;
}
return "";
})
.title(function(d){return dayFormat(d.key)+ " "+d.value+ " rollcalls"})
.label(function(d){return dayFormat(d.key) + " "+d.value+ " rollcalls"})
.keyAccessor(function(d) {
return 1000*d.key.getFullYear()+week(d.key);
var r=d.key;
r.setDate(r.getDate() + d.key.getDay());
console.log(r);
return r;
})
.valueAccessor(function(d) { return +d.key.getDay(); })
.colorAccessor(function(d) { return +d.value; })
.colors(color)
.on ("renderlet.collabel",function (chart) {
return;
// rotate x-axis labels
chart.selectAll('g.cols text')
.attr("style","text-anchor:left;")
//.attr('transform', 'translate(-10,10) rotate(215)');
});
return graph;
}
function drawSearch(dom){
var dim=ndx.dimension(function(d) {return d.report.toLowerCase()+" "+ d.desc.toLowerCase() });
var filter = function (query) {
// query = _normalize(query);
return function (d) {
return d.indexOf(query.toLowerCase()) !== -1;
};
};
var chart=dc.textFilterWidget(dom)
.placeHolder("search by name")
.filterFunctionFactory(filter)
.on("filtered",function(){
console.log("filter");
})
.on("renderlet.urlparam",function(){
var q=urlParam("q");
var input=d3.select(this.anchor() +" input");
if (input.property("value")) {
if (q != input.property("value")) {
urlParam("q",input.property("value"));
}
return; // nothing else to do, already set
}
if (q) {
console.log("filtering for "+q);
input.property("value",q).dispatch("input");
}
})
.dimension(dim);
return chart;
}
function drawTable(dom){
var dim = ndx.dimension(function(d) {
return d.identifier
});
var graph = dc.dataTable(dom)
.dimension(dim)
.size(100)
.sortBy(function(d) {
return d.date;
})
.order (d3.descending)
.showGroups(false)
.group(function(d) {
return null;
})
.columns([
function(d) {
return "<span title='"+d.identifier+"'>" +dayFormat(d.date) +"</span>";
}
,function(d){
if (docs[d.report])
return "<div class='rapporteur'>" +docs[d.report].rapporteur +"</div><a href='"+ docs[d.report].doc+"'>"+ d.report +"</a>";
return d.report;
}
,function(d){
return docs[d.report]? "<a href='"+docs[d.report].oeil+"'>"+docs[d.report].title +"</a>"+d.desc : d.desc;}
,function(d){ return d.for;}
,function(d){ return d.against;}
,function(d){ return d.abstention;}
])
.on("renderlet.govote", function(g) {
g.selectAll("tr.dc-table-row")
.on("click", function(d) {
window.open("vote.html?v="+d3.select(this).datum().identifier);
console.log(d3.select(this).datum());
});
});
return graph;
}
var urlParam = function (name,value) {
if (value) {
var uri=window.location.href;
var re = new RegExp("([?&])" + name + "=.*?(&|#|$)", "i");
if (uri.match(re)) {
uri=uri.replace(re, '$1' + name + "=" + value + '$2');
} else {
var hash = '';
if( uri.indexOf('#') !== -1 ){
hash = uri.replace(/.*#/, '#');
uri = uri.replace(/#.*/, '');
}
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
uri= uri + separator + name + "=" + value + hash;
}
history.pushState({q:value},"search for "+value,uri);
return uri;
} else {
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (results == null) {
return null;
} else {
return decodeURI(results[1]) || 0;
}
}
};
</script>
<svg class="d-none">
<symbol id="logo" viewBox="0 0 24 24"><path d="M6 13c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-8c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-3 .5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm15 5.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM14 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm-11 10c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm7 7c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-17c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM10 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 5.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm8 .5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-8c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm3 8.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM14 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-4-12c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0 8.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm4-4.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-4c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/></symbol>
</svg>
</body>
</html>