Position of districts, towns, regions in a political space based on the elections results. Mathod: Weighted MDS, rotated by PCA
https://bl.ocks.org/michalskop/91a24fcaba5e2caa42d8a596f8abf4a2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Explodable</title>
<!--<link rel="stylesheet" href="bootstrap.min.css">-->
<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.v3.min.js"></script>-->
<script src="d3.tip.js"></script>
<!--<script src="jquery-1.11.1.min.js"></script>-->
<style>
.circle {
fill: #888;
stroke-opacity: 0.01;
stroke: #888;
stroke-width: 0;
fill-opacity: 0.2;
visibility: hidden;
}
.party {
visibility: hidden;
fill-opacity: 0.01;
stroke-opacity: 1;
/*stroke: #f00;*/
}
.text {
visibility: hidden;
fill-opacity: 0.99;
/*fill: #444;*/
}
.text.active {
fill-opacity: 0.85;
}
.big {
stroke-width: 2px;
}
.small {
}
.stronger {
color: yellow;
}
.visible {
visibility: visible;
}
.active {
fill-opacity: 0.75;
stroke-opacity: 1;
}
.ellipse {
fill-opacity: 0;
stroke: #f00;
stroke-opacity: 0.75;
}
/* D3 tips */
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
/*.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}*/
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.top {
width: 100vw;
padding: 10px;
color: white;
/*font-size: 3em;*/
/*background-color: #fed201;*/
}
</style>
</head>
<body>
<h1 class="text-center top bg-primary">
<strong>POLITICAL MAP OF CZECHIA: ELECTIONS 2017</strong><br/>
<small>POLITICKÁ MAPA ČR: VOLBY 2017</small><br />
</h1>
<!-- chart -->
<div class="row">
<div class="col-1" style="">
<img src="nuts2.png" width="150" />
</div>
<p class="col-9" id="chart"></p>
<div class="col-2">
<img src="windrose.png" width="150" />
</div>
</div>
<div class="alert alert-info" >Reset: <button id="reset-0" value="0" class="reset btn btn-primary">Czech Republic</button> <button id="reset-1" value="1" class="reset btn btn-primary">Regions (kraje)</button> <button id="reset-2" value="2" class="reset btn btn-primary">Sub-Regions (okresy)</button> <button id="reset-3" value="3" class="reset btn btn-primary">Towns (obce)</button> <button id="reset-5" value="5" class="reset btn btn-primary">Districts (okrsky)</button> | <button class="party-toggle doshow btn btn-success">Toggle parties</button>
</div>
<div class="alert alert-info container">
<i class="fa fa-info-circle"></i> Explorable: General Elections in Czechia 2017, MDS based on results from districts (weighted)<br />
90% of people live inside the ellipse (on district level)
</div>
<script type="text/javascript">
// Chart dimensions.
var margin = {top: 10, right: 0, bottom: 0, left: 30},
width = 960 - margin.right,
height = 500 - margin.top - margin.bottom;
//Various scales. These domains make assumptions of data, naturally.
var xmax = 450,
ymax = 15;
var
xScale = d3.scale.linear()
.domain([-xmax, xmax])
.range([0, width]),
yScale = d3.scale.linear()
.domain([-ymax, ymax])
.range([height, 0]),
radiusScale = d3.scale.sqrt()
.domain([0, 1000000])
.range([0, 50]);
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';
}
/* Initialize tooltip */
tip = d3.tip().attr('class', 'd3-tip').html(function(d) {
return '<span class="stronger">' + d['name'] + "</span><br>";
});
// Create the SVG container and set the origin.
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 + ")");
/* 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);
// Load the data.
d3.csv("cz_2017_show.csv", function(data) {
data.sort(function(a, b) {
return parseFloat(b.size) - parseFloat(a.size);
});
// var circle = svg.selectAll(".circle")
// .data(data)
// .enter().append("circle")
// .attr("r",function(d) {
// return Math.max(1,radiusScale(d['size']));
// })
// .attr("cx", function(d) {return xScale(d['dim1']);})
// .attr("cy", function(d) {return yScale(d['dim2']);})
// .attr("class", function(d) {
// clas = "circle ";
// if (d['size'] > 1500) clas += "big";
// else clas += "small";
// if (d['level'] == 3) clas += " active explorable visible";
// else clas += " explorable";
// clas += " level-" + d['level']
// return clas;
// })
// .attr("style", function(d) {
// return "stroke:" + region2color(d['region']) + ";fill:" + region2color(d['region']);
// })
// .attr("id", function(d) {return "id-" + d.id;})
// .on("mouseover", tip.show)
// .on("mouseout", tip.hide)
// .on("click", clicked)
//texts:
svg.selectAll(".text")
.data(data)
.enter().append("text")
.attr("x", function(d) {return xScale(d['dim1']);})
.attr("y", function(d) {return yScale(d['dim2']) + Math.max(Math.min(70, Math.sqrt(parseInt(d['size'])) / 10), 2) / 3;})
.attr("font-size", function(d) {
if (d['size'] > 10) {
var si = 0;
si = Math.max(Math.min(70, Math.sqrt(parseInt(d['size'])) / 10), 2);
return si + "px"
} else {
return 0
}
})
.attr("font-weight", function(d) {
if (d['size'] > 50000) {
return "bold";
}
return "default";
})
.attr("class", function(d) {
clas = "text ";
if (d['level'] == 3) clas += " visible";
else clas += "";
clas += " level-" + d['level']
return clas;
})
.attr("fill", function(d) {
return region2color(d['region'])
})
.attr("id", function(d) {return "text-id-" + d.id;})
.attr("text-anchor", "middle")
.text(function(d) {return d['name']});
function clicked(item) {
if (this.classList.contains("explored")) {
deexplore(item);
} else {
if(this.classList.contains("explorable")) {
explore(item);
}
}
}
function deexplore(item) {
svg.selectAll(".circle").filter(
function(d,i) {
return d.parent_id == item.id;
}
)
.transition()
.duration(200)
.attr("cx", function(d) {
return xScale(item.dim1);
})
.attr("cy", function(d) {
return yScale(item['dim2']);
})
.each("end", atEnd);
svg.selectAll(".text").filter(
function(d, i) {
return d.parent_id == item.id;
}
)
}
function atEnd(it) {
svg.selectAll(".circle").filter(
function(d,i) {
return d.id == it.id
}
)
.classed("visible",false);
svg.selectAll(".text").filter(
function(d, i) {
return d.parent_id == item.id;
}
)
.classed("visible",false);
svg.selectAll(".circle").filter(
function(d,i) {
return d.id == it.parent_id;
}
).classed("active",true)
.classed("explorable",true)
.classed("explored",false)
svg.selectAll(".text").filter(
function(d,i) {
return d.id == it.parent_id;
}
).classed("active",true)
.classed("explorable",true)
.classed("explored",false)
}
function explore(item) {
svg.selectAll(".circle")
.classed("active",false);
svg.selectAll(".text")
.classed("active",false);
svg.selectAll(".circle").filter(
function(d,i) {
return d.parent_id == item.id;
}
)
.classed("visible",true)
.classed("active",true)
.attr("cx", function(d) {
return xScale(item.dim1);
})
.attr("cy", function(d) {
return yScale(item.dim2);
})
.transition()
.duration(200)
.attr("cx", function(d) {
return xScale(d.dim1);
})
.attr("cy", function(d) {
return yScale(d['dim2']);
});
svg.selectAll(".text").filter(
function(d,i) {
return d.parent_id == item.id;
}
)
.classed("visible",true)
.classed("active",true)
svg.select("#id-"+item.id)
.classed("explorable",false)
.classed("active",false)
.classed("explored",true)
// texts:
svg.select("#text-id-"+item.id)
.classed("explorable",false)
.classed("active",false)
.classed("explored",true)
}
});
d3.csv("cz_2017_party.csv", function(data) {
var circle = svg.selectAll(".party")
.data(data)
.enter().append("circle")
.attr("r",function(d) {
return Math.max(1,radiusScale(d['size']));
})
.attr("cx", function(d) {return xScale(d['dim1']);})
.attr("cy", function(d) {return yScale(d['dim2']);})
.attr("class", function(d) {
clas = "party ";
if (d['size'] > 50000) clas += "big";
else clas += "small";
return clas;
})
.attr("stroke", function(d) {return d['color']})
.on("mouseover", tip.show)
.on("mouseout", tip.hide)
// partylines:
// var line = svg.selectAll(".partyline")
// .data(data)
// .enter().append("line")
// .attr("x1", function() {return xScale(-7)})
// .attr("y1", function() {return yScale(0.75)})
// .attr("x2", function(d) {return xScale(d['dim1'])})
// .attr("y2", function(d) {return yScale(d['dim2'])})
// .attr("stroke", function(d) {return d['color']})
// .attr("stroke-width", function(d) {
// if (parseInt(d['size']) > 50000) {
// return parseInt(d['size'] / 50000)
// } else {
// return 0
// }
// })
})
//ellipse is calculated to cover 90 % of the districts (voters)
svg.append("ellipse")
.attr("cx", function() {return xScale(0)})
.attr("cy", function() {return yScale(0)})
.attr("rx", function() {return 2.13*(xScale(114.5) - xScale(0))})
.attr("ry", function() {return 2.13*(Math.abs(yScale(3.73) - yScale(0)))})
.attr("class", "ellipse")
.style("stroke-dasharray", ("3, 5"))
$(document).ready(function(){
$('.reset').click(function() {
level = $(this).attr("value");
// svg.selectAll(".circle").filter(
// function(d,i) {
// return d.level == level;
// }
// )
// .classed("active",true)
// .classed("explorable",true)
// .classed("explored",false)
// .classed("visible",true);
// texts:
svg.selectAll(".text").filter(
function(d,i) {
return d.level == level;
}
)
.classed("active",true)
.classed("explorable",true)
.classed("explored",false)
.classed("visible",true);
// svg.selectAll(".circle").filter(
// function(d,i) {
// return !(d.level == level);
// }
// )
// .classed("active",false)
// .classed("explorable",true)
// .classed("explored",false)
// .classed("visible",false);
// texts:
svg.selectAll(".text").filter(
function(d,i) {
return !(d.level == level);
}
)
.classed("active",false)
.classed("explorable",true)
.classed("explored",false)
.classed("visible",false);
});
});
$('.party-toggle').click(function() {
if (this.classList.contains("doshow")) {
svg.selectAll(".party")
.classed("visible",true);
} else {
svg.selectAll(".party")
.classed("visible",false);
}
$('.party-toggle').toggleClass("doshow");
});
</script>
</body>
</html>
"","X.1","X","id","name","abbreviation","size","color","dim1","dim2","dim1.1","dim2.1","dim1","dim2"
"1",1,1,1,"Občanská demokratická strana","ODS",572962,"#004494",3.24875268889783,2.01996404403452,372.054936752421,7.53783740661778,372.054936752421,7.53783740661778
"2",2,2,2,"Řád národa - Vlastenecká unie","ŘN-VU",8735,"#2b468b",-0.243966375953231,-0.00112432058451153,-0.910401786629928,-0.128759885413685,-27.9396135277354,-0.00419559238392889
"3",3,3,3,"Cesta odpovědné společnosti","CESTA",3758,"#ab2324",-0.0201066062935877,-0.176075585357553,-2.3026566960394,-0.65705582117659,-2.3026566960394,-0.65705582117659
"4",4,4,4,"Česká strana sociálně demokratická","ČSSD",368347,"#F07D00",-1.22877663634042,-0.760706842900444,-4.58538780486655,-87.1179690869228,-140.722442578905,-2.83870621995443
"5",5,5,5,"Volte Pravý Blok www.cibulka.net","PB",491,"#888888",0.5132121594497,-0.169759157819547,58.7742853363858,-0.633485003709426,58.7742853363858,-0.633485003709426
"6",6,6,6,"Radostné Česko","RČ",3852,"#51ecf2",-0.141295949700741,0.0431085567792674,-0.527269729480211,4.93689514157503,-16.1815504790294,0.160866869286965
"7",7,7,7,"Starostové a nezávislí","STAN",262157,"#5d8c00",0.195817000747851,0.940947280549359,22.4254317902565,3.51130389173355,22.4254317902565,3.51130389173355
"8",8,8,8,"Komunistická strana Čech a Moravy","KSČM",393100,"#8c0000",-1.6562531288134,0.389569330645214,-6.18058862288543,44.614412531063,-189.678074047467,1.45374383355032
"9",9,9,9,"Strana zelených","Zelení",74335,"#06b15d",0.90622004538996,-0.146255766442874,103.782489453121,-0.545778124359432,103.782489453121,-0.545778124359432
"10",10,10,10,"ROZUMNÍ – stop migraci a diktátu EU","Rozumní",36528,"#6fb7c5",-0.586984775752917,0.93031385327127,-2.19043294995893,106.54177002195,-67.2229019967281,3.47162345973079
"11",11,11,11,"Společnost proti developerské výstavbě v Prokopském údolí","SPDVPÚ",438,"#676767",0.393847894277769,-0.130755309099426,45.1044038828644,-0.487935546652077,45.1044038828644,-0.487935546652077
"12",12,12,12,"Strana svobodných občanů","Svobodní",79229,"#009982",0.739755429816905,0.0683626819939048,2.76052247914528,7.82905802968249,84.7185630944912,0.255106908002748
"13",13,13,13,"Blok proti islamizaci - Obrana domova","BPI",5077,"#e30613",-0.224002543727997,0.290229637922085,-25.6533076598625,1.08304097179308,-25.6533076598625,1.08304097179308
"14",14,14,14,"Občanská demokratická aliance","ODA",8030,"#002d72",0.122220602119364,0.441238189447366,0.456086844335409,50.5316539571028,13.9969959999602,1.64655491738437
"15",15,15,15,"Česká pirátská strana","Piráti",546393,"#000000",1.63334616946663,1.18379730791063,187.054714214606,4.41753983481782,187.054714214606,4.41753983481782
"16",16,16,16,"Občané 2011","Občané 2011",359,"#CBD4FF",0.211381159386139,0.226299021611588,0.788804540843524,25.9163058057824,24.2078765043653,0.844473066351118
"17",17,17,17,"Unie hrdosti, aktivity, vlastenectví, empatie a lidskosti 2017","HAVEL",436,"#888888",0.204664542692852,1.01332821838149,23.4386734783699,3.78140560088447,23.4386734783699,3.78140560088447
"18",18,18,18,"Česká národní fronta","ČNF",117,"#F8F8F8",-0.347656665496513,-1.23165708959168,-1.29733963610831,-141.052318982202,-39.8144737624657,-4.59613670325882
"19",19,19,19,"Referendum o Evropské unii","REU",4276,"#034ea2",-0.00185438350583197,0.290127475079856,-0.212368439227399,1.08265973387155,-0.212368439227399,1.08265973387155
"20",20,20,20,"TOP 09","TOP 09",268811,"#723769",1.96311268347084,0.282413249310394,7.32568694109856,32.3426415218671,224.820364991959,1.05387279593576
"21",21,21,21,"ANO 2011","ANO",1500113,"#261060",-2.10789067921757,-1.97741446253292,-241.400687721593,-7.37905644810227,-241.400687721593,-7.37905644810227
"22",22,22,22,"Dobrá volba 2016","DV 2016",3722,"#d60a1e",-0.090608482474333,0.286093838071186,-0.338120874264546,32.764151359562,-10.3767003660896,1.06760753528491
"23",23,23,23,"Sdružení pro republiku - Republikánská strana Československa Miroslava Sládka","SPR-RSČ",9857,"#ed1f24",-0.457741258802272,-0.148898901312515,-52.4216249746085,-0.555641429080106,-52.4216249746085,-0.555641429080106
"24",24,24,24,"Křesťansko-demokratická unie - Československá strana lidová","KDU-ČSL",293643,"#e6ac21",-0.415645435591887,-1.29233532883843,-1.55105122863312,-148.001336228836,-47.6007105062331,-4.82256781370984
"25",25,25,25,"Česká strana národně sociální","ČSNS",1573,"#ffd132",-0.0845130869023947,0.323391098512723,-9.6786410703641,1.20678856959633,-9.6786410703641,1.20678856959633
"26",26,26,26,"Realisté","Realisté",35995,"#013888",0.506569303570037,0.0283215679143991,1.89034901723691,3.24345377077502,58.0135295753796,0.105686719855086
"27",27,27,27,"Sportovci pro společnost","SPS",10593,"#888888",-0.0593489593232954,0.547675844222533,-6.79678492696898,2.04374502480552,-6.79678492696898,2.04374502480552
"28",28,28,28,"Dělnická strana sociální spravedlnosti","DSSS",10402,"#183F7C",-0.592042992929067,-0.29089740403884,-2.20930854269721,-33.3142672358456,-67.802181139146,-1.08553285397713
"29",29,29,29,"Svoboda a přímá demokracie - Tomio Okamura","SPD",538574,"#0066a5",-1.92778315322257,-3.03321778902831,-220.774342594831,-11.3189650974626,-220.774342594831,-11.3189650974626
"30",30,30,30,"Strana práv občanů","SPO",18556,"#115787",-0.430107800355259,-0.368938945891762,-1.60501998833627,-42.2517714716639,-49.2569751476492,-1.37675806424084
"31",31,31,31,"Národ Sobě","NáS",300,"#e8e5ce",-0.0223207648825892,0.422855707781031,-2.55622743923755,1.57795757856531,-2.55622743923755,1.57795757856531
name,dim1,dim2,size,id,parent_id,region,level
Praha 1,374.3092247983,-1.2720709263,14036,500054,554782,Hlavní město Praha,4
Praha 2,344.5225346899,-1.1644485101,20814,500089,554782,Hlavní město Praha,4
Praha 3,276.3745192617,-0.6285866055,32571,500097,554782,Hlavní město Praha,4
Praha 4,225.6716913519,-0.184627879,63462,500119,554782,Hlavní město Praha,4
Praha 5,287.016068243,-0.87334482,38802,500143,554782,Hlavní město Praha,4
Praha 6,282.3376494601,-0.3593167165,53196,500178,554782,Hlavní město Praha,4
Praha 7,324.6684315544,-1.7769106773,20064,500186,554782,Hlavní město Praha,4
Praha 8,201.1641878236,0.444591221,51154,500208,554782,Hlavní město Praha,4
Praha 9,220.5613156321,-0.2971454423,24951,500216,554782,Hlavní město Praha,4
Praha 10,222.8121021844,-0.2939962391,51895,500224,554782,Hlavní město Praha,4
Praha-Běchovice,243.50057993,0.4016280062,1105,538060,554782,Hlavní město Praha,4
Praha-Benice,250.1850568324,0.0999040624,363,538078,554782,Hlavní město Praha,4
Praha-Březiněves,229.3761450389,1.1462093074,721,538124,554782,Hlavní město Praha,4
Praha-Dolní Počernice,268.8058713715,-0.0148660711,1339,538175,554782,Hlavní město Praha,4
Praha-Dubeč,206.7325649363,-1.1118108919,1905,538205,554782,Hlavní město Praha,4
Praha 20,168.0903667638,1.4330583836,7944,538213,554782,Hlavní město Praha,4
Praha-Klánovice,307.5410986362,1.2108853828,1877,538302,554782,Hlavní město Praha,4
Praha-Koloděje,264.4549043541,2.6326702479,784,538353,554782,Hlavní město Praha,4
Praha-Kolovraty,254.1568870224,0.9161390983,1965,538361,554782,Hlavní město Praha,4
Praha-Královice,170.5979050984,0.8309726429,194,538388,554782,Hlavní město Praha,4
Praha-Křeslice,296.4156755127,-1.7522417878,595,538400,554782,Hlavní město Praha,4
Praha-Nedvězí,205.7860096781,-1.4077826902,167,538531,554782,Hlavní město Praha,4
Praha-Satalice,228.8567803914,1.1271358798,1248,538736,554782,Hlavní město Praha,4
Praha 22,263.94644009,0.754054616,5067,538931,554782,Hlavní město Praha,4
Praha 21,242.3954256064,0.3416485263,5497,538949,554782,Hlavní město Praha,4
Praha-Vinoř,178.1333894484,-0.4035017072,2158,539007,554782,Hlavní město Praha,4
Praha-Lipence,292.4939484677,0.4363712559,1442,539449,554782,Hlavní město Praha,4
Praha-Lochkov,205.5009184389,1.0136718246,418,539465,554782,Hlavní město Praha,4
Praha-Přední Kopanina,292.7959651632,1.7953633878,311,539589,554782,Hlavní město Praha,4
Praha 16,257.2344271037,1.3284435838,4346,539601,554782,Hlavní město Praha,4
Praha-Řeporyje,269.9971942671,-0.3424573215,2069,539635,554782,Hlavní město Praha,4
Praha-Slivenec,298.2102045041,3.192801784,1844,539678,554782,Hlavní město Praha,4
Praha 13,230.0124370776,0.062728308,28221,539694,554782,Hlavní město Praha,4
Praha-Šeberov,276.7885423825,-0.0809381601,1581,539724,554782,Hlavní město Praha,4
Praha-Újezd,254.6175838761,-0.4515231147,1577,539791,554782,Hlavní město Praha,4
Praha-Zbraslav,253.1322578329,-0.3026379294,5173,539864,554782,Hlavní město Praha,4
Praha-Zličín,224.9679500258,0.2157084507,2801,539899,554782,Hlavní město Praha,4
Moravská Ostrava a Přívoz,-31.8516658341,-1.8325989177,14700,545911,554821,Moravskoslezský kraj,4
Plzeň 1,42.1460130264,-1.0438794427,23541,545970,554791,Plzeňský kraj,4
Plzeň 2-Slovany,111.3500980692,-1.586078687,16622,545988,554791,Plzeňský kraj,4
Plzeň 3,71.958052913,-1.1651577636,21810,546003,554791,Plzeňský kraj,4
Slezská Ostrava,-59.8009656331,-1.3618656391,7981,546046,554821,Moravskoslezský kraj,4
Ostrava-Jih,-102.0650951397,-2.7152036897,42304,546135,554821,Moravskoslezský kraj,4
Plzeň 4,60.5367075058,-0.7992435582,12244,546208,554791,Plzeňský kraj,4
Poruba,-82.5100086958,-1.6597296521,29247,546224,554821,Moravskoslezský kraj,4
Praha 11,128.8685008524,-0.0950302921,39116,547034,554782,Hlavní město Praha,4
Praha-Kunratice,284.4851769895,0.1737630983,4238,547042,554782,Hlavní město Praha,4
Praha-Libuš,210.9782615517,0.0641753172,4509,547051,554782,Hlavní město Praha,4
Praha 12,159.6062816648,0.4605296856,28428,547107,554782,Hlavní město Praha,4
Praha-Velká Chuchle,291.4806775506,-0.4975488221,1304,547115,554782,Hlavní město Praha,4
Praha-Lysolaje,241.2764556211,2.3714188188,680,547140,554782,Hlavní město Praha,4
Praha-Nebušice,194.2484709009,1.2433736709,1181,547158,554782,Hlavní město Praha,4
Praha 17,157.4721713866,0.1487192433,11826,547174,554782,Hlavní město Praha,4
Praha-Suchdol,234.7272193592,2.4026837107,3393,547271,554782,Hlavní město Praha,4
Praha-Ďáblice,267.4539470708,1.6708932756,1842,547298,554782,Hlavní město Praha,4
Praha-Dolní Chabry,307.1295914485,0.2916622961,2253,547301,554782,Hlavní město Praha,4
Praha-Čakovice,202.4185906066,1.0215748926,4999,547310,554782,Hlavní město Praha,4
Praha-Troja,344.88320342,-0.0664665717,693,547328,554782,Hlavní město Praha,4
Praha 19,209.3837621692,0.5396874908,3471,547344,554782,Hlavní město Praha,4
Praha 14,178.7027333403,-0.9660052289,20018,547361,554782,Hlavní město Praha,4
Praha-Dolní Měcholupy,277.9448523816,0.0215732348,1315,547379,554782,Hlavní město Praha,4
Praha 15,180.8529123292,-0.5364128083,16200,547387,554782,Hlavní město Praha,4
Praha-Petrovice,187.8653060809,0.6115553877,3120,547395,554782,Hlavní město Praha,4
Praha-Štěrboholy,259.596586294,1.3007847864,972,547409,554782,Hlavní město Praha,4
Praha 18,162.4977114352,-0.8913552118,8235,547417,554782,Hlavní město Praha,4
Brno-střed,194.1051561127,-4.4458731857,27710,550973,582786,Jihomoravský kraj,4
Brno-Žabovřesky,139.1666471174,-2.5453843475,11355,550990,582786,Jihomoravský kraj,4
Brno-Královo Pole,134.1522916449,-2.9722833488,12730,551007,582786,Jihomoravský kraj,4
Brno-sever,115.2604120787,-3.2427572496,21887,551031,582786,Jihomoravský kraj,4
Brno-Židenice,75.2203285407,-5.4994886615,9821,551058,582786,Jihomoravský kraj,4
Brno-Černovice,76.3758987307,-3.2531742254,3551,551066,582786,Jihomoravský kraj,4
Brno-jih,39.0494771511,-3.2758864132,3733,551074,582786,Jihomoravský kraj,4
Brno-Bohunice,20.3215683665,-2.6711113843,7351,551082,582786,Jihomoravský kraj,4
Brno-Starý Lískovec,5.2829687356,-3.0230840773,6419,551091,582786,Jihomoravský kraj,4
Brno-Nový Lískovec,66.2124061609,-4.1209569659,5367,551112,582786,Jihomoravský kraj,4
Brno-Kohoutovice,31.9771194852,-3.1527068441,6690,551147,582786,Jihomoravský kraj,4
Brno-Jundrov,143.4802195713,-2.4851095176,2351,551171,582786,Jihomoravský kraj,4
Brno-Bystrc,63.0557564785,-2.89156538,12479,551198,582786,Jihomoravský kraj,4
Brno-Kníničky,136.1928638627,-3.3952112231,595,551210,582786,Jihomoravský kraj,4
Brno-Komín,117.8213914787,-3.2283709223,4340,551228,582786,Jihomoravský kraj,4
Brno-Medlánky,151.2521424406,-3.8179933363,2881,551236,582786,Jihomoravský kraj,4
Brno-Řečkovice a Mokrá Hora,89.7418986647,-2.9548082261,8104,551244,582786,Jihomoravský kraj,4
Brno-Maloměřice a Obřany,86.9705740136,-4.5788072686,2848,551252,582786,Jihomoravský kraj,4
Brno-Vinohrady,18.3976626175,-4.0489027246,6612,551279,582786,Jihomoravský kraj,4
Brno-Líšeň,49.0620555469,-3.8965325365,13232,551287,582786,Jihomoravský kraj,4
Brno-Slatina,39.1375240421,-4.4541872982,4620,551295,582786,Jihomoravský kraj,4
Brno-Tuřany,36.9283416226,-4.8288502168,2893,551309,582786,Jihomoravský kraj,4
Brno-Chrlice,33.9483612802,-4.254113344,1709,551317,582786,Jihomoravský kraj,4
Brno-Bosonohy,74.5016982245,-3.6435733243,1370,551325,582786,Jihomoravský kraj,4
Brno-Žebětín,133.2869361742,-5.5658084009,2444,551368,582786,Jihomoravský kraj,4
Brno-Ivanovice,194.3694850245,-1.723201241,1057,551376,582786,Jihomoravský kraj,4
Brno-Jehnice,190.6488722987,-0.6877904544,653,551406,582786,Jihomoravský kraj,4
Brno-Ořešín,85.8264797328,0.7458046598,336,551422,582786,Jihomoravský kraj,4
Brno-Útěchov,194.2343176832,-2.0328965979,498,551431,582786,Jihomoravský kraj,4
Nová Bělá,-15.8973319729,-3.9265450251,1106,554219,554821,Moravskoslezský kraj,4
Vítkovice,-102.0518136548,-2.358009972,1976,554227,554821,Moravskoslezský kraj,4
Stará Bělá,-9.4237914398,-3.8710601194,2172,554235,554821,Moravskoslezský kraj,4
Pustkovec,23.9613074221,-0.3080303688,721,554243,554821,Moravskoslezský kraj,4
Mariánské Hory a Hulváky,-78.1860018859,-2.1627110028,4697,554286,554821,Moravskoslezský kraj,4
Petřkovice,-26.5244172695,-2.2097525555,1584,554308,554821,Moravskoslezský kraj,4
Lhotka,2.5872159514,-1.847178936,721,554324,554821,Moravskoslezský kraj,4
Hošťálkovice,-65.8051306465,-2.0121187556,904,554332,554821,Moravskoslezský kraj,4
Nová Ves,-35.7790579211,-4.086922764,283,554367,554821,Moravskoslezský kraj,4
Proskovice,-24.4084186064,-2.4569980139,669,554375,554821,Moravskoslezský kraj,4
Michálkovice,-76.1672190727,-1.7421036042,1351,554430,554821,Moravskoslezský kraj,4
Radvanice a Bartovice,-91.4162757539,-2.2467950986,2922,554537,554821,Moravskoslezský kraj,4
Krásné Pole,3.2418279546,-2.5754209417,1424,554561,554821,Moravskoslezský kraj,4
Martinov,-52.2012272023,-2.1278696145,617,554570,554821,Moravskoslezský kraj,4
Polanka nad Odrou,-45.0454717537,-2.5945229549,2643,554588,554821,Moravskoslezský kraj,4
Hrabová,-39.042487067,-1.0589025379,1930,554669,554821,Moravskoslezský kraj,4
Svinov,-27.9434841801,-1.597616837,2348,554685,554821,Moravskoslezský kraj,4
Třebovice,4.8646136637,-4.786974109,1121,554715,554821,Moravskoslezský kraj,4
Plesná,-27.1468926551,-0.8639187353,837,554723,554821,Moravskoslezský kraj,4
Plzeň 5-Křimice,83.3820215798,-0.8099786774,955,554731,554791,Plzeňský kraj,4
Plzeň 6-Litice,73.0437339333,-2.4549546339,1034,554758,554791,Plzeňský kraj,4
Plzeň 7-Radčice,63.6813784974,-2.1544647738,533,554766,554791,Plzeňský kraj,4
Plzeň 8-Černice,125.1183800114,-1.9457405702,906,554774,554791,Plzeňský kraj,4
Plzeň 10-Lhota,152.9276645255,-0.0813657819,681,557978,554791,Plzeňský kraj,4
Plzeň 9-Malesice,127.7930466623,-2.6148578775,397,559199,554791,Plzeňský kraj,4
// d3.tip
// Copyright (c) 2013 Justin Palmer
//
// Tooltips for d3.js SVG visualizations
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module with d3 as a dependency.
define(['d3'], factory)
} else {
// Browser global.
root.d3.tip = factory(root.d3)
}
}(this, function (d3) {
// Public - contructs a new tooltip
//
// Returns a tip
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)
}
// Public - show the tooltip on the screen
//
// Returns a tip
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
}
// Public - hide the tooltip
//
// Returns a tip
tip.hide = function() {
nodel = d3.select(node)
nodel.style({ opacity: 0, 'pointer-events': 'none' })
return tip
}
// Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value.
//
// n - name of the attribute
// v - value of the attribute
//
// Returns tip or attribute value
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
}
// Public: Proxy style calls to the d3 tip container. Sets or gets a style value.
//
// n - name of the property
// v - value of the property
//
// Returns tip or style property value
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
}
// Public: Set or get the direction of the tooltip
//
// v - One of n(north), s(south), e(east), or w(west), nw(northwest),
// sw(southwest), ne(northeast) or se(southeast)
//
// Returns tip or direction
tip.direction = function(v) {
if (!arguments.length) return direction
direction = v == null ? v : d3.functor(v)
return tip
}
// Public: Sets or gets the offset of the tip
//
// v - Array of [x, y] offset
//
// Returns offset or
tip.offset = function(v) {
if (!arguments.length) return offset
offset = v == null ? v : d3.functor(v)
return tip
}
// Public: sets or gets the html value of the tooltip
//
// v - String value of the tip
//
// Returns html value or 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
}
// Private - gets the screen coordinates of a shape
//
// Given a shape on the screen, will return an SVGPoint for the directions
// n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
// sw(southwest).
//
// +-+-+
// | |
// + +
// | |
// +-+-+
//
// Returns an Object {n, s, e, w, nw, sw, ne, se}
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
};
}));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Explodable</title>
<!--<link rel="stylesheet" href="bootstrap.min.css">-->
<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.v3.min.js"></script>-->
<script src="d3.tip.js"></script>
<!--<script src="jquery-1.11.1.min.js"></script>-->
<style>
.circle {
/*fill: #888;
stroke-opacity: 0.01;
stroke: #888;
stroke-width: 0;
fill-opacity: 0.2;
visibility: hidden;*/
}
.party {
/*visibility: hidden;
fill-opacity: 0.01;
stroke-opacity: 1;*/
/*stroke: #f00;*/
}
.text {
/*visibility: hidden;
fill-opacity: 0.99;*/
/*fill: #444;*/
}
.text.active {
/*fill-opacity: 0.85;*/
}
.big {
/*stroke-width: 2px;*/
}
.small {
}
.stronger {
/*color: yellow;*/
}
.visible {
/*visibility: visible;*/
}
.active {
/*fill-opacity: 0.75;
stroke-opacity: 1;*/
}
.ellipse {
/*fill-opacity: 0;
stroke: #f00;
stroke-opacity: 0.75;*/
}
/* D3 tips */
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
/*.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}*/
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.top {
width: 100vw;
padding: 10px;
color: white;
/*font-size: 3em;*/
/*background-color: #fed201;*/
}
</style>
</head>
<body>
<h1 class="text-center top bg-primary">
<strong>POLITICAL MAP OF CZECHIA: ELECTIONS 2017</strong><br/>
<small>POLITICKÁ MAPA ČR: VOLBY 2017</small><br />
</h1>
<!-- chart -->
<div class="row">
<p class="col-9" id="chart"></p>
</div>
<script type="text/javascript">
// Chart dimensions.
var margin = {top: 10, right: 0, bottom: 0, left: 30},
width = 960 - margin.right,
height = 500 - margin.top - margin.bottom;
//Various scales. These domains make assumptions of data, naturally.
var xmax = 450,
ymax = 15;
var
xScale = d3.scale.linear()
.domain([-xmax, xmax])
.range([0, width]),
yScale = d3.scale.linear()
.domain([-ymax, ymax])
.range([height, 0]),
radiusScale = d3.scale.sqrt()
.domain([0, 1000000])
.range([0, 50]);
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';
}
/* Initialize tooltip */
tip = d3.tip().attr('class', 'd3-tip').html(function(d) {
return '<span class="stronger">' + d['name'] + "</span><br>";
});
// Create the SVG container and set the origin.
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 + ")");
/* 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);
// Load the data.
d3.csv("cz_2017_print_pbop.csv", function(data) {
data.sort(function(a, b) {
return parseFloat(b.size) - parseFloat(a.size);
});
// var circle = svg.selectAll(".circle")
// .data(data)
// .enter().append("circle")
// .attr("r",function(d) {
// return Math.max(1,radiusScale(d['size']));
// })
// .attr("cx", function(d) {return xScale(d['dim1']);})
// .attr("cy", function(d) {return yScale(d['dim2']);})
// .attr("class", function(d) {
// clas = "circle ";
// if (d['size'] > 1500) clas += "big";
// else clas += "small";
// if (d['level'] == 3) clas += " active explorable visible";
// else clas += " explorable";
// clas += " level-" + d['level']
// return clas;
// })
// .attr("style", function(d) {
// return "stroke:" + region2color(d['region']) + ";fill:" + region2color(d['region']);
// })
// .attr("id", function(d) {return "id-" + d.id;})
// .on("mouseover", tip.show)
// .on("mouseout", tip.hide)
// .on("click", clicked)
//texts:
svg.selectAll(".text")
.data(data)
.enter().append("text")
.attr("x", function(d) {return xScale(d['dim1']);})
.attr("y", function(d) {return yScale(d['dim2']) + Math.max(Math.min(70, Math.sqrt(parseInt(d['size'])) / 10), 2) / 3;})
.attr("font-size", function(d) {
if (d['size'] > 10) {
var si = 0;
si = Math.max(Math.min(70, Math.sqrt(parseInt(d['size'])) / 10), 2);
return si + "px"
} else {
return 0
}
})
.attr("font-weight", function(d) {
if (d['size'] > 50000) {
return "bold";
}
return "default";
})
.attr("class", function(d) {
clas = "text ";
if (d['level'] == 4) clas += " visible";
else clas += "";
clas += " level-" + d['level']
return clas;
})
.attr("fill", function(d) {
return region2color(d['region'])
})
.attr("id", function(d) {return "text-id-" + d.id;})
.attr("text-anchor", "middle")
.attr("fill-opacity", 0.85)
.text(function(d) {return d['name']});
function clicked(item) {
if (this.classList.contains("explored")) {
deexplore(item);
} else {
if(this.classList.contains("explorable")) {
explore(item);
}
}
}
});
// d3.csv("cz_2017_party.csv", function(data) {
// var circle = svg.selectAll(".party")
// .data(data)
// .enter().append("circle")
// .attr("r",function(d) {
// return Math.max(1,radiusScale(d['size']));
// })
// .attr("cx", function(d) {return xScale(d['dim1']);})
// .attr("cy", function(d) {return yScale(d['dim2']);})
// .attr("class", function(d) {
// clas = "party ";
// if (d['size'] > 50000) clas += "big";
// else clas += "small";
// return clas;
// })
// .attr("stroke", function(d) {return d['color']})
// .on("mouseover", tip.show)
// .on("mouseout", tip.hide)
//
// // partylines:
// // var line = svg.selectAll(".partyline")
// // .data(data)
// // .enter().append("line")
// // .attr("x1", function() {return xScale(-7)})
// // .attr("y1", function() {return yScale(0.75)})
// // .attr("x2", function(d) {return xScale(d['dim1'])})
// // .attr("y2", function(d) {return yScale(d['dim2'])})
// // .attr("stroke", function(d) {return d['color']})
// // .attr("stroke-width", function(d) {
// // if (parseInt(d['size']) > 50000) {
// // return parseInt(d['size'] / 50000)
// // } else {
// // return 0
// // }
// // })
//
//
// })
//ellipse is calculated to cover 90 % of the districts (voters)
svg.append("ellipse")
.attr("cx", function() {return xScale(0)})
.attr("cy", function() {return yScale(0)})
.attr("rx", function() {return 2.13*(xScale(114.5) - xScale(0))})
.attr("ry", function() {return 2.13*(Math.abs(yScale(3.73) - yScale(0)))})
.attr("class", "ellipse")
.style("stroke-dasharray", ("3, 5"))
.style("fill-opacity", 0)
.style("stroke", "red")
.style("stroke-opacity", 0.75)
</script>
</body>
</html>