Public
Edited
Apr 22
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
map = d3.select(mapContainer)
Insert cell
projection = d3.geoNaturalEarth1()
Insert cell
mapLayers = {
let mapLayers = [];
mapLayers["countries"] = drawMapLayer(map,"countries",world.features,world.idField);
return mapLayers;
}
Insert cell
Insert cell
colorScale = d3.scaleLinear().domain([-25,0,25]).range(["red","gray","green"])
Insert cell
colorByID(mapLayers["countries"],gdp,"id","Country Code",year,'',colorScale)
Insert cell
Insert cell
sparkline = map.select("#sparkline").selectAll("line")
.data(gdp_pivot)
.join("line");
Insert cell
drawSparkline = (evt,d) => {
let thisCountryCode = d.id; // get the country code from the data of the moused-over item
let thisCountryName = "";
if (d.properties != null) {thisCountryName = d.properties.name} else {thisCountryName = d.name;}
sparkline.transition().duration(1000)
.attr("x1", d=>scaleX(+d.Year)).attr("y1",scaleY(0)) // 0 baseline of sparkline
.attr("x2", d=>scaleX(+d.Year)).attr("y2",d=>scaleY(+d[thisCountryCode])) // data value, up or down, from country
.style("stroke", d => +d[thisCountryCode] > 0 ? "green" : "red"); // color on positive or negative growth

map.select("#countryname")
.text(thisCountryName) // from the country object data passed in through the mouseover
.attr("x",10)
.attr("y",40);
}
Insert cell
Insert cell
{
mapLayers["countries"].on("mouseover",updateVisual);
treemap.selectAll("rect").on("mouseover", (evt,d) => updateVisual(evt,d.data))
sparkline.style("opacity", d => d.Year == year ? 1 : 0.25);
}
Insert cell
updateVisual = (evt,d) => {
mutable log = d; // this puts the data (d) value into the log above so we can watch it (useful for debugging too)
let countryID = d.id;
drawSparkline(evt,d);
mapLayers["countries"].style("stroke-width","");
mapLayers["countries"].filter(d => d.id == countryID).style("stroke-width","3px");
treemap.selectAll("rect").style("stroke-width","");
treemap.selectAll("rect").filter(d => d.data.id == countryID).style("stroke-width","3px");
}
Insert cell
Insert cell
Insert cell
scaleX = d3.scaleLinear().domain([1960,2011]).range([10,200]);
Insert cell
scaleY = d3.scaleLinear().domain([-20,20]).range([50,-50]);
Insert cell
Insert cell
Insert cell
treemapLayer = map.select("#treemap")
Insert cell
import {dvTreemap,layoutChildren} from "@emfielduva/dvlib_layout"
Insert cell
Insert cell
gdp_year = {
let newdata = [];
gdp.forEach(d => {
newdata.push({id:d["Country Code"],name: d["Country Name"],selYear:Number(d[year]),selYearABS:Math.abs(d[year])});
})
newdata.sort((a,b) => d3.descending(a.selYear,b.selYear));
return newdata;
}
Insert cell
Insert cell
treemap = {
let tmLayoutData = layoutChildren("gdp", gdp_year);
let treemap = dvTreemap(treemapLayer,tmLayoutData,150,250,"selYearABS");
treemap.selectAll("rect").style("fill", d => colorScale(d.data.selYear));
return treemap;
}
Insert cell
Insert cell
world = getMapData("world110m")
Insert cell
gdp = FileAttachment("world-gdp-growth.csv").csv()
Insert cell
gdp_pivot = FileAttachment("world-gdp-growth_pivot.csv").csv()
Insert cell
Insert cell
Insert cell
import {getMapData, drawMapLayer} with {projection} from "@emfielduva/dvlib_maps"
Insert cell
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