index.html
<!DOCTYPE html>
<html>
<head>
<title>Slovensko - referendum 2015</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/journal/bootstrap.min.css">
<link rel="stylesheet" href="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="d3.tip.js"></script>
<style type="text/css">
.leaflet-tile-pane {
opacity: .4
}
.leaflet-container {
background-color: #fff;
}
html, body{
width: 100%;
height: 100%;
}
#map {
width: 100%;
height: 90%;
}
circle {
cursor: pointer;
fill-opacity: 0.8;
stroke-opacity: 0.01;
}
circle:hover {
stroke-opacity: 1;
}
.towns {
width: 100000px;
height: 100000px;
}
svg:not(:root) {
overflow: visible;
}
.d3-tip {
line-height: 1;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
.d3-tip small {
font-size: 0.5em;
}
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.stronger {
color: yellow;
font-weight: bold;
}
.navbar {
margin-bottom: 0;
}
</style>
</head>
<body>
<div class="navbar navbar-default" role=navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand">Slovensko - referendum 2015</a>
</div>
</div>
</div>
<div style="position:fixed;top:125px;z-index:1000;">
<div class="alert alert-info" style="float:left;" id="legend">
<h3>Účasť</h3>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="blue"></svg> 100 %<br/>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="green"></svg> 50 %<br/>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="yellow"></svg> 21.4 %<br/>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="red"></svg> 0 %<br/>
</div>
</div>
<div id="map"></div>
<script type="text/javascript">
var map = L.map('map', {'zoomControl':false}).setView([48.55,19.467773], 8);
L.tileLayer('//{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png', {
attribution: 'CC-BY Michal Škop | © <a href="//osm.org/copyright">OpenStreetMap</a> contributors | dáta Štatistický úrad SR'
}).addTo(map);
L.control.zoom({"position":"topright"}).addTo(map);
var svg = d3.select(map.getPanes().overlayPane).append("svg").attr("class", "towns");
var radiusScale = d3.scale.sqrt().domain([0, 400000]).range([0, 120]);
var color = colorscale([0,0.214,0.5,1],["red", "yellow", "green", "blue"]);
var tip = changetooltip();
svg.call(tip);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
d3.csv('sk.csv', function(data) {
d3.json('sk_referendum.json',function(mayors) {
nodes = data
.map(function(d) {
mpoint = projectPoint(d.lat,d.long);
ret = {
x: mpoint.x,
y: mpoint.y,
name: d.name,
value: d
};
if (typeof(mayors[d.id]) != 'undefined') {
ret['mayor'] = mayors[d.id];
ret['r'] = radiusScale(mayors[d.id]["turnout"]);
}
return ret;
});
var circle = svg.selectAll("svg")
.data(nodes)
.enter().append("svg:svg")
.append("svg:circle")
.attr("class","town")
.attr("cx", function (d) {return d.x})
.attr("cy", function (d) {return d.y})
.attr("r", function (d) {return d.r})
.attr("fill", function (d) {
if (typeof(d.mayor) != 'undefined') {
return color(parseFloat(d.mayor.turnout_perc.replace(",","."))/100);
} else {
return '#ccf';
}
})
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
map.on("viewreset", changeit);
map.on("moveend", changeit);
map.on("zoomstart", hidepoints);
$(".towns").show(100);
});
});
function matrixVal(s) {
return s.split('(')[1].split(')')[0].split(',');
}
function hidepoints() {
$(".towns").hide();
}
function changeit() {
var s = $(".leaflet-map-pane").css("-webkit-transform");
if (typeof(s) == 'undefined')
var s = $(".leaflet-map-pane").css("transform");
var sar = matrixVal(s);
$(".towns").css('left',-1*parseFloat(sar[4]));
$(".towns").css('top',-1*parseFloat(sar[5]));
d3.selectAll(".town").each(function(d,i) {
mpoint = projectPoint(d.value.lat,d.value.long,d.value.id);
$(this)
.attr("r",
function() {
if (typeof(d.mayor) != 'undefined')
return radiusScale(d.mayor["turnout"]) * Math.pow(map.getZoom(),3) / 512;
else
return 0;
}
)
.attr("cx", mpoint.x)
.attr("cy", mpoint.y);
$(this).attr('transform',"translate(" + sar[4] + "," + sar[5] + ")");
});
$(".towns").show(300);
}
function projectPoint(x, y, id) {
var point = map.latLngToLayerPoint(new L.LatLng(x, y));
if (!isNumeric(point.x)) alert(id);
return point;
}
function changetooltip() {
tip = d3.tip().attr('class', 'd3-tip').html(function(d) {
html = '<span class="stronger">' + d.name + "</span><br>";
if (typeof(d.mayor) != 'undefined') {
html += 'Účasť: '+d.mayor.turnout+ ' ('+d.mayor.turnout_perc+'%)<br>';
html += 'Otázka 1 (manželstvo): '+d.mayor.q1+'%<br>';
html += 'Otázka 2 (adopcie): '+d.mayor.q2+'%<br>';
html += 'Otázka 3 (sex.výchova): '+d.mayor.q3+'%<br>';
}
return html;
});
return tip;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function colorscale(domain,range) {
return d3.scale.linear()
.domain(domain)
.range(range);
}
</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-8592359-13', 'ocks.org');
ga('send', 'pageview');
</script>
</body>
</html>
autopush.sh
#!/bin/bash
cd /home/michal/project/gist/ba56b4f6c4df364f9a47
git add -A
git commit -m "update"
# needed to be authentized
# using git config --global credential.helper 'cache --timeout 3600'
# also good for security
git push
chart1.html
<!DOCTYPE html>
<html lang="sk">
<head>
<meta charset="utf-8">
<title>Referendum 2015: sever a juh, vidiek a mestá</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="WPCA scatter plot">
<meta name="author" content="Michal Škop">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/journal/bootstrap.min.css">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="./d3.scatterplot.js"></script>
<script src="./d3.tip.js"></script>
<style type="text/css">
.tick {
fill-opacity: 0;
stroke: #000000;
stroke-width: 1;
}
.domain {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
}
.axis line {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
stroke: gray;
}
circle {
fill-opacity: .5;
fill:#080;
stroke:#080;
stroke-opacity: 0.99;
stroke-width: 1;
}
circle:hover {
fill-opacity: 1;
}
.label {
font-family: sans-serif;
font-size: 15px;
}
.stronger {
color: yellow;
font-weight: bold;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
pointer-events: none;
max-width: 400px;
}
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}
.d3-tip:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}
line {
stroke:gray;
stroke-width:1;
opacity: .15;
}
.centerline {
stroke: #b00;
stroke-width: 3;
stroke-opacity: 1;
}
.averageline {
stroke: #080;
stroke-width: 2;
stroke-opacity: 1;
stroke-dasharray: 10, 5;
}
#chart {
}
</style>
</head>
<body>
<h1>Slovensko: referendum 2015 <small>sever a juh, vidiek a mestá</small></h1>
<div id="chart"></div>
<p class="bg-info"><span class="glyphicon glyphicon-info-sign" aria-hidden="false"> </span> Každý bod je jedna obec. Veľkosť bodu reprezentuje počet obyvateľov. Účasť v referende bola väčšia <strong>na severe</strong> ako na juhu a <strong>na vidieku</strong> ako vo väčších mestách.
<footer><small>CC-BY Michal Škop, <a href="//kohovolit.eu">KohoVolit.eu</a>, <a href="//uhk.cz">UHK</a> | dáta Štatistický úrad SR</small></footer>
<script type="text/javascript">
d3.csv('sk.csv', function(data) {
d3.json("sk_referendum.json", function(data2) {
points = [];
data.forEach(function(d) {
if (typeof(data2[d.id]) != 'undefined') {
d2 = data2[d.id];
points.push({
'r' : Math.sqrt(parseInt(d2["turnout"]) / parseFloat(d2.turnout_perc.replace(",","."))*100),
'x': parseFloat(d.lat),
'y': parseFloat(d2.turnout_perc.replace(",",".")),
'name': d.name
});
}
});
var scatterplot = [{
"data": points,
"margin": {top: 10, right: 10, bottom: 30, left: 30},
"axes": {"labels":{"y":"Účasť (%)", "x":"← Juh - Sever → (zem.šírka)"}},
"minmax":{
"y":{'min':0,'max':100},
"x":{'min':47.7,'max':49.6},
"r":{'min':0,'max':Math.sqrt(400000)},
"rrange":{'min':0,'max':33}
},
"size":{"width":700,"height":400},
}];
var svg = d3.select("#chart")
.append("svg")
.attr("width",scatterplot[0]['size']['width'])
.attr("height",scatterplot[0]['size']['height']);
tip = d3.tip().attr('class', 'd3-tip').html(
function(d) {
return "<span class=\'stronger\'>" + d["name"] + "</span><br>" +
'Účasť: '+d.y+'%';
});
svg.call(tip)
var sp = d3.scatterplot()
.data(function(d) {return d.data})
.margin(function(d) {return d.margin})
.axes(function(d) {return d.axes})
.minmax(function(d) {return d.minmax})
.size(function(d) {return d.size})
var scatter = svg.selectAll(".scatterplot")
.data(scatterplot)
.enter()
.append("svg:g")
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")")
.call(sp);
var line = d3.svg.line()
.x(
function(d) {
return d[0]; })
.y(function(d) { return d[1]; });
var width = scatterplot[0].size['width'] - scatterplot[0].margin.left - scatterplot[0].margin.right,
height = scatterplot[0].size['height'] - scatterplot[0].margin.top - scatterplot[0].margin.bottom;
var xScale = d3.scale.linear()
.domain([scatterplot[0].minmax['x']['min'], scatterplot[0].minmax['x']['max']])
.range([0, width])
var yScale = d3.scale.linear()
.domain([scatterplot[0].minmax['y']['min'], scatterplot[0].minmax['y']['max']])
.range([height, 0])
centerline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(50)],[xScale(scatterplot[0].minmax['x']['max']),yScale(50)]);
svg.append("path")
.datum(centerline)
.attr("class", "centerline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
averageline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(21.4)],[xScale(scatterplot[0].minmax['x']['max']),yScale(21.4)]);
svg.append("path")
.datum(averageline)
.attr("class", "averageline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
})
})
</script>
</body>
</html>
chart1_650.html
<!DOCTYPE html>
<html lang="sk">
<head>
<meta charset="utf-8">
<title>Referendum 2015: sever a juh, vidiek a mestá</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="WPCA scatter plot">
<meta name="author" content="Michal Škop">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/journal/bootstrap.min.css">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="./d3.scatterplot.js"></script>
<script src="./d3.tip.js"></script>
<style type="text/css">
.tick {
fill-opacity: 0;
stroke: #000000;
stroke-width: 1;
}
.domain {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
}
.axis line {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
stroke: gray;
}
circle {
fill-opacity: .5;
fill:#080;
stroke:#080;
stroke-opacity: 0.99;
stroke-width: 1;
}
circle:hover {
fill-opacity: 1;
}
.label {
font-family: sans-serif;
font-size: 15px;
}
.stronger {
color: yellow;
font-weight: bold;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
pointer-events: none;
max-width: 400px;
}
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}
.d3-tip:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}
line {
stroke:gray;
stroke-width:1;
opacity: .15;
}
.centerline {
stroke: #b00;
stroke-width: 3;
stroke-opacity: 1;
}
.averageline {
stroke: #080;
stroke-width: 2;
stroke-opacity: 1;
stroke-dasharray: 10, 5;
}
#chart {
}
</style>
</head>
<body>
<h3>Slovensko: referendum 2015 <small>sever a juh, vidiek a mestá</small></h3>
<div id="chart"></div>
<p class="bg-info"><small><span class="glyphicon glyphicon-info-sign" aria-hidden="false"> </span> Každý bod je jedna obec. Veľkosť bodu reprezentuje počet obyvateľov. Účasť v referende bola väčšia <strong>na severe</strong> ako na juhu a <strong>na vidieku</strong> ako vo väčších mestách.</small>
<footer><small>CC-BY Michal Škop, <a href="//kohovolit.eu">KohoVolit.eu</a>, <a href="//uhk.cz">UHK</a> | dáta Štatistický úrad SR</small></footer>
<script type="text/javascript">
d3.csv('sk.csv', function(data) {
d3.json("sk_referendum.json", function(data2) {
points = [];
data.forEach(function(d) {
if (typeof(data2[d.id]) != 'undefined') {
d2 = data2[d.id];
points.push({
'r' : Math.sqrt(parseInt(d2["turnout"]) / parseFloat(d2.turnout_perc.replace(",","."))*100),
'x': parseFloat(d.lat),
'y': parseFloat(d2.turnout_perc.replace(",",".")),
'name': d.name
});
}
});
var scatterplot = [{
"data": points,
"margin": {top: 10, right: 10, bottom: 30, left: 30},
"axes": {"labels":{"y":"Účasť (%)", "x":"← Juh - Sever → (zem.šírka)"}},
"minmax":{
"y":{'min':0,'max':100},
"x":{'min':47.7,'max':49.6},
"r":{'min':0,'max':Math.sqrt(400000)},
"rrange":{'min':0,'max':25}
},
"size":{"width":650,"height":250},
}];
var svg = d3.select("#chart")
.append("svg")
.attr("width",scatterplot[0]['size']['width'])
.attr("height",scatterplot[0]['size']['height']);
tip = d3.tip().attr('class', 'd3-tip').html(
function(d) {
return "<span class=\'stronger\'>" + d["name"] + "</span><br>" +
'Účasť: '+d.y+'%';
});
svg.call(tip)
var sp = d3.scatterplot()
.data(function(d) {return d.data})
.margin(function(d) {return d.margin})
.axes(function(d) {return d.axes})
.minmax(function(d) {return d.minmax})
.size(function(d) {return d.size})
var scatter = svg.selectAll(".scatterplot")
.data(scatterplot)
.enter()
.append("svg:g")
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")")
.call(sp);
var line = d3.svg.line()
.x(
function(d) {
return d[0]; })
.y(function(d) { return d[1]; });
var width = scatterplot[0].size['width'] - scatterplot[0].margin.left - scatterplot[0].margin.right,
height = scatterplot[0].size['height'] - scatterplot[0].margin.top - scatterplot[0].margin.bottom;
var xScale = d3.scale.linear()
.domain([scatterplot[0].minmax['x']['min'], scatterplot[0].minmax['x']['max']])
.range([0, width])
var yScale = d3.scale.linear()
.domain([scatterplot[0].minmax['y']['min'], scatterplot[0].minmax['y']['max']])
.range([height, 0])
centerline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(50)],[xScale(scatterplot[0].minmax['x']['max']),yScale(50)]);
svg.append("path")
.datum(centerline)
.attr("class", "centerline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
averageline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(21.4)],[xScale(scatterplot[0].minmax['x']['max']),yScale(21.4)]);
svg.append("path")
.datum(averageline)
.attr("class", "averageline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
})
})
</script>
</body>
</html>
chart2.html
<!DOCTYPE html>
<html lang="sk">
<head>
<meta charset="utf-8">
<title>W-PCA Scatterplot Chart</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="WPCA scatter plot">
<meta name="author" content="Michal Škop">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="./d3.scatterplot.js"></script>
<script src="./d3.tip.js"></script>
<style type="text/css">
.tick {
fill-opacity: 0;
stroke: #000000;
stroke-width: 1;
}
.domain {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
}
.axis line {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
stroke: gray;
}
circle {
fill-opacity: .5;
fill:#080;
stroke:#080;
stroke-opacity: 0.99;
stroke-width: 1;
}
circle:hover {
fill-opacity: 1;
}
.label {
font-family: sans-serif;
font-size: 15px;
}
.stronger {
color: yellow;
font-weight: bold;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
pointer-events: none;
max-width: 400px;
}
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}
.d3-tip:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}
line {
stroke:gray;
stroke-width:1;
opacity: .15;
}
.centerline {
stroke: #b00;
stroke-width: 3;
stroke-opacity: 1;
}
.averageline {
stroke: #080;
stroke-width: 2;
stroke-opacity: 1;
stroke-dasharray: 10, 5;
}
#chart {
}
</style>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
d3.csv('sk.csv', function(data) {
d3.json("sk_referendum.json", function(data2) {
points = [];
data.forEach(function(d) {
if (typeof(data2[d.id]) != 'undefined') {
d2 = data2[d.id];
points.push({
'r' : Math.sqrt(parseInt(d2["turnout"]) / parseFloat(d2.turnout_perc.replace(",","."))*100),
'x': parseInt(d2["turnout"]) / parseFloat(d2.turnout_perc.replace(",","."))*100,
'y': parseFloat(d2.turnout_perc.replace(",",".")),
'name': d.name
});
}
});
var scatterplot = [{
"data": points,
"margin": {top: 10, right: 10, bottom: 30, left: 30},
"axes": {"labels":{"y":"Účasť (%)", "x":"← Juh - Sever → (zem.šírka)"}},
"minmax":{
"y":{'min':0,'max':100},
"x":{'min':20,'max':600000},
"r":{'min':0,'max':Math.sqrt(400000)},
"rrange":{'min':0,'max':33}
},
"size":{"width":700,"height":500},
}];
var svg = d3.select("#chart")
.append("svg")
.attr("width",scatterplot[0]['size']['width'])
.attr("height",scatterplot[0]['size']['height']);
tip = d3.tip().attr('class', 'd3-tip').html(
function(d) {
return "<span class=\'stronger\'>" + d["name"] + "</span><br>" +
'Účasť: '+d.y+'%';
});
svg.call(tip)
var sp = d3.scatterplot()
.data(function(d) {return d.data})
.margin(function(d) {return d.margin})
.axes(function(d) {return d.axes})
.minmax(function(d) {return d.minmax})
.size(function(d) {return d.size})
var scatter = svg.selectAll(".scatterplot")
.data(scatterplot)
.enter()
.append("svg:g")
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")")
.call(sp);
var line = d3.svg.line()
.x(
function(d) {
return d[0]; })
.y(function(d) { return d[1]; });
var width = scatterplot[0].size['width'] - scatterplot[0].margin.left - scatterplot[0].margin.right,
height = scatterplot[0].size['height'] - scatterplot[0].margin.top - scatterplot[0].margin.bottom;
var xScale = d3.scale.linear()
.domain([scatterplot[0].minmax['x']['min'], scatterplot[0].minmax['x']['max']])
.range([0, width])
var yScale = d3.scale.linear()
.domain([scatterplot[0].minmax['y']['min'], scatterplot[0].minmax['y']['max']])
.range([height, 0])
centerline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(50)],[xScale(scatterplot[0].minmax['x']['max']),yScale(50)]);
svg.append("path")
.datum(centerline)
.attr("class", "centerline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
averageline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(21.4)],[xScale(scatterplot[0].minmax['x']['max']),yScale(21.4)]);
svg.append("path")
.datum(averageline)
.attr("class", "averageline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
})
})
</script>
</body>
</html>
chart3.html
<!DOCTYPE html>
<html lang="sk">
<head>
<meta charset="utf-8">
<title>Referendum 2015: sever a juh, vidiek a mestá</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="WPCA scatter plot">
<meta name="author" content="Michal Škop">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/journal/bootstrap.min.css">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="./d3.scatterplot.js"></script>
<script src="./d3.tip.js"></script>
<style type="text/css">
.tick {
fill-opacity: 0;
stroke: #000000;
stroke-width: 1;
}
.domain {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
}
.axis line {
fill: none;
fill-opacity: 0;
stroke: black;
stroke-width: 1;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
stroke: gray;
}
circle {
fill-opacity: .5;
fill:#080;
stroke:#080;
stroke-opacity: 0.99;
stroke-width: 1;
}
circle:hover {
fill-opacity: 1;
}
.label {
font-family: sans-serif;
font-size: 15px;
}
.stronger {
color: yellow;
font-weight: bold;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
pointer-events: none;
max-width: 400px;
}
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}
.d3-tip:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}
line {
stroke:gray;
stroke-width:1;
opacity: .15;
}
.centerline {
stroke: #b00;
stroke-width: 3;
stroke-opacity: 1;
}
.averageline {
stroke: #080;
stroke-width: 2;
stroke-opacity: 1;
stroke-dasharray: 10, 5;
}
#chart {
}
</style>
</head>
<body>
<h1>Slovensko: referendum 2015 <small>východ a západ, vidiek a mestá</small></h1>
<div id="chart"></div>
<p class="bg-info"><span class="glyphicon glyphicon-info-sign" aria-hidden="false"> </span> Každý bod je jedna obec. Veľkosť bodu reprezentuje počet obyvateľov. Účasť v referende bola väčšia <strong>na vidieku</strong> ako vo väčších mestách.
<footer><small>CC-BY Michal Škop, <a href="//kohovolit.eu">KohoVolit.eu</a>, <a href="//uhk.cz">UHK</a> | dáta Štatistický úrad SR</small></footer>
<script type="text/javascript">
d3.csv('sk.csv', function(data) {
d3.json("sk_referendum.json", function(data2) {
points = [];
data.forEach(function(d) {
if (typeof(data2[d.id]) != 'undefined') {
d2 = data2[d.id];
points.push({
'r' : Math.sqrt(parseInt(d2["turnout"]) / parseFloat(d2.turnout_perc.replace(",","."))*100),
'x': parseFloat(d.long),
'y': parseFloat(d2.turnout_perc.replace(",",".")),
'name': d.name
});
}
});
var scatterplot = [{
"data": points,
"margin": {top: 10, right: 10, bottom: 30, left: 30},
"axes": {"labels":{"y":"Účasť (%)", "x":"← Západ - Východ → (zem.délka)"}},
"minmax":{
"y":{'min':0,'max':100},
"x":{'min':16.8,'max':22.6},
"r":{'min':0,'max':Math.sqrt(400000)},
"rrange":{'min':0,'max':33}
},
"size":{"width":700,"height":400},
}];
var svg = d3.select("#chart")
.append("svg")
.attr("width",scatterplot[0]['size']['width'])
.attr("height",scatterplot[0]['size']['height']);
tip = d3.tip().attr('class', 'd3-tip').html(
function(d) {
return "<span class=\'stronger\'>" + d["name"] + "</span><br>" +
'Účasť: '+d.y+'%';
});
svg.call(tip)
var sp = d3.scatterplot()
.data(function(d) {return d.data})
.margin(function(d) {return d.margin})
.axes(function(d) {return d.axes})
.minmax(function(d) {return d.minmax})
.size(function(d) {return d.size})
var scatter = svg.selectAll(".scatterplot")
.data(scatterplot)
.enter()
.append("svg:g")
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")")
.call(sp);
var line = d3.svg.line()
.x(
function(d) {
return d[0]; })
.y(function(d) { return d[1]; });
var width = scatterplot[0].size['width'] - scatterplot[0].margin.left - scatterplot[0].margin.right,
height = scatterplot[0].size['height'] - scatterplot[0].margin.top - scatterplot[0].margin.bottom;
var xScale = d3.scale.linear()
.domain([scatterplot[0].minmax['x']['min'], scatterplot[0].minmax['x']['max']])
.range([0, width])
var yScale = d3.scale.linear()
.domain([scatterplot[0].minmax['y']['min'], scatterplot[0].minmax['y']['max']])
.range([height, 0])
centerline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(50)],[xScale(scatterplot[0].minmax['x']['max']),yScale(50)]);
svg.append("path")
.datum(centerline)
.attr("class", "centerline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
averageline = Array([xScale(scatterplot[0].minmax['x']['min']),yScale(21.4)],[xScale(scatterplot[0].minmax['x']['max']),yScale(21.4)]);
svg.append("path")
.datum(averageline)
.attr("class", "averageline")
.attr("d", line)
.attr("transform", "translate(" + scatterplot[0].margin.left + "," + scatterplot[0].margin.top + ")");
})
})
</script>
</body>
</html>
d3.scatterplot.js
d3.scatterplot = function() {
function scatterplot(selection) {
selection.each(function(d, i) {
var data = (typeof(data) === "function" ? data(d) : d.data),
margin = (typeof(margin) === "function" ? margin(d) : d.margin),
axes = (typeof(axes) === "function" ? axes(d) : d.axes),
minmax = (typeof(minmax) === "function" ? minmax(d) : d.minmax),
size = (typeof(size) === "function" ? size(d) : d.size);
var width = size['width'] - margin.left - margin.right,
height = size['height'] - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.domain([minmax['x']['min'], minmax['x']['max']])
.range([0, width])
var yScale = d3.scale.linear()
.domain([minmax['y']['min'], minmax['y']['max']])
.range([height, 0])
var rScale = d3.scale.linear()
.domain([minmax['r']['min'],minmax['r']['max']])
.range([minmax['rrange']['min'],minmax['rrange']['max']]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var element = d3.select(this);
element.append("g")
.attr("class", "axis x-axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
element.append("g")
.attr("class", "axis y-axis")
.call(yAxis);
element.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d.x);
})
.attr("cy", function(d) {
return yScale(d.y);
})
.attr("r", function(d) {
return rScale(d.r);
})
.attr("class", function(d) {
if (typeof(d['class'] != 'undefined')) return d['class'];
else return 'circle';
})
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
element.append("text")
.attr("class", "x-label label")
.attr("text-anchor", "end")
.attr("x", width)
.attr("y", height-5)
.text(axes['labels']['x']);
element.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("y", 5)
.attr("x", 0)
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text(axes['labels']['y']);
});
}
scatterplot.data = function(value) {
if (!arguments.length) return value;
data = value;
return scatterplot;
};
scatterplot.margin = function(value) {
if (!arguments.length) return value;
margin = value;
return scatterplot;
};
scatterplot.axes = function(value) {
if (!arguments.length) return value;
axes = value;
return scatterplot;
};
scatterplot.minmax = function(value) {
if (!arguments.length) return value;
minmax = value;
return scatterplot;
};
scatterplot.size = function(value) {
if (!arguments.length) return value;
size = value;
return scatterplot;
};
return scatterplot;
}
d3.tip.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['d3'], factory)
} else {
root.d3.tip = factory(root.d3)
}
}(this, function (d3) {
return function() {
var direction = d3_tip_direction,
offset = d3_tip_offset,
html = d3_tip_html,
node = initNode(),
svg = null,
point = null,
target = null
function tip(vis) {
svg = getSVGNode(vis)
point = svg.createSVGPoint()
document.body.appendChild(node)
}
tip.show = function() {
var args = Array.prototype.slice.call(arguments)
if(args[args.length - 1] instanceof SVGElement) target = args.pop()
var content = html.apply(this, args),
poffset = offset.apply(this, args),
dir = direction.apply(this, args),
nodel = d3.select(node),
i = directions.length,
coords,
scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
nodel.html(content)
.style({ opacity: 1, 'pointer-events': 'all' })
while(i--) nodel.classed(directions[i], false)
coords = direction_callbacks.get(dir).apply(this)
nodel.classed(dir, true).style({
top: (coords.top + poffset[0]) + scrollTop + 'px',
left: (coords.left + poffset[1]) + scrollLeft + 'px'
})
return tip
}
tip.hide = function() {
nodel = d3.select(node)
nodel.style({ opacity: 0, 'pointer-events': 'none' })
return tip
}
tip.attr = function(n, v) {
if (arguments.length < 2 && typeof n === 'string') {
return d3.select(node).attr(n)
} else {
var args = Array.prototype.slice.call(arguments)
d3.selection.prototype.attr.apply(d3.select(node), args)
}
return tip
}
tip.style = function(n, v) {
if (arguments.length < 2 && typeof n === 'string') {
return d3.select(node).style(n)
} else {
var args = Array.prototype.slice.call(arguments)
d3.selection.prototype.style.apply(d3.select(node), args)
}
return tip
}
tip.direction = function(v) {
if (!arguments.length) return direction
direction = v == null ? v : d3.functor(v)
return tip
}
tip.offset = function(v) {
if (!arguments.length) return offset
offset = v == null ? v : d3.functor(v)
return tip
}
tip.html = function(v) {
if (!arguments.length) return html
html = v == null ? v : d3.functor(v)
return tip
}
function d3_tip_direction() { return 'n' }
function d3_tip_offset() { return [0, 0] }
function d3_tip_html() { return ' ' }
var direction_callbacks = d3.map({
n: direction_n,
s: direction_s,
e: direction_e,
w: direction_w,
nw: direction_nw,
ne: direction_ne,
sw: direction_sw,
se: direction_se
}),
directions = direction_callbacks.keys()
function direction_n() {
var bbox = getScreenBBox()
return {
top: bbox.n.y - node.offsetHeight,
left: bbox.n.x - node.offsetWidth / 2
}
}
function direction_s() {
var bbox = getScreenBBox()
return {
top: bbox.s.y,
left: bbox.s.x - node.offsetWidth / 2
}
}
function direction_e() {
var bbox = getScreenBBox()
return {
top: bbox.e.y - node.offsetHeight / 2,
left: bbox.e.x
}
}
function direction_w() {
var bbox = getScreenBBox()
return {
top: bbox.w.y - node.offsetHeight / 2,
left: bbox.w.x - node.offsetWidth
}
}
function direction_nw() {
var bbox = getScreenBBox()
return {
top: bbox.nw.y - node.offsetHeight,
left: bbox.nw.x - node.offsetWidth
}
}
function direction_ne() {
var bbox = getScreenBBox()
return {
top: bbox.ne.y - node.offsetHeight,
left: bbox.ne.x
}
}
function direction_sw() {
var bbox = getScreenBBox()
return {
top: bbox.sw.y,
left: bbox.sw.x - node.offsetWidth
}
}
function direction_se() {
var bbox = getScreenBBox()
return {
top: bbox.se.y,
left: bbox.e.x
}
}
function initNode() {
var node = d3.select(document.createElement('div'))
node.style({
position: 'absolute',
top: 0,
opacity: 0,
'pointer-events': 'none',
'box-sizing': 'border-box'
})
return node.node()
}
function getSVGNode(el) {
el = el.node()
if(el.tagName.toLowerCase() == 'svg')
return el
return el.ownerSVGElement
}
function getScreenBBox() {
var targetel = target || d3.event.target,
bbox = {},
matrix = targetel.getScreenCTM(),
tbbox = targetel.getBBox(),
width = tbbox.width,
height = tbbox.height,
x = tbbox.x,
y = tbbox.y
point.x = x
point.y = y
bbox.nw = point.matrixTransform(matrix)
point.x += width
bbox.ne = point.matrixTransform(matrix)
point.y += height
bbox.se = point.matrixTransform(matrix)
point.x -= width
bbox.sw = point.matrixTransform(matrix)
point.y -= height / 2
bbox.w = point.matrixTransform(matrix)
point.x += width
bbox.e = point.matrixTransform(matrix)
point.x -= width / 2
point.y -= height / 2
bbox.n = point.matrixTransform(matrix)
point.y += height
bbox.s = point.matrixTransform(matrix)
return bbox
}
return tip
};
}));
index650.html
<!DOCTYPE html>
<html>
<head>
<title>Slovensko - referendum 2015</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/journal/bootstrap.min.css">
<link rel="stylesheet" href="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="d3.tip.js"></script>
<style type="text/css">
.leaflet-tile-pane {
opacity: .4
}
.leaflet-container {
background-color: #fff;
}
html, body{
width: 100%;
height: 100%;
}
#map {
width: 100%;
height: 90%;
}
circle {
cursor: pointer;
fill-opacity: 0.8;
stroke-opacity: 0.01;
}
circle:hover {
stroke-opacity: 1;
}
.towns {
width: 100000px;
height: 100000px;
}
svg:not(:root) {
overflow: visible;
}
.d3-tip {
line-height: 1;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
.d3-tip small {
font-size: 0.5em;
}
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.stronger {
color: yellow;
font-weight: bold;
}
.navbar {
margin-bottom: 0;
}
</style>
</head>
<body>
<div class="navbar navbar-default" role=navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand">Slovensko - referendum 2015</a>
</div>
</div>
</div>
<div style="position:fixed;top:125px;z-index:1000;">
<div class="alert alert-info" style="float:left;" id="legend">
<h3>Účasť</h3>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="blue"></svg> 100 %<br/>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="green"></svg> 50 %<br/>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="yellow"></svg> 21.4 %<br/>
<svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="red"></svg> 0 %<br/>
</div>
</div>
<div id="map"></div>
<script type="text/javascript">
var map = L.map('map', {'zoomControl':false}).setView([48.55,19.467773], 7);
L.tileLayer('//{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png', {
attribution: 'CC-BY Michal Škop | © <a href="//osm.org/copyright">OpenStreetMap</a> contributors | dáta Štatistický úrad SR'
}).addTo(map);
L.control.zoom({"position":"topright"}).addTo(map);
var svg = d3.select(map.getPanes().overlayPane).append("svg").attr("class", "towns");
var radiusScale = d3.scale.sqrt().domain([0, 400000]).range([0, 120]);
var color = colorscale([0,0.214,0.5,1],["red", "yellow", "green", "blue"]);
var tip = changetooltip();
svg.call(tip);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
d3.csv('sk.csv', function(data) {
d3.json('sk_referendum.json',function(mayors) {
nodes = data
.map(function(d) {
mpoint = projectPoint(d.lat,d.long);
ret = {
x: mpoint.x,
y: mpoint.y,
name: d.name,
value: d
};
if (typeof(mayors[d.id]) != 'undefined') {
ret['mayor'] = mayors[d.id];
ret['r'] = radiusScale(mayors[d.id]["turnout"]) * Math.pow(7,3) / 512;
}
return ret;
});
var circle = svg.selectAll("svg")
.data(nodes)
.enter().append("svg:svg")
.append("svg:circle")
.attr("class","town")
.attr("cx", function (d) {return d.x})
.attr("cy", function (d) {return d.y})
.attr("r", function (d) {return d.r})
.attr("fill", function (d) {
if (typeof(d.mayor) != 'undefined') {
return color(parseFloat(d.mayor.turnout_perc.replace(",","."))/100);
} else {
return '#ccf';
}
})
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
map.on("viewreset", changeit);
map.on("moveend", changeit);
map.on("zoomstart", hidepoints);
$(".towns").show(100);
});
});
function matrixVal(s) {
return s.split('(')[1].split(')')[0].split(',');
}
function hidepoints() {
$(".towns").hide();
}
function changeit() {
var s = $(".leaflet-map-pane").css("-webkit-transform");
if (typeof(s) == 'undefined')
var s = $(".leaflet-map-pane").css("transform");
var sar = matrixVal(s);
$(".towns").css('left',-1*parseFloat(sar[4]));
$(".towns").css('top',-1*parseFloat(sar[5]));
d3.selectAll(".town").each(function(d,i) {
mpoint = projectPoint(d.value.lat,d.value.long,d.value.id);
$(this)
.attr("r",
function() {
if (typeof(d.mayor) != 'undefined')
return radiusScale(d.mayor["turnout"]) * Math.pow(map.getZoom(),3) / 512;
else
return 0;
}
)
.attr("cx", mpoint.x)
.attr("cy", mpoint.y);
$(this).attr('transform',"translate(" + sar[4] + "," + sar[5] + ")");
});
$(".towns").show(300);
}
function projectPoint(x, y, id) {
var point = map.latLngToLayerPoint(new L.LatLng(x, y));
if (!isNumeric(point.x)) alert(id);
return point;
}
function changetooltip() {
tip = d3.tip().attr('class', 'd3-tip').html(function(d) {
html = '<span class="stronger">' + d.name + "</span><br>";
if (typeof(d.mayor) != 'undefined') {
html += 'Účasť: '+d.mayor.turnout+ ' ('+d.mayor.turnout_perc+'%)<br>';
html += 'Otázka 1 (manželstvo): '+d.mayor.q1+'%<br>';
html += 'Otázka 2 (adopcie): '+d.mayor.q2+'%<br>';
html += 'Otázka 3 (sex.výchova): '+d.mayor.q3+'%<br>';
}
return html;
});
return tip;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function colorscale(domain,range) {
return d3.scale.linear()
.domain(domain)
.range(range);
}
</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-8592359-13', 'ocks.org');
ga('send', 'pageview');
</script>
</body>
</html>
map_210.jpg
���� JFIF H H �� Created with GIMP�� C
�� C
�� q � �� �� �� ��Ӌ���M�(�Bb6h EZ�Z� "-�0Xpl� �`������Sܷ,<B�n���?L�K�V�a�f�{�ڦe����ٖT��}������<�v8� k���v�n���PI���[�������l��H���m�ymy��\鋅Z;�e[��+�ݧ��K�O�����N��q�Ͳ��1 ��Χ)��߯oس���-oTͧ���|�|�N⦅�˅L���\{*�}�l�����6kf6%�B#7�`��[薎��x�1�*,���Ie�yY�s+�7����뇁_��#Еr�r�4�Bi|�C��g����R�L��l����)i�Ш�9$��3s�e�ļ��c����C7:��%�S��n�����T`qY�٤�m�~�尼J��]d��|n�� ��6~��w6�U��0��gB�2�;�R���t�˸�$Q�&�<���e���1z/E�ڎ[,Ȫ���s�7�/����&��8����ƹ|��z|�bl���uYF�q*��/;�Yh�����W��� L�a^�j��L38ھc�^��>���N�v���k=.�N�?M�7���*�ncSM������D���� C��p�qە�Z�eT��}\���������2BCRe�� Xt i1���v�l��F\nGO[����YZ(��B��C��>``� �*���5���c�V��L�[�Z��� 0�I���P � � L���A�h<�X2g��X$)P�
A!(X
�%
C��0�GfH<�à`���� ' !1A"#23�� =��oEs��ư"��|Ij����Q����H������� �c�A����l��Ƨ�!4]p�i��1�yd�d@��y_������l�O�#:��N�=�Z'2�4C�n[�qI�F1� -M1��� �}Bv����&2�����5*��}+h��{���u6-��xy�O���CU��}V���'x2:��)�U��C϶��&g셚*h��چSY����m�[Χ*���R�.VuiU��Im.I�2�˾�oR|I^F>uB�i���Z��Vz��j���ِ��
8]��ɷ�,/�M�>E�^B.N-9�W�����������U���0��1�]�8L�V?7�[NK[Y�*�V�*�q�lb���^R�ڑ�օb��+�i��]o�@X�f��+Yea��3)/�e�Y��_���J؞W2c�cL��l!���W�?@�B���n��4�+��{������͕���.�[�N�RשK0�l����7a��슋t~�LU��%l�M�X�{�kV�B0:�D$��0�8+
J��m�:�p�h6�X�+�����EW �.�"���ҟ����0AWsoH�Ѐ�ʲ���"�&������jFc��5�2���`ǩ�w8�ڞ�.�HZ֦�ӎ��f������j%�Ƶ=�h���}��� �}�����:��6��Ưd�����o_W�������;s���S�&�6L��`E�zud�B"��^5XTپ6�V}D�@�K��@X�����#�l��_�4�*�w�~�Y�4�y�W7��uM�-p<C���+!�
'cBp]� ��mnx�>�b O���O����Z7v���Y�%M� k�C �'�� ���֦���<'����+��|��~���|����� 1 !1A "0Q#2a�@q���BP���� ?�f�+�} A��M�|{��s.ŚT�Kom}��2��:w9�ϳ"q�k �$�Uǵ�W�0+w�x�m�e �clGBG�(�������x���Nc����-�
G1��0[���u�f��I�}����u"���7���K(W�0ܝ:�ZTx���~h��A����1X�=L�Kz"8�ZΞ1�؝lD���ɩQ���V���{�J�z`��v�A��� �N�X2v�ֳ���#���h;y�Y�r�:�WI�T�V4#����eV2c;�H��Ω��2�U��jb ?�
a��9�3��M,K���(�ت\��0�w��&Z,#8�)4�{
�@"P�Y` ;ĩ��DӤ��D�YӨK��9F0�?���L��V�)V?U=��"�D63�mU�A�^�e>L9� �ت6nH��E�LSڷ(�y�Ű�Z��uJ�[k�j�����S��KlK,��'Cz��%�-��G�bNf����P��.���s���R��e�A��X�ܴ���h�wx�7ϰ���G�eϬꕚҲ�j8���a5�CH�-�I%�k<�!��E������x��-����jwX����`Ncs���-f�.6�^̴�:���ܨ�{����5�0�,[�jӿ��K鷥l8܉H���~��n��=�@�b1�����><AE@cL�B'mv�=jMg2��Q�G��S���5�|t9Ա�Nٴ��rf%u��Q�މo�3�?XX�����3/���&��D`L7������7nz��@��������ƢVg�Aȃ�����,b9�2˭�,w?�� y��N��U���!���1����0���Z��l��Xo��ja���$����� �� : !1AQq"a��� ����#02��BR34@`�� ?�P)b�L���u��z���D���RT�0v��J���~�.'=�GBK!
.*2��Sש����3��K�Q *z$
.$5�q�g�N�[L����\����LSΰ�äA���ݮ"�G-�����˽��֫���������U��q���L�p�W�|$ �xRF �УJYm �g�4��.�������JHA�S�x�A˅Y��}��v�ƙ�мƂҡ?�IRT SS$G?q���miz��U�/_r����ۏ8�>�>?*���~�FN�?�ᾑ�Yة��������*b�_�Ď4��5z�:U�jxN�i���}C��Lݶ�A�E��+M� n4��m�ʹ��ws�) ����AJ8x�.����;�/���� @�g��Z0-
X�u5=0�,q�c�'���(9�?��xZ['9ʙ�v�a(B�<�0�qVҳ� P!�vBw���c���f�e;��Kn�~����Fł�r�H��4�R ���r�h���_lqz���N����{[����=�31��[h�p��+��;���>�m@+�ƶ�
u����N�S�!�!"g�:Pv�����0#�(�ݠ%NnO�]�i�ټR�>'�l��u�p�>��I�:V��J�겻z�j�H�?��*i릐1f9y�[J�����Dw�>����X�8V%߈�x�x�.��=��M�m�c�3r#Δ�S���d'�5stը�Dм���(E*�gVc�V�&픸������~_z��� �L��-d0�3�_��J֒���=�u{t��o/v�g^� *��Ie�Jh|G�<�W�����lT�B̂���u����P�̍�ő��:H麹R:� L ��~�5ָ[S����w֒��&N�s��RZR�ů��|V�m������A�ii`��?�5|ʓ�wwh��xz��M�\�����w�ynYe]��yVݳU�P�Ot��a�M�:��>�[���;�]��
Y�b)j)Cu4�Z�Q�m�g�Xm�v��� �°�K N��
��Y�1��}+aՂ���w�#/���{-�%&wn�סIa��h��D8��<�@O��ZE�JB`��y�LJ9��Z�a!�՜�)��;��+g[/f�ԥ[����2�Ӗ7ח�
�<8DI��)2Ā{�z��!�ʕ�F���[6�����(:p?�mm�o:��_=� �Qa������՝��p���)�43ƌ�� �����M�� ǵ�ݝˁ� �9x���t�Q)Lۡ� JaK����X�Rq�I�4��r��i���-6��I8�Q���O*}��Ж�j�e�*��. %�uD������ҭ�V�aAՙ�9
y��O>��n
�Jx*���V��k��0�IN�*�r� 3��ww�[��Sp�B2?���υ:�o$bN���:� �ؤ�'"�F��#J�ucf�����0��'ˡ:{��VfE
:@! +^������J��S�wZA���L��W��� ��e��w[�'�/����6��8�B��rs??����;A)RT +|�s��vX��OXeD|���kg����p"wxkVi}�����y��X�IJ ���|iǺ���Bf��JM�R��6ۣA>1�tl�ʯ����ԏ�9S�ۈH֯:��i
�vc02�{���v�+�}� ��R�ȏ\7�g9��I:#�)ZJT$_����"E[�3h������@��4��iJ�eK�kں���}*�@��ׯ]�?�EH/-kC���$�&��� 1IN�#�� 1 !1AQ"a 2BqR�����#�b��� ?�vVW"`����9Uʽ���*
�X�V,�j
��N�-����tB�YB�;5=F^ʑ�U)
@��D�?�'u���ח�XDz���\������{�%��a~U.��;�a�[V���vU��P���Ӯ}Sb:�hV��fgiFe��u�@蹌h:��������z~��Uw~+�v#ɑB+j�j�g�Gc��#u`0����M��o�ʫe�u���*
f�Xa��:� ���g�c;�g�N�(�Ξ�w����� ��%�~�F���S��挗�E���T�J��@$Z�S���"�S��y~D�0�*��)n���7���i^���;�Y�`I^�"��ݷL%�|GU���s��U�u=�����$�Bp�g7;�5�Ӿam�(km��/8�i@>�G�T�=`�.�-h��L�ڌ��0q����=��k�}>���kt�������ⶶRB�)^d+:�MP0��G�~xX��M`�c]%ڕ��ËJ��U,,�l2�����6�b�1=������m�˙�:u��ThEcc��If�#��E�TK�n.g�8�J��Vtl�4C�o�n��dr���/�.$7G�� �&a:�d ��/� X�����b����9�@��{갺���B2�B
9����a�Yl�����u -Ká��('I@������kX�d�vr� ���(�Q.��cD�4b.�!C�gUl�L��,P�*��CԆ6�$4� ��FME�kX��`&�4��\�;�}D&��N��u��/��� &>�8��tw g1(�������l~,Ӫ]�p=�@�yx�i�)��ƺ�?���*��i�Er�8cq1��ā �'�b��6����ê�f���l�j�*u0b�$�t��lJ{A���i;�<.dk(��E�����bj7"U�ܽ�ڒ��R �wVӪ����5�D�n��T�%���ܱ���,��%�vWLԮ�/!Zм��L[-��ǩR\eb#N��WNr��8�׃�Y��oú�$Zg(M�"�'K9��� ٧M�2L|I�0�b\'��9��A�duDa��+�9��7�h�fc>Se'=�H�P�6)���~e6�s{�܈��bA�M�ɋh���>}�9-�Se����Ê�
Vs��E�1o*Ұᅅ�mPh��~P��q���x�閪âg������T,���3l�0�[���TG��C�=c�ȑ�VeZ8h�1�T'=�G�- �E���Yd�d��+/����p�C��<HQ�$`[D�� Kox%��,�G���<�g�jrw�����q�� ' !1AQaq����� ������ ?!��Yc��mc�p&�� ��߯��p��T��Hl��J+kqP���8��h� u9�)�S*�?������a�ms��65�8�i�Y.Y�]�1X_�Xd�J��*��Q �Qr�Y9Jf��L�n����ۧK)��HЁ���F�<K��N��5+%�1]-yD�vY hm�%7���P��0VoqR�����!��~����pb㭥_n�ś0���\INN������Fi�%����A�"��#e�l��6.b ��O�TR�n��&r¼��Q��/��n�Al_��<V��e4�h���U���Ţ+
*�o�(T���5cԭ+��j�r�*Pu���p��֬�\���Bä�"�G�y�Ԭ�u&I�i����B&ٜ��7K� "�U��6���U�3y�W��ۮV���5X������|Ũ��@q}��N�[��DbPУ�aQQ`#�4Y�z>�p`JW��dw�%^w}����<��g"�3��ϥ���,�,*X3y5egp4�M�KV2���n(�/�l��bGٰ&:��u�%�W�Lf�c�r�"���eˈ�q�,+z������ O����l���S�,.ZL}��ݤ�r�X����� 0A�8f3��2nj3���+��ܨY��ض�Iv������R���u4�Z^�)�y�>��U�˹��`�fF�e��� I ZE؋�?2ն�RՑ���о��\���;�;�
)�XN��Km�y�;�D D{�LT�+���~�7�CDF��I����(���0�����qwp�-$�hEk`��[Y1�
�>"�[�;
�~aH�!�.hF��g:��ylY/���-��Qp�\Ru��˂��*�X����m��i,��,bP��
k��� G#˹�t�)a��� y�������wqn�� ���Y[���� ���J ~��/�!
��c$Yx�F��:�[��߉l��g�:ca�����f�l>�!*�xuxj`2��+W�
���̣yJ=ŋ�W�UE�H�h���q�g�W�7�� 73�mz����9�ci3[�<hF����
#(��Ȗ�a��`H�o]Fq���5R�@,�P�R�'$GM�K� �����]_�T`Кp���P 6L�2�Cj��i��r�k��s�VU��&� ��@|�ӆKk��Df�6ϣ-��ukq�(-]!W5��|� e���w� ڿU�n����9́�u;��{AJ����0���E+5L�bc���ɛ��
X���"���[���E^0�7Ar5u���S.���_=G��ʄ�~���J ��E���,��a���(����)�^~e w��S�ܮN`5Od��d�ph��]x��$��Q}D��&g�.0b��
~�f�&����*��X����w�;4��`�#)[c
�n�j��P+��)*ێ����V˩t�{�)<��9�1��P�P ̸���3���bv�d��y�^':���ɤj#��1&�4Ҟbz�'�Բ���`�;<�$�D�N-���y�<̹ˍ[~}s2��U�oL��jᎾ?sY����T)�Ϥ�
�7-��1���C��"ᯕL �:ae��)J(:�_�3Kci�"S��QگO3n���zU��7)b�PPާ���������()"(�{�4;��C]�2X�؞N�A�c���w%��X�g��RT ��3��[lh��_ �������*&\�[�d�.��/��Q\���"�D�B� 5�T�P�sLt]��J�f+�y��������`脗?yT�ۈ�{9e{�߈�A�UWQ]d�,�zݓz�ҝO��/��НO�?���
��� �>��}��k�}+��� ��L'F �$m��9>�CI2�|�f�3���仄P���=���!�2�n���{B��6�r�wC�w��A��M�?v�y$�@'=�� �Y9�QԊq �A�$W5��I ��I��$�K +�`�JI�@ @bH�A$ $�A �� * !1AQaq����� ��0��@P�� ?�ZJ+��z-O�+9�Y�_�iXZ���?�H�XT��S�,�N�4Ż6^�@>�3K�E%g[R9~1O��Ε����‖(Q��$��Z��t��w��tK|�\�l��s�t��% ��-�I��9&z�1���j��x��R[��6�G�N��}Ni�K�P�1�>��攆�c�^"�ڳ��z54��"v�;�1�
��?�PEr���AŮ�iI�0q�F$�b�m-i0T�n��鬺��^�=^����T�
6���Z<K������/B�X�.6�2~D���V���{ހ�?_U��Z�f��X����Px)��M�ҦS!������4�#qh�?Q��3�R�
�̼��(�}��z�ff/ӧ��L�Q�F�g⬫ho`�Zؼ�?w�����iE�62$.4���0N�m�4wwW�=��:�\A��_-BA5y�z
��M��Sꆎy(TҘt��N&��P�_�R T����O��P�.������CbF8چ <�f3Q �c��[�s��Qf�a�����|'u��3��[D�]�qf�w� (s��)f��Z�0߰��ڧ,͢f
"�m�~�-���i�Y�>�əGK���2s����5h�B,1�n�S�,,^�������U
�϶~w�Z��6���JD!����
E����T�/qۄ�)� �}����Z �q���F&,������b4�9�
�I�.��ΔR!b'�z��S�1��Z���C�O���}&����S���h���Bu39�R��&K1�@lsnq�9�,��m��r�>qS��n�Sr׆�k�O�f�$Q�P�'܊u�Xގ`α;J̴,ޛ��`�]g���Fj�N��� �oi��Ԥ\L��R6��a�Ck=�ó=�
p�>�X3�oH�f�m+~��.(]�ۭ�;�(lg��*jj��gJY�8ޡ��H5zmӥ"|o��\R�����D$6����O�$�gA�{*9�0��[�9��+Ϝ||����v��Ƹ�ԠP�q�vX]�1'$��%d����Ok���IѺ�1�e�J�7��8���ˁ#����}�`�rq{��f�Q4_�c���Ӛl[�;��H�!��pi`���Y�,�� �0����M�^�mi�V3���in
JЌ菻o���4>�ޙb$�g� Rv����|�҉�&�tAk+9�HK��8�m6��1A='OL���HJ�0���5�FI�ۇ1�ʚ�a(k-��c:M�
��j�f���2':JF���l���M�0�l'_�/�nhC�(?�,�r�J��o�٧Z���x��ػ�)��?6�VVQxH��4b U��N����?�7�� ��� ( !1 AQaq�� ���0���@�� ?�s�����E�� �~�����rp����<t$ WJ`#\7
J¨���5���n�#�<���2T
���xJ?Q~��_<`�E��ymE��G��U�d�7:fS_o�_W�ٗ�Jssw;����� `S6�5�\*�(����k@ɥ4���d�ˆ}�z���;ul�X��"�g�^yv(eq�1�<Q����9h�I��������~���._�\�`�I���y>I��(#��ˎ�:���ɞT4) 8e�1�'U�<��U�TIs��W��p�L��=��y
A2:P�u���5t�I�!��"0_���&V�/D1�Q�8��85�da�:�7�l��0D&{���-���ӯg���4�!�0&3�T�f2e�)4b��0ۃ�d�7��m��΅>F�^��IG-������ʚ��El����8�����!\G���� ����K�æqm�*K���)1�
_��m�j&�JA�g�p��#�eH�,;�͕<��535W2�,3���19uem�Z��e
��&a�N7T�ͮ��Wk�7" �=�TIY�����҃ H #���zc�[��\�����J���
�q;��PLP�*o}.b#�,�ld�╬s0�R`g�8
\�M!��N��)Y�ȉ}d:uƹ����\�
���\�'C����������E������0K��FGF�'
��IʃE���z�p{�E�+��!%EY�CN�P��Zt�0���DRa����5J�@F6�y 4F��o� )���l��� h�4x��ⅺy��*C`c���j������3�|QH$Suc�ssx���u�ؙ�;
i�?�t��vʫ� )&/^N8�x��1�`����"������T�b�T ��%�I-KDo$d�Q
�g1!a�T��
atc?j��>*���a�v� O����
���w,5����ìc�t2�lx!�+T�}�`hN�3D_���e^fD�7I�`L3=��� �a��<�Vc0F�0�ÑM�
.�� ��d�0�L�P&���3���n&W�2=��*)Q�Ww�ہ�ls18RYX����|����'����7f� ���������G�w�C8�k$� ��L� {���1�SC�0���C@�-���bH�)LV�v��D���Ӻ����,��nr5���hv+�K�3�nq�^XP� �
��B�9��;x��L��
�?`���8�D8T3�@3 ��F���.$xD�J�1aը'�����9X��8 ��1�k��Fp֦��ⷀ��$L
�q��d��n�u㙂���9��6���ζ���qHN+ƛ��x�N�Z�<&\4�А�Qk�)-
{� (d���Q�m"0h1H��̜���(�J��G��M^��;�䐥�%����Lmo��x� �TkՄ�7B�Pp:���8+bEz��c����ASga���
Dc v2�����
"Վ
��"L
�6��nc�#M�Eh�ٕ��mc���� � ��T�2G�V�2���)7v��90{�o/@�4D�ј#)�WDTG�����
i���_�� <~�u�̉�Aټs�Y�r^!��nO��=�N}X{_G��Bؑ����|E#K��v�ͤ̚
������4*dD�(�Q��W�%��[a�%2�U(�ӧ%V�SO �p1��D�b����e�m�2�̿az��핫�x�\*���5NQ���� ǂ,�������e�����k�1�0ƨ}h��}? ��0�7��]��{��S���I���� �Lҽ���pɂ�l`�!��e�� 2o"����Z�L
E�`ӝ�/'C�^�K�R��x?,�Ҟ�Xv[���M*Yo�S����\3�� ���7���`#�=��#��������_+��u�:��������o���f��ܝ�y���1n���\1���q�����?�o��f>zM8bS������N!��Å���G��|��O@u��� �n'�NY�_3��� ������ Q�?�� & !1AQaq����������� ?�� >0�-��1�i� ��k9M��km� ��[�5Vt��/?��69/�#v|��� ����� ��a��:O�Z�Ke2���\q��< cR���$[�(���Y7�#�o9aX������� 8B
C��xT�/D��:p
k� ���>���= i�a��
��/��~��G��x��f#�'�� r��VF��E:�R�A�(n><��������xS`�����.]�}\��J}��&i���W�1ڱ���T9��ȩ57�0��`S@!
Z�G�Ӯ�̄�K.>� �ܦ�{ް[G��{���]i��wd"���$;I�˜��pu��[!&��1���M�Qh�/�ߟ���
��'F���X�@���<�:��8�{>w�Tڃ� �J@n2�sEI��O��N!�͝����l���+��G�|`�C�}~�"����4�!�+�@ /�g
�WQۤ�7o�y�u�+"to�:���<�ۄA�J����~v�h�eDJbL.�X)��+�K�Bs����m�*{����2��d@�6����U��+EJ �J B�F��i�ez
9��ěJB�C'^NI��3[⏇ό���䣊i���P-��D]��䂵�,>pD���:����*�`��g3��~�����\{�!\r�͎Rw�x�G(�/>�C$��h�y�F"��~��!�lRK@�Gct����V���t�:����A�Z �pٳϋ��.t�l��8J5r�����X�6`��Ż��4�,��O��E�t�����=�\Q�M�D"ߜҾ�h�����Dx�iJ�-R��#8�jP}�i�J�7K�ЪmV�"o��N�ZvD�C�T��W�Lh.�v�x��UdxQ$5� B����5�
���/���p鉶F�����*4~�L���\q�;#��U�!�ӬG�e�Gn���3������ߜ[g�ը N %�ө��5X���KJ���L4A���hf�Gm� � �<m�9�� �`����jBō/��ĉ�9u���ȡ8�
����q��PZB�<