tooltip styles, code cleanup, case doubling
This commit is contained in:
parent
a714af2c1d
commit
f5ba23cc75
236
generate.js
236
generate.js
@ -239,6 +239,27 @@ const processRecords = async () => {
|
||||
return calcGrowthRate(ts, ts.length - 1, 7);
|
||||
};
|
||||
|
||||
const convertTsObjectToArray = (obj) => {
|
||||
return Object.keys(obj).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: obj[date].value,
|
||||
delta: obj[date].delta,
|
||||
};
|
||||
})
|
||||
};
|
||||
|
||||
const mergeTsArrayIntoObject = (source, target) => {
|
||||
source.forEach((ts) => {
|
||||
target[ts.key] = target[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
target[ts.key].value += ts.value;
|
||||
target[ts.key].delta += ts.delta;
|
||||
});
|
||||
};
|
||||
|
||||
const normalizeRecord = (record) => {
|
||||
record.timeSeriesDaily = [];
|
||||
record.timeSeriesMonthly = [];
|
||||
@ -508,41 +529,11 @@ const processRecords = async () => {
|
||||
|
||||
stateItem.total += record.total;
|
||||
stateItem.cases.total += record.cases.total;
|
||||
record.timeSeriesDaily.forEach((ts) => {
|
||||
stateItem.timeSeriesDaily[ts.key] = stateItem.timeSeriesDaily[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
stateItem.timeSeriesDaily[ts.key].value += ts.value;
|
||||
stateItem.timeSeriesDaily[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
record.timeSeriesMonthly.forEach((ts) => {
|
||||
stateItem.timeSeriesMonthly[ts.key] = stateItem.timeSeriesMonthly[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
stateItem.timeSeriesMonthly[ts.key].value += ts.value;
|
||||
stateItem.timeSeriesMonthly[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
record.cases.timeSeriesDaily.forEach((ts) => {
|
||||
stateItem.cases.timeSeriesDaily[ts.key] = stateItem.cases.timeSeriesDaily[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
stateItem.cases.timeSeriesDaily[ts.key].value += ts.value;
|
||||
stateItem.cases.timeSeriesDaily[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
record.cases.timeSeriesMonthly.forEach((ts) => {
|
||||
stateItem.cases.timeSeriesMonthly[ts.key] = stateItem.cases.timeSeriesMonthly[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
stateItem.cases.timeSeriesMonthly[ts.key].value += ts.value;
|
||||
stateItem.cases.timeSeriesMonthly[ts.key].delta += ts.delta;
|
||||
});
|
||||
mergeTsArrayIntoObject(record.timeSeriesDaily, stateItem.timeSeriesDaily);
|
||||
mergeTsArrayIntoObject(record.timeSeriesMonthly, stateItem.timeSeriesMonthly);
|
||||
mergeTsArrayIntoObject(record.cases.timeSeriesDaily, stateItem.cases.timeSeriesDaily);
|
||||
mergeTsArrayIntoObject(record.cases.timeSeriesMonthly, stateItem.cases.timeSeriesMonthly);
|
||||
|
||||
stateItem.counties.push(record);
|
||||
} else {
|
||||
@ -556,41 +547,10 @@ const processRecords = async () => {
|
||||
item.total += record.total;
|
||||
item.cases.total += record.cases.total;
|
||||
|
||||
record.timeSeriesDaily.forEach((ts) => {
|
||||
item.timeSeriesDaily[ts.key] = item.timeSeriesDaily[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
item.timeSeriesDaily[ts.key].value += ts.value;
|
||||
item.timeSeriesDaily[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
record.timeSeriesMonthly.forEach((ts) => {
|
||||
item.timeSeriesMonthly[ts.key] = item.timeSeriesMonthly[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
item.timeSeriesMonthly[ts.key].value += ts.value;
|
||||
item.timeSeriesMonthly[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
record.cases.timeSeriesDaily.forEach((ts) => {
|
||||
item.cases.timeSeriesDaily[ts.key] = item.cases.timeSeriesDaily[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
item.cases.timeSeriesDaily[ts.key].value += ts.value;
|
||||
item.cases.timeSeriesDaily[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
record.cases.timeSeriesMonthly.forEach((ts) => {
|
||||
item.cases.timeSeriesMonthly[ts.key] = item.cases.timeSeriesMonthly[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
item.cases.timeSeriesMonthly[ts.key].value += ts.value;
|
||||
item.cases.timeSeriesMonthly[ts.key].delta += ts.delta;
|
||||
});
|
||||
mergeTsArrayIntoObject(record.timeSeriesDaily, item.timeSeriesDaily);
|
||||
mergeTsArrayIntoObject(record.timeSeriesMonthly, item.timeSeriesMonthly);
|
||||
mergeTsArrayIntoObject(record.cases.timeSeriesDaily, item.cases.timeSeriesDaily);
|
||||
mergeTsArrayIntoObject(record.cases.timeSeriesMonthly, item.cases.timeSeriesMonthly);
|
||||
});
|
||||
|
||||
Object.keys(perStateTotals).forEach((stateName) => {
|
||||
@ -608,36 +568,12 @@ const processRecords = async () => {
|
||||
population: item.population,
|
||||
deathsPerMillion: item.population > 0 ? item.total / item.population * 1000000 : 0,
|
||||
casesPerMillion: item.population > 0 ? item.cases.total / item.population * 1000000 : 0,
|
||||
timeSeriesDaily: Object.keys(item.timeSeriesDaily).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.timeSeriesDaily[date].value,
|
||||
delta: item.timeSeriesDaily[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesMonthly: Object.keys(item.timeSeriesMonthly).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.timeSeriesMonthly[date].value,
|
||||
delta: item.timeSeriesMonthly[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesDaily: convertTsObjectToArray(item.timeSeriesDaily),
|
||||
timeSeriesMonthly: convertTsObjectToArray(item.timeSeriesMonthly),
|
||||
cases: {
|
||||
total: item.cases.total,
|
||||
timeSeriesDaily: Object.keys(item.cases.timeSeriesDaily).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.cases.timeSeriesDaily[date].value,
|
||||
delta: item.cases.timeSeriesDaily[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesMonthly: Object.keys(item.cases.timeSeriesMonthly).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.cases.timeSeriesMonthly[date].value,
|
||||
delta: item.cases.timeSeriesMonthly[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesDaily: convertTsObjectToArray(item.cases.timeSeriesDaily),
|
||||
timeSeriesMonthly: convertTsObjectToArray(item.cases.timeSeriesMonthly),
|
||||
},
|
||||
};
|
||||
|
||||
@ -646,6 +582,7 @@ const processRecords = async () => {
|
||||
stateItem.rollingAverageDaily = getRollingAverage(stateItem);
|
||||
stateItem.doublingDaily = getDoublingTime(stateItem);
|
||||
stateItem.cases.rollingAverageDaily = getRollingAverage(stateItem.cases);
|
||||
stateItem.cases.doublingDaily = getDoublingTime(stateItem.cases);
|
||||
|
||||
// insert into states array for the country
|
||||
perCountryTotals[item.country].states.push(stateItem);
|
||||
@ -672,36 +609,12 @@ const processRecords = async () => {
|
||||
population: item.population,
|
||||
deathsPerMillion: item.population > 0 ? item.total / item.population * 1000000 : 0,
|
||||
casesPerMillion: item.population > 0 ? item.cases.total / item.population * 1000000 : 0,
|
||||
timeSeriesDaily: Object.keys(item.timeSeriesDaily).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.timeSeriesDaily[date].value,
|
||||
delta: item.timeSeriesDaily[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesMonthly: Object.keys(item.timeSeriesMonthly).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.timeSeriesMonthly[date].value,
|
||||
delta: item.timeSeriesMonthly[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesDaily: convertTsObjectToArray(item.timeSeriesDaily),
|
||||
timeSeriesMonthly: convertTsObjectToArray(item.timeSeriesMonthly),
|
||||
cases: {
|
||||
total: item.cases.total,
|
||||
timeSeriesDaily: Object.keys(item.cases.timeSeriesDaily).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.cases.timeSeriesDaily[date].value,
|
||||
delta: item.cases.timeSeriesDaily[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesMonthly: Object.keys(item.cases.timeSeriesMonthly).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: item.cases.timeSeriesMonthly[date].value,
|
||||
delta: item.cases.timeSeriesMonthly[date].delta,
|
||||
};
|
||||
}),
|
||||
timeSeriesDaily: convertTsObjectToArray(item.cases.timeSeriesDaily),
|
||||
timeSeriesMonthly: convertTsObjectToArray(item.cases.timeSeriesMonthly),
|
||||
},
|
||||
};
|
||||
|
||||
@ -710,6 +623,7 @@ const processRecords = async () => {
|
||||
countryItem.rollingAverageDaily = getRollingAverage(countryItem);
|
||||
countryItem.doublingDaily = getDoublingTime(countryItem);
|
||||
countryItem.cases.rollingAverageDaily = getRollingAverage(countryItem.cases);
|
||||
countryItem.cases.doublingDaily = getDoublingTime(countryItem.cases);
|
||||
return countryItem;
|
||||
});
|
||||
|
||||
@ -731,77 +645,23 @@ const processRecords = async () => {
|
||||
worldData.total += countryData.total;
|
||||
worldData.cases.total += countryData.cases.total;
|
||||
|
||||
countryData.timeSeriesDaily.forEach((ts) => {
|
||||
worldData.timeSeriesDaily[ts.key] = worldData.timeSeriesDaily[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
worldData.timeSeriesDaily[ts.key].value += ts.value;
|
||||
worldData.timeSeriesDaily[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
countryData.timeSeriesMonthly.forEach((ts) => {
|
||||
worldData.timeSeriesMonthly[ts.key] = worldData.timeSeriesMonthly[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
worldData.timeSeriesMonthly[ts.key].value += ts.value;
|
||||
worldData.timeSeriesMonthly[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
countryData.cases.timeSeriesDaily.forEach((ts) => {
|
||||
worldData.cases.timeSeriesDaily[ts.key] = worldData.cases.timeSeriesDaily[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
worldData.cases.timeSeriesDaily[ts.key].value += ts.value;
|
||||
worldData.cases.timeSeriesDaily[ts.key].delta += ts.delta;
|
||||
});
|
||||
|
||||
countryData.cases.timeSeriesMonthly.forEach((ts) => {
|
||||
worldData.cases.timeSeriesMonthly[ts.key] = worldData.cases.timeSeriesMonthly[ts.key] || {
|
||||
value: 0,
|
||||
delta: 0,
|
||||
};
|
||||
worldData.cases.timeSeriesMonthly[ts.key].value += ts.value;
|
||||
worldData.cases.timeSeriesMonthly[ts.key].delta += ts.delta;
|
||||
});
|
||||
mergeTsArrayIntoObject(countryData.timeSeriesDaily, worldData.timeSeriesDaily);
|
||||
mergeTsArrayIntoObject(countryData.timeSeriesMonthly, worldData.timeSeriesMonthly);
|
||||
mergeTsArrayIntoObject(countryData.cases.timeSeriesDaily, worldData.cases.timeSeriesDaily);
|
||||
mergeTsArrayIntoObject(countryData.cases.timeSeriesMonthly, worldData.cases.timeSeriesMonthly);
|
||||
});
|
||||
|
||||
worldData.timeSeriesDaily = Object.keys(worldData.timeSeriesDaily).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: worldData.timeSeriesDaily[date].value,
|
||||
delta: worldData.timeSeriesDaily[date].delta,
|
||||
};
|
||||
});
|
||||
worldData.timeSeriesMonthly = Object.keys(worldData.timeSeriesMonthly).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: worldData.timeSeriesMonthly[date].value,
|
||||
delta: worldData.timeSeriesMonthly[date].delta,
|
||||
};
|
||||
});
|
||||
worldData.cases.timeSeriesDaily = Object.keys(worldData.cases.timeSeriesDaily).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: worldData.cases.timeSeriesDaily[date].value,
|
||||
delta: worldData.cases.timeSeriesDaily[date].delta,
|
||||
};
|
||||
});
|
||||
worldData.cases.timeSeriesMonthly = Object.keys(worldData.cases.timeSeriesMonthly).sort().map((date) => {
|
||||
return {
|
||||
key: date,
|
||||
value: worldData.cases.timeSeriesMonthly[date].value,
|
||||
delta: worldData.cases.timeSeriesMonthly[date].delta,
|
||||
};
|
||||
});
|
||||
worldData.timeSeriesDaily = convertTsObjectToArray(worldData.timeSeriesDaily);
|
||||
worldData.timeSeriesMonthly = convertTsObjectToArray(worldData.timeSeriesMonthly);
|
||||
worldData.cases.timeSeriesDaily = convertTsObjectToArray(worldData.cases.timeSeriesDaily);
|
||||
worldData.cases.timeSeriesMonthly = convertTsObjectToArray(worldData.cases.timeSeriesMonthly);
|
||||
|
||||
worldData.deathGrowthRate = getGrowthRate(worldData.timeSeriesDaily);
|
||||
worldData.casesGrowthRate = getGrowthRate(worldData.cases.timeSeriesDaily);
|
||||
worldData.rollingAverageDaily = getRollingAverage(worldData);
|
||||
worldData.doublingDaily = getDoublingTime(worldData);
|
||||
worldData.cases.rollingAverageDaily = getRollingAverage(worldData.cases);
|
||||
worldData.cases.doublingDaily = getDoublingTime(worldData.cases);
|
||||
|
||||
worldData.population = 7781841000;
|
||||
worldData.deathsPerMillion = worldData.total / worldData.population * 1000000;
|
||||
|
140
tmpl/master.pug
140
tmpl/master.pug
@ -25,6 +25,22 @@ html
|
||||
bottom: -1px;
|
||||
border-bottom: 2px solid #b5b5b5;
|
||||
}
|
||||
#hero-tooltip table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#hero-tooltip th, #hero-tooltip td {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
[class^="tooltip-color-"] {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 2px solid black;
|
||||
display: inline-block;
|
||||
}
|
||||
[class^="tooltip-value-"] {
|
||||
text-align: right;
|
||||
font-family: monospace;
|
||||
}
|
||||
.geo-bg-dark {
|
||||
background-color: #8e8e8e;
|
||||
color: white;
|
||||
@ -223,6 +239,7 @@ html
|
||||
doubling,
|
||||
totalCases,
|
||||
newCases,
|
||||
doublingCases,
|
||||
) {
|
||||
const canvas = document.getElementById(id);
|
||||
charts.heroMaxValue = totalCases.reduce((max, value) => Math.max(max, value), 0);
|
||||
@ -234,7 +251,8 @@ html
|
||||
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 deathDoublingData = doubling.slice(start, end);
|
||||
const caseDoublingData = doublingCases.slice(start, end);
|
||||
const totalCaseData = totalCases.slice(start, end);
|
||||
const newCaseData = newCases.slice(start, end);
|
||||
|
||||
@ -286,19 +304,30 @@ html
|
||||
label: 'New Deaths',
|
||||
data: newData,
|
||||
fill: false,
|
||||
borderColor: 'rgb(96, 96, 96, 0.25)',
|
||||
backgroundColor: 'rgb(96, 96, 96, 0.25)',
|
||||
borderColor: 'rgb(20,24,59, 0.15)',
|
||||
backgroundColor: 'rgb(20,24,59, 0.15)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
{
|
||||
label: 'Days to 2x deaths',
|
||||
data: doublingData,
|
||||
data: deathDoublingData,
|
||||
fill: false,
|
||||
borderColor: 'rgb(187,40,193, 0.5)',
|
||||
backgroundColor: 'rgb(187,40,193, 0.5)',
|
||||
borderColor: 'rgba(127,30,75,0.5)',
|
||||
backgroundColor: 'rgb(127,30,75, 0.5)',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
}
|
||||
borderDash: [ 4, 4 ],
|
||||
},
|
||||
{
|
||||
label: 'Days to 2x cases',
|
||||
data: caseDoublingData,
|
||||
fill: false,
|
||||
borderColor: 'rgba(87,86,38,0.5)',
|
||||
backgroundColor: 'rgb(87,86,38, 0.5)',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderDash: [ 4, 4 ],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
@ -313,6 +342,102 @@ html
|
||||
intersect: false,
|
||||
position: 'middle',
|
||||
axis: 'x',
|
||||
enabled: false,
|
||||
custom: function(tooltipModel) {
|
||||
let tooltipEl = document.getElementById('hero-tooltip');
|
||||
|
||||
// Create element on first render
|
||||
if (!tooltipEl) {
|
||||
tooltipEl = document.createElement('div');
|
||||
tooltipEl.id = 'hero-tooltip';
|
||||
const border = '1px solid #606060';
|
||||
tooltipEl.innerHTML = `
|
||||
<div class="text-center" style="font-size: 125%; border-bottom: ${border};">
|
||||
<strong class="tooltip-title"></strong>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><span class="tooltip-color-cases-total"></span></td>
|
||||
<th>Total Cases</th>
|
||||
<td class="tooltip-value-cases-total"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="tooltip-color-cases-new"></span></td>
|
||||
<th>New Cases</th>
|
||||
<td class="tooltip-value-cases-new"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="tooltip-color-deaths-total"></span></td>
|
||||
<th>Total Deaths</th>
|
||||
<td class="tooltip-value-deaths-total"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="tooltip-color-deaths-new"></span></td>
|
||||
<th>New Deaths</th>
|
||||
<td class="tooltip-value-deaths-new"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="text-center pt-1" style="border-top: ${border}">
|
||||
Deaths 2x every <strong class="tooltip-2x-deaths"></strong><br />
|
||||
Cases 2x every <strong class="tooltip-2x-cases"></strong><br />
|
||||
</div>
|
||||
`;
|
||||
tooltipEl.style.zIndex = '1000';
|
||||
document.body.appendChild(tooltipEl);
|
||||
}
|
||||
|
||||
if (tooltipModel.opacity === 0) {
|
||||
tooltipEl.style.opacity = '0';
|
||||
return;
|
||||
}
|
||||
|
||||
tooltipEl.style.backgroundImage = 'linear-gradient(to bottom, rgba(52, 52, 52, 0.75), rgba(24, 24, 24, 0.75))';
|
||||
tooltipEl.style.color = 'white';
|
||||
tooltipEl.style.textShadow = '1px 1px 1px black';
|
||||
tooltipEl.style.borderRadius = '2px';
|
||||
tooltipEl.style.boxShadow = '2px 2px 3px rgba(0, 0, 0, 0.75)';
|
||||
|
||||
if (tooltipModel.dataPoints) {
|
||||
tooltipEl.querySelector('.tooltip-title').textContent = tooltipModel.title.join(' ');
|
||||
const setData = (cls, index, colorIndex) => {
|
||||
colorIndex = typeof(colorIndex) === 'number' ? colorIndex : index;
|
||||
const color = tooltipModel.labelColors[colorIndex];
|
||||
const value = Number(tooltipModel.dataPoints[index].value).toLocaleString();
|
||||
tooltipEl.querySelector('.tooltip-value-' + cls).textContent = value;
|
||||
const colorEl = tooltipEl.querySelector('.tooltip-color-' + cls);
|
||||
colorEl.style.backgroundColor = color.backgroundColor;
|
||||
colorEl.style.borderColor = color.borderColor;
|
||||
};
|
||||
|
||||
setData('cases-total', 0);
|
||||
setData('cases-new', 1);
|
||||
setData('deaths-total', 2);
|
||||
setData('deaths-new', 4, 3);
|
||||
|
||||
const daysToDoubleDeaths = Number(tooltipModel.dataPoints[5].value).toLocaleString();
|
||||
const daysToDoubleCases = Number(tooltipModel.dataPoints[6].value).toLocaleString();
|
||||
tooltipEl.querySelector('.tooltip-2x-deaths').textContent = daysToDoubleDeaths + ' days';
|
||||
tooltipEl.querySelector('.tooltip-2x-cases').textContent = daysToDoubleCases + ' days';
|
||||
}
|
||||
|
||||
const position = this._chart.canvas.getBoundingClientRect();
|
||||
|
||||
// Display, position, and set styles for font
|
||||
tooltipEl.style.opacity = '1';
|
||||
tooltipEl.style.position = 'absolute';
|
||||
|
||||
tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
|
||||
tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
|
||||
tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
|
||||
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
|
||||
tooltipEl.style.pointerEvents = 'none';
|
||||
|
||||
const tooltipSize = tooltipEl.getBoundingClientRect();
|
||||
const chartArea = this._chart.chartArea;
|
||||
const chartHeight = chartArea.bottom - chartArea.top;
|
||||
tooltipEl.style.left = (position.left + window.pageXOffset + tooltipModel.x) + 'px';
|
||||
tooltipEl.style.top = (position.top + window.pageYOffset + chartArea.top + (chartHeight / 2) - (tooltipSize.height / 2)) + 'px';
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
yAxes: [
|
||||
@ -400,6 +525,7 @@ html
|
||||
!{JSON.stringify(data.doublingDaily.map(x => x.value))},
|
||||
!{JSON.stringify(data.cases.timeSeriesDaily.map(x => x.value))},
|
||||
!{JSON.stringify(data.cases.timeSeriesDaily.map(x => x.delta))},
|
||||
!{JSON.stringify(data.cases.doublingDaily.map(x => x.value))},
|
||||
);
|
||||
|
||||
mixin dataTable(items, label, type)
|
||||
|
Loading…
Reference in New Issue
Block a user