Published
Edited
Apr 14, 2021
2 forks
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
echartOption = ({
backgroundColor: '#FFFFFF',
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: 60,
name: yMetric,
type: scatterStyling.includes('log') ? 'log' : 'value'
},
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],
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
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(14);
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(9, 14);
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("COVID-19 & World Bank Metrics - Merged Data WDI 2020 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
devIndicatorMetadata = d3.csvParse(
await FileAttachment("World Development Indicators - Metadata 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