Published
Edited
Oct 27, 2020
Also listed in…
CoViD19
Sri Lanka
Insert cell
Insert cell
drawMap(3, {})
Insert cell
Insert cell
Insert cell
Insert cell
import { slider } from '@jashkenas/inputs'
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { range, sum } from '@nuuuwan/list-utils'
Insert cell
import {
drawRegionMap,
drawRegionDorlingCartogram,
REGION_TYPE,
REGION_INDEX
} from '@nuuuwan/sri-lanka-regions'
Insert cell
import { getRandomColor, hsla } from '@nuuuwan/color-utils'
Insert cell
import { getSVG, drawText, drawText2, drawCircle } from '@nuuuwan/svg-utils'
Insert cell
import { addDefaults } from '@nuuuwan/option-utils'
Insert cell
Insert cell
(await getData())[0]
Insert cell
async function getDataByTimeAndDSD() {
const dsdNameToId = Object.assign(
Object.entries(REGION_INDEX[REGION_TYPE.DSD]).reduce(function(
dsdNameToId,
[id, d]
) {
dsdNameToId[d.name] = id;
return dsdNameToId;
},
{}),
{
Sainthamarathu: 'LK-5225',
Walallawita: 'LK-1339',
"K.F.G. & G. Korale": 'LK-2130',
Panduwasnuwara: 'LK-6148',
"N. Palatha Central": 'LK-7115',
"N. Palatha East": 'LK-7133',
"Arachchikattuwa PS": 'LK-6230',
Kantalai: 'LK-5321',
Hildummulla: 'LK-8142',
"Dehiwala-Mount Lavinia": 'LK-1130',
Hanwella: 'LK-1115',
Ambalanthota: 'LK-3315',
"Valikamam East": 'LK-4118',
"Valikamam North": 'LK-4112',
"Valikamam South": 'LK-4115',
"Valikamam South-West": 'LK-4109',
"Valikamam West": 'LK-4106',
"Thenmaradchy (Chavakachcheri)": 'LK-4130',
"Vadamaradchi South-West": 'LK-4121',
"Vadamaradchy North": 'LK-4127'
}
);

const data = await getData();

const dataByTimeAndDSD = data.reduce(function(dataByTimeAndDSD, d) {
const ut = getUnixTimeFromDateStr(d.ds);
const dsdName = d.polygon_name;
const dsdID = dsdNameToId[dsdName];
if (!dataByTimeAndDSD[ut]) {
dataByTimeAndDSD[ut] = {};
}
if (!dataByTimeAndDSD[ut][dsdID]) {
dataByTimeAndDSD[ut][dsdID] = parseFloat(
d.all_day_ratio_single_tile_users
);
}
return dataByTimeAndDSD;
}, {});
return Object.entries(dataByTimeAndDSD)
.map(function([ts, dataForTimeByDSD]) {
return Object({
ut: parseInt(ts),
dataByDSD: Object.entries(dataForTimeByDSD)
.map(function([dsdID, p]) {
return Object({ dsdID, p });
})
.sort((a, b) => a.dsdID.localeCompare(b.dsdID))
});
})
.sort((a, b) => b.ut - a.ut);
}
Insert cell
DATA_BY_TIME_AND_DSD = await getDataByTimeAndDSD()
Insert cell
MAX_DAYS_AGO = DATA_BY_TIME_AND_DSD.length
Insert cell
Insert cell
Insert cell
function drawMap(days_ago, options = {}) {
const dataByTimeAndDSD = DATA_BY_TIME_AND_DSD;
const latestDataByDSD = dataByTimeAndDSD[days_ago];
if (!latestDataByDSD) {
return null;
}
const ut = latestDataByDSD.ut;
const dataByDSD = latestDataByDSD.dataByDSD;
const dsdToP = dataByDSD.reduce(function(dsdToP, d) {
dsdToP[d.dsdID] = d.p;
return dsdToP;
}, {});

options = addDefaults(options, {
width: 600,
height: 1000,
legendWidth: 100,
maxRadius: 10
});

function pToColor(p) {
if (p !== undefined) {
let h = (1 - p * 2) * 240;
if (h < 0) {
h = 0;
}
return hsla(h, 100, 50, 1.0);
}
return '#eee';
}

options = addDefaults(options, {
fRegionInfoToColor: function(regionInfo) {
return pToColor(dsdToP[regionInfo.regionID]);
},
caption: `% of Population that stayed within 600m of home on ${formatDate(
ut
)}`,
fAppendLabel: function(regionInfo, svg, x, y, r) {},
fAppendLegend: function(svg) {
const LEGEND_ITEM_HEIGHT = 20;
const xOffset = options.width - options.legendWidth;

[
[0.1, '10%'],
['0.2', '20%'],
[0.3, '30%'],
[0.4, '40%'],
[0.5, '≥ 50%'],
[undefined, 'No Data']
].map(function([p, label], i) {
drawText2(
svg,
[xOffset + LEGEND_ITEM_HEIGHT, (i + 2) * LEGEND_ITEM_HEIGHT],
label,
{ textAnchor: 'start' }
);
drawCircle(
svg,
xOffset,
(i + 2) * LEGEND_ITEM_HEIGHT,
LEGEND_ITEM_HEIGHT / 3,
{ fill: pToColor(p), stroke: 'gray' }
);
});
}
});

return drawRegionMap('LK', REGION_TYPE.DSD, options);
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more