D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
dgaitsgo
Full window
Github gist
EU 2014 Electricity Generation by Member State and Source
<!DOCTYPE html> <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