Compare COVID19 Case Rate of Change by Country
var dsource = "WHO Daily\nSituation Reports (GitHub)";
function rawToObjects(data) {
console.log(data);
latestDate = new moment(String(data['China'][data['China'].length - 1]['date']), "YYYY-MM-DD");
console.log(latestDate);
var r = {};
for (var oldkey in data) {
var key = oldkey;
if (key == "US")
key = "United States";
else if (key == "Korea, South")
key = "South Korea";
if (!r.hasOwnProperty(key)) {
r[key] = {
positive: {},
death: {},
recovered: {},
deathrt: {},
proc: {},
droc: {},
drroc: {},
}
}
data[oldkey].forEach((d, i) => {
var ddt = new moment(String(d['date']), "YYYY-MM-DD");
var index = ddt.format("YYYY-MM-DD");
r[key]["positive"][index] = d["confirmed"];
r[key]["recovered"][index] = d["recovered"];
r[key]["death"][index] = d["deaths"];
r[key]["deathrt"][index] = Math.round(d["deaths"] / d["confirmed"] * 10000) / 100;
});
}
for (var i in r) {
var e = r[i];
for (var index in e["positive"]) {
var prev = new moment(String(index), "YYYY-MM-DD").subtract(1, "day").format("YYYY-MM-DD");
if (e["positive"].hasOwnProperty(prev)) {
e["proc"][index] = Math.round((e["positive"][index] - e["positive"][prev]) / e["positive"][prev] * 100);
e["droc"][index] = Math.round((e["death"][index] - e["death"][prev]) / e["death"][prev] * 100);
e["drroc"][index] = Math.round((e["deathrt"][index] - e["deathrt"][prev]) / e["deathrt"][prev] * 100);
}
}
}
console.log(r);
processData(r);
}
function getData() {
fetch("https://pomber.github.io/covid19/timeseries.json")
.then(response => response.json())
.then(rawToObjects)
}
var latestDate = 0;
var processed;
var myChart;
var toShow = [];
var lineColorCounter = 0;
var baselineColorCounter = 0;
var outbreak = true;
var fullCSV = "";
var lineColors = [
'rgba(68, 114, 196, 1)',
'rgba(255, 192, 0, 1)',
'rgba(112, 173, 71, 1)',
'rgba(0, 63, 105, 1)',
'rgba(132, 60, 12, 1)',
'rgba(234, 20, 31, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)'
];
var baslineColors = [
'rgba(0, 168, 255, 0.25)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)',
'rgba(112, 173, 71, 1)'
];
function coreGenLables(t) {
var e = t.data.datasets,
i = t.options.legend || {},
n = i.labels && i.labels.usePointStyle;
return t._getSortedDatasetMetas().map((function(t) {
var i = t.controller.getStyle(n ? 0 : void 0);
return {
text: e[t.index].label,
fillStyle: i.backgroundColor,
hidden: !t.visible,
lineCap: i.borderCapStyle,
lineDash: i.borderDash,
lineDashOffset: i.borderDashOffset,
lineJoin: i.borderJoinStyle,
lineWidth: 8,
strokeStyle: i.borderColor,
pointStyle: i.pointStyle,
rotation: i.rotation,
datasetIndex: t.index
}
}), this)
}
function drawString(ctx, text, posX, posY, textColor, rotation, font, fontSize) {
var lines = text.split("\n");
if (!rotation) rotation = 0;
if (!font) font = "'serif'";
if (!fontSize) fontSize = 16;
if (!textColor) textColor = '#000000';
ctx.save();
ctx.font = fontSize + "px " + font;
ctx.fillStyle = textColor;
ctx.translate(posX, posY);
ctx.rotate(rotation * Math.PI / 180);
for (i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], 0, i * fontSize);
}
ctx.restore();
}
Chart.plugins.register({
beforeDraw: function(chart, easing) {
if (chart.config.options.chartArea && chart.config.options.chartArea.backgroundColor) {
var ctx = chart.ctx;
var chartArea = chart.chartArea;
ctx.save();
ctx.fillStyle = chart.config.options.chartArea.backgroundColor;
ctx.fillRect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
ctx.restore();
}
}
});
Chart.plugins.register({
afterDraw: function(chart, easing) {
var ctx = chart.ctx;
drawString(ctx, "InfoMullet.com\nSource: " + dsource + "\nCurrent as of: " + latestDate.format("YYYY-MM-DD"), 0, 16);
}
});
Chart.defaults.fontSize = 24;
Chart.defaults.fontFamily = "Calibri";
function downloadCanvas(canvas, filename) {
console.log(canvas);
var lnk = document.createElement('a');
lnk.download = filename;
lnk.href = canvas.toDataURL("image/png;base64");
if (document.createEvent) {
e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false,
false, 0, null);
lnk.dispatchEvent(e);
} else if (lnk.fireEvent) {
lnk.fireEvent("onclick");
}
}
function genFullCSV(data, labels, dp) {
fullCSV = "Location\tDatapoint\t" + labels.join("\t") + "\n";
for (const key in data) {
var vals = [];
for (var i = 0; i {
var opt = $('').val(newKey).text(newKey);
if (toShow.includes(newKey)) {
opt.prop('selected', true);
}
$('#countrylist').append(opt);
});
$('#countrylist').trigger("chosen:updated");
}
function generateBase(title, index, label) {
var color = processed[title]["baseColor"] ? baslineColors[baselineColorCounter++] : lineColors[lineColorCounter++];
return {
label: title + label,
fill: false,
borderWidth: processed[title]["width"],
borderColor: color,
backgroundColor: color,
pointHitRadius: 10,
pointRadius: 0,
yAxisID: "yaxis",
xAxisID: "xaxis",
pointBackgroundColor: 'rgba(0,0,0,0)',
pointBorderColor: 'rgba(0,0,0,0)',
data: processed[title][index],
};
}
function toPoints(labels, data) {
var ret = [];
labels.forEach((label, i) => {
ret.push({
x: label,
y: data[label]
});
});
return ret;
}
function createDatasetObject() {
var set = [];
toShow.forEach(x => {
set.push(generateBase(x, 'points', ""))
})
return set;
}
function refreshChart() {
toShow = $("#countrylist").chosen().val();
if (outbreak)
toShow.push("Outbreak Threshold Risk");
lineColorCounter = 0;
baselineColorCounter = 0;
toShow.sort();
myChart.data.datasets = createDatasetObject();
myChart.update({
duration: 800,
easing: 'easeInQuad'
});
}
$(document).ready(function() {
$('head').append('');
$('head').append('');
$('#chartholder').append('');
$('#controlholder').append('');
$('#controlholder').append('');
$('#controlholder').css("display", "inline-block");
$('#chartholder').css("display", "inline-block");
$('#controlholder').append('');
$("#get_csv").on('click', function(e) {
downloadCSV()
});
$("#get_PNG").on('click', function(e) {
downloadCanvas($("#chartCanvas").get(0), "chart.png")
});
$("#countrylist").chosen({
max_selected_options: 6
}).change(refreshChart);
getData();
});
outbreak = false;
function processData(data) {
toShow = ['United States', 'Canada', 'Mexico'];
processed = {labels:[]};
for(var dt = latestDate.clone(); latestDate.diff(dt, "day"){if(i > 0 && i % 10 != 9) {e.label="";}});
}
},
yaxis: {
scaleLabel: {
display: true,
labelString: "% OF CHANGE IN DAILY CASES",
fontSize: 32
},
ticks: {
autoSkip: false,
min: yticks[0],
max: yticks[yticks.length - 1],
},
afterTickToLabelConversion: s => s.ticks.forEach(x => x.label += "%"),
beforeBuildTicks: function(s) {
s.min = yticks[0];
s.max = yticks[yticks.length - 1];
},
afterBuildTicks: function(s) {
s.ticks = s.ticks.filter(t => yticks.includes(t.value));
}
}
}
}
});
$(".main-container").width("100%");
$("#page").width("100%");
$("#page").css("maxWidth","100%");
}
Built with:
jQuery | Chosen | ChartJS | JSon transform of CSSEGISandData/COVID-19 | CSSEGISandData/COVID-19