covid19/tmpl/country.pug

216 lines
5.7 KiB
Plaintext
Raw Normal View History

2020-04-27 03:04:16 +00:00
extends ./master.pug
mixin sortableLinks(col, label)
span.sortables.float-left.mr-2.d-inline-flex.flex-column(style="font-size: 50%")
a(href="#sort:" + col + ":asc") ▲
a(href="#sort:" + col + ":desc") ▼
block
block main
h2
a.float-right(href="/" style="font-size: 50%") ◀ All Countries
=data.name
div.card
div.card-body
canvas.mx-auto(id="main-chart" width="800" height="450")
script.
(function() {
const canvas = document.getElementById('main-chart');
const chart = new Chart(canvas.getContext('2d'), {
type: 'line',
data: {
labels: !{JSON.stringify(data.timeSeriesDaily.map(x => x.key))},
datasets: [
{
label: 'Deaths',
data: !{JSON.stringify(data.timeSeriesDaily.map(x => x.value))},
fill: true,
borderColor: 'rgb(196, 64, 64)',
backgroundColor: 'rgba(196, 64, 64, 0.5)',
}
],
},
options: {
responsive: false,
title: {
display: true,
position: 'top',
text: !{JSON.stringify(data.name || '')}
},
scales: {
yAxes: [
{
display: true,
ticks: {
precision: 0,
beginAtZero: true,
}
},
],
xAxes: [
{
display: true,
},
],
}
}
});
}());
div#table.table-responsive: table.table.table-sm.table-hover
thead: tr
th #
th: +sortableLinks("name") State/Province
th: +sortableLinks("total") Deaths
th: +sortableLinks("yesterday") …since yesterday
th: +sortableLinks("week") …since last week
th: +sortableLinks("month") …month-to-date
th Last 14 days
tbody: each item, i in data.states
- const yesterday = item.timeSeriesDaily[item.timeSeriesDaily.length - 1].delta || 0;
- const lastWeek = item.timeSeriesDaily[item.timeSeriesDaily.length - 1].value - item.timeSeriesDaily[item.timeSeriesDaily.length - 7].value;
- const lastMonth = item.timeSeriesMonthly[item.timeSeriesMonthly.length - 1].delta || 0;
tr(id="row-" + item.stateSafeName data-name=item.state data-total=item.total data-yesterday=yesterday data-week=lastWeek data-month=lastMonth)
td.sort-order= i + 1
td
if item.state
= item.state
else
em.text-muted All #{item.country}
td.text-right: +formatNumber(item.total)
td.text-right: +formatNumber(yesterday)
td.text-right: +formatNumber(lastWeek)
td.text-right: +formatNumber(lastMonth)
td
canvas(id="sparkline-" + i width="200" height="50")
script.
(function() {
const canvas = document.getElementById('sparkline-#{i}');
const chart = new Chart(canvas.getContext('2d'), {
type: 'line',
data: {
labels: [ 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14 ],
datasets: [
{
data: #{JSON.stringify(item.timeSeriesDaily.slice(-14).map(x => x.value))},
}
],
},
options: {
responsive: false,
legend: {
display: false,
},
elements: {
line: {
borderColor: '#000000',
borderWidth: 1,
},
point: {
radius: 0,
},
},
tooltips: {
enabled: false,
},
scales: {
yAxes: [
{
display: false,
ticks: {
precision: 0,
beginAtZero: true,
}
},
],
xAxes: [
{
display: false,
},
],
}
}
});
}());
script.
(function() {
const tbody = document.getElementById('table').querySelector('tbody');
const allRows = [].slice.call(tbody.querySelectorAll('tbody tr'));
const resortTable = () => {
let nextChild = null;
for (let i = allRows.length - 1; i >= 0; i--) {
const row = allRows[i];
if (!row) {
continue;
}
if (row === nextChild) {
continue;
}
tbody.insertBefore(row, nextChild);
row.querySelector('.sort-order').textContent = (i + 1).toString();
nextChild = row;
}
};
const handleSort = (value, dir) => {
const newSortDir = dir === 'desc' ? 'desc' : 'asc';
const sortByNumberThenName = (attr) => {
allRows.sort((a, b) => {
const aValue = Number(a.getAttribute('data-' + attr));
const bValue = Number(b.getAttribute('data-' + attr));
if (aValue === bValue) {
const aName = a.getAttribute('data-name');
const bName = b.getAttribute('data-name');
return aName.localeCompare(bName);
}
return aValue < bValue ?
(newSortDir === 'asc' ? -1 : 1) :
(newSortDir === 'asc' ? 1 : -1);
});
resortTable();
};
switch (value) {
case 'name':
allRows.sort((a, b) => {
const aName = a.getAttribute('data-name');
const bName = b.getAttribute('data-name');
if (newSortDir === 'asc') {
return aName.localeCompare(bName);
}
return bName.localeCompare(aName);
});
resortTable();
break;
case 'total':
sortByNumberThenName('total');
break;
case 'yesterday':
sortByNumberThenName('yesterday');
break;
case 'week':
sortByNumberThenName('week');
break;
case 'month':
sortByNumberThenName('month');
break;
}
};
const handleHash = (hash) => {
const sortValue = hash.replace(/^#sort:/, '').split(':');
handleSort(sortValue[0], sortValue[1]);
};
window.addEventListener('hashchange', () => {
handleHash(window.location.hash);
});
handleHash(window.location.hash);
}());