COVID19 Cases by Country

Spread the love

var latestDate = new moment(); var processed; var myChart; var toShow = []; var lineColorCounter = 0; var baselineColorCounter = 0; var outbreak = true; var baslineColors = [ 'rgba(234, 20, 31, 0.25)', '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 min = min max = max > indx ? max : indx); return max; } function shiftKeys(a, n) { var na = []; a.forEach((current, indx) => { na[indx + n] = current; }); return na; } function refreshChart() { toShow = [$("#countrylist").chosen().val()]; lineColorCounter = 0; baselineColorCounter = 0; myChart.data.datasets = createDatasetObject(); myChart.update({ duration: 800, easing: 'easeInSine' }); } function rawToObjects(data) { var fromDate = new moment([2020, 0, 22]); latestDate = new moment(data['China'][data['China'].length - 1]['date'], "YYYY-MM-DD"); var r = {}; for (const key in data) { if (!r.hasOwnProperty(key)) { r[key] = { positive: [], death: [], } } data[key].forEach(d => { var dataDate = new moment(String(d["date"]), "YYYYMMDD"); var index = dataDate.diff(fromDate, 'days'); if (typeof d["confirmed"] == "number") r[key]["positive"][index] = d["confirmed"]; if (typeof d["deaths"] == "number") r[key]["death"][index] = d["deaths"]; }); }; for (var i in r) { var e = r[i]; for (var j = 0; j < e["positive"].length; j++) { if (e["positive"][j] === 0 && (j == 0 || typeof e["positive"][j - 1] == 'undefined')) { delete e["positive"][j]; } } for (var j = 0; j < e["death"].length; j++) { if (e["death"][j] === 0 && (j == 0 || typeof e["death"][j - 1] == 'undefined')) { delete e["death"][j]; } } } return r; } $(document).ready(function() { $('head').append(''); $('head').append(''); $('#chartholder').append(''); $('#controlholder').append(''); $('#controlholder').append(''); $('#controlholder').css("display", "inline-block"); $('#chartholder').css("display", "inline-block"); $("#get_PNG").on('click', function(e) { downloadCanvas($("#chartCanvas").get(0), "chart.png") }); $('#controlholder').append(''); $("#get_csv").on('click', function(e) { downloadCSV() }); $("#countrylist").chosen().change(refreshChart); fetch("https://pomber.github.io/covid19/timeseries.json") .then(response => response.json()) .then(rawToObjects) .then(processData) });
var lineColors = [ 'rgba(68, 114, 196, 1)', 'rgba(255, 192, 0, 1)', 'rgba(0, 63, 105, 1)', 'rgba(234, 20, 31, 1)', 'rgba(132, 60, 12, 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)', 'rgba(112, 173, 71, 1)' ]; function filterData(data) { var filtered = {}; for (const key in data) { var e = data[key]; if (e["death"][(e["death"].length - 1)] > 5) { filtered[key] = { width: 8, death: e["death"], positive: e["positive"], dcalc: [], mid: [], hoped: [], feared: [] }; } } return filtered; } function padDataBack(data) { for (const key in data) { var e = data[key]; var min = 20 - aMin(e["death"]); e["death"] = shiftKeys(e["death"], min); e["positive"] = shiftKeys(e["positive"], min); } } function createDatasetObject() { var set = []; toShow.forEach(x => { set.push(generateBase(x, "positive", " Reported")); set.push(generateBase(x, "dcalc", " Calculated")); set.push(generateBase(x, "death", " Deaths")); set.push(generateBase(x, "feared", " Forecasted Feared")); set.push(generateBase(x, "mid", " Forecasted Mid")); set.push(generateBase(x, "hoped", " Forecasted Hoped")); }) set.push({ label: 'Outbreak Threshold Risk', fill: false, borderWidth: processed['Outbreak Threshold Risk']["width"], borderColor: 'rgba(0, 168, 255, 0.25)', backgroundColor: 'rgba(0, 168, 255, 0.25)', pointHitRadius: 0, pointRadius: 0, yAxisID: "yaxis", xAxisID: "xaxis", pointBackgroundColor: 'rgba(0,0,0,0)', pointBorderColor: 'rgba(0,0,0,0)', data: processed['Outbreak Threshold Risk']["points"], }) return set; } var hoped = [90,80,95,90,80,70,90,85,70,60,65,55,60,50,55,45,50,40,45,]; var feared = [133,125,120,115,112,108,105,102,101,101,101,101,101,101,100,100,100,100,100,]; var mid = [100,100,100,100,100,90,80,95,90,80,70,90,85,70,60,65,55,60,50,]; function processData(data) { var filt = filterData(data); padDataBack(filt); for (const key in filt) { var e = filt[key]; var d = e["death"].length; var t = d - 20; e["dcalc"] = []; for (var i = 0; i 0; i--) { if(e["dcalc"][t - i - 1]) droc += (e["dcalc"][t - i] - e["dcalc"][t - i - 1])/e["dcalc"][t - i - 1]; } droc = droc / 7; e["mid"][t - 1] = e["dcalc"][t - 1]; e["hoped"][t - 1] = e["dcalc"][t - 1]; e["feared"][t - 1] = e["dcalc"][t - 1]; for (var i = 0; i < 20; i++) { e["mid"][t + i] = Math.round(e["mid"][t - 1 + i] * (1+droc* (mid[i] / 100))); e["hoped"][t + i] = Math.round(e["hoped"][t - 1 + i] * (1+droc* (hoped[i] / 100))); e["feared"][t + i] = Math.round(e["feared"][t - 1 + i] * (1+droc* (feared[i] / 100))); } for (var i = 0; i < 250; i++) { if (typeof e["mid"][i] == 'number' && e["mid"][i] < 1) e["mid"][i] = 0; if (typeof e["hoped"][i] == 'number' && e["hoped"][i] < 1) e["hoped"][i] = 0; if (typeof e["feared"][i] == 'number' && e["feared"][i] < 1) e["feared"][i] = 0; if (typeof e["positive"][i] == 'number' && e["positive"][i] < 1) e["positive"][i] = 0; if (typeof e["dcalc"][i] == 'number' && e["dcalc"][i] < 1) e["dcalc"][i] = 0; } /* //setup first 7 values for (var i = d - 27; i < d - 20; i++) { e["mid"][i] = e["dcalc"][i]; e["hoped"][i] = e["dcalc"][i]; e["feared"][i] = e["dcalc"][i]; } for (var i = 0; i < 20; i++) { var mavg = 0; var havg = 0; var favg = 0; for (var j = 1; j < 7; j++) { mavg += e["mid"][d - 20 + i - j] - e["mid"][d - 21 + i - j]; havg += e["hoped"][d - 20 + i - j] - e["hoped"][d - 21 + i - j]; favg += e["feared"][d - 20 + i - j] - e["feared"][d - 21 + i - j]; } e["mid"][d - 20 + i] = e["mid"][d - 21 + i] + ((mid[i] / 100) * (mavg / 7)); e["hoped"][d - 20 + i] = e["hoped"][d - 21 + i] + ((hoped[i] / 100) * (havg / 7)); e["feared"][d - 20 + i] = e["feared"][d - 21 + i] + ((feared[i] / 100) * (favg / 7)); } //remove seed values for (var i = d - 27; i < d - 21; i++) { delete e["mid"][i]; delete e["hoped"][i]; delete e["feared"][i]; } */ } displayData(filt); } function trimArray(a) { var m = a.length; for (var i = 0; i 0; i--) { if (a[i] === null) { delete a[i]; } else { break; } } } function displayData(data) { toShow = ['China']; processed = {}; var maxLength = 0; for (const key in data) { var e = data[key]; processed[key] = e; e["positive"].forEach((c, i) => maxLength = i > maxLength ? i : maxLength); } fullCSV = "Location,Datapoint"; for (var i = 0; i < maxLength+1; i++) { fullCSV += ","+i; } fullCSV += "\n"; for (const key in data) { var e = data[key]; var sdcalc = key + ",calc,"; var spositive = key + ",posi,"; var sdeath = key + ",death,"; var sfeared = key + ",fear,"; var smid = key + ",mid,"; var shoped = key + ",hope," 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"); processed["labels"] = [...Array(maxLength + 2).keys()]; processed['Outbreak Threshold Risk'] = { points: Array.from(processed["labels"]).fill(800), baseColor: true, width: 70 }; var ctx = document.getElementById('chartCanvas').getContext('2d'); var yticks = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]; myChart = new Chart(ctx, { type: 'line', responsive: false, data: { labels: processed["labels"], datasets: createDatasetObject() }, options: { aspectRatio: 1000 / 800, title: { display: true, text: ["Confirmed (Tested) Cases vs. Calculated Actual Infected", "(Logarithmic Scale)", ""] }, legend: { position: 'bottom', labels: { boxWidth: 12, fontSize: 14, generateLabels: coreGenLables }, }, chartArea: { backgroundColor: 'rgba(235, 235, 235, 1)' }, scales: { xaxis: { gridLines: { display: false }, scaleLabel: { display: true, labelString: "Days Since First Calculated Infection (Day 20 is First Confirmed Death)", fontSize: 30 }, ticks: { beginAtZero: true, maxRotation: 0, minRotation: 0, autoSkip: false, }, afterFit: function(s) { s.ticks.forEach(t=>{if(t.value > 0 && t.value % 10 != 0) {t.label="";}}); }, }, yaxis: { type: "logarithmic", scaleLabel: { display: true, labelString: "Cumulative Total", fontSize: 32 }, ticks: { autoSkip: false, min: yticks[0], max: yticks[yticks.length - 1], }, 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%"); }