data = {
const position = []
const cdata = []
const maxCO2 = d3.max(envData.filter(x => countries.features.some(f => f.properties.name === x.country)), x => +x.co2_per_capita)
for (const feature of countries.features) {
let coordinates;
if (feature.geometry.type == "Polygon") {
coordinates = feature.geometry.coordinates
} else if (feature.geometry.type == "MultiPolygon") {
coordinates = feature.geometry.coordinates[0]
} else {
throw `All elements must be polygons or multipolgyons. ${feature.geometry}`
}
const center = (() => {
const centers = coordinates.map(coords =>
[
d3.mean(coords, x => x[0]),
d3.mean(coords, x => x[1]),
]
)
return centers[0]
})();
position.push(polarToCartesian(center[0], center[1], 1.01))
position.push(polarToCartesian(center[0], center[1], 1.03))
position.push(polarToCartesian(center[0], center[1], 1.05))
position.push(polarToCartesian(center[0], center[1], 1.07))
const cenv = envData.filter(x => +x.year === year && x.country === feature.properties.name);
if (cenv.length > 0) {
const obs = cenv[cenv.length - 1];
const v = +obs.co2_per_capita;
const color = d3.color(interpolateColor(v))
cdata.push({
center,
value: v,
color: [color.r / 256, color.g / 256, color.b / 256],
})
}
}
const scale = d3.scaleQuantize()
.domain([0, 1])
.range(d3.range(1, 100))
return {
position: gl.regl.buffer(cdata.flatMap(x => {
const reps = scale(x.value)
return d3.range(0, reps + 1).map((_, rep) => polarToCartesian(x.center[0], x.center[1], 1 + 0.002 * rep))
})),
count: d3.sum(cdata, x => scale(x.value) + 1),
color: gl.regl.buffer(cdata.flatMap(x => {
const reps = scale(x.value)
return d3.range(0, reps + 1).map(() => x.color)
})),
}
return {
position: gl.regl.buffer(position),
color: gl.regl.buffer(position.map(([x, y, z], i) => ([Math.sin(x), Math.sin(y), Math.cos(z)]))),
count: position.length,
}
}