-
Notifications
You must be signed in to change notification settings - Fork 960
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9b89e8a
Showing
535 changed files
with
39,408 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
function isChrome() { | ||
// Snippet taken from: http://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome/13348618#13348618 | ||
// | ||
// please note | ||
// that IE11 now returns undefined again for window.chrome | ||
// and new Opera 30 outputs true for window.chrome | ||
// and new IE Edge outputs to true now for window.chrome | ||
// and if not iOS Chrome check | ||
// so use the below updated condition | ||
var isChromium = window.chrome, | ||
winNav = window.navigator, | ||
vendorName = winNav.vendor, | ||
isOpera = winNav.userAgent.indexOf("OPR") > -1, | ||
isIEedge = winNav.userAgent.indexOf("Edge") > -1, | ||
isIOSChrome = winNav.userAgent.match("CriOS"); | ||
|
||
if (isIOSChrome) { | ||
// is Google Chrome on IOS | ||
return true; | ||
} else if (isChromium !== null && isChromium !== undefined && vendorName === "Google Inc." && isOpera == false && isIEedge == false) { | ||
// is Google Chrome | ||
return true; | ||
} else { | ||
// not Google Chrome | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
function Co2eqCalculator() { | ||
// Node dependencies | ||
if (typeof require != 'undefined') { | ||
d3 = require('d3'); | ||
math = require('mathjs'); | ||
} | ||
|
||
this.defaultCo2eqFootprint = { | ||
'biomass': 740, | ||
'coal': 820, | ||
'gas': 490, | ||
'hydro': 24, | ||
'nuclear': 12, | ||
'oil': 650, | ||
'solar': 45, | ||
'wind': 12, | ||
}; // in gCo2eq/kWh | ||
|
||
this.countryCo2eqFootprint = { | ||
'DE': function (productionMode) { | ||
return productionMode == 'other' ? 700 : null; | ||
}, | ||
'DK': function (productionMode) { | ||
return productionMode == 'other' ? 700 : null; | ||
}, | ||
'FI': function (productionMode) { | ||
return productionMode == 'other' ? 700 : null; | ||
}, | ||
'GB': function (productionMode) { | ||
return productionMode == 'other' ? 300 : null; | ||
}, | ||
'NO': function (productionMode) { | ||
return productionMode == 'other' ? 700 : null; | ||
}, | ||
'SE': function (productionMode) { | ||
return productionMode == 'other' ? 700 : null; | ||
} | ||
}; | ||
|
||
this.footprintOf = function(productionMode, countryKey) { | ||
var defaultFootprint = this.defaultCo2eqFootprint[productionMode]; | ||
var countryFootprint = this.countryCo2eqFootprint[countryKey] || function () { }; | ||
return countryFootprint(productionMode) || defaultFootprint; | ||
}; | ||
|
||
this.compute = function(countries) { | ||
var validCountries = d3.entries(countries) | ||
.map(function(d) { return d.value.data }) | ||
.filter(function (d) { | ||
return d.countryCode !== undefined; | ||
}); | ||
var validCountryKeys = validCountries.map(function (d) { return d.countryCode }); | ||
|
||
// x_i: unknown co2 (consumption) footprint of i-th country | ||
// f_ij: known co2 footprint of j-th system of i-th country | ||
// v_ij: power volume of j-th system of i-th country | ||
// CO2 mass flow balance equation for each country i: | ||
// x_i * (sum_j_intern(v_ij) + sum_j_import(v_ij) - sum_j_export(v_ij)) = | ||
// sum_j_intern(f_ij * v_ij) | ||
// + sum_j_import(x_j * v_ij) | ||
// - x_i * sum_j_export(v_ij) | ||
|
||
// We wish to solve Ax = b | ||
var n = validCountries.length; | ||
var A = math.sparse().resize([n, n]); | ||
var b = math.zeros(n); | ||
|
||
var that = this; | ||
|
||
validCountries.forEach(function (country, i) { | ||
A.set([i, i], -country.totalProduction - country.totalNetExchange); | ||
// Intern | ||
d3.entries(country.production).forEach(function (production) { | ||
var footprint = that.footprintOf(production.key, country.countryCode); | ||
if (footprint === undefined) { | ||
console.warn(country.countryCode + ' CO2 footprint of ' + production.key + ' is unknown'); | ||
return; | ||
} | ||
// Accumulate | ||
b.set([i], b.get([i]) - footprint * production.value); | ||
}); | ||
// Exchanges | ||
d3.entries(country.exchange).forEach(function (exchange) { | ||
var j = validCountryKeys.indexOf(exchange.key); | ||
if (j < 0) { | ||
console.warn(country.countryCode + ' neighbor ' + exchange.key + ' has no data'); | ||
return; | ||
} | ||
if (exchange.value > 0) { | ||
// Import | ||
A.set([i, j], exchange.value); | ||
} else { | ||
// Accumulate export | ||
A.set([i, i], A.get([i, i]) - Math.abs(exchange.value)); | ||
} | ||
}); | ||
}); | ||
|
||
// Solve | ||
var x = math.lusolve(A, b); | ||
this.assignments = {}; | ||
x.toArray().forEach(function (x, i) { | ||
that.assignments[validCountries[i].countryCode] = x[0]; | ||
}); | ||
|
||
return this; | ||
} | ||
|
||
return this; | ||
} | ||
|
||
if (typeof module != 'undefined') | ||
module.exports = { | ||
Co2eqCalculator: Co2eqCalculator | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
function CountryMap(selector, co2color) { | ||
var that = this; | ||
|
||
this.STROKE_WIDTH = 0.3; | ||
|
||
this.selectedCountry = undefined; | ||
|
||
this.root = d3.select(selector); | ||
this.co2color = co2color; | ||
this.graticule = this.root | ||
.on('click', function (d, i) { | ||
if (that.selectedCountry !== undefined) { | ||
that.selectedCountry | ||
.style('stroke', 'black') | ||
.style('stroke-width', that.STROKE_WIDTH); | ||
} | ||
that.seaClickHandler.call(this, d, i); | ||
}) | ||
.append('path') | ||
.attr('class', 'graticule') | ||
this.land = this.root.append('g'); | ||
} | ||
|
||
CountryMap.prototype.render = function() { | ||
var computedMapWidth = this.root.node().getBoundingClientRect().width, | ||
computedMapHeight = this.root.node().getBoundingClientRect().height; | ||
|
||
this._projection = d3.geo.mercator() | ||
.center([3, 48]) | ||
.translate([0.6 * computedMapWidth, 0.6 * computedMapHeight]) | ||
.scale(700); | ||
|
||
this.path = d3.geo.path() | ||
.projection(this._projection); | ||
|
||
var graticuleData = d3.geo.graticule() | ||
.step([5, 5]); | ||
|
||
this.graticule | ||
.datum(graticuleData) | ||
.attr('d', this.path); | ||
|
||
var that = this; | ||
if (this._data) { | ||
var getCo2Color = function (d) { | ||
return (d.data.co2 !== undefined) ? that.co2color(d.data.co2) : 'gray'; | ||
}; | ||
var selector = this.land.selectAll('.country') | ||
.data(this._data); | ||
selector.enter() | ||
.append('path') | ||
.attr('class', 'country') | ||
.attr('stroke', 'black') | ||
.attr('stroke-width', that.STROKE_WIDTH) | ||
.attr('fill', getCo2Color) | ||
.on('mouseover', function (d, i) { | ||
return that.countryMouseOverHandler.call(this, d, i); | ||
}) | ||
.on('mouseout', function (d, i) { | ||
return that.countryMouseOutHandler.call(this, d, i); | ||
}) | ||
.on('click', function (d, i) { | ||
d3.event.stopPropagation(); // To avoid call click on sea | ||
if (that.selectedCountry !== undefined) { | ||
that.selectedCountry | ||
.style('stroke', 'black') | ||
.style('stroke-width', that.STROKE_WIDTH); | ||
} | ||
that.selectedCountry = d3.select(this); | ||
// that.selectedCountry | ||
// .style('stroke', 'darkred') | ||
// .style('stroke-width', 1.5); | ||
return that.countryClickHandler.call(this, d, i); | ||
}); | ||
selector | ||
.attr('d', this.path) | ||
.transition() | ||
.attr('fill', getCo2Color); | ||
} | ||
} | ||
|
||
CountryMap.prototype.projection = function(arg) { | ||
if (!arg) return this._projection; | ||
else this._projection = arg; | ||
return this; | ||
}; | ||
|
||
CountryMap.prototype.onSeaClick = function(arg) { | ||
if (!arg) return this.seaClickHandler; | ||
else this.seaClickHandler = arg; | ||
return this; | ||
}; | ||
|
||
CountryMap.prototype.onCountryClick = function(arg) { | ||
if (!arg) return this.countryClickHandler; | ||
else this.countryClickHandler = arg; | ||
return this; | ||
}; | ||
|
||
CountryMap.prototype.onCountryMouseOver = function(arg) { | ||
if (!arg) return this.countryMouseOverHandler; | ||
else this.countryMouseOverHandler = arg; | ||
return this; | ||
}; | ||
|
||
CountryMap.prototype.onCountryMouseOut = function(arg) { | ||
if (!arg) return this.countryMouseOutHandler; | ||
else this.countryMouseOutHandler = arg; | ||
return this; | ||
}; | ||
|
||
CountryMap.prototype.data = function(data) { | ||
if (!data) { | ||
return this._data; | ||
} else { | ||
this._data = data; | ||
} | ||
return this; | ||
}; |
Oops, something went wrong.