xxxxxxxxxx
<html>
<head>
<meta charset='utf-8'>
<title>Electricity Energy Sources of EU27</title>
<style>
html, body {
height: 100%;
}
html {
display: table;
margin: auto;
}
body {
display: table-cell;
vertical-align: middle;
font-size: 12px;
font-family: 'Helvetica Neue', Helvetica, Arial, Sans-serif;
}
.breakdownGroupsTexts {
z-index: 1.0;
}
</style>
</head>
<body style='background: #F9F9F9'>
<h1>EU 2014 Electricity Generation by Member State and Source</h1>
<p>Hover over bars to see breakdown of electricity source</p>
</body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var euData =`Country;CountryCode;Year;Electricity source;Biomass and Waste;Coal;Gas;Geothermal;Hydroelectric;Nuclear;Oil;Solar Tide Wave;Wind
Austria;AT;2014;;6.92000007629395;5.30999994277954;7.88000011444092;0;39.5499992370605;0;0.689999997615814;0.569999992847443;3.74000000953674
Belgium;BE;2014;;6.17000007629395;5.98000001907349;16.7600002288818;0;0.270000010728836;32.0900001525879;0.0700000002980232;3;4.42000007629395
Bulgaria;BG;2014;;0.0299999993294477;22.75;1.54999995231628;0;4.34999990463257;15.8599996566772;0.119999997317791;1.41999995708466;1.3400000333786
Cyprus;CY;2014;;0;0;0;0;0;0;4.17000007629395;0;0.180000007152557
Czech Republic;CZ;2014;;4.92000007629395;41.1699981689453;1.24000000953674;0;2.05999994277954;28.6299991607666;0.0700000002980232;2.09999990463257;0.469999998807907
Denmark;DK;2014;;5.19999980926514;10.3599996566772;3.21000003814697;0;0.00999999977648258;0;0.349999994039536;0.589999973773956;13.1099996566772
Estonia;EE;2014;;1.03999996185303;9.98999977111816;0.119999997317791;0;0.0199999995529652;0;0.0500000007450581;0;0.649999976158142
Finland;FI;2014;;10.8199996948242;10.3000001907349;0;0;13.2200002670288;22.6499996185303;2.5;0;1.12000000476837
France;FR;2014;;7.61999988555908;17.3999996185303;16.3500003814697;0.219999998807907;62.1699981689453;415.899993896484;3.01999998092651;6.61999988555908;16.8899993896484
Germany;DE;2014;;44.25;259.339996337891;59.310001373291;0;17.1299991607666;91.7799987792969;8.89000034332275;33.8800010681152;57.9500007629395
Greece;GR;2014;;0.310000002384186;24.4799995422363;7.51999998092651;0;4.28000020980835;0;4.13000011444092;2.30999994277954;4.21000003814697
Hungary;HU;2014;;1.98000001907349;5.75;7.30000019073486;6.07000017166138;0.28999999165535;14.7700004577637;0.150000005960464;0;0.709999978542328
Ireland;IE;2014;;1.3400000333786;5.19000005722046;0;7.30999994277954;0.860000014305115;0;0.449999988079071;0;6.07999992370605
Italy;IT;2014;;16.3199996948242;38.2599983215332;105.519996643066;0;54.7200012207031;0;17.5599994659424;24.6599998474121;15.1499996185303
Latvia;LV;2014;;0.300000011920929;0;2.04999995231628;0;2.79999995231628;0;0;0;0.129999995231628
Lithuania;LT;2014;;0.379999995231628;0;2.89000010490417;0;0.379999995231628;0;0.209999993443489;0;0.810000002384186
Luxembourg;LU;2014;;0.119999997317791;0;1.86000001430511;0;0.0900000035762787;0;0;0.0299999993294477;0.0900000035762787
Malta;MT;2014;;0;0;0;0;0;0;2.04999995231628;0;0
Netherlands;NL;2014;;5.75;28.8700008392334;45.5200004577637;0;0.109999999403954;3.86999988555908;1.07000005245209;0.610000014305115;7.1100001335144
Poland;PL;2014;;13.8400001525879;125.849998474121;5.61999988555908;0.150000005960464;2.25999999046326;0;1.95000004768372;0;5.61999988555908
Portugal;PT;2014;;3.19000005722046;10.7399997711182;8.3100004196167;0;15.1099996566772;0;2.25;0.649999976158142;19.1100006103516
Romania;RO;2014;;0.109999999403954;18.4500007629395;6.78000020980835;0;14.8699998855591;10.7399997711182;0.699999988079071;0;0
Slovakia;SK;2014;;0.720000028610229;3.39000010490417;3.25;0;3.90000009536743;14.4200000762939;0.509999990463257;0.360000014305115;0
Slovenia;SI;2014;;0.270000010728836;4.98999977111816;0.519999980926514;0;4.48999977111816;6.05999994277954;0;0.25;0
Spain;ES;2014;;4.96999979019165;37.8199996948242;68.9300003051758;0;39.1699981689453;54.8300018310547;14.7200002670288;14.1400003433228;79.5100021362305
Sweden;SK;2014;;11.9700002670288;1.74000000953674;1.6599999666214;0;64.0400009155273;62.2900009155273;1.05999994277954;0.0500000007450581;10.1599998474121
United Kingdom;GB;2014;;21.7099990844727;100.919998168945;92.3099975585938;0.5;5.8600001335144;57.9099998474121;3.32999992370605;3.91000008583069;24.3600006103516`
//Helper functions :
/******************************************************************************/
function relax() {
var labels = d3.selectAll('.breakdownTexts')
var lines = d3.selectAll('.breakdownLines')
var alpha = 0.02;
var spacing = 10;
var again = false;
labels.each(function (d, i) {
var a = this;
var da = d3.select(a);
var y1 = da.attr('dy');
labels.each(function (d, j) {
var b = this;
if (a == b)
return ;
var db = d3.select(b);
var y2 = db.attr('dy');
var deltaY = y1 - y2;
if (Math.abs(deltaY) > spacing) {
return ;
}
again = true;
var sign = deltaY > 0 ? 1 : -1;
var adjust = sign * alpha;
da.attr('dy', +y1 + adjust);
db.attr('dy', +y2 - adjust);
if (again) {
lines.attr('y2', function (d, i) {
var ref = d3.select('#bdt_' + d.source.replace(/ /g,''))
return (+ref.attr('y') + +ref.attr('dy') - 5)
})
setTimeout(relax, 20)
}
})
})
}
/******************************************************************************/
var scsv = d3.dsvFormat(';');
euData = scsv.parse(euData);
var width = 1000,
height = 500,
margin = {
top : 100,
bottom : 100,
left : 30,
right : 200
},
colorPalette = {
'Biomass and Waste' : '#7ee081',
'Coal' : '#313b72',
'Gas' : '#f9c80e',
'Geothermal' : '#157a6e',
'Hydroelectric' : '#087e8b',
'Nuclear' : '#7b287d',
'Oil' : '#db324d',
'Wind' : '#b3b5bb'
},
horizontalPadding = margin.left + margin.right;
verticalPadding = margin.top + margin.bottom;
euData.forEach(function (country) {
var total =
+country['Biomass and Waste'] +
+country['Coal'] +
+country['Gas'] +
+country['Geothermal'] +
+country['Hydroelectric'] +
+country['Nuclear'] +
+country['Oil'] +
+country['Solar Tide Wave'] +
+country['Wind'];
country.total = total;
});
var svg = d3.select('body')
.append('svg')
.attr('width', width + horizontalPadding)
.attr('height', height + verticalPadding);
var normScale = d3.scaleLinear()
.domain([0, 101])
.range([height, 0 ]);
var xScale = d3.scaleBand()
.domain(euData.map(function (d) {
return (d.CountryCode);
}))
.range([0, width])
.padding(0.1);
var yScale = d3.scaleLinear()
.domain([0, 50 + d3.max(euData, function (d) {
return (d.total);
})])
.range([height, 0]);
var g = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var tempG = svg.append('g')
.attr('class', 'transformGroup')
.attr('x', '0')
.attr('y', '0')
.attr('width', width + horizontalPadding)
.attr('height', height + verticalPadding)
g.append('g')
.attr('class', 'xAxis')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(xScale));
g.append('g')
.attr('class', 'yAxis')
.call(d3.axisLeft(yScale).ticks(10))
.attr('transform', 'translate(0,' + 0 +')')
.append('text')
.attr('transform', 'rotate(-90), translate(' + width / 2 + ',' + height - 200 + ')')
.text('Terawatt Hours (TWh)')
.attr('fill', 'black')
.attr('fill-opacity', 1.0)
.attr('dx', 80)
.attr('dy', '-10')
.style('opacity', 1.0)
.style('background-color', 'rgba(255, 255, 255, 0.5)')
var rects = svg.selectAll('rect')
.data(euData)
.enter()
.append('rect')
.attr('class', 'unselected')
//Don't add margins here :(
.attr('x', function (d) {
return (xScale(d.CountryCode) + margin.left);
})
.attr('rx', '2')
.attr('fill', 'white')
.attr('stroke', 'black')
.attr('width', xScale.bandwidth())
.on('mouseover', hover)
.on('mouseout', offHover);
rects.transition()
.duration(2000)
.delay(function (d, i) {
return (yScale(d.total));
})
.attr('y', function (d) {
return (yScale(d.total) + margin.top);
})
.attr('height', function (d) {
return (height - yScale(d.total));
})
function hover(hData, i) {
var hovGlob = d3.select(this);
hovGlob.attr('class', 'selected')
var percentagePerSource = [];
var rectsToDim = svg.selectAll(".unselected").attr('opacity', '0.2')
Object.keys(hData).forEach(function (key) {
if (key != 'CountryCode' && key != 'Country' &&
key != 'Electricity source' && key != 'Year' && key != 'total') {
var percent = (100 * hData[key] / hData.total).toFixed(2);
if (percent > 0.0000000) {
percentagePerSource.push({
source : key,
percent : percent
});
}
}
});
var byPercent = percentagePerSource.slice(0);
percentagePerSource = byPercent.sort(function(a, b) {
return (b.percent - a.percent);
});
function spaceOut() {
var hites = [];
var yz = [];
var addPoint = 0;
tempG.selectAll('rect').each(function(d, i) {
yz.push(+d3.select(this).attr('y'));
hites.push(+d3.select(this).attr('height'));
});
tempG.selectAll('rect').each(function(d, i) {
if (i == 0)
;
else {
var hereSay = d3.select(this);
addPoint = yz[i - 1] - hites[i];
yz[i] = addPoint;
// hereSay.attr('y', yz[i])
hereSay.attr('y', addPoint)
}
})
}
function dissappear() {
hovGlob
.attr('stroke-opacity', '0')
.attr('fill-opacity', '0');
var breakdownGroup = tempG.selectAll('rect')
.data(percentagePerSource)
.enter()
.append('g')
.attr('class', 'breakdownGroup')
breakdownGroup
.append('rect')
.attr('class', 'sourceRects')
.attr('id', function (d) {
return ('bdr_' + d.source.replace(/ /g,''))
})
.attr('rx', '2')
.attr('stroke-opacity', '1')
.attr('stroke', 'white')
.attr('fill', function(d) {
return (colorPalette[d.source])
})
.attr('width', xScale.bandwidth())
.attr('y', function (d) {
return (normScale(d.percent) + margin.bottom);
})
.attr('x', function (d, i) {
return (hovGlob.attr('x'));
})
.attr('height', function (d) {
return (height - normScale(d.percent));
})
.call(spaceOut)
textLabels = breakdownGroup
.append('text')
.attr('class', 'breakdownTexts')
.attr('id', function (d) {
return ('bdt_' + d.source.replace(/ /g,''))
})
.text(function(d, i) {
return (d.source + ' - ' + d.percent + '%')
})
.attr('x', function (d, i) {
return (d3.select('#bdr_' + d.source.replace(/ /g,'')).attr('x'))
})
.attr('y', function (d, i) {
return (d3.select('#bdr_' + d.source.replace(/ /g,'')).attr('y'))
})
.attr('dx', function (d, i) {
return (+d3.select('#bdr_' + d.source.replace(/ /g,'')).attr('width') + 5)
})
.attr('dy', function (d, i) {
return (d3.select('#bdr_' + d.source.replace(/ /g,'')).attr('height') / 2)
})
.attr('fill', 'black')
.attr('fill-opacity', 1.0)
.style('opacity', 1.0)
.style('background-color', 'rgba(255, 255, 255, 0.5)')
breakdownGroup
.append('line')
.attr('class', 'breakdownLines')
.attr('stroke', 'black')
.attr('stroke-width', '1px')
.attr('fill', 'black')
.attr('x1', function (d) {
var ref = d3.select('#bdr_' + d.source.replace(/ /g,''))
return (+ref.attr('x') + +ref.attr('width'))
})
.attr('y1', function (d) {
var ref = d3.select('#bdr_' + d.source.replace(/ /g,''))
return (+ref.attr('y') + +ref.attr('height') / 2)
})
.attr('x2', function (d) {
var ref = d3.select('#bdt_' + d.source.replace(/ /g,''))
return (+ref.attr('x') + +ref.attr('dx') - 3)
})
.attr('y2', function (d) {
var ref = d3.select('#bdt_' + d.source.replace(/ /g,''))
return (+ref.attr('y') + +ref.attr('dy'))
})
relax()
}
d3.select(this)
.transition()
.duration(500)
.attr('y', margin.top)
.attr('height', height)
.on('end', dissappear);
}
function offHover(d, i) {
d3.select(this).attr('class', 'unselected')
var rectsToDim = svg.selectAll(".unselected")
.attr('opacity', '1.0')
d3.selectAll('.breakdownGroup').remove()
tempG.selectAll('.sourceRects').remove()
.transition(200);
d3.select(this)
.attr('fill', 'white')
.attr('stroke-opacity', '1')
.transition()
.duration(900)
.attr('fill-opacity', '1')
.attr('y', function (d) {
return (yScale(d.total) + margin.top);
})
.attr('height', function (d) {
return (height - yScale(d.total));
})
}
</script>
</html>
https://d3js.org/d3.v4.min.js