graph tweaks

This commit is contained in:
tmont 2020-04-30 23:28:21 -07:00
parent 8bff273d8b
commit 38a8191744
2 changed files with 67 additions and 20 deletions

View File

@ -157,25 +157,28 @@ const processGlobalDeaths = async () => {
const getRollingAverage = (item) => {
return item.timeSeriesDaily.map((item, i, arr) => {
const prevValues = arr.slice(Math.max(0, i - 6), i);
const valueAverage = (item.value + prevValues.reduce((sum, next) => sum + next.value, 0)) / (1 + prevValues.length);
const deltaAverage = (item.delta + prevValues.reduce((sum, next) => sum + next.delta, 0)) / (1 + prevValues.length);
let valueAverage = (item.value + prevValues.reduce((sum, next) => sum + next.value, 0)) / (1 + prevValues.length);
let deltaAverage = (item.delta + prevValues.reduce((sum, next) => sum + next.delta, 0)) / (1 + prevValues.length);
if (valueAverage < 1) {
valueAverage = Math.round(valueAverage);
}
if (deltaAverage < 1) {
deltaAverage = Math.round(deltaAverage);
}
return {
key: item.key,
value: Math.round(valueAverage),
delta: Math.round(deltaAverage),
value: Math.round(valueAverage * 10) / 10,
delta: Math.round(deltaAverage * 10) / 10,
};
});
};
const getDoublingTime = (item) => {
return item.timeSeriesDaily.map((item, i, arr) => {
const prevItems = arr.slice(Math.max(i - 7, 0), i);
const sum = prevItems.reduce((sum, next) => sum + next.value, 0);
let value;
if (sum < 10) {
if (item.value < 10) {
value = 0;
} else {
const growthRate = calcGrowthRate(arr, i, 7);

View File

@ -32,6 +32,31 @@ html
}
});
// https://stackoverflow.com/a/45172506
Chart.defaults.lineVerticalTooltip = Chart.defaults.line;
Chart.controllers.lineVerticalTooltip = Chart.controllers.line.extend({
draw: function(ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
const activePoint = this.chart.tooltip._active[0];
const ctx = this.chart.ctx;
const x = activePoint.tooltipPosition().x;
const topY = this.chart.legend.bottom;
const bottomY = this.chart.chartArea.bottom;
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(96, 96, 96, 0.75)';
ctx.stroke();
ctx.restore();
}
}
});
const charts = {
logarithmic: false,
heroChart: null,
@ -40,7 +65,7 @@ html
function makeSparkline(id, data) {
const canvas = document.getElementById(id);
const maxValue = data[data.length - 1];
const maxValue = data.reduce((max, value) => Math.max(max, value), 0);
const chart = new Chart(canvas.getContext('2d'), {
type: 'line',
data: {
@ -73,7 +98,8 @@ html
ticks: {
precision: 0,
beginAtZero: true,
max: Math.pow(10, Math.ceil(Math.log10(maxValue))),
min: 0,
max: maxValue > 0 ? Math.pow(10, Math.ceil(Math.log10(maxValue))) : 0,
callback: value => Number(value.toString()),
}
},
@ -139,14 +165,29 @@ html
const canvas = document.getElementById(id);
charts.heroMaxValue = totalDeaths[totalDeaths.length - 1];
const firstNonZeroDeathIndex = totalDeaths.findIndex(value => value > 0);
const start = Math.max(0, firstNonZeroDeathIndex - 2);
const end = totalDeaths.length;
const totalData = totalDeaths.slice(start, end);
const newData = newDeaths.slice(start, end);
const rollingData = rollingAverage.slice(start, end);
const doublingData = doubling.slice(start, end);
const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
const realLabels = labels
.slice(start, end)
.map((date) => date.replace(/\d{4}-(\d\d?)-(\d\d?)/, (_, m, d) => `${months[Number(m) - 1]} ${Number(d)}`));
charts.heroChart = new Chart(canvas.getContext('2d'), {
type: 'line',
type: 'lineVerticalTooltip',
data: {
labels: labels,
labels: realLabels,
datasets: [
{
label: 'Cumulative',
data: totalDeaths,
data: totalData,
fill: '1',
borderColor: 'rgb(196, 64, 64)',
borderWidth: 1,
@ -154,7 +195,7 @@ html
},
{
label: 'New (rolling)',
data: rollingAverage,
data: rollingData,
fill: 'origin',
borderColor: 'rgb(20,24,59)',
borderWidth: 1,
@ -162,14 +203,14 @@ html
},
{
label: 'New',
data: newDeaths,
data: newData,
fill: false,
borderColor: 'rgb(96, 96, 96, 0.25)',
borderWidth: 1,
},
{
label: 'Days to 2x',
data: doubling,
data: doublingData,
fill: false,
borderColor: 'rgb(187,40,193, 0.5)',
borderWidth: 2,
@ -339,7 +380,7 @@ html
script.
makeSparkline(
"sparkline-#{i}",
#{JSON.stringify(item.timeSeriesDaily.slice(-14).map(x => x.value))},
#{JSON.stringify(item.timeSeriesDaily.slice(-14).map(x => x.delta))},
);
@ -371,7 +412,6 @@ html
const resortTable = (col) => {
let nextChild = null;
const highlightedIndex = headers.findIndex(cell => cell.getAttribute('data-col') === col);
console.log(col, highlightedIndex);
headers.forEach((cell, i) => {
if (i !== highlightedIndex) {
cell.classList.remove('sorted');
@ -383,8 +423,11 @@ html
for (let i = allRows.length - 1; i >= 0; i--) {
const row = allRows[i];
if (!row) {
console.log(i + ' no row!');
continue;
}
const name = row.getAttribute('data-name');
console.log(row.id, name, !name && row);
const cells = [].slice.call(row.querySelectorAll('td'));
cells.forEach((cell, i) => {
if (i !== highlightedIndex) {
@ -401,6 +444,7 @@ html
row.querySelector('.sort-order').textContent = (i + 1).toString();
nextChild = row;
}
console.log('---');
};
const handleSort = (value, dir) => {
@ -412,7 +456,7 @@ html
if (aValue === bValue) {
const aName = a.getAttribute('data-name');
const bName = b.getAttribute('data-name');
return aName && bName ? aName.localeCompare(bName) : 0;
return aName && bName ? aName.localeCompare(bName) : -1;
}
return aValue < bValue ?