Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
corradio committed Nov 15, 2016
1 parent f9480ac commit 1589e58
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 109 deletions.
41 changes: 41 additions & 0 deletions api/static/app/countryconfig.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
function addCountriesConfiguration(countries) {
// Names
countries['AT'].fullname = 'Austria';
countries['BE'].fullname = 'Belgium';
countries['BG'].fullname = 'Bulgaria';
countries['BA'].fullname = 'Bosnia and Herzegovina';
countries['BY'].fullname = 'Belarus';
countries['CH'].fullname = 'Switzerland';
countries['CZ'].fullname = 'Czech Republic';
countries['DE'].fullname = 'Germany';
countries['DK'].fullname = 'Denmark';
countries['ES'].fullname = 'Spain';
countries['EE'].fullname = 'Estonia';
countries['FI'].fullname = 'Finland';
countries['FR'].fullname = 'France';
countries['GB'].fullname = 'United Kingdom';
countries['GR'].fullname = 'Greece';
countries['HR'].fullname = 'Croatia';
countries['HU'].fullname = 'Hungary';
countries['IE'].fullname = 'Ireland';
countries['IS'].fullname = 'Iceland';
countries['IT'].fullname = 'Italy';
countries['XK'].fullname = 'Kosovo';
countries['LT'].fullname = 'Lithuania';
countries['LU'].fullname = 'Luxembourg';
countries['LV'].fullname = 'Latvia';
countries['MD'].fullname = 'Moldova';
countries['MK'].fullname = 'Macedonia (FYROM)';
countries['ME'].fullname = 'Montenegro';
countries['NL'].fullname = 'Netherlands';
countries['NO'].fullname = 'Norway';
countries['PL'].fullname = 'Poland';
countries['PT'].fullname = 'Portugal';
countries['RO'].fullname = 'Romania';
countries['RU'].fullname = 'Russia';
countries['RS'].fullname = 'Serbia';
countries['SK'].fullname = 'Slovakia';
countries['SI'].fullname = 'Slovenia';
countries['SE'].fullname = 'Sweden';
countries['UA'].fullname = 'Ukraine';

// Capacities
countries['AT'].capacity = {
biomass: 393,
coal: 819,
Expand Down
6 changes: 2 additions & 4 deletions api/static/app/countrytable.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,8 @@ CountryTable.prototype.data = function(arg) {

// Set header
var header = d3.select('.country-table-header');
header.select('img.country-flag')
.attr('width', 4 * this.FLAG_SIZE_MULTIPLIER)
.attr('height', 3 * this.FLAG_SIZE_MULTIPLIER)
.attr('src', 'libs/flag-icon-css/flags/4x3/' + this._data.countryCode.toLowerCase() + '.svg')
header.select('i#country-flag')
.attr('class', 'flag-icon flag-icon-' + this._data.countryCode.toLowerCase())
header.select('span.country-name')
.text(this._data.countryCode);
header.select('span.country-last-update')
Expand Down
177 changes: 88 additions & 89 deletions api/static/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ var customDate;
function isMobile() {
return (/android|blackberry|iemobile|ipad|iphone|ipod|opera mini|webos/i).test(navigator.userAgent);
}
function isSmallScreen() {
// Should be in sync with media queries in CSS
return screen.width < 600;
}

function trackAnalyticsEvent(eventName, paramObj) {
if (window.location.href.indexOf("electricitymap") !== -1) {
Expand Down Expand Up @@ -118,28 +122,37 @@ d3.entries(exchanges).forEach(function(entry) {
console.error('Exchange sorted key pair ' + entry.key + ' is not sorted alphabetically');
});

function selectCountry(countryCode) {
if (!countryCode || !countries[countryCode]) {
// Unselected
d3.select('.country-table-initial-text')
.style('display', 'block');
countryTable.hide();
selectedCountryCode = undefined;
} else {
// Selected
console.log(countries[countryCode]);
trackAnalyticsEvent('countryClick', {countryCode: countryCode});
d3.select('.country-table-initial-text')
.style('display', 'none');
countryTable
.show()
.data(countries[countryCode]);
selectedCountryCode = countryCode;
}
if (isSmallScreen())
d3.select('#country-table-back-button').style('display',
selectedCountryCode ? 'block' : 'none');
}

// Mobile
if (isMobile()) {
if (isSmallScreen()) {
d3.select('.map').selectAll('*').remove();
d3.select('.legend').style('display', 'none');

function onSelectedCountryChange() {
var countryCode = d3.select('select.country-picker').node().value;
if (countries[countryCode]) {
d3.select('.country-table-initial-text')
.style('display', 'none');
countryTable
.show()
.data(countries[countryCode]);
selectedCountryCode = countryCode;
d3.select('select.country-picker').node().selectedIndex = 0;
}
}
d3.select('#country-table-back-button')
.on('click', function() { selectCountry(undefined); });
} else {
d3.select('.panel-container')
.style('width', 330);
d3.select('.country-picker')
.style('display', 'none');

// Attach event handlers
function windMouseOver(coordinates) {
Expand Down Expand Up @@ -181,7 +194,7 @@ function dataLoaded(err, state, solar, wind) {
return;
}

if (!isMobile()) {
if (!isSmallScreen()) {
if (wind) {
console.log('wind', wind);
var t_before = moment(wind.forecasts[0][0].header.refTime).add(wind.forecasts[0][0].header.forecastTime, 'hours');
Expand Down Expand Up @@ -283,38 +296,34 @@ function dataLoaded(err, state, solar, wind) {
});
console.log('countries', countries);

// Populate exchange pairs for arrows
d3.entries(state.exchanges).forEach(function(obj) {
var exchange = exchanges[obj.key];
if (!exchange) {
console.error('Missing exchange configuration for ' + obj.key);
return;
}
// Copy data
d3.keys(obj.value).forEach(function(k) {
exchange[k] = obj.value[k];
// Render country picker if we're on mobile
if (isSmallScreen()) {
var validCountries = d3.values(countries).filter(function(d) {
return d.production;
}).sort(function(x, y) {
return d3.ascending(x.fullname || x.countryCode, y.fullname || y.countryCode)
});
});
console.log('exchanges', exchanges);
var selector = d3.select('.country-picker-container p')
.selectAll('a')
.data(validCountries);
var enterA = selector.enter().append('a');
enterA
.attr('href', '#')
.append('i')
enterA
.append('text')
selector.select('text')
.text(function(d) { return ' ' + (d.fullname || d.countryCode); })
selector.select('i')
.attr('class', function(d) { return 'flag-icon flag-icon-' + d.countryCode.toLowerCase(); })
selector.on('click', function(d) { return selectCountry(d.countryCode); });
}

// Render country map
countryMap
.data(d3.values(countries))
.onSeaClick(function () {
d3.select('.country-table-initial-text')
.style('display', 'block');
countryTable.hide();
selectedCountryCode = undefined;
})
.onCountryClick(function (d, i) {
console.log(d);
trackAnalyticsEvent('countryClick', {countryCode: d.countryCode});
d3.select('.country-table-initial-text')
.style('display', 'none');
countryTable
.show()
.data(d);
selectedCountryCode = d.countryCode;
})
.onSeaClick(function () { selectCountry(undefined); })
.onCountryClick(function (d) { selectCountry(d.countryCode); })
.onCountryMouseOver(function (d) {
d3.select(this)
.style('opacity', 0.8)
Expand All @@ -331,8 +340,8 @@ function dataLoaded(err, state, solar, wind) {
tooltip
.style('left', (d3.event.pageX - w - 5) + 'px')
.style('top', (d3.event.pageY - h - 5) + 'px');
tooltip.select('img.country-flag')
.attr('src', 'libs/flag-icon-css/flags/4x3/' + d.countryCode.toLowerCase() + '.svg');
tooltip.select('i.country-flag')
.attr('class', function(d) { return 'flag-icon flag-icon-' + d.countryCode.toLowerCase(); })
tooltip.select('.country-emission-rect')
.style('background-color', d.co2intensity ? co2color(d.co2intensity) : 'gray');
tooltip.select('.country-emission-intensity')
Expand All @@ -349,11 +358,26 @@ function dataLoaded(err, state, solar, wind) {
})
.render();

// Update country table if it is visible
if (selectedCountryCode)
countryTable.data(countries[selectedCountryCode]).render()
// Render country table if it already was visible
if (selectedCountryCode)
countryTable.data(countries[selectedCountryCode]).render()

if (!isSmallScreen()) {
// Populate exchange pairs for arrows
d3.entries(state.exchanges).forEach(function(obj) {
var exchange = exchanges[obj.key];
if (!exchange) {
console.error('Missing exchange configuration for ' + obj.key);
return;
}
// Copy data
d3.keys(obj.value).forEach(function(k) {
exchange[k] = obj.value[k];
});
});
console.log('exchanges', exchanges);

if (!isMobile())
// Render exchanges
exchangeLayer
.data(d3.values(exchanges))
.projection(countryMap.projection())
Expand All @@ -376,16 +400,16 @@ function dataLoaded(err, state, solar, wind) {
tooltip.select('.country-emission-rect')
.style('background-color', d.co2intensity ? co2color(d.co2intensity) : 'gray');
var i = d.netFlow > 0 ? 0 : 1;
tooltip.select('span.from')
tooltip.select('span#from')
.text(d.countryCodes[i]);
tooltip.select('span.to')
tooltip.select('span#to')
.text(d.countryCodes[(i + 1) % 2]);
tooltip.select('span.flow')
tooltip.select('span#flow')
.text(Math.abs(Math.round(d.netFlow)));
tooltip.select('img.from')
.attr('src', 'libs/flag-icon-css/flags/4x3/' + d.countryCodes[i].toLowerCase() + '.svg');
tooltip.select('img.to')
.attr('src', 'libs/flag-icon-css/flags/4x3/' + d.countryCodes[(i + 1) % 2].toLowerCase() + '.svg')
tooltip.select('i#from')
.attr('class', 'flag-icon flag-icon-' + d.countryCodes[i].toLowerCase());
tooltip.select('i#to')
.attr('class', 'flag-icon flag-icon-' + d.countryCodes[(i + 1) % 2].toLowerCase());
})
.onExchangeMouseOut(function (d) {
d3.select(this)
Expand All @@ -397,6 +421,7 @@ function dataLoaded(err, state, solar, wind) {
.style('display', 'none');
})
.render();
}

d3.select('.loading')
.transition()
Expand Down Expand Up @@ -457,40 +482,14 @@ function fetchAndReschedule() {
document.getElementById('connection-warning').className = "show";
}, 15 * 1000);
var Q = queue()
if (isMobile()) {
if (isSmallScreen()) {
Q
.defer(d3.json, ENDPOINT + '/v1/state');
if (d3.select('.country-table-initial-text').style() != 'none') {
Q.defer(geolocaliseCountryCode);
}
Q.await(function(err, state, countryCode) {
Q.defer(geolocaliseCountryCode);
Q.await(function(err, state, geolocalisedCountryCode) {
handleConnectionError(err);
if (!err) {
dataLoaded(err, state.data);
if (d3.select('.country-table-initial-text').style() != 'none') {
if (countryCode && countries[countryCode] ) {
// Select one country
d3.select('.country-table-initial-text')
.style('display', 'none');
countryTable
.show()
.data(countries[countryCode]);
} else {
// Show picker
var countryCodes = d3.entries(countries)
.filter(function (d) { return d.value.production; })
.map(function (d) { return d.key; });
countryCodes.unshift('< press to select >');
var countryOptions = d3.select('select.country-picker')
.selectAll('option')
.data(countryCodes);
countryOptions.enter()
.append('option');
countryOptions
.text(function(d) { return d });
countryOptions.exit().remove();
}
}
}
setTimeout(fetchAndReschedule, REFRESH_TIME_MINUTES * 60 * 1000);
});
Expand All @@ -510,7 +509,7 @@ function fetchAndReschedule() {

function redraw() {
countryTable.render();
if (!isMobile()) {
if (!isSmallScreen()) {
countryMap.render();
co2Colorbar.render();
windColorbar.render();
Expand Down
35 changes: 22 additions & 13 deletions api/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<title>Electricity Map | Real-time CO2 emissions of the European electricity production</title>

<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="libs/flag-icon-css/css/flag-icon.min.css">
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">

<script src="libs/d3.v3.min.js"></script>
Expand Down Expand Up @@ -111,7 +112,7 @@
<svg class="map sea"></svg>
<canvas class="map wind"></canvas>
<!-- <canvas class="map solar"></canvas> -->
<div class="legend">
<div class="legend large-screen-visible">
<div class="co2-legend">
<span class="colorbar-unit">Carbon intensity (gCO2eq/kWh)</span>
<svg class="co2-colorbar"></svg>
Expand All @@ -123,12 +124,15 @@
</div>
<div class="content">
<div class="panel panel-container">
<h1 style="line-height: 1.3; color: white; font-size: 1.6em; padding-bottom: 15px;
border-bottom: solid grey 1px; margin-top: 0px;">
<h1>
Real-time CO2 emissions of the European electricity production
</h1>
<p>
<span id="country-table-back-button" style="display: none" class="small-screen-visible"><a href="#"><< back</a></span>
</p>
<hr />
<div class="country-table-header" style="display: none">
<img class="country-flag">
<i id="country-flag"></i>
<b>
<span class="country-name"></span>
</b>
Expand All @@ -142,15 +146,20 @@
</div>
<svg class="country-table" style="display: none"></svg>
<div class="country-table-initial-text">
This map shows in real-time <span style="color: lightgray">where your electricity comes from</span> and <span style="color: lightgray">how much CO2</span> was emitted to produce it.<br />
It takes into account electricity <span style="color: lightgray">imports and exports</span> of each country.
<!--The map also shows renewable resources like wind and sun.--><br />
<br />
<span style="color: lightgray; font-size: 14px; color: white;"><i>Tip: Click on a country to start exploring ⟶</i></span><br />
<div class="country-picker-container" style="text-align: center">
<select class="country-picker" onchange="onSelectedCountryChange();"></select>
<p>
This shows in real-time <span style="color: lightgray">where your electricity comes from</span> and <span style="color: lightgray">how much CO2</span> was emitted to produce it.<br />
We take into account electricity <span style="color: lightgray">imports and exports</span> of each country.
<!--The also shows renewable resources like wind and sun.-->
</p>
<p class="small-screen-visible" style="font-style: italic">
You're currently seeing a <span style="color: lightgray">limited mobile version</span>. For the <span style="color: lightgray">full experience</span>, visit this page on your computer.
</p>
<p>
<span style="color: lightgray; font-size: 14px; color: white;"><i>Tip: Click on a country to start exploring ⟶</i></span>
</p>
<div class="country-picker-container small-screen-visible" style="margin-left: 20px">
<p></p>
</div>
<br />
Like the map? <a href="https://docs.google.com/forms/d/e/1FAIpQLSc-_sRr3mmhe0bifigGxfAzgh97-pJFcwpwWZGLFc6vvu8laA/viewform?c=0&w=1" target="_blank">We would love to hear your feedback</a>!<br />
Found bugs or have ideas? Report them <a href="https://github.com/corradio/electricitymap/issues/new" target="_blank">here</a>.<br />
<br />
Expand Down Expand Up @@ -184,7 +193,7 @@
</div>
<div id="exchange-tooltip" class="tooltip panel">
Cross-border export:<br />
<img class="from country-flag"></img> <span class="from"></span><img class="to country-flag"></img> <span class="to"></span>: <span class="flow"></span> MW
<i id="from"></i> <span id="from"></span><i id="to"></i> <span id="to"></span>: <span id="flow"></span> MW
</div>
</body>

Expand Down
Loading

0 comments on commit 1589e58

Please sign in to comment.