Published
Edited
Apr 7, 2021
Insert cell
md`# CoViD Curves`
Insert cell
renderCoViDCurveClusters()
Insert cell
md`### Code`
Insert cell
d3 = require('d3')
Insert cell
import { getSVG, drawPath, drawText, drawLine } from '@nuuuwan/svg-utils'
Insert cell
import {
COUNTRY_NAME_TO_ID,
COUNTRY_TO_COUNTRY_DATA
} from '@nuuuwan/country-utils'
Insert cell
import { clusterKMeans } from '@nuuuwan/k-means-clustering'
Insert cell
COVID_DATA = {
const URL = 'https://pomber.github.io/covid19/timeseries.json';
const dataList = await d3.json(URL);
return Object.entries(dataList).map(function([countryName, timeSeriesList]) {
const countryID = COUNTRY_NAME_TO_ID[countryName];
timeSeriesList = timeSeriesList.map(function(d) {
d.active = d.confirmed - d.deaths - d.recovered;
return d;
});
const region = COUNTRY_TO_COUNTRY_DATA[countryID]?.region;
return {
countryID,
countryName,
region,
timeSeriesList
};
}, {}).filter(
function(countryData) {
return Math.max(...countryData.timeSeriesList.map(d => d.active)) > 1000;
});
}
Insert cell
BOX_DIM = 200
Insert cell
N_VECTOR = 10
Insert cell
Q_VECTOR = 10
Insert cell
function fNodeToVector(data) {
const activeList = data.timeSeriesList.map(d => d.active);
const maxActive = Math.max(...activeList);
const nTimeSeriesList = activeList.length;
return d3.range(0, N_VECTOR).map(function(i) {
return (
(Q_VECTOR * activeList[parseInt((i * nTimeSeriesList) / N_VECTOR)]) /
maxActive
);
});
}
Insert cell
function renderCoViDCurveClusters() {
const sortedClusterToSortedNodeList = clusterKMeans(
5,
COVID_DATA,
fNodeToVector,
{}
);

const nCountries = COVID_DATA.length;
const nColumns = parseInt(width / BOX_DIM);
const nRows = Math.ceil(nCountries / nColumns);
const height = BOX_DIM * nRows;
const svg = getSVG({ width, height });
let iRow = -1;
Object.values(sortedClusterToSortedNodeList).forEach(function(nodeList) {
nodeList.forEach(function(iCountry, i) {
const iColumn = i % nColumns;
if (iColumn === 0) {
iRow += 1;
}
drawCoViDCurve(svg, iRow, iColumn, COVID_DATA[iCountry]);
});
});

return svg.node();
}
Insert cell
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