fix bugs
This commit is contained in:
@@ -318,7 +318,7 @@ function buildMixedTrendChart(canvasId, labels, samples, lines) {
|
||||
type: 'bar',
|
||||
label: 'Total Cases',
|
||||
data: samples,
|
||||
backgroundColor: '#d34646',
|
||||
backgroundColor: '#007ce8',
|
||||
maxBarThickness: 60,
|
||||
yAxisID: 'y',
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ function prepareMapForExport() {
|
||||
[14.7, 107.6]
|
||||
]);
|
||||
|
||||
map.fitBounds(bounds);
|
||||
window.map.fitBounds(bounds);
|
||||
|
||||
}
|
||||
async function exportFullDashboard() {
|
||||
@@ -273,7 +273,7 @@ async function exportFullDashboard() {
|
||||
|
||||
if (mapEl && originalMapHTML !== null) {
|
||||
mapEl.innerHTML = originalMapHTML;
|
||||
map.invalidateSize();
|
||||
window.map.invalidateSize();
|
||||
}
|
||||
|
||||
const img = canvas.toDataURL("image/jpeg", 0.95);
|
||||
@@ -329,8 +329,8 @@ async function getMapImage() {
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
|
||||
const zoom = map.getZoom();
|
||||
const projection = map.options.crs;
|
||||
const zoom = window.map.getZoom();
|
||||
const projection = window.map.options.crs;
|
||||
|
||||
const projectedRings = [];
|
||||
|
||||
@@ -341,8 +341,7 @@ async function getMapImage() {
|
||||
const rows = window.latestProvinceData || [];
|
||||
|
||||
rows.forEach(r => {
|
||||
const province = normalizeProvince(r.patient_province, window.validProvinces);
|
||||
console.log(province, totals[province]);
|
||||
const province = window.normalizeProvince(r.patient_province, window.validProvinces);
|
||||
if (!province) return;
|
||||
|
||||
if (!totals[province]) {
|
||||
@@ -360,7 +359,7 @@ async function getMapImage() {
|
||||
return "#f3f4f600";
|
||||
}
|
||||
|
||||
map.eachLayer(layer => {
|
||||
window.map.eachLayer(layer => {
|
||||
if (!layer.toGeoJSON) return;
|
||||
if (layer instanceof L.CircleMarker) {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const COLORS = [
|
||||
|
||||
'#2563eb', // blue
|
||||
'#ef4444', // blue
|
||||
'#10b981', // emerald
|
||||
'#f59e0b', // amber
|
||||
'#ef4444', // red
|
||||
|
||||
@@ -93,7 +93,8 @@ function renderTrend(valueId, changeId, current, previous, suffix = '') {
|
||||
function getSubtypeColor(label, index = 0) {
|
||||
|
||||
const specialColors = {
|
||||
'A/H5N1': '#dc2626'
|
||||
'A/H5N1': '#dc2626',
|
||||
'Influenza': '#b90c00'
|
||||
};
|
||||
|
||||
return specialColors[label]
|
||||
@@ -131,7 +132,10 @@ function renderDashboard(data = {}) {
|
||||
'doughnut',
|
||||
(data.pathogen_distribution || [])
|
||||
.sort((a, b) => b.total - a.total),
|
||||
'pathogen'
|
||||
'pathogen',
|
||||
'total',
|
||||
getSubtypeColor
|
||||
|
||||
);
|
||||
|
||||
buildDistributionChart(
|
||||
@@ -254,6 +258,8 @@ function normalizeProvince(name, validSet) {
|
||||
|
||||
return match || null;
|
||||
}
|
||||
window.normalizeProvince = normalizeProvince;
|
||||
|
||||
function renderProvinceHeatmap(rows = []) {
|
||||
|
||||
window.latestProvinceData = rows;
|
||||
@@ -264,7 +270,7 @@ function renderProvinceHeatmap(rows = []) {
|
||||
|
||||
map = L.map('provinceMap')
|
||||
.setView([12.7, 104.9], 7);
|
||||
|
||||
window.map = map;
|
||||
L.tileLayer(
|
||||
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
{
|
||||
@@ -593,7 +599,7 @@ function renderProgramTrend(rows = []) {
|
||||
|
||||
}),
|
||||
|
||||
color: '#1976D2'
|
||||
color: '#d21919'
|
||||
},
|
||||
|
||||
{
|
||||
@@ -722,20 +728,33 @@ function renderProgramTrend(rows = []) {
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function renderAFITrend(
|
||||
rows = [],
|
||||
data = {},
|
||||
canvasId,
|
||||
COLORS,
|
||||
type = 'trend'
|
||||
) {
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DATA
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const rows =
|
||||
data.rows || [];
|
||||
|
||||
const totals =
|
||||
data.totals || [];
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| EMPTY
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
if (!rows.length) {
|
||||
if (!totals.length) {
|
||||
|
||||
if (type === 'donut') {
|
||||
|
||||
@@ -761,6 +780,57 @@ function renderAFITrend(
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| LABELS
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const labels = [...new Set(
|
||||
|
||||
totals.map(r =>
|
||||
|
||||
`${r.year}-W${r.period}`
|
||||
|
||||
)
|
||||
|
||||
)].sort((a, b) => {
|
||||
|
||||
const [yearA, weekA] =
|
||||
a.split('-W').map(Number);
|
||||
|
||||
const [yearB, weekB] =
|
||||
b.split('-W').map(Number);
|
||||
|
||||
if (yearA !== yearB) {
|
||||
return yearA - yearB;
|
||||
}
|
||||
|
||||
return weekA - weekB;
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| TOTAL CASES (BLUE BARS)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const totalCases = labels.map(label => {
|
||||
|
||||
const row = totals.find(r =>
|
||||
|
||||
`${r.year}-W${r.period}`
|
||||
=== label
|
||||
|
||||
);
|
||||
|
||||
return Number(
|
||||
row?.total_cases || 0
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DONUT
|
||||
@@ -800,16 +870,26 @@ function renderAFITrend(
|
||||
'total'
|
||||
);
|
||||
|
||||
if (charts[canvasId]) {
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DONUT CENTER TOTAL
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| MUST MATCH SUM OF BLUE BARS
|
||||
|
|
||||
*/
|
||||
|
||||
const totalCases = rows.reduce(
|
||||
(sum, r) =>
|
||||
sum + Number(r.total_cases || 0),
|
||||
const donutTotal =
|
||||
|
||||
totalCases.reduce(
|
||||
(a, b) => a + b,
|
||||
0
|
||||
);
|
||||
|
||||
if (charts[canvasId]) {
|
||||
|
||||
charts[canvasId].$afiTotalCases =
|
||||
totalCases;
|
||||
donutTotal;
|
||||
|
||||
charts[canvasId].update();
|
||||
|
||||
@@ -818,90 +898,6 @@ function renderAFITrend(
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| YEARLY VIEW
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const years = [...new Set(
|
||||
rows.map(r => Number(r.year))
|
||||
)];
|
||||
|
||||
const totalYears =
|
||||
Math.max(...years) - Math.min(...years);
|
||||
|
||||
const useYearlyView =
|
||||
totalYears >= 5;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| LABELS
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
let labels;
|
||||
|
||||
if (useYearlyView) {
|
||||
|
||||
labels = [...new Set(
|
||||
rows.map(r => String(r.year))
|
||||
)].sort();
|
||||
|
||||
} else {
|
||||
|
||||
labels = [...new Set(
|
||||
rows.map(r =>
|
||||
`${r.year}-W${r.period}`
|
||||
)
|
||||
)].sort((a, b) => {
|
||||
|
||||
const [yearA, weekA] =
|
||||
a.split('-W').map(Number);
|
||||
|
||||
const [yearB, weekB] =
|
||||
b.split('-W').map(Number);
|
||||
|
||||
if (yearA !== yearB) {
|
||||
return yearA - yearB;
|
||||
}
|
||||
|
||||
return weekA - weekB;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| TOTAL CASES
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const totalCases = labels.map(label => {
|
||||
|
||||
if (useYearlyView) {
|
||||
|
||||
return rows
|
||||
.filter(r =>
|
||||
String(r.year) === label
|
||||
)
|
||||
.reduce(
|
||||
(sum, r) =>
|
||||
sum + Number(r.total_cases || 0),
|
||||
0
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
const row = rows.find(r =>
|
||||
`${r.year}-W${r.period}` === label
|
||||
);
|
||||
|
||||
return row?.total_cases || 0;
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| PATHOGENS
|
||||
@@ -929,26 +925,6 @@ function renderAFITrend(
|
||||
|
||||
data: labels.map(label => {
|
||||
|
||||
if (useYearlyView) {
|
||||
|
||||
const filtered = rows.filter(r =>
|
||||
String(r.year) === label &&
|
||||
r.pathogen === pathogen
|
||||
);
|
||||
|
||||
const total =
|
||||
filtered.reduce(
|
||||
(sum, r) =>
|
||||
sum + Number(r.positivity_rate || 0),
|
||||
0
|
||||
);
|
||||
|
||||
return filtered.length
|
||||
? total / filtered.length
|
||||
: 0;
|
||||
|
||||
}
|
||||
|
||||
const row = rows.find(r =>
|
||||
|
||||
`${r.year}-W${r.period}`
|
||||
@@ -958,7 +934,9 @@ function renderAFITrend(
|
||||
|
||||
);
|
||||
|
||||
return row?.positivity_rate || 0;
|
||||
return Number(
|
||||
row?.positivity_rate || 0
|
||||
);
|
||||
|
||||
}),
|
||||
|
||||
@@ -970,6 +948,12 @@ function renderAFITrend(
|
||||
})
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| BUILD
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
buildMixedTrendChart(
|
||||
canvasId,
|
||||
labels,
|
||||
@@ -978,6 +962,8 @@ function renderAFITrend(
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function renderPathogenChart(rows = []) {
|
||||
buildDistributionChart(
|
||||
'pathogenChart',
|
||||
|
||||
Reference in New Issue
Block a user