Built with blockbuilder.org
forked from bumbeishvili's block: Polls.ge
license: mit |
Built with blockbuilder.org
forked from bumbeishvili's block: Polls.ge
<!DOCTYPE html> | |
<html lang="en" > | |
<head> | |
<meta charset="UTF-8"> | |
<link rel="shortcut icon" type="image/x-icon" href="https://production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /> | |
<link rel="mask-icon" type="" href="https://production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /> | |
<title>CodePen - Elections</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link rel="shortcut icon" type="image/x-icon" href="https://raw.githubusercontent.com/bumbeishvili/Assets/master/Projects/D3/Polls/pollsPng.png" /> | |
<meta property="og:title" content="მატყუარა ეგზიტპოლები?!" /> | |
<meta property="og:description" content="ეგზიტპოლების, წინასაარჩევნო გამოკითხვებისა და რეალური შედეგების შედარება" /> | |
<meta property="og:image" content="https://raw.githubusercontent.com/bumbeishvili/Assets/master/Projects/D3/Polls/pollsFinal.png" /> | |
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.min.css'> | |
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.css'> | |
<style> | |
h1 { | |
text-align: center; | |
margin: 5px; | |
} | |
.buttons button { | |
margin-bottom: 10px; | |
} | |
.buttons { | |
position: fixed; | |
left: 20px; | |
} | |
.toggle-lang { | |
position: fixed; | |
right: 10px; | |
top: 10px; | |
} | |
.custom-tooltip { | |
position: fixed; | |
max-width: 500px; | |
} | |
.custom-tooltip td, | |
.custom-tooltip th { | |
padding: 5px !important; | |
} | |
.custom-tooltip .card .card-content .card-title { | |
line-height: 26px; | |
} | |
.poll-card { | |
color: black; | |
} | |
.poll-info { | |
position: absolute; | |
max-width: 300px; | |
right: 15px; | |
} | |
.dispersion { | |
position: absolute; | |
max-width: 300px; | |
right: 15px; | |
bottom: 30px; | |
} | |
.cesko-color { | |
background-color: #60C028; | |
} | |
.fb-comments { | |
margin-left: 30%; | |
} | |
@media only screen and (max-width: 1000px) { | |
.poll-info { | |
position: relative; | |
max-width: 90%; | |
left: 5%; | |
} | |
.dispersion { | |
position: relative; | |
max-width: 90%; | |
left: 5%; | |
margin-top: 50px; | |
} | |
.buttons { | |
position: relative; | |
top: 40px; | |
max-width: 90%; | |
left: 5%; | |
margin-top: 0; | |
margin-bottom: 10px; | |
} | |
.toggle-lang { | |
position: relative; | |
float: right; | |
right: 5%; | |
} | |
.fb-comments { | |
margin-left: 0%; | |
max-width: 90%; | |
} | |
} | |
</style> | |
</head> | |
<body translate="no" > | |
<div id="fb-root"></div> | |
<script> | |
(function(d, s, id) { | |
var js, fjs = d.getElementsByTagName(s)[0]; | |
if (d.getElementById(id)) return; | |
js = d.createElement(s); js.id = id; | |
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8&appId=813508885415765"; | |
fjs.parentNode.insertBefore(js, fjs); | |
}(document, 'script', 'facebook-jssdk')); | |
</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','https://www.google-analytics.com/analytics.js','ga'); | |
ga('create', 'UA-79501479-2', 'auto'); | |
ga('send', 'pageview'); | |
</script> | |
<button class="toggle-lang btn-floating" onclick="toggle()">En</button> | |
<h1 class="header">არჩევნები 2016</h1> | |
<div class="tooltip-template" style='display:none'> | |
<div class="row"> | |
<div class="col"> | |
<div class="card " style="background-color:#PARTY_COLOR"> | |
<div class="card-content white-text"> | |
<span class="card-title">#PARTY_NAME</span> | |
<table> | |
<tr> | |
<th>#VOTE_PERCENT_TEXT</th> | |
<td>#VOTE_PERCENT %</td> | |
</tr> | |
<tr> | |
<th>#VOTE_COUNT_TEXT</th> | |
<td>#VOTE_COUNT</td> | |
</tr> | |
</table> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class=" poll-info"> | |
<div class="card "> | |
<div class="card-content "> | |
<span class="card-title"> გამოკითხვათა შეჯამება</span> | |
<br> | |
<div class="poll-info-content"> | |
კვლევის განმავლობაში სულ მოსაზრება გამოთქვა <span>2000</span> -მა ადამიანმა, გამოკითხვა მიმდინარეობდა | |
<br><br> ინფორმაციის წყარო | |
</div> | |
</div> | |
</div> | |
<div class="fb-share-button" data-href="http://polls.ge/" data-layout="button_count" data-size="large" data-mobile-iframe="false"><a class="fb-xfbml-parse-ignore" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fpolls.ge%2F&src=sdkpreparse">Share </a></div> | |
<div style="float:right" class="fb-like" data-href="https://www.facebook.com/polls.ge/" data-layout="button_count" data-action="like" data-size="small" data-show-faces="true" data-share="false"> | |
</div></div> | |
<div class=" dispersion"> | |
<div class="card "> | |
<div class="card-content "> | |
<span class="card-title"> </span> | |
<div class="dispersion-info-content"> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="buttons"></div> | |
<div id='graphContent'></div> | |
</div> | |
<div class="row"> | |
<div class="fb-comments " data-href="http://polls.ge/" data-numposts="5"></div> | |
</div> | |
<div class="custom-tooltip"></div> | |
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js'></script> | |
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script> | |
<script src='https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.min.js'></script> | |
<script src='https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.js'></script> | |
<script > | |
var selector = '#graphContent'; | |
var gauge; | |
(function setLanguage(){ | |
if(!localStorage.getItem('lang')){ | |
localStorage.setItem('lang','En'); | |
} | |
var lang = localStorage.getItem('lang'); | |
if(lang=='Ge'){ | |
set('.toggle-lang','En') | |
}else{ | |
set('.toggle-lang','Ge') | |
} | |
})() | |
function extractDispersion() { | |
polls.cesko.data.sort(function(x, y) { | |
return d3.ascending(x.electNumber, y.electNumber); | |
}) | |
console.log("##################"); | |
var dispersions = {}; | |
var maxDispersion = 0; | |
var keys = Object.keys(polls); | |
keys.forEach(function(key) { | |
dispersions[key] = 0; | |
polls[key].data.sort(function(x, y) { | |
return d3.ascending(x.electNumber, y.electNumber); | |
}) | |
polls.cesko.data.forEach(function(v, i) { | |
var ceskoNode = polls['cesko'].data[i]; | |
var pollNode = polls[key].data[i]; | |
if (!isNaN(ceskoNode.electNumber)) { | |
if (ceskoNode.votePercent > 0 && pollNode.votePercent > 0) { | |
dispersions[key] += Math.pow(ceskoNode.votePercent - pollNode.votePercent, 2); | |
} | |
} | |
}) | |
dispersions[key] = Math.sqrt(dispersions[key]); | |
if (dispersions[key] > maxDispersion) { | |
maxDispersion = dispersions[key]; | |
} | |
}) | |
global.dispersions = dispersions; | |
global.maxDispersion = maxDispersion; | |
console.log(global); | |
} | |
function drawGauge() { | |
gauge = c3.generate({ | |
bindto: '.dispersion-info-content', | |
data: { | |
columns: [ | |
['განსხვავება', global.dispersions[global.currentSource] / (global.maxDispersion + 0.0001) * 100] | |
], | |
type: 'gauge', | |
}, | |
tooltip: { | |
show: false | |
}, | |
gauge: { | |
// label: { | |
// format: function(value, ratio) { | |
// return value; | |
// },min | |
// show: false // to turn off the min/max labels. | |
// }, | |
unit: '', | |
width: 39 // for adjusting arc thickness | |
}, | |
color: { | |
pattern: ['#60B044', '#F6C600', '#F97600', '#FF0000'], // the three color levels for the percentage values. | |
threshold: { | |
// unit: 'value', // percentage is default | |
// max: 200, // 100 is default | |
values: [30, 60, 90, 100] | |
} | |
}, | |
size: { | |
height: 240, | |
width: 260 | |
} | |
}); | |
gaugeText(); | |
} | |
function isSmallScreen() { | |
return window.innerWidth < 1000; | |
} | |
function toggle() { | |
set('.toggle-lang', global.currentLang); | |
global.currentLang = global.currentLang == "En" ? "Ge" : 'En'; | |
localStorage.setItem('lang', global.currentLang); | |
drawContent(); | |
gaugeText(); | |
} | |
function drawContent() { | |
clear(); | |
set('.header', global.texts['header' + global.currentLang]); | |
var currentSource = global.currentSource; | |
if (!currentSource) { | |
currentSource = 'cesko'; | |
} | |
gaugeText(); | |
//addAverage(polls); | |
draw({ | |
data: { | |
children: merge(polls[currentSource]), | |
votePercent: 1 // without it, circles are overlapping - http://stackoverflow.com/questions/14790340/d3-js-pack-layout-circles-are-overlapping | |
} | |
}) | |
global.currentSource = currentSource; | |
composePollInfo(); | |
generateButtons(polls); | |
get('.' + global.currentSource).disabled = true; | |
} | |
function composePollInfo() { | |
var poll = polls[global.currentSource]; | |
var lang = global.currentLang; | |
set('.poll-info .card-title', poll['name' + lang]); | |
set('.dispersion .card-title', global.texts['dispersionTitle' + lang]); | |
var pollInfo = "" | |
if (global.currentSource == "cesko") { | |
pollInfo += global.texts['ceskoActivity' + lang]; | |
pollInfo += poll['activity' + lang]; | |
pollInfo += global.texts['ceskoSummary' + lang]; | |
} else if (poll.type == "pointOfView" || poll.type == "exitpoll") { | |
pollInfo += poll['pollDate' + lang]; | |
} else { | |
pollInfo += global.texts['pollInfoCount' + lang]; | |
pollInfo += poll.polled; | |
pollInfo += global.texts['pollInfoTime' + lang]; | |
pollInfo += poll['pollDate' + lang]; | |
} | |
if (poll.source) { | |
pollInfo += "<br> <a target='_blank' href='" + poll.source + "'>" + global.texts['pollInfoSource' + lang] + "</a>"; | |
} | |
set('.poll-info .poll-info-content', pollInfo); | |
} | |
var global = { | |
transition: null, | |
currentSource: null, | |
currentLang: localStorage.getItem('lang'), | |
defaultRespondentCountIfNotSpecified: 1200, // this is standart number of sociological polls, according to tornike bakakuri | |
texts: { | |
headerEn: "Elections 2016", | |
headerGe: "არჩევნები 2016", | |
contactGe: "<!--<a target='_blank' href='https://www.facebook.com/polls.ge/'>მოგვწერეთ</a>, სხვა გამოკითხვების დასამატებლად-->", | |
contactEn: "<!--<a target='_blank' href='https://www.facebook.com/polls.ge/'>Write us </a>, to add more polls-->", | |
votePercentGe: "პროცენტულობა", | |
votePercentEn: "Percent", | |
voteCountGe: "მიღებული ხმები", | |
voteCountEn: "Votes", | |
voteTotalGe: "გამოკითხულთა რაოდენობა", | |
voteTotalEn: "Number of respondents", | |
pollDateGe: "გამოკითხვის თარიღი", | |
pollDateEn: "Date of poll", | |
pollInfoCountGe: "კვლევის განმავლობაში სულ მოსაზრება გამოთქვა ", | |
pollInfoCountEn: "During the poll, total number of interviewed citizens, was ", | |
pollInfoTimeGe: "-მა ადამიანმა, გამოკითხვის დრო - ", | |
pollInfoTimeEn: ". Poll date - ", | |
pollInfoSourceGe: "<br> ინფორმაციის წყარო", | |
pollInfoSourceEn: "<br> Information source", | |
ceskoActivityGe: " დაფიქსირდა არჩევნების ", | |
ceskoActivityEn: " election activity was ", | |
ceskoVoteCountGe: ". <br><br> დათვლილია ", | |
ceskoVoteCountEn: ". <br><br> It's already counted ", | |
ceskoLastChangeGe: " მოქალაქის ხმა 1814276-დან <br><br> ბოლო განახლების დრო - ", | |
ceskoLastChangeEn: " vote from 1814276. <br><br> Last update time - ", | |
ceskoSummaryGe: "<br><br> დათვლილია ხმების 100%, სულ 1759937 ხმა", | |
ceskoSummaryEn: "<br><br>100 % finished counting votes , counted 1759937 ", | |
gaugeMinGe: 'ძაან მცირე აცდენა', | |
gaugeMinEn: 'Very small difference', | |
gaugeMaxGe: 'ძაან დიდი აცდენა', | |
gaugeMaxEn: 'Very big difference', | |
dispersionTitleGe: 'აცდენა ცესკოსგან', | |
dispersionTitleEn: 'Difference from Cesko ', | |
}, | |
partiesInfo: { | |
'1': { | |
shortNameGe: "ბურჭულაძე", | |
nameGe: "პაატა ბურჭულაძე - სახელმწიფო ხალხისთვის", | |
shortNameEn: "Burchuladze", | |
nameEn: "Paata Burchuladze ", | |
color: "#ED1B24" | |
}, | |
'3': { | |
shortNameGe: "ბურჯანაძე", | |
nameGe: '"ნინო ბურჯანაძე - დემოკრატიული მოძრაობა"', | |
shortNameEn: "Burjanadze", | |
nameEn: "Nino Burjanadze - Democratic movement ", | |
color: '#022EC1' | |
}, | |
'4': { | |
shortNameGe: "ბაღათურია", | |
nameGe: '"ჯონდი ბაღათურია - ქართული დასი"', | |
shortNameEn: "Baghaturia", | |
nameEn: "Nino Burjanadze - Democratic movement ", | |
color: '#B1241B' | |
}, | |
'5': { | |
shortNameGe: "ნაციონალები", | |
nameGe: 'ერთიანი ნაციონალური მოძრაობა', | |
shortNameEn: "Nationals", | |
nameEn: 'United national movement', | |
color: '#E4012E' | |
}, | |
'6': { | |
shortNameGe: "რესპუბლიკელები", | |
nameGe: 'უსუფაშვილი - რესპუბლიკელები', | |
shortNameEn: "Republicans", | |
nameEn: "Usupashvili - Republicans", | |
color: '#F3701E' | |
}, | |
'7': { | |
shortNameGe: "მეჭიაური", | |
nameGe: 'თამაზ მეჭიაური ერთიანი საქართველოსთვის', | |
shortNameEn: "Mechiauri", | |
nameEn: "Tamaz Mechiauri for united Georgia ", | |
color: '#e5ab87' | |
}, | |
'8': { | |
shortNameGe: "პატრ. ალიანსი", | |
nameGe: 'დავით თარხან-მოურავი, ირმა ინაშვილი - საქართველოს პატრიოტთა ალიანსი, გაერთიანებული ოპოზიცია', | |
shortNameEn: "Patr.Aliance", | |
nameEn: "Patriotic Aliance, United Oposition", | |
color: '#E1BC63' | |
}, | |
'10': { | |
shortNameGe: "ნათელაშვილი", | |
nameGe: 'შალვა ნათელაშვილი - საქართველოს ლეიბორისტული პარტია', | |
shortNameEn: "Natelashvili", | |
nameEn: "Shalva Natelashvili - Georgian labor party", | |
color: '#41499A' | |
}, | |
'14': { | |
shortNameGe: "დავით თევზაძე", | |
nameGe: 'დავით თევზაძე - საქართველოს მშვიდობისათვის', | |
shortNameEn: "David tevzadze", | |
nameEn: "David tevzadze - Georgia for peace", | |
color: '#191F6B' | |
}, | |
'19': { | |
shortNameGe: "თოფაძე", | |
nameGe: 'თოფაძე - მრეწველები, ჩვენი სამშობლო', | |
shortNameEn: "Topadze", | |
nameEn: "Topadze - Industrials, our homeland", | |
color: '#5F1016' | |
}, | |
'23': { | |
shortNameGe: "სახალხო პარტია", | |
nameGe: 'ჩვენები - სახალხო პარტია', | |
shortNameEn: "Public party", | |
nameEn: "Ours - public party ", | |
color: '#FECD28' | |
}, | |
'25': { | |
shortNameGe: "მემარცხენეები", | |
nameGe: 'კახა ძაგანია, სოსო შატბერაშვილი, პაატა ჯიბლაძე, არჩილ ბენიძე - მემარცხენე ალიანსი', | |
shortNameEn: "Left", | |
nameEn: "Left wing aliance", | |
color: '#BBA252' | |
}, | |
'26': { | |
shortNameGe: "ერ. ფორუმი", | |
nameGe: 'ეროვნული ფორუმი', | |
shortNameEn: "Forum", | |
nameEn: "National forum", | |
color: '#FDDB55' | |
}, | |
'27': { | |
shortNameGe: "ალასანია", | |
nameGe: 'ირაკლი ალასანია - თავისუფალი დემოკრატები', | |
shortNameEn: "Alasania", | |
nameEn: "Irakli Alasania - Free Democrats", | |
color: '#01308A' | |
}, | |
'41': { | |
shortNameGe: "ოცნება", | |
nameGe: 'ქართული ოცნება - დემოკრატიული საქართველო', | |
shortNameEn: "Dream", | |
nameEn: "Georgian Dream", | |
color: '#004B91' | |
}, | |
'sxva': { | |
shortNameGe: "სხვას", | |
nameGe: 'სხვა', | |
shortNameEn: "Other", | |
nameEn: "Other", | |
color: '#46a812' | |
}, | |
'aravis': { | |
shortNameGe: "არავის", | |
nameGe: 'არავის', | |
shortNameEn: "No one", | |
nameEn: "No one ", | |
color: '#aa8ace' | |
}, | |
'argadamiwyvetia': { | |
shortNameGe: "არ ვიცი", | |
nameGe: 'არ გადამიწყვეტია', | |
shortNameEn: "Don't know", | |
nameEn: "I don't know yet ", | |
color: '#aab3c1' | |
}, | |
'uari': { | |
shortNameGe: "უარი", | |
nameGe: 'უარი პასუხზე', | |
shortNameEn: "No!", | |
nameEn: "Don't answered", | |
color: '#46a812' | |
} | |
} | |
}; | |
function draw(p) { | |
var attrs = { | |
circlePadding: 4, | |
data: p.data, | |
selector: selector, | |
width: window.innerWidth - 20, | |
height: window.innerHeight - 25, | |
} | |
//test | |
var dynamic = {}; | |
dynamic.svgWidth = attrs.width; | |
dynamic.svgHeight = attrs.height - 80; | |
//#################### LAYOUTS ############### | |
var layouts = {} | |
layouts.bubble = d3.layout.pack() | |
.size([dynamic.svgWidth, dynamic.svgHeight]) | |
.sort(function(a, b) { | |
return a.name > b.name | |
}) | |
.value(function(d) { | |
return Math.max(d.votePercent, 0.05); | |
}) | |
.padding(attrs.circlePadding); | |
// ########## DATA GENERATION ########## | |
var nodes = layouts.bubble.nodes(attrs.data) | |
.filter(function(d) { | |
//filtering big parent circles | |
return !d.children; | |
}) | |
//########### DRAWING ############# | |
//drawing svg | |
var svg = d3.select(attrs.selector) | |
.append('svg') | |
.attr('width', dynamic.svgWidth) | |
.attr('height', dynamic.svgHeight); | |
//drawing circles | |
var circleGroups = svg.selectAll('circle-group') | |
.data(nodes) | |
.enter() | |
.append('g') | |
.attr('class', 'circle-group') | |
circleGroups.transition().duration(1000) | |
.attr('cursor', 'pointer') | |
.attr('transform', function(d) { | |
return 'translate(' + d.x + ',' + d.y + ')' | |
}) | |
//circle | |
circleGroups | |
.append('circle') | |
.attr('fill', function(d) { | |
if (d.votePercent == 0) { | |
return 'none'; | |
} | |
return d.party.color; | |
}) | |
.attr('class', function(d) { | |
return 'test' + d.electNumber; | |
}) | |
.attr('r', function(d) { | |
return d.r | |
}) | |
//text | |
circleGroups.append('text') | |
.attr("dy", ".3em") | |
.attr("transform", function(d) { | |
if (d.votePercent >= 1) return "translate(0,-10)"; | |
}) | |
.attr('class', 'title') | |
.style("text-anchor", "middle") | |
.attr('fill', function(d) { | |
return 'white' | |
}) | |
.text(text) | |
//text | |
circleGroups.append('text') | |
.attr("dy", ".3em") | |
.attr('class', 'circle-percent') | |
.attr("transform", "translate(0,15)") | |
.style("text-anchor", "middle") | |
.attr('fill', function(d) { | |
return 'white' | |
}) | |
.text(function(d) { | |
if (isSmallScreen() && d.votePercent < 3.5) { | |
return ""; | |
} | |
if (d.votePercent >= 4) { | |
return d.votePercent.toFixed(2) + ' %'; | |
} | |
if (d.votePercent >= 1.2) { | |
return d.votePercent.toFixed(1) + ' %'; | |
} | |
}) | |
//######################## TOOLTIP ###################### | |
circleGroups.on('mouseenter', mouseEnter); | |
circleGroups.on('mouseleave', mouseLeave); | |
circleGroups.on('mousemove', mouseMove); | |
//######################## FUNCTIONS ######################### | |
function mouseMove(d) { | |
var y = d3.event.pageY - 200; | |
var x = d3.event.pageX + 20; | |
if (isSmallScreen()) { | |
y -= 500; | |
} | |
d3.select('.custom-tooltip').style('top', y + 'px').style('left', x + 'px') | |
} | |
function mouseEnter(d) { | |
var circleGroup = d3.select(this) | |
.select('circle'); | |
var countTextReplacer = ""; | |
var countReplacer = ""; | |
var tooltipContent = get('.tooltip-template').innerHTML; | |
tooltipContent = tooltipContent.replace(/#PARTY_COLOR/i, d.party.color); | |
tooltipContent = tooltipContent.replace(/#PARTY_NAME/i, d.party['name' + global.currentLang]); | |
tooltipContent = tooltipContent.replace(/#VOTE_PERCENT_TEXT/i, global.texts['votePercent' + global.currentLang]); | |
tooltipContent = tooltipContent.replace(/#VOTE_PERCENT/i, d.votePercent.toFixed(2)); | |
if (polls[global.currentSource].type != 'exitpoll') { | |
countTextReplacer = global.texts['voteCount' + global.currentLang]; | |
countReplacer = (polls[global.currentSource].polled * d.votePercent / 100).toFixed(0); | |
} | |
tooltipContent = tooltipContent.replace(/#VOTE_COUNT_TEXT/i, countTextReplacer); | |
tooltipContent = tooltipContent.replace(/#VOTE_COUNT/i, countReplacer); | |
set('.custom-tooltip', tooltipContent); | |
d3.select('.custom-tooltip').transition().style('opacity', 1) | |
circleGroup.attr('stroke', '#82b1ff') | |
.attr('stroke-width', 10); | |
} | |
function mouseLeave() { | |
var circleGroup = d3.select(this). | |
select('circle'); | |
circleGroup.attr('stroke', 'none') | |
.attr('stroke-width', 0); | |
d3.select('.custom-tooltip') | |
.transition() | |
.style('opacity', 0.1) | |
.each('end', function() { | |
get('.custom-tooltip').innerHTML = ""; | |
}); | |
} | |
function text(d) { | |
var smallScreen = isSmallScreen(); | |
var n = ''; | |
var electNumber = ""; | |
if (!isNaN(d.electNumber)) { | |
electNumber = d.electNumber + ". "; | |
n = 'N '; | |
} | |
if (d.votePercent > 30) { | |
return n + electNumber + d.party['shortName' + global.currentLang]; | |
} | |
if (d.votePercent > 1 && isNaN(d.electNumber)) { | |
return d.party['shortName' + global.currentLang]; | |
} | |
if (d.votePercent <= 1.2) { | |
return ""; | |
} | |
if (smallScreen) { | |
if (d.votePercent > 5 && !isNaN(d.electNumber)) { | |
return 'N ' + d.electNumber; | |
} | |
if (d.votePercent < 3) { | |
return ""; | |
} | |
} else { | |
if (d.votePercent > 11) { | |
return electNumber + d.party['shortName' + global.currentLang]; | |
} | |
if (isNaN(d.electNumber)) { | |
return "" | |
} | |
if (d.votePercent > 2) { | |
return 'N ' + d.electNumber; | |
} | |
if (d.votePercent > 0.4) { | |
return 'N ' + d.electNumber; | |
} | |
} | |
} | |
global.transition = function(source) { | |
if (global.currentSource == source) { | |
return; | |
} | |
get('.' + global.currentSource).disabled = false; | |
global.currentSource = source; | |
get('.' + global.currentSource).disabled = true; | |
gauge.load({ | |
columns: [ | |
[global.difference, global.dispersions[global.currentSource] / (global.maxDispersion + 0.0001) * 100] | |
] | |
}); | |
gaugeText(); | |
d3.select('.c3-gauge-value').text(''); | |
composePollInfo(); | |
var newNodes = layouts.bubble.nodes({ | |
children: merge(polls[source]), | |
votePercent: 1 | |
}) | |
.filter(function(d) { | |
//filtering big parent circles | |
return !d.children; | |
}) | |
var newCircleGroup = svg.selectAll('.circle-group') | |
.data(newNodes) | |
newCircleGroup.transition() | |
.duration(1000) | |
.attr('transform', function(d) { | |
return 'translate(' + d.x + ',' + d.y + ')' | |
}) | |
newCircleGroup.select('circle') | |
.attr('fill', function(d) { | |
return d.party.color; | |
}) | |
.transition() | |
.duration(1000) | |
.attr('r', function(d) { | |
return d.r | |
}).delay(1000) | |
newCircleGroup.select('circle') | |
.transition() | |
.delay(2000) | |
.attr('fill', function(d) { | |
if (d.votePercent == 0) { | |
return "none"; | |
} | |
return d.party.color; | |
}) | |
newCircleGroup.select('.title') | |
.attr("dy", ".3em") | |
.attr("transform", function(d) { | |
if (d.votePercent >= 1) return "translate(0,-10)"; | |
}) | |
.style("text-anchor", "middle") | |
.attr('fill-opacity', 0) | |
.text(text) | |
.transition() | |
.duration(1000) | |
.attr('fill-opacity', 1) | |
newCircleGroup.select('.circle-percent') | |
.attr("dy", ".3em") | |
.attr("transform", "translate(0,15)") | |
.style("text-anchor", "middle") | |
.attr('fill-opacity', 0) | |
.text(function(d) { | |
if (d.votePercent >= 4) { | |
return d.votePercent.toFixed(2) + ' %'; | |
} | |
if (d.votePercent >= 1.2) { | |
return d.votePercent.toFixed(1) + ' %'; | |
} | |
}) | |
.transition() | |
.duration(1000) | |
.attr('fill-opacity', 1) | |
} | |
} | |
var polls = { | |
"cesko": { | |
"nameGe": "ცესკო შედეგები", | |
"nameEn": "cesko results", | |
"polled": 1759937, //1814276, | |
"pollDateGe": '10 ოქტომბერი დილის 1-ლი სთ.', | |
"pollDateEn": '10 october 1 a.m. ', | |
"activityEn": "51.63% ", | |
"activityGe": "51.63% - იანი აქტივობა ", | |
"type": "results", | |
"source": "http://results.cec.gov.ge/#", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 3.45 | |
}, { | |
"electNumber": "3", | |
"votePercent": 3.53 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0.13 | |
}, { | |
"electNumber": "5", | |
"votePercent": 27.11 | |
}, { | |
"electNumber": "6", | |
"votePercent": 1.55 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0.16 | |
}, { | |
"electNumber": "8", | |
"votePercent": 5.01 | |
}, { | |
"electNumber": "10", | |
"votePercent": 3.14 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0.22 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0.78 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0.09 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0.04 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0.73 | |
}, { | |
"electNumber": "27", | |
"votePercent": 4.62 | |
}, { | |
"electNumber": "41", | |
"votePercent": 48.67 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 0 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 0 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
"tns": { | |
"nameGe": "TNS ეგზიტპოლი (GDS,მაესტრო, იმედი,1tv)", | |
"nameEn": "TNS exitpoll (GDS, maestro,imedi,1tv)", | |
"polled": 0, | |
"pollDateGe": '8 ოქტომბერი', | |
"pollDateEn": '8 october', | |
"source": "http://www.interpressnews.ge/ge/skhva/401340-tns-opinion-is-egzitpolis-pirveladi-shedegebis-thanakhmad-amomrcheveltha-538-mkhars-qarthul-ocnebas-utcers-kholo-195-qnacionaluri-modzraobasq.html", | |
"type": "exitpoll", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 2.7 | |
}, { | |
"electNumber": "3", | |
"votePercent": 0 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 19.5 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 5 | |
}, { | |
"electNumber": "10", | |
"votePercent": 3.1 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 4 | |
}, { | |
"electNumber": "41", | |
"votePercent": 53.8 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 0 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 0 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
"gfkexit": { | |
"nameGe": "GFK-ს ეგზიტპოლი (რუსთავი2)", | |
"nameEn": "GFK Exitpoll (Rustavi2)", | |
"polled": 0, | |
"pollDateGe": '8 ოქტომბერი', | |
"pollDateEn": '8 october', | |
"type": "exitpoll", | |
"source": "http://www.interpressnews.ge/ge/skhva/401339-gfk-is-egzitpolis-pirveladi-shedegebith-qarthul-ocnebas-amomrcheveltha-399-ma-nacionalur-modzraobas-ki-3274-ma-dautcira-mkhari.html", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 3.25 | |
}, { | |
"electNumber": "3", | |
"votePercent": 2.81 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 32.74 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 5.76 | |
}, { | |
"electNumber": "10", | |
"votePercent": 4.21 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 3.21 | |
}, { | |
"electNumber": "41", | |
"votePercent": 39.9 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 8.12 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 0 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
/* | |
"average": { | |
"nameGe": 'გამოკითხვათა შეჯამება', | |
"nameEn": 'Polls summary', | |
"pollDateGe": '7 სექტემბრიდან დღემდე', | |
"pollDateEn": 'From 7 sept. ', | |
"polled": 0, | |
}, | |
*/ | |
"wpa": { | |
"nameGe": "სოციოლოგიური კომპანია WPA", | |
"nameEn": "Sociological company WPA", | |
"polled": 1329, | |
"pollDateGe": '7-11 სექტემბერი', | |
"pollDateEn": '7-11 September', | |
"type": "poll", | |
"source": "http://www.interpressnews.ge/ge/sazogadoeba/398603-wpa-s-kvlevis-thanakhmad-gamokithkhultha-25-mkhars-utcers-qarthul-ocnebas-kholo-16-patriottha-alianss.html?ar=A", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 1 | |
}, { | |
"electNumber": "3", | |
"votePercent": 3 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 12 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0 | |
}, { | |
"electNumber": "7", | |
"votePercent": 1 | |
}, { | |
"electNumber": "8", | |
"votePercent": 16 | |
}, { | |
"electNumber": "10", | |
"votePercent": 4 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 2 | |
}, { | |
"electNumber": "41", | |
"votePercent": 25 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 1 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 16 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 18 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
"NDI": { | |
"nameGe": "NDI საქართველო", | |
"nameEn": "NDI Georgia", | |
"polled": 4113, | |
"pollDateGe": '8 ივნ - 6 ივლ.', | |
"pollDateEn": '8 jun - 6 jul.', | |
"type": "poll", | |
"source": "https://www.ndi.org/files/Public-Attitude-Findings-Georgian.pdf", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 4 | |
}, { | |
"electNumber": "3", | |
"votePercent": 0 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 14 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 4 | |
}, { | |
"electNumber": "10", | |
"votePercent": 0 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 0 | |
}, { | |
"electNumber": "41", | |
"votePercent": 19 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 7 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 8 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 38 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 13 | |
}] | |
}, | |
"imedi": { | |
"nameGe": "TV იმედი - GPM", | |
"nameEn": "TV Imedi - GPM", | |
"polled": 1199, | |
"pollDateGe": '27 სექ. - 3 ოქტ', | |
"pollDateEn": '27 sep - 3 oct.', | |
"type": "poll", | |
"source": "http://liberali.ge/news/view/25011/imedis-kvleva-qartuli-otsneba--36-ertiani-natsionaluri-modzraoba-13", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 2 | |
}, { | |
"electNumber": "3", | |
"votePercent": 2 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 13 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 2 | |
}, { | |
"electNumber": "10", | |
"votePercent": 3 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 4 | |
}, { | |
"electNumber": "41", | |
"votePercent": 36 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 2 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 36 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
"rustavi2": { | |
"nameGe": "რუსთავი2 - GFK", | |
"nameEn": "Rustavi2 - GFK", | |
"polled": global.defaultRespondentCountIfNotSpecified, | |
"pollDateGe": 'ოქტომბრის განმავლობაში', | |
"pollDateEn": 'during october', | |
"type": "poll", | |
"source": "http://factcheck.ge/article/qhvela-gamokithkhva-erthad-partiebis-tsinasaarchevno-reitingebi/", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 2.6 | |
}, { | |
"electNumber": "3", | |
"votePercent": 1.5 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 26 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0.7 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 1.5 | |
}, { | |
"electNumber": "10", | |
"votePercent": 3.8 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 3.6 | |
}, { | |
"electNumber": "41", | |
"votePercent": 25.4 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 0 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 35 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
"experts": { | |
"nameGe": "ექსპერტთა გამოკითხვა", | |
"nameEn": "Expert polls", | |
"polled": 0, | |
"pollDateGe": '22-29 სექ.', | |
"pollDateEn": '22-29 sep', | |
"source": "http://netgazeti.ge/news/144856/", | |
"type": "pointOfView", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 9 | |
}, { | |
"electNumber": "3", | |
"votePercent": 4 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 26 | |
}, { | |
"electNumber": "6", | |
"votePercent": 5 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 6 | |
}, { | |
"electNumber": "10", | |
"votePercent": 3 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 7 | |
}, { | |
"electNumber": "41", | |
"votePercent": 36 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 0 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 0 | |
}, { | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
/* | |
"test": { | |
"nameGe": "test", | |
"nameEn": "test", | |
"polled": 0, | |
"pollDateGe": '27 სექ. - 3 ოქტ', | |
"pollDateEn": '27 sep - 3 oct.', | |
"source": "", | |
"data": [{ | |
"electNumber": "1", | |
"votePercent": 0 | |
}, { | |
"electNumber": "3", | |
"votePercent": 0 | |
}, { | |
"electNumber": "4", | |
"votePercent": 0 | |
}, { | |
"electNumber": "5", | |
"votePercent": 0 | |
}, { | |
"electNumber": "6", | |
"votePercent": 0 | |
}, { | |
"electNumber": "7", | |
"votePercent": 0 | |
}, { | |
"electNumber": "8", | |
"votePercent": 0 | |
}, { | |
"electNumber": "10", | |
"votePercent": 0 | |
}, { | |
"electNumber": "14", | |
"votePercent": 0 | |
}, { | |
"electNumber": "19", | |
"votePercent": 0 | |
}, { | |
"electNumber": "23", | |
"votePercent": 0 | |
}, { | |
"electNumber": "25", | |
"votePercent": 0 | |
}, { | |
"electNumber": "26", | |
"votePercent": 0 | |
}, { | |
"electNumber": "27", | |
"votePercent": 0 | |
}, { | |
"electNumber": "41", | |
"votePercent": 0 | |
}, { | |
"electNumber": "sxva", | |
"votePercent": 0 | |
}, { | |
"electNumber": "aravis", | |
"votePercent": 0 | |
}, { | |
"electNumber": "argadamiwyvetia", | |
"votePercent": 0 | |
},{ | |
"electNumber": "uari", | |
"votePercent": 0 | |
}] | |
}, | |
*/ | |
} | |
function merge(poll) { | |
var data = poll.data; | |
data.forEach(function(d) { | |
d.party = global.partiesInfo[d.electNumber] | |
}) | |
/* | |
if(poll.type=='exitpoll' || poll.type=='results'){ | |
data = data.filter(function(d){ | |
return !isNaN(d.electNumber) | |
}) | |
} | |
*/ | |
return data; | |
} | |
/* | |
function addAverage(polls) { | |
var keys = Object.keys(polls); | |
var partiesInfoKeys = Object.keys(global.partiesInfo); | |
var total = 0 | |
keys.forEach(function(k) { | |
if (polls[k].type == "poll") total += polls[k].polled; | |
}); | |
polls.average.polled = total; | |
polls.average.data = partiesInfoKeys.map(function(pk, i) { | |
var poll = { | |
electNumber: pk, | |
}; | |
var voted = 0; | |
keys.forEach(function(k) { | |
if (polls[k].type == "poll") { | |
voted += polls[k].data[i].votePercent * polls[k].polled; | |
console.log(polls[k].data[i].electNumber == pk); // all output must be true | |
} | |
}) | |
poll.votePercent = voted / polls.average.polled; | |
return poll; | |
}) | |
} | |
*/ | |
function generateButtons(polls) { | |
var contact = ' <div class="contact"> </div>'; | |
var keys = Object.keys(polls); | |
var buttons = keys.map(function(key) { | |
var btnClass = " deep-purple lighten-2 "; | |
if (key == "average") btnClass = " teal darken-2 "; | |
if (key == "cesko") btnClass = " cesko-color " | |
if(polls[key].type=="exitpoll") btnClass=' blue lighten-1 '; | |
return "<br><button class=' waves-effect waves-light btn " + btnClass + key + "' onclick=\"global.transition(" + "'" + key + "'" + ")\">" + polls[key]['name' + global.currentLang] + "</button>"; | |
}).join(''); | |
set('.buttons', contact + buttons); | |
set('.contact', global.texts['contact' + global.currentLang]); | |
} | |
function set(selector, content) { | |
document.querySelector(selector).innerHTML = content; | |
} | |
function get(selector) { | |
return document.querySelector(selector); | |
} | |
function clear() { | |
set('#graphContent', ''); | |
set('.buttons', ''); | |
} | |
function gaugeText() { | |
d3.select('.c3-chart-arcs-gauge-min').text(global.texts['gaugeMin' + global.currentLang]).attr('transform', 'translate(25,0)'); | |
d3.select('.c3-chart-arcs-gauge-max').text(global.texts['gaugeMax' + global.currentLang]).attr('transform', 'translate(-25,0)'); | |
} | |
drawContent(); | |
extractDispersion() | |
drawGauge(); | |
</script> | |
</body> | |
</html> | |