Public
Edited
May 15, 2023
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
sustainability = {
worldMap.select("#piecharts").remove()

let adjSize = 20;
const simulation = d3
.forceSimulation(data)
.force(
"x",
d3.forceX((d) => mapProjection([parseFloat(d[baseX]), parseFloat(d[baseY])])[0])
)
.force(
"y",
d3.forceY((d) => mapProjection([parseFloat(d[baseX]), parseFloat(d[baseY])])[1])
)
.force(
"collide",
d3.forceCollide(boxSize+1).strength(repulsionFactor)
)

const nodeG = worldMap.append("g")
.attr("id", "piecharts")
.attr("stroke", "white")
.attr("stroke-width", 0.5)
.selectAll("g")
.data(data)
.join("g")
.call(drag(simulation));

let colors = index === 'gdp' ? gdpColors: popnColors;

nodeG.append("g")
.each(function(node) {
// d3.select(this).append('g')
// .append("rect")
// .attr("stroke-width", 0.4)
// .attr("stroke", "#8F5601")
// .attr('fill', '#FFFCF6')
// .attr("width", boxSize * 2)
// .attr("height", boxSize * 2);

let linePoints = processDataEq(node);
console.log(linePoints[0]['val'] > linePoints[1]['val']);
d3.select(this).append('path')
.datum(linePoints)
.attr("stroke", d => d[2] > 0 ? 'green' : 'red')
.attr("stroke-width", stroke/1.4)
.attr("stroke-opacity", 1)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("d", lineP);

})

simulation.on("tick", () => {
nodeG.attr("transform", d => `translate(${d.x}, ${d.y})`)
});

invalidation.then(() => simulation.stop());

return worldMap.node();
}
Insert cell
Insert cell
gdpColors = ['#F19817', 'black']
Insert cell
popnColors = ['#005DAA', '#C9BBAE']
Insert cell
Insert cell

colorScaleP = {
let domain = index === 'gdp' ? [gdpColorDomain[0], 0, gdpColorDomain[1]] : popnColorDomain;
let scale = index === 'gdp' ? d3.scaleDivergingLog : d3.scaleLinear;
let range = index === 'gdp' ? d3.interpolateRdYlBu : d3.schemeBuPu;
let baseScale = index === 'gdp' ? scale().domain(domain).interpolator(range) : scale().domain(domain).range(range);
return baseScale
}
Insert cell
gdpColorDomain = {
let nodes = data.map(row => row['gdp_urban_2050_c'] - row['gdp_urban_2019']);
return d3.extent(nodes);
}
Insert cell
popnColorDomain = {
let nodes = data.map(row => row['urban_2050_c'] - row['urban_2019']);
return d3.extent(nodes);
}
Insert cell
Insert cell
Insert cell
baseX = 'lng'
Insert cell
baseY = 'lat'
Insert cell
Insert cell
yScaleP = {
let slopeP = index === 'gdp' ? gdpDomain : popnDomain;

if (scaleButton === 'log') {
return d3.scaleSymlog().range([0, boxSize*2]).domain(slopeP.reverse());
} else {
return d3.scaleLinear().range([0, boxSize*2]).domain(slopeP.reverse());
}
}
Insert cell
Insert cell
function processDataEq(node){
if (index === 'gdp') {
return [{year: 2019, val: node['gdp_urban_2019']}, {year: 2050, val: node['gdp_urban_2050_c']}, node['gdp_urban_2050_c'] - node['gdp_urban_2019']];
} else {
return [{year: 2019, val: node['urban_2019']}, {year: 2050, val: node['urban_2050_c']}, node['urban_2050_c'] - node['urban_2019']];
}

}
Insert cell
Insert cell
Insert cell
data[0]
Insert cell
new Set(data.filter(row => row['urban_2019'] > row['urban_2050_a']).map(row => row['Country']))
Insert cell
new Set(data.filter(row => row['gdp_2019'] > row['gdp_urban_2050_a']).map(row => row['Country']))
Insert cell
data = FileAttachment("urban-data-growth-gdpc-full.csv").csv({typed:true});
Insert cell
import {radio, slider} from "@jashkenas/inputs"
Insert cell
import {Swatches} from "@d3/color-legend"
Insert cell
import {activeColorScheme} from "b3a0a78984d6df2e"
Insert cell
import {worldMap, mapPath, mapProjection} from "b3a0a78984d6df2e"
Insert cell
import {legend, swatches} from "@d3/color-legend"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more