|
|
|
// SARS-CoV-2-Viz
|
|
|
|
// Animated COVID case count visualization
|
|
|
|
// Copyright 2022 Edward L. Platt <ed@elplatt.com>
|
|
|
|
|
|
|
|
function main() {
|
|
|
|
let ui = UI();
|
|
|
|
let tracker = ProgressTracker(
|
|
|
|
(id) => { ui.addDisplay(id); },
|
|
|
|
(id, progress) => ui.display(progress, id)
|
|
|
|
);
|
|
|
|
document.getElementById("header").appendChild(ui.node);
|
|
|
|
|
|
|
|
let onDataProgress = tracker.getTracker();
|
|
|
|
let dataPromise = getData(
|
|
|
|
(progress) => {
|
|
|
|
onDataProgress(`Fetching data: Received ${progress} bytes`)
|
|
|
|
})
|
|
|
|
.then((dataCSV) => {
|
|
|
|
return parseData(
|
|
|
|
dataCSV,
|
|
|
|
(progress) => onDataProgress(`Parsing data: ${progress}`)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
let onFeatureProgress = tracker.getTracker();
|
|
|
|
let featurePromise = getFeatures(
|
|
|
|
(progress) => {
|
|
|
|
onFeatureProgress(`Fetching features: Received ${progress} bytes`);
|
|
|
|
})
|
|
|
|
.then((features) => {
|
|
|
|
return parseFeatures(
|
|
|
|
features,
|
|
|
|
(progress) => onFeatureProgress(`Parsing features: ${progress}`));
|
|
|
|
});
|
|
|
|
|
|
|
|
let onMetadataProgress = tracker.getTracker();
|
|
|
|
let metadataPromise = getMetadata(
|
|
|
|
(progress) => {
|
|
|
|
onMetadataProgress(`Fetching metadata: ${progress}`);
|
|
|
|
})
|
|
|
|
.then((metadataCSV) => {
|
|
|
|
return parseMetadata(
|
|
|
|
metadataCSV,
|
|
|
|
(progress) => onMetadataProgress(`Parsing metadata: ${progress}`));
|
|
|
|
});
|
|
|
|
|
|
|
|
Promise.all([
|
|
|
|
dataPromise, featurePromise, metadataPromise
|
|
|
|
]).then((values) => {
|
|
|
|
const [rawDataForDay, us, metadata] = values;
|
|
|
|
const population = populationMap(metadata);
|
|
|
|
const dataForDay = normalizeData(rawDataForDay, population);
|
|
|
|
|
|
|
|
if (false) {
|
|
|
|
console.log("Data for Day")
|
|
|
|
console.log(dataForDay);
|
|
|
|
console.log("US");
|
|
|
|
console.log(us);
|
|
|
|
console.log("Population");
|
|
|
|
console.log(population);
|
|
|
|
}
|
|
|
|
|
|
|
|
let msPerFrame = 200;
|
|
|
|
let dates = dataForDay.map((data) => data["10001"].date);
|
|
|
|
let chart = createChoropleth(us, msPerFrame);
|
|
|
|
let day = dataForDay.length - 1;
|
|
|
|
let data = dataForDay[day];
|
|
|
|
|
|
|
|
ui.clearDisplays();
|
|
|
|
ui.display("Initializing visualization");
|
|
|
|
ui.display(dataForDay[day]["10001"].date);
|
|
|
|
ui.setFrames(dates, day);
|
|
|
|
ui.setMsPerFrame(msPerFrame);
|
|
|
|
ui.showControls();
|
|
|
|
|
|
|
|
document.getElementById("content").appendChild(chart.node);
|
|
|
|
chart.update(data);
|
|
|
|
ui.onTick((day) => {
|
|
|
|
chart.update(dataForDay[day]);
|
|
|
|
ui.display(dates[day]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
main();
|
|
|
|
|