xxxxxxxxxx
<html lang="cs">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Michal Škop, KohoVolit.eu">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="d3.tip.js"></script>
<script src="regression.js"></script>
<style type="text/css">
text {
font-family: sans-serif;
}
.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: 15px;
}
.axis {
}
circle {
fill-opacity: .8;
stroke-opacity: 0.99;
stroke-width: 1;
/*fill: #456;*/
/*stroke: #456;*/
}
circle:hover {
stroke-opacity: 1;
fill-opacity: 1;
}
path {
fill-opacity: 0;
stroke: black;
stroke-width: 1;
fill: none;
}
.label {
font-family: sans-serif;
font-size: 15px;
}
/* this is because of Bootstrap - very important! */
svg:not(:root) {
overflow: visible;
}
/* D3 tips */
.d3-tip {
line-height: 1;
/*font-weight: bold;*/
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
.d3-tip small {
font-size: 0.5em;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.stronger {
color: yellow;
font-weight: bold;
}
.top {
width: 100vw;
padding: 10px;
color: white;
/*font-size: 3em;*/
/*background-color: #fed201;*/
}
#center-line {
stroke:rgb(255,0,0);
stroke-width: 1;
}
.info {
padding: 10px;
width: 100vw;
}
</style>
</head>
<body>
<h1 class="text-center top bg-primary">
OKRESY ČR eurovolby 2019<br />
<small><span id="subtitle"></span></small>
</h1>
<div class="row">
<div id="chart" class="col-md-9"></div>
<div class="col-md-3">
<div class="alert alert-info">
<i class="fa fa-info-circle"></i> Color legend:<br />
<img src="okresy.png" width="200" />
</div>
</div>
</div>
<div class="alert alert-info info">
<i class="fa fa-info-circle"></i> <br />
Comparison between 2 parties or 2 groups of parties<br />
Parameters:<br />
<ul>
<li>
<strong>x</strong> party on x axis (e.g., <i>x=Nevoliči</i> or <i>x=ODS,Piráti,STAN+TOP</i>)
</li>
<li>
<strong>y</strong> party on y axis (e.g., <i>y=ANO</i> or <i>y=ANO,EU TROLL,KSČM,ČSSD</i>)
</li>
<li>
<strong>level</strong> is level of detail: <i>1</i> regions, <i>2</i> sub-regions, <i>3</i> municipalities, <i>2_nonvoters</i> sub-regions including non voters (e.g., <i>level=3</i> or <i>level=2_nonvoters</i>)
</li>
</ul>
Examples:<br />
<ul>
<li>
<a href="https://bl.ocks.org/michalskop/raw/291b1e431ae74d1612b7ef218c1f3dfe/?x=Nevoliči&y=ODS,Piráti,STAN+TOP,KDU-ČSL,Hlas&level=2_nonvoters">Non voters vs. ODS+Piráti+STAN+TOP+KDU-ČSL+Hlas on sub-regional level including non voters</a>
</li>
<li>
<a href="https://bl.ocks.org/michalskop/raw/291b1e431ae74d1612b7ef218c1f3dfe/?x=Piráti&y=SPD&level=2">KDU-ČSL vs. SPD on sub-regional level (excluding non voters)</a>
</li>
</ul>
</div>
<script>
if (getUrlParameter('level')) {
var level = getUrlParameter('level');
} else
var level = "2";
var csv = "regions_" + level + ".csv"
if (getUrlParameter('x')) {
var xs = getUrlParameter('x');
xs = xs.split(',');
} else
var xs = ['ANO'];
if (getUrlParameter('y')) {
var ys = getUrlParameter('y');
ys = ys.split(',');
} else
var ys = ['ODS', 'Piráti', 'KDU-ČSL', 'STAN+TOP'];
if (getUrlParameter('maxrange'))
var maxrange = parseFloat(getUrlParameter('maxrange'));
else
var maxrange = 35
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 700 - margin.left - margin.right,
height = 550 - margin.top - margin.bottom;
d3.csv(csv, function(data) {
data.sort(function(a, b) {
return parseFloat(b.population) - parseFloat(a.population);
});
// find ranges for axes:
var maxpopulation = 0;
var maxy = 0
var maxx = 0
for (var k in data){
data[k]['xn'] = sumInRegion(data[k],xs)
data[k]['yn'] = sumInRegion(data[k],ys)
if (parseInt(data[k]['population']) > maxpopulation)
maxpopulation = parseInt(data[k]['population']);
data[k]['id'] = k;
if (data[k]['xn']/data[k]['population'] > maxx)
maxx = data[k]['xn']/data[k]['population'];
if (data[k]['yn']/data[k]['population'] > maxy)
maxy = data[k]['yn']/data[k]['population'];
}
if (getUrlParameter('maxdomain'))
if (isNumeric(getUrlParameter('maxdomain')))
var maxdomain = getUrlParameter('maxdomain');
else
var maxdomain = maxpopulation;
else
var maxdomain = maxpopulation;
var x = d3.scale.linear()
.range([0, width])
.domain([0,1.1*maxx]);
var y = d3.scale.linear()
.range([height, 0])
.domain([0,1.1*maxy]);
var r = d3.scale.sqrt()
.domain([0, maxdomain])
.range([1, maxrange]);
var formatAsPercentage = d3.format("%");
titlex = createTitle(xs)
titley = createTitle(ys)
$("#subtitle").html(titlex + " vs. " + titley);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(formatAsPercentage);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(formatAsPercentage);
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
/* Initialize tooltip */
var tip = changetooltip();
/* Invoke the tip in the context of your visualization */
svg.call(tip);
// Add tooltip div
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(titley);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", x(maxx))
.attr("dy", "-1em")
.style("text-anchor", "end")
.text(titlex);
svg.append("line")
.attr("x1", x(0))
.attr("y1", y(0))
.attr("x2", function() { return x(Math.min(maxx, maxy))})
.attr("y2", function() { return y(Math.min(maxx, maxy))})
.attr("id", "center-line")
.style("stroke-dasharray", ("3, 5"));
nodes = data
.map(function(d) {
return {
x: x(d.xn/d.population),
y: y(d.yn/d.population),
xn: d.xn,
yn: d.yn,
r: r(d.population),
name: d.name,
id: d.id,
color: group2color(d.group),
xp: Math.round((d.xn / d.population) * 1000) / 10,
yp: Math.round((d.yn / d.population) * 1000) / 10
}
});
dats = [];
for (i in nodes) {
dats.push([nodes[i].x,nodes[i].y]);
}
dats.sort(function(a, b) {
return parseFloat(a[0]) - parseFloat(b[0]);
});
var myRegression = regression('polynomial', dats, 3);
var bubbles = svg.selectAll("svg")
.data(nodes)
.enter().append("svg:svg").append("svg:circle")
.attr("cx", function (d) {
return d.x
})
.attr("cy", function (d) {return d.y})
.attr("r", function (d) {return d.r})
//.attr("stroke-width", function(d) {return d.r2})
.attr("title", function(d) {return d.name;})
.attr("fill",function(d) { return d.color })
.attr("stroke",function(d) { return d.color })
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
var line = d3.svg.line()
.interpolate("basis-open")
.tension(0.1) // <=== THERE IT IS!
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; });
svg.append("path")
.attr("d",line(myRegression['points']));
});
//tooltip
function changetooltip() {
tip = d3.tip().attr('class', 'd3-tip').html(function(d) {
html = '<span class="stronger">' + d.name + "</span><br>" + titlex + ": " + d.xp + "% " + d.xn + "<br>" + titley + ": " + d.yp + "% " + d.yn;
return html;
});
return tip;
}
function createTitle(arr) {
ar = []
for (k in arr) {
ar.push(arr[k])
}
return ar.join(" + ");
}
function sumInRegion(items,arr) {
var s = 0
for (var k in items) {
if ($.inArray(k,arr) >= 0) {
s = s + parseInt(items[k])
}
}
return s
}
//helper function for default values
function getUrlParameter(sParam) {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];
}
}
}
// helper function for coloring by region
// function region2color(r){
// if (r == 'Hlavní město Praha') return '#b276b2';
// if (r == 'Středočeský kraj') return '#f17cb0';
// if ((r == 'Plzeňský kraj') || (r == 'Jihočeský kraj')) return '#5DA5DA' //'#aec7e8';
// if ((r == 'Ústecký kraj') || (r == 'Karlovarský kraj')) return '#FAA43A';
// if ((r == 'Královéhradecký kraj') || (r == 'Pardubický kraj') || (r == 'Liberecký kraj')) return '#60bd68';
// if ((r == 'Zlínský kraj') || (r == 'Olomoucký kraj')) return '#decf3f';
// if ((r == 'Jihomoravský kraj') || (r == 'Kraj Vysočina')) return '#b2912f';
// if (r == 'Moravskoslezský kraj') return '#f15854';
// return '#4d4d4d';
// }
// helper function for coloring by region
function region2color(r){
if (r == '1100') return '#b276b2';
if (r == '2100') return '#f17cb0';
if ((r == '3100') || (r == '3200')) return '#5DA5DA' //'#aec7e8';
if ((r == '4100') || (r == '4200')) return '#FAA43A';
if ((r == '5100') || (r == '5200') || (r == '5300')) return '#60bd68';
if ((r == '6100') || (r == '6200')) return '#b2912f';
if ((r == '7100') || (r == '7200')) return '#decf3f';
if (r == '8100') return '#f15854';
return '#4d4d4d';
}
function group2color(g){
if (g == "Praha") {
return "#C6A373"
}
if (g == "Bible Belt") {
return "#53AFB5"
}
if (g == "Neviditelní") {
return "#B9504C"
}
if (g == "Jádro") {
return "#118AB2"
}
}
// helper function
function toObjectWithId(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[arr[i]['id']] = arr[i];
return rv;
}
</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>
</html>
https://d3js.org/d3.v3.min.js
https://code.jquery.com/jquery-1.11.1.min.js