Published
Edited
Apr 15, 2021
Comments locked
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
viewof xMetric = select({
title: "Select World Development Indicator for x-axis:",
// description: "Select COVID-19 metric for y-axis.",
options: devIndicatorMetrics,
value: "Adjusted net national income per capita (constant 2010 US$) [NY.ADJ.NNTY.PC.KD]"
})
Insert cell
viewof yMetric = select({
title: "Select BP Energy Outlook metric for y-axis:",
options: covidMetrics,
value: "Energy intensity level of primary energy (MJ/$2011 PPP GDP) [EG.EGY.PRIM.PP.KD]"
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
echartOption = ({
backgroundColor: '#EDF2F7',
title: {
text: `${xMetric.split(" [")[0]} &\n${yMetric} by Country`,
padding: [0, 5]
},
legend: {
top: 35,
data: Object.keys(echartsSeries)
},
xAxis: {
nameLocation: 'center',
name: xMetric.split(' [')[0],
nameTextStyle: {
lineHeight: 25,
}
},
yAxis: {
nameLocation: 'center',
nameGap: 20,
name: yMetric
},
tooltip: {
showDelay: 0,
formatter: params => params.data[3] ? `<b>${params.data[3]}</b>
<div>Population: ${params.data[2]}</div>
<div>${xMetric.split(' [')[0]}: ${params.data[0]}</div>
<div>${yMetric}: ${params.data[1]}</div>
` : ''
},
toolbox: {
show: true,
feature: {
dataZoom: {
title: {
zoom: 'area zooming',
back: 'restore area zooming'
}
},
saveAsImage: { title: 'save as image' }
}
},
dataZoom: [
{
id: 'dataZoomY',
type: 'slider',
yAxisIndex: [0],
showDataShadow: false,
left: '92%',
width: '15px'
},
{
id: 'dataZoomX',
type: 'slider',
xAxisIndex: [0],
showDataShadow: false,
height: '15px',
top: '97%'
}
],
series: Object.keys(echartsSeries).map(continent => ({
name: continent,
data: echartsSeries[continent],
markLine: {
silent: true,
data: scatterStyling.includes('change') ? echartsMarklines[continent] : []
},
type: 'scatter',
cursor: 'default',
symbolSize: data => scatterStyling.includes('size') ? Math.sqrt(data[2]) / 5e2 : 5,
hoverAnimation: false,
itemStyle: {
color: scatterStyling.includes('colour') ? undefined : '#000000'
},
label: {
show: true,
position: 'right',
formatter: param => param.data[3]
}
}))
});
Insert cell
echartsInitialised = {
echarts.init(chartContainer).setOption(echartOption);
return true;
};
Insert cell
echartsMarklines = {
const echartsMarklines = {};
mergedSpreadsheetData.forEach(row => {
if (row.Continent_Name && row[xMetric] !== "..") {
const prevRow = mergedSpreadsheetDataPrevWeek.find(pwr => pwr.Three_Letter_Country_Code === row.Three_Letter_Country_Code);
if (prevRow) {
const echartsRow = [{
symbolSize: 6,
symbol: 'diamond',
coord: [ parseFloat(row[xMetric]), parseFloat(prevRow[yMetric]) ]
},
{
symbolSize: 6,
// symbol: 'none',
coord: [parseFloat(row[xMetric]) , parseFloat(row[yMetric]) ]
}];

echartsMarklines[row.Continent_Name]
? echartsMarklines[row.Continent_Name].push(echartsRow)
: echartsMarklines[row.Continent_Name] = [echartsRow];
}
}
});
return echartsMarklines;
};
Insert cell
echartsSeries = {
const echartsSeries = {};
mergedSpreadsheetData.forEach(row => {
if (row.Continent_Name && row[xMetric] !== '..') {
const echartsRow = [
parseFloat(row[xMetric]), // x-axis
parseFloat(row[yMetric]), // y-axis
row['Population (2019)'], // size
row['Countries and Territories'].replace(/_/g, ' ') // label
];
echartsSeries[row.Continent_Name]
? echartsSeries[row.Continent_Name].push(echartsRow)
: echartsSeries[row.Continent_Name] = [echartsRow];
}
});
return echartsSeries;
};
Insert cell
Insert cell
devIndicatorMetrics = {
const emptyMetricCount = {};
const filteredDevIndicatorMetrics = [];
const allDevIndicatorMetrics = Object.keys(mergedSpreadsheetData[0]).slice(12);
mergedSpreadsheetData.forEach(d => {
allDevIndicatorMetrics.forEach(m => {
emptyMetricCount[m] = emptyMetricCount[m] ? emptyMetricCount[m] : 0
if (d[m] === "..") {
emptyMetricCount[m] = emptyMetricCount[m] + 1;
}
})
})
allDevIndicatorMetrics.forEach(m => {
if (emptyMetricCount[m] <= 100) {
filteredDevIndicatorMetrics.push(m);
}
})
return filteredDevIndicatorMetrics;
};
Insert cell
covidMetrics = Object.keys(mergedSpreadsheetData[0]).slice(10,13);
Insert cell
covidMetricsDefinitions = {
const defs = {}
defs["Sum of COVID-19 cases"] = "Total of recorded cases of Covid-19";
defs["Sum of COVID-19 related deaths"] = "Total of recorded deaths related to Covid-19";
defs["Sum of COVID-19 cases per million inhabitants"] = "Total of recorded cases of Covid-19 divided by inhabitants and multiplied by 1,000,000. Note that countries with less than one million inhabitants are also included";
defs["Sum of COVID-19 related deaths per million inhabitants"] = "Total of Covid-19 related deaths divided by inhabitants and multiplied by 1,000,000. Note that countries with less than one million inhabitants are also included";
defs["COVID-19 related deaths per COVID-19 Case"] = "Ratio of Total of recorded cases of Covid-19 and recorded deaths related to Covid-19 to date. This ratio should not be interpreted as a nation's fatality rate and should be taken with a grain of salt, since the pandemic is still ongoing and the availablility of testing and accuracy of recorded cases is different for each country";
return defs;
};
Insert cell
Insert cell
mergedSpreadsheetData = d3.csvParse(
await FileAttachment("blog2019@1.csv").text(),
d3.autoType
).map(row => {
const countryInfo = countryMetaData.find(cmd =>
cmd["Three_Letter_Country_Code"] === row["Country Code"]
);
return {
...countryInfo,
...row
};
});
Insert cell
mergedSpreadsheetDataPrevWeek = d3.csvParse(
await FileAttachment("blog2018@4.csv").text(),
d3.autoType
).map(row => {
const countryInfo = countryMetaData.find(cmd =>
cmd["Three_Letter_Country_Code"] === row["Country Code"]
);
return {
...countryInfo,
...row
};
});
Insert cell
devIndicatorMetadata = d3.csvParse(
await FileAttachment("coal_meta@1.csv").text(),
d3.autoType
);
Insert cell
countryMetaData = d3.csvParse(
await FileAttachment("country-and-continent-codes-list-csv_csv.txt").text(),
d3.autoType
);
Insert cell
Insert cell
echarts = require("https://cdn.jsdelivr.net/npm/echarts@4.7.0/dist/echarts.min.js")
Insert cell
import { select, checkbox } from "@jashkenas/inputs";
Insert cell
d3 = require("d3@5")
Insert cell
Insert cell
_mergedSpreadsheetData = {
const url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vT3VoiA9l4A9Men0BY4y0BA8HiCAkKOdplzWTJ_DsKyfTk9Ex_YbaRB3tcAbiYG-rIce3Dj0vINwP8f/pub?gid=144603776&single=true&output=csv"
let spreadsheetData;
const spreadsheet = await d3.csv(url).then(data => {
spreadsheetData = [ ... data ];
});
return spreadsheetData.map(row => {
const countryInfo = countryMetaData.find(cmd => cmd["Three_Letter_Country_Code"] === row["Country Code"]);
return {
...countryInfo,
...row
};
});
};
Insert cell
_devIndicatorMetadata = {
const url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vT3VoiA9l4A9Men0BY4y0BA8HiCAkKOdplzWTJ_DsKyfTk9Ex_YbaRB3tcAbiYG-rIce3Dj0vINwP8f/pub?gid=125150895&single=true&output=csv"
let spreadsheetData;
const spreadsheet = await d3.csv(url).then(data => {
spreadsheetData = [ ... data ];
});
return spreadsheetData;
};
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