Merge branch 'master' of github.com:khantey1998/nrml-dashboard
This commit is contained in:
@@ -139,6 +139,87 @@ class DashboardController extends Controller
|
|||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Influenza subtype distribution (Overview)
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function influenzaSubtypeDetected(Request $request)
|
||||||
|
{
|
||||||
|
$range = $this->getEpiRange($request);
|
||||||
|
|
||||||
|
if (!$range) {
|
||||||
|
return response()->json(['error' => 'Missing epiweek range'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->service->influenzaSubtypeDetected(
|
||||||
|
$range['startYear'],
|
||||||
|
$range['startWeek'],
|
||||||
|
$range['endYear'],
|
||||||
|
$range['endWeek']
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function covidDistributedByAgeGroup(Request $request)
|
||||||
|
{
|
||||||
|
$range = $this->getEpiRange($request);
|
||||||
|
|
||||||
|
if (!$range) {
|
||||||
|
return response()->json(['error' => 'Missing epiweek range'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->service->covidDistributedByAgeGroup(
|
||||||
|
$range['startYear'],
|
||||||
|
$range['startWeek'],
|
||||||
|
$range['endYear'],
|
||||||
|
$range['endWeek']
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function covidLineageRelativeOverTime(Request $request)
|
||||||
|
{
|
||||||
|
$range = $this->getEpiRange($request);
|
||||||
|
|
||||||
|
if (!$range) {
|
||||||
|
return response()->json(['error' => 'Missing epiweek range'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->service->covidLineageRelativeOverTime(
|
||||||
|
$range['startYear'],
|
||||||
|
$range['startWeek'],
|
||||||
|
$range['endYear'],
|
||||||
|
$range['endWeek']
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function influenzaRelativeOverTime(Request $request)
|
||||||
|
{
|
||||||
|
$range = $this->getEpiRange($request);
|
||||||
|
|
||||||
|
if (!$range) {
|
||||||
|
return response()->json(['error' => 'Missing epiweek range'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->service->influenzaRelativeOverTime(
|
||||||
|
$range['startYear'],
|
||||||
|
$range['startWeek'],
|
||||||
|
$range['endYear'],
|
||||||
|
$range['endWeek']
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -575,6 +575,33 @@ class DashboardService
|
|||||||
*/
|
*/
|
||||||
public function provinceCircles($startYear, $startWeek, $endYear, $endWeek)
|
public function provinceCircles($startYear, $startWeek, $endYear, $endWeek)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
return SurveillanceCase::join('case_lab_results', function ($join) {
|
||||||
|
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
|
||||||
|
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
|
||||||
|
})
|
||||||
|
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
|
||||||
|
$q->whereRaw(
|
||||||
|
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
|
||||||
|
[
|
||||||
|
$startYear * 100 + $startWeek,
|
||||||
|
$endYear * 100 + $endWeek
|
||||||
|
]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6) and case_lab_results.indicator="Influenza"')
|
||||||
|
->selectRaw("
|
||||||
|
surveillance_cases.patient_province,
|
||||||
|
case_lab_results.subtype as pathogen_name,
|
||||||
|
COUNT(DISTINCT surveillance_cases.lab_code) as total
|
||||||
|
")
|
||||||
|
->groupBy(
|
||||||
|
'surveillance_cases.patient_province',
|
||||||
|
'case_lab_results.subtype'
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
|
||||||
return SurveillanceCase::leftJoin(
|
return SurveillanceCase::leftJoin(
|
||||||
'case_lab_results',
|
'case_lab_results',
|
||||||
'surveillance_cases.lab_code',
|
'surveillance_cases.lab_code',
|
||||||
@@ -590,28 +617,156 @@ class DashboardService
|
|||||||
->whereRaw(
|
->whereRaw(
|
||||||
"(surveillance_cases.year_data < ? OR (surveillance_cases.year_data = ? AND surveillance_cases.week_data <= ?))",
|
"(surveillance_cases.year_data < ? OR (surveillance_cases.year_data = ? AND surveillance_cases.week_data <= ?))",
|
||||||
[$endYear, $endYear, $endWeek]
|
[$endYear, $endYear, $endWeek]
|
||||||
);
|
)
|
||||||
|
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6)');
|
||||||
})
|
})
|
||||||
|
|
||||||
->selectRaw("
|
->selectRaw("
|
||||||
surveillance_cases.patient_province,
|
surveillance_cases.patient_province,
|
||||||
surveillance_cases.surveillance_id,
|
case_lab_results.pathogen_name,
|
||||||
|
|
||||||
COUNT(DISTINCT surveillance_cases.lab_code) as total,
|
COUNT(DISTINCT surveillance_cases.lab_code) as total
|
||||||
|
|
||||||
COUNT(DISTINCT CASE
|
|
||||||
WHEN case_lab_results.is_positive = 1
|
|
||||||
THEN surveillance_cases.lab_code
|
|
||||||
END) as positive
|
|
||||||
")
|
")
|
||||||
|
|
||||||
->groupBy(
|
->groupBy(
|
||||||
'surveillance_cases.patient_province',
|
'surveillance_cases.patient_province',
|
||||||
'surveillance_cases.surveillance_id'
|
'case_lab_results.pathogen_name'
|
||||||
)
|
)
|
||||||
|
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start Overview Section */
|
||||||
|
|
||||||
|
public function influenzaSubtypeDetected($startYear, $startWeek, $endYear, $endWeek)
|
||||||
|
{
|
||||||
|
return SurveillanceCase::join('case_lab_results', function ($join) {
|
||||||
|
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
|
||||||
|
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
|
||||||
|
})
|
||||||
|
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
|
||||||
|
$q->whereRaw(
|
||||||
|
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
|
||||||
|
[
|
||||||
|
$startYear * 100 + $startWeek,
|
||||||
|
$endYear * 100 + $endWeek
|
||||||
|
]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6) and case_lab_results.indicator="Influenza"')
|
||||||
|
->selectRaw("
|
||||||
|
case_lab_results.subtype,
|
||||||
|
COUNT(DISTINCT surveillance_cases.lab_code) as total
|
||||||
|
")
|
||||||
|
->groupBy(
|
||||||
|
'case_lab_results.subtype'
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function covidDistributedByAgeGroup($startYear, $startWeek, $endYear, $endWeek)
|
||||||
|
{
|
||||||
|
return SurveillanceCase::join('case_lab_results', function ($join) {
|
||||||
|
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
|
||||||
|
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
|
||||||
|
})
|
||||||
|
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
|
||||||
|
$q->whereRaw(
|
||||||
|
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
|
||||||
|
[
|
||||||
|
$startYear * 100 + $startWeek,
|
||||||
|
$endYear * 100 + $endWeek
|
||||||
|
]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6) and case_lab_results.indicator="Covid-19"')
|
||||||
|
->selectRaw("
|
||||||
|
CASE
|
||||||
|
WHEN patient_age_inday <= 28 THEN '0–28 days'
|
||||||
|
WHEN patient_age_inday <= 364 THEN '29 days–11 months'
|
||||||
|
WHEN patient_age_inday <= 1460 THEN '1–4 years'
|
||||||
|
WHEN patient_age_inday <= 5110 THEN '5–14 years'
|
||||||
|
WHEN patient_age_inday <= 8765 THEN '15–24 years'
|
||||||
|
WHEN patient_age_inday <= 18250 THEN '25–49 years'
|
||||||
|
WHEN patient_age_inday <= 23725 THEN '50–64 years'
|
||||||
|
ELSE '65+ years'
|
||||||
|
END as age_group,
|
||||||
|
CASE
|
||||||
|
WHEN patient_age_inday <= 28 THEN 1
|
||||||
|
WHEN patient_age_inday <= 364 THEN 2
|
||||||
|
WHEN patient_age_inday <= 1460 THEN 3
|
||||||
|
WHEN patient_age_inday <= 5110 THEN 4
|
||||||
|
WHEN patient_age_inday <= 8765 THEN 5
|
||||||
|
WHEN patient_age_inday <= 18250 THEN 6
|
||||||
|
WHEN patient_age_inday <= 23725 THEN 7
|
||||||
|
ELSE 8
|
||||||
|
END as age_order,
|
||||||
|
COUNT(*) as total
|
||||||
|
")
|
||||||
|
->groupBy('age_group', 'age_order')
|
||||||
|
->orderBy('age_order')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function covidLineageRelativeOverTime($startYear, $startWeek, $endYear, $endWeek)
|
||||||
|
{
|
||||||
|
return SurveillanceCase::join('case_lab_results', function ($join) {
|
||||||
|
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
|
||||||
|
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
|
||||||
|
})
|
||||||
|
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
|
||||||
|
$q->whereRaw(
|
||||||
|
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
|
||||||
|
[
|
||||||
|
$startYear * 100 + $startWeek,
|
||||||
|
$endYear * 100 + $endWeek
|
||||||
|
]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id=6 and case_lab_results.indicator="Covid-19" and case_lab_results.pathogen_name not in("","unable to align","N/A","NA")')
|
||||||
|
->selectRaw("
|
||||||
|
case_lab_results.pathogen_name as lineage,
|
||||||
|
concat(surveillance_cases.year_data,'-',surveillance_cases.week_data) as week,
|
||||||
|
COUNT(DISTINCT surveillance_cases.lab_code) as total
|
||||||
|
")
|
||||||
|
->groupBy(
|
||||||
|
'case_lab_results.pathogen_name',
|
||||||
|
'week'
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function influenzaRelativeOverTime($startYear, $startWeek, $endYear, $endWeek)
|
||||||
|
{
|
||||||
|
return SurveillanceCase::join('case_lab_results', function ($join) {
|
||||||
|
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
|
||||||
|
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
|
||||||
|
})
|
||||||
|
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
|
||||||
|
$q->whereRaw(
|
||||||
|
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
|
||||||
|
[
|
||||||
|
$startYear * 100 + $startWeek,
|
||||||
|
$endYear * 100 + $endWeek
|
||||||
|
]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6) and case_lab_results.indicator="Influenza"')
|
||||||
|
->selectRaw("
|
||||||
|
case_lab_results.subtype as lineage,
|
||||||
|
concat(surveillance_cases.year_data,'-',surveillance_cases.week_data) as week,
|
||||||
|
COUNT(DISTINCT surveillance_cases.lab_code) as total
|
||||||
|
")
|
||||||
|
->groupBy(
|
||||||
|
'case_lab_results.subtype',
|
||||||
|
'week'
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End Overview Section */
|
||||||
|
|
||||||
public function provinceProgram($surveillanceId, $startYear, $startWeek, $endYear, $endWeek)
|
public function provinceProgram($surveillanceId, $startYear, $startWeek, $endYear, $endWeek)
|
||||||
{
|
{
|
||||||
return SurveillanceCase::selectRaw("
|
return SurveillanceCase::selectRaw("
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class DataRetrievalService
|
|||||||
$this->getILICases(now()->subDays(config('app.lookback_days.ILI'))->toDateString(), $toDate); // done
|
$this->getILICases(now()->subDays(config('app.lookback_days.ILI'))->toDateString(), $toDate); // done
|
||||||
$this->getLBMCases(now()->subDays(config('app.lookback_days.LBM'))->toDateString(), $toDate); // done
|
$this->getLBMCases(now()->subDays(config('app.lookback_days.LBM'))->toDateString(), $toDate); // done
|
||||||
$this->getAFICases(now()->subDays(config('app.lookback_days.AFI'))->toDateString(), $toDate); // done
|
$this->getAFICases(now()->subDays(config('app.lookback_days.AFI'))->toDateString(), $toDate); // done
|
||||||
//$this->getNSDCases(now()->subDays(config('app.lookback_days.NDS'))->toDateString(), $toDate);
|
$this->getNSDCases(now()->subDays(config('app.lookback_days.NDS'))->toDateString(), $toDate);
|
||||||
$this->getSEQCases(now()->subDays(config('app.lookback_days.SEQ'))->toDateString(), $toDate); // done
|
$this->getSEQCases(now()->subDays(config('app.lookback_days.SEQ'))->toDateString(), $toDate); // done
|
||||||
Log::channel('jobs')->info($toDate->toDateString(). ' Service Reload Data Successfully Ran');
|
Log::channel('jobs')->info($toDate->toDateString(). ' Service Reload Data Successfully Ran');
|
||||||
return true;
|
return true;
|
||||||
@@ -42,24 +42,35 @@ class DataRetrievalService
|
|||||||
->select("
|
->select("
|
||||||
SELECT
|
SELECT
|
||||||
patient.labcode,
|
patient.labcode,
|
||||||
patient.patdate,
|
min(if(year(tps.collected)=0,patient.patdate, tps.collected)) as patdate,
|
||||||
patient.isnewcase,
|
patient.isnewcase,
|
||||||
l.labname_en,
|
l.labname_en,
|
||||||
l.labaddress_en,
|
l.labaddress_en,
|
||||||
1 as surveillance_id,
|
1 as surveillance_id,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'Y') as year_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,patient.patdate, tps.collected), 'Y')) as year_data,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'W') as week_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,patient.patdate, tps.collected), 'W')) as week_data,
|
||||||
patient.patage,
|
patient.patage,
|
||||||
patient.patsex,
|
patient.patsex,
|
||||||
NULL as is_alive,
|
NULL as is_alive,
|
||||||
p.proname_en
|
p.proname_en
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.sari_patients sr_p on sr_p.patid = patient.patid
|
inner join niphc0_nphl.sari_patients sr_p on sr_p.patid = patient.patid
|
||||||
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid and tps.status = 1
|
||||||
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
||||||
left join niphc0_nphl.province p on p.proid = patient.frompro
|
left join niphc0_nphl.province p on p.proid = patient.frompro
|
||||||
WHERE patient.patgroup =2
|
WHERE patient.patgroup =2
|
||||||
and patient.status = 1
|
and patient.status = 1
|
||||||
".$cond);
|
".$cond . "
|
||||||
|
group by
|
||||||
|
patient.labcode,
|
||||||
|
patient.isnewcase,
|
||||||
|
l.labname_en,
|
||||||
|
l.labaddress_en,
|
||||||
|
patient.patage,
|
||||||
|
patient.patsex,
|
||||||
|
p.proname_en;"
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
$this->insert_surveillance_cases($sari_cases);
|
$this->insert_surveillance_cases($sari_cases);
|
||||||
|
|
||||||
@@ -71,7 +82,7 @@ class DataRetrievalService
|
|||||||
if(trs.rtitle='Negatives', 0, 1) as is_positive,
|
if(trs.rtitle='Negatives', 0, 1) as is_positive,
|
||||||
if(trs.rtitle !='Negatives', concat('Influenza ',LEFT(UPPER(trs.rtitle),1)),'') pathogen_name,
|
if(trs.rtitle !='Negatives', concat('Influenza ',LEFT(UPPER(trs.rtitle),1)),'') pathogen_name,
|
||||||
if(trs.rtitle !='Negatives', trs.rtitle, '') as subtype,
|
if(trs.rtitle !='Negatives', trs.rtitle, '') as subtype,
|
||||||
'SARI Influenza Test' as indicator
|
'Influenza' as indicator
|
||||||
FROM `labopatients` patient
|
FROM `labopatients` patient
|
||||||
inner join sari_patients sr_p on sr_p.patid = patient.patid
|
inner join sari_patients sr_p on sr_p.patid = patient.patid
|
||||||
inner join test_patsample tps on tps.patientid = patient.patid
|
inner join test_patsample tps on tps.patientid = patient.patid
|
||||||
@@ -93,7 +104,7 @@ class DataRetrievalService
|
|||||||
if(trs.rtitle='Negative', 0, 1) as is_positive,
|
if(trs.rtitle='Negative', 0, 1) as is_positive,
|
||||||
if(trs.rtitle !='Negative', 'SARS-CoV-2', '') as pathogen_name,
|
if(trs.rtitle !='Negative', 'SARS-CoV-2', '') as pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'SARI Covid Test' as indicator
|
'Covid-19' as indicator
|
||||||
FROM `labopatients` patient
|
FROM `labopatients` patient
|
||||||
inner join sari_patients sr_p
|
inner join sari_patients sr_p
|
||||||
on sr_p.patid = patient.patid
|
on sr_p.patid = patient.patid
|
||||||
@@ -126,24 +137,33 @@ class DataRetrievalService
|
|||||||
->select("
|
->select("
|
||||||
SELECT
|
SELECT
|
||||||
patient.labcode,
|
patient.labcode,
|
||||||
patient.patdate,
|
min(if(year(tps.collected)=0,patient.patdate, tps.collected)) as patdate,
|
||||||
patient.isnewcase,
|
patient.isnewcase,
|
||||||
l.labname_en,
|
l.labname_en,
|
||||||
l.labaddress_en,
|
l.labaddress_en,
|
||||||
2 as surveillance_id,
|
2 as surveillance_id,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'Y') as year_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,patient.patdate, tps.collected), 'Y')) as year_data,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'W') as week_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,patient.patdate, tps.collected), 'W')) as week_data,
|
||||||
patient.patage,
|
patient.patage,
|
||||||
patient.patsex,
|
patient.patsex,
|
||||||
NULL as is_alive,
|
NULL as is_alive,
|
||||||
p.proname_en
|
p.proname_en
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.ili_patients sr_p on sr_p.patid = patient.patid
|
inner join niphc0_nphl.ili_patients sr_p on sr_p.patid = patient.patid
|
||||||
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid and tps.status = 1
|
||||||
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
||||||
left join niphc0_nphl.province p on p.proid = patient.frompro
|
left join niphc0_nphl.province p on p.proid = patient.frompro
|
||||||
WHERE patient.patgroup =3
|
WHERE patient.patgroup =3
|
||||||
and patient.status = 1
|
and patient.status = 1
|
||||||
".$cond
|
".$cond . "
|
||||||
|
group by
|
||||||
|
patient.labcode,
|
||||||
|
patient.isnewcase,
|
||||||
|
l.labname_en,
|
||||||
|
l.labaddress_en,
|
||||||
|
patient.patage,
|
||||||
|
patient.patsex,
|
||||||
|
p.proname_en;"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -158,7 +178,7 @@ class DataRetrievalService
|
|||||||
if(trs.rtitle='Negatives', 0, 1) as is_positive,
|
if(trs.rtitle='Negatives', 0, 1) as is_positive,
|
||||||
if(trs.rtitle !='Negatives', concat('Influenza ',LEFT(UPPER(trs.rtitle),1)),'') pathogen_name,
|
if(trs.rtitle !='Negatives', concat('Influenza ',LEFT(UPPER(trs.rtitle),1)),'') pathogen_name,
|
||||||
if(trs.rtitle !='Negatives', trs.rtitle, '') as subtype,
|
if(trs.rtitle !='Negatives', trs.rtitle, '') as subtype,
|
||||||
'ILI Influenza Test' as indicator
|
'Influenza' as indicator
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.ili_patients sr_p on sr_p.patid = patient.patid
|
inner join niphc0_nphl.ili_patients sr_p on sr_p.patid = patient.patid
|
||||||
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
||||||
@@ -182,7 +202,7 @@ class DataRetrievalService
|
|||||||
if(trs.rtitle='Negative', 0, 1) as is_positive,
|
if(trs.rtitle='Negative', 0, 1) as is_positive,
|
||||||
if(trs.rtitle !='Negative', 'SARS-CoV-2', '') as pathogen_name,
|
if(trs.rtitle !='Negative', 'SARS-CoV-2', '') as pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'ILI Covid Test' as indicator
|
'Covid-19' as indicator
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.ili_patients sr_p on sr_p.patid = patient.patid
|
inner join niphc0_nphl.ili_patients sr_p on sr_p.patid = patient.patid
|
||||||
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
||||||
@@ -211,24 +231,34 @@ class DataRetrievalService
|
|||||||
->select("
|
->select("
|
||||||
SELECT
|
SELECT
|
||||||
patient.labcode,
|
patient.labcode,
|
||||||
patient.patdate,
|
min(if(year(tps.collected)=0,patient.patdate, tps.collected)) as patdate,
|
||||||
patient.isnewcase,
|
patient.isnewcase,
|
||||||
l.labname_en,
|
l.labname_en,
|
||||||
l.labaddress_en,
|
l.labaddress_en,
|
||||||
3 as surveillance_id,
|
3 as surveillance_id,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'Y') year_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,patient.patdate, tps.collected), 'Y')) as year_data,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'W') week_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,patient.patdate, tps.collected), 'W')) as week_data,
|
||||||
patient.patage,
|
patient.patage,
|
||||||
patient.patsex,
|
patient.patsex,
|
||||||
NULL as is_alive,
|
NULL as is_alive,
|
||||||
p.proname_en
|
p.proname_en
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.lbms_patients on lbms_patients.patid = patient.patid
|
inner join niphc0_nphl.lbms_patients on lbms_patients.patid = patient.patid
|
||||||
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid and tps.status = 1
|
||||||
left join niphc0_nphl.province p on p.proid = patient.frompro
|
left join niphc0_nphl.province p on p.proid = patient.frompro
|
||||||
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
||||||
WHERE patient.patgroup = 17
|
WHERE patient.patgroup = 17
|
||||||
and patient.status = 1
|
and patient.status = 1
|
||||||
".$cond);
|
".$cond . "
|
||||||
|
group by
|
||||||
|
patient.labcode,
|
||||||
|
patient.isnewcase,
|
||||||
|
l.labname_en,
|
||||||
|
l.labaddress_en,
|
||||||
|
patient.patage,
|
||||||
|
patient.patsex,
|
||||||
|
p.proname_en;"
|
||||||
|
);
|
||||||
|
|
||||||
$this->insert_surveillance_cases($lbm_cases);
|
$this->insert_surveillance_cases($lbm_cases);
|
||||||
|
|
||||||
@@ -241,7 +271,7 @@ class DataRetrievalService
|
|||||||
if(trs.rtitle='Negatives', 0, 1) as is_positive,
|
if(trs.rtitle='Negatives', 0, 1) as is_positive,
|
||||||
if(trs.rtitle !='Negatives', concat('Influenza ',LEFT(UPPER(trs.rtitle),1)),'') pathogen_name,
|
if(trs.rtitle !='Negatives', concat('Influenza ',LEFT(UPPER(trs.rtitle),1)),'') pathogen_name,
|
||||||
if(trs.rtitle !='Negatives', trs.rtitle, '') as subtype,
|
if(trs.rtitle !='Negatives', trs.rtitle, '') as subtype,
|
||||||
'LBM Influenza Test' as indicator
|
'Influenza' as indicator
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.lbms_patients sr_p on sr_p.patid = patient.patid
|
inner join niphc0_nphl.lbms_patients sr_p on sr_p.patid = patient.patid
|
||||||
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
||||||
@@ -264,7 +294,7 @@ class DataRetrievalService
|
|||||||
if(trs.rtitle='Negative', 0, 1) as is_positive,
|
if(trs.rtitle='Negative', 0, 1) as is_positive,
|
||||||
if(trs.rtitle !='Negative', 'SARS-CoV-2', '') as pathogen_name,
|
if(trs.rtitle !='Negative', 'SARS-CoV-2', '') as pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'LBM Covid Test' as indicator
|
'Covid-19' as indicator
|
||||||
FROM niphc0_nphl.`labopatients` patient
|
FROM niphc0_nphl.`labopatients` patient
|
||||||
inner join niphc0_nphl.lbms_patients sr_p on sr_p.patid = patient.patid
|
inner join niphc0_nphl.lbms_patients sr_p on sr_p.patid = patient.patid
|
||||||
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
||||||
@@ -287,19 +317,19 @@ class DataRetrievalService
|
|||||||
public function getAFICases($dateFrom, $dateTo = NULL)
|
public function getAFICases($dateFrom, $dateTo = NULL)
|
||||||
{
|
{
|
||||||
$cond = "";
|
$cond = "";
|
||||||
$cond .= " and afi_lab_result.results_date >= '".date('Y-m-d', strtotime($dateFrom))."' ";
|
$cond .= " and afi_case.date_of_interview >= '".date('Y-m-d', strtotime($dateFrom))."' ";
|
||||||
$cond .= (!empty($dateTo)) ? " and afi_lab_result.results_date <='".date('Y-m-d', strtotime($dateTo))."' ":"";
|
$cond .= (!empty($dateTo)) ? " and afi_case.date_of_interview <='".date('Y-m-d', strtotime($dateTo))."' ":"";
|
||||||
$afi_cases = DB::connection('mysql_afi')
|
$afi_cases = DB::connection('mysql_afi')
|
||||||
->select("
|
->select("
|
||||||
SELECT
|
SELECT
|
||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
afi_lab_result.results_date as patdate,
|
afi_case.date_of_interview as patdate,
|
||||||
1 as isnewcase,
|
1 as isnewcase,
|
||||||
afi_case.sentinel_site as labname_en,
|
afi_case.sentinel_site as labname_en,
|
||||||
'' as labaddress_en,
|
'' as labaddress_en,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
niphc0_nphl.get_epi_period(afi_lab_result.results_date, 'Y') as year_data,
|
niphc0_nphl.get_epi_period(afi_case.date_of_interview, 'Y') as year_data,
|
||||||
niphc0_nphl.get_epi_period(afi_lab_result.results_date, 'W') as week_data,
|
niphc0_nphl.get_epi_period(afi_case.date_of_interview, 'W') as week_data,
|
||||||
ifnull(DATEDIFF(afi_case.date_of_interview, date_of_birth),180) as patage,
|
ifnull(DATEDIFF(afi_case.date_of_interview, date_of_birth),180) as patage,
|
||||||
if(afi_case.sex='Male','M','F') as patsex,
|
if(afi_case.sex='Male','M','F') as patsex,
|
||||||
NULL as is_alive,
|
NULL as is_alive,
|
||||||
@@ -309,7 +339,8 @@ class DataRetrievalService
|
|||||||
left join niphc0_nphl.province p on p.proid = afi_case.residence_province
|
left join niphc0_nphl.province p on p.proid = afi_case.residence_province
|
||||||
where
|
where
|
||||||
afi_case.afi_event is NOT null
|
afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null " .$cond);
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null " .$cond);
|
||||||
|
|
||||||
$this->insert_surveillance_cases($afi_cases);
|
$this->insert_surveillance_cases($afi_cases);
|
||||||
|
|
||||||
@@ -321,13 +352,14 @@ class DataRetrievalService
|
|||||||
if(afi_lab_result.influenza_result='Positive',1,0) as is_positive,
|
if(afi_lab_result.influenza_result='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.influenza_result='Positive', concat('Influenza ',LEFT(UPPER(JSON_UNQUOTE(JSON_EXTRACT(afi_lab_result.influenza_subtypes, '$[0].id'))),1)),'') pathogen_name,
|
if(afi_lab_result.influenza_result='Positive', concat('Influenza ',LEFT(UPPER(JSON_UNQUOTE(JSON_EXTRACT(afi_lab_result.influenza_subtypes, '$[0].id'))),1)),'') pathogen_name,
|
||||||
if(afi_lab_result.influenza_result='Positive', REPLACE(UPPER(JSON_UNQUOTE(JSON_EXTRACT(afi_lab_result.influenza_subtypes, '$[0].id'))),'_','/'),'') as subtype,
|
if(afi_lab_result.influenza_result='Positive', REPLACE(UPPER(JSON_UNQUOTE(JSON_EXTRACT(afi_lab_result.influenza_subtypes, '$[0].id'))),'_','/'),'') as subtype,
|
||||||
'AFI Influenza Test' as indicator
|
'Influenza' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.influenza_result in('Negative', 'Positive')
|
and afi_lab_result.influenza_result in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
union
|
union
|
||||||
|
|
||||||
@@ -337,13 +369,15 @@ class DataRetrievalService
|
|||||||
if(afi_lab_result.sarscov2_result='Positive',1,0) as is_positive,
|
if(afi_lab_result.sarscov2_result='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.sarscov2_result='Positive', 'SARS-CoV-2','') pathogen_name,
|
if(afi_lab_result.sarscov2_result='Positive', 'SARS-CoV-2','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Covid Test' as indicator
|
'Covid-19' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.sarscov2_result in('Negative', 'Positive')
|
and afi_lab_result.sarscov2_result in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null
|
||||||
|
".$cond."
|
||||||
|
|
||||||
union
|
union
|
||||||
|
|
||||||
@@ -351,15 +385,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.dengue_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.dengue_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.dengue_pcr='Positive', 'Dengue','') pathogen_name,
|
if(afi_lab_result.dengue_pcr='Positive', 'Dengue Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Dengue PCR Test' as indicator
|
'Dengue Virus|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.dengue_pcr in('Negative', 'Positive')
|
and afi_lab_result.dengue_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
union
|
union
|
||||||
|
|
||||||
@@ -367,15 +402,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.chikungunya_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.chikungunya_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.chikungunya_pcr='Positive', 'Chikungunya','') pathogen_name,
|
if(afi_lab_result.chikungunya_pcr='Positive', 'Chikungunya Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Chikungunya PCR Test' as indicator
|
'Chikungunya Virus|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.chikungunya_pcr in('Negative', 'Positive')
|
and afi_lab_result.chikungunya_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
union
|
union
|
||||||
|
|
||||||
@@ -383,15 +419,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.leptospira_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.leptospira_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.leptospira_pcr='Positive', 'Leptospira','') pathogen_name,
|
if(afi_lab_result.leptospira_pcr='Positive', 'Leptospira spp.','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Leptospira PCR Test' as indicator
|
'Leptospira spp.|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.leptospira_pcr in('Negative', 'Positive')
|
and afi_lab_result.leptospira_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
union
|
union
|
||||||
|
|
||||||
@@ -399,15 +436,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.plasmodium_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.plasmodium_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.plasmodium_pcr='Positive', 'Plasmodium','') pathogen_name,
|
if(afi_lab_result.plasmodium_pcr='Positive', 'Plasmodium spp.','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Plasmodium PCR Test' as indicator
|
'Plasmodium spp.|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.plasmodium_pcr in('Negative', 'Positive')
|
and afi_lab_result.plasmodium_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -415,15 +453,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.rickettsia_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.rickettsia_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.rickettsia_pcr='Positive', 'Rickettsia','') pathogen_name,
|
if(afi_lab_result.rickettsia_pcr='Positive', 'Rickettsia spp.','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Rickettsia PCR Test' as indicator
|
'Rickettsia spp.|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.rickettsia_pcr in('Negative', 'Positive')
|
and afi_lab_result.rickettsia_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -431,15 +470,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.salmonella_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.salmonella_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.salmonella_pcr='Positive', 'Salmonella','') pathogen_name,
|
if(afi_lab_result.salmonella_pcr='Positive', 'Salmonella spp.','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Salmonella PCR Test' as indicator
|
'Salmonella spp.|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.salmonella_pcr in('Negative', 'Positive')
|
and afi_lab_result.salmonella_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -447,15 +487,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.westnile_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.westnile_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.westnile_pcr='Positive', 'Westnile Nile','') pathogen_name,
|
if(afi_lab_result.westnile_pcr='Positive', 'West Nile Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Westnile PCR Test' as indicator
|
'West Nile Virus|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.westnile_pcr in('Negative', 'Positive')
|
and afi_lab_result.westnile_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -463,15 +504,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.zika_pcr='Positive',1,0) as is_positive,
|
if(afi_lab_result.zika_pcr='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.zika_pcr='Positive', 'ZIKA','') pathogen_name,
|
if(afi_lab_result.zika_pcr='Positive', 'ZIKA Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI ZIKA PCR Test' as indicator
|
'ZIKA Virus|PCR' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.zika_pcr in('Negative', 'Positive')
|
and afi_lab_result.zika_pcr in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -481,15 +523,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.chikungunya_serum='Positive',1,0) as is_positive,
|
if(afi_lab_result.chikungunya_serum='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.chikungunya_serum='Positive', 'Chikungunya','') pathogen_name,
|
if(afi_lab_result.chikungunya_serum='Positive', 'Chikungunya Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Chikungunya Serum Test' as indicator
|
'Chikungunya Virus|Serum' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.chikungunya_serum in('Negative', 'Positive')
|
and afi_lab_result.chikungunya_serum in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -497,15 +540,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.dengue_serum='Positive',1,0) as is_positive,
|
if(afi_lab_result.dengue_serum='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.dengue_serum='Positive', 'Dengue','') pathogen_name,
|
if(afi_lab_result.dengue_serum='Positive', 'Dengue Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Dengue Serum Test' as indicator
|
'Dengue Virus|Serum' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.dengue_serum in('Negative', 'Positive')
|
and afi_lab_result.dengue_serum in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -513,15 +557,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.westnile_serum='Positive',1,0) as is_positive,
|
if(afi_lab_result.westnile_serum='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.westnile_serum='Positive', 'Westnile','') pathogen_name,
|
if(afi_lab_result.westnile_serum='Positive', 'West Nile Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Westnile Serum Test' as indicator
|
'West Nile Virus|Serum' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.westnile_serum in('Negative', 'Positive')
|
and afi_lab_result.westnile_serum in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -529,15 +574,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.zika_serum='Positive',1,0) as is_positive,
|
if(afi_lab_result.zika_serum='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.zika_serum='Positive', 'ZIKA','') pathogen_name,
|
if(afi_lab_result.zika_serum='Positive', 'ZIKA Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI ZIKA Serum Test' as indicator
|
'ZIKA Virus|Serum' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.zika_serum in('Negative', 'Positive')
|
and afi_lab_result.zika_serum in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond."
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond."
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@@ -545,15 +591,16 @@ class DataRetrievalService
|
|||||||
afi_lab_result.sample_code as labcode,
|
afi_lab_result.sample_code as labcode,
|
||||||
4 as surveillance_id,
|
4 as surveillance_id,
|
||||||
if(afi_lab_result.je_virus='Positive',1,0) as is_positive,
|
if(afi_lab_result.je_virus='Positive',1,0) as is_positive,
|
||||||
if(afi_lab_result.je_virus='Positive', 'Japanese Encephalitis','') pathogen_name,
|
if(afi_lab_result.je_virus='Positive', 'Japanese Encephalitis Virus','') pathogen_name,
|
||||||
'' as subtype,
|
'' as subtype,
|
||||||
'AFI Japanese Encephalitis Test' as indicator
|
'Japanese Encephalitis Virus|Serum' as indicator
|
||||||
FROM afi_db.`afi_tbl_afiform` as afi_case
|
FROM afi_db.`afi_tbl_afiform` as afi_case
|
||||||
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
INNER join afi_db.afi_tbl_result as afi_lab_result on afi_lab_result.unique_afi_id = afi_case.unique_afi_id
|
||||||
where afi_lab_result.sample_code is not null
|
where afi_lab_result.sample_code is not null
|
||||||
and afi_lab_result.je_virus in('Negative', 'Positive')
|
and afi_lab_result.je_virus in('Negative', 'Positive')
|
||||||
and afi_case.afi_event is NOT null
|
and afi_case.afi_event is NOT null
|
||||||
and afi_lab_result.results_date is not null ".$cond
|
and afi_case.date_of_interview is not null
|
||||||
|
and afi_lab_result.sample_code is not null ".$cond
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->insert_surveillance_case_lab_results($afi_lab_results);
|
$this->insert_surveillance_case_lab_results($afi_lab_results);
|
||||||
@@ -561,62 +608,179 @@ class DataRetrievalService
|
|||||||
|
|
||||||
public function getNSDCases($dateFrom, $dateTo = NULL)
|
public function getNSDCases($dateFrom, $dateTo = NULL)
|
||||||
{
|
{
|
||||||
return [];
|
$cond = "";
|
||||||
|
$cond .= " and sc.sc_date >= '".date('Y-m-d', strtotime($dateFrom))."' ";
|
||||||
|
$cond .= (!empty($dateTo)) ? " and sc.sc_date <='".date('Y-m-d', strtotime($dateTo))."' ":"";
|
||||||
|
$nds_cases = DB::connection('mysql_nds')
|
||||||
|
->select("
|
||||||
|
SELECT
|
||||||
|
DISTINCT
|
||||||
|
sc.sc_sample_code as labcode,
|
||||||
|
sc.sc_date as patdate,
|
||||||
|
1 as isnewcase,
|
||||||
|
site_ad.sn_name as labname_en,
|
||||||
|
'' as labaddress_en,
|
||||||
|
5 as surveillance_id,
|
||||||
|
niphc0_nphl.get_epi_period(sc.sc_date, 'Y') as year_data,
|
||||||
|
niphc0_nphl.get_epi_period(sc.sc_date, 'W') as week_data,
|
||||||
|
ifnull(DATEDIFF(sc.sc_date, patient.pat_dob),180) as patage,
|
||||||
|
if(patient.pat_gender='Male','M','F') as patsex,
|
||||||
|
NULL as is_alive,
|
||||||
|
pro.pro_eng as proname_en
|
||||||
|
from nds_db.tbl_nds_site_invest case_inv
|
||||||
|
inner join nds_db.tbl_nds_siteinvet_patient inv_patient
|
||||||
|
on inv_patient.pksi_id = case_inv.pksi_id
|
||||||
|
inner join nds_db.tbl_nds_site_address site_ad
|
||||||
|
on site_ad.pksn_id = case_inv.fksn_id
|
||||||
|
inner join nds_db.tbl_nds_patient patient
|
||||||
|
on patient.pkpat_id = inv_patient.fkpat_id
|
||||||
|
inner join nds_db.tbl_nds_basic_sample bs
|
||||||
|
on bs.fkpat_id = inv_patient.fkpat_id
|
||||||
|
inner join nds_db.tbl_nds_sample_collection sc
|
||||||
|
on sc.fkbs_id = bs.pkbs_id
|
||||||
|
left join nds_db.tblprovince pro
|
||||||
|
on pro.pkpro_code = JSON_UNQUOTE(JSON_EXTRACT(patient.pat_address, '$[0].province'))
|
||||||
|
where
|
||||||
|
sc.sc_sample_code is not null
|
||||||
|
and length(sc_sample_code)>0 " .$cond);
|
||||||
|
|
||||||
|
$this->insert_surveillance_cases($nds_cases);
|
||||||
|
|
||||||
|
$nds_lab_results = DB::connection('mysql_nds')
|
||||||
|
->select("
|
||||||
|
SELECT
|
||||||
|
DISTINCT
|
||||||
|
sc.sc_sample_code as labcode,
|
||||||
|
5 as surveillance_id,
|
||||||
|
rt.rt_positive as is_positive,
|
||||||
|
trt.trt_name pathogen_name,
|
||||||
|
'' as subtype,
|
||||||
|
trt.trt_name as indicator
|
||||||
|
from nds_db.tbl_nds_site_invest case_inv
|
||||||
|
inner join nds_db.tbl_nds_siteinvet_patient inv_patient
|
||||||
|
on inv_patient.pksi_id = case_inv.pksi_id
|
||||||
|
inner join nds_db.tbl_nds_patient patient
|
||||||
|
on patient.pkpat_id = inv_patient.fkpat_id
|
||||||
|
inner join nds_db.tbl_nds_basic_sample bs
|
||||||
|
on bs.fkpat_id = inv_patient.fkpat_id
|
||||||
|
inner join nds_db.tbl_nds_sample_collection sc
|
||||||
|
on sc.fkbs_id = bs.pkbs_id
|
||||||
|
inner join nds_db.tbl_nds_result_test rt
|
||||||
|
on rt.fkpat_id = bs.fkpat_id
|
||||||
|
inner join nds_db.tbl_nds_test_result_type trt
|
||||||
|
on trt.pktrt_id = rt.fktrt_id
|
||||||
|
|
||||||
|
where
|
||||||
|
sc.sc_sample_code is not null
|
||||||
|
and length(sc_sample_code)>0 " .$cond);
|
||||||
|
|
||||||
|
$this->insert_surveillance_case_lab_results($nds_lab_results);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSEQCases($dateFrom, $dateTo = NULL)
|
public function getSEQCases($dateFrom, $dateTo = NULL)
|
||||||
{
|
{
|
||||||
$cond = "";
|
$cond = "";
|
||||||
$cond .= " and patient.patdate >= '".date('Y-m-d', strtotime($dateFrom))."' ";
|
$cond .= " and c.patdate >= '".date('Y-m-d', strtotime($dateFrom))."' ";
|
||||||
$cond .= (!empty($dateTo)) ? " and patient.patdate <='".date('Y-m-d', strtotime($dateTo))."' ":"";
|
$cond .= (!empty($dateTo)) ? " and c.patdate <='".date('Y-m-d', strtotime($dateTo))."' ":"";
|
||||||
$seq_cases = DB::connection('mysql_nphl')
|
$seq_cases = DB::connection('mysql_nphl')
|
||||||
->select("
|
->select("
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
patient.labcode,
|
c.labcode,
|
||||||
patient.patdate,
|
min(if(year(tps.collected)=0,c.patdate, tps.collected)) as patdate,
|
||||||
patient.isnewcase,
|
c.isnewcase,
|
||||||
l.labname_en,
|
l.labname_en,
|
||||||
l.labaddress_en,
|
l.labaddress_en,
|
||||||
6 as surveillance_id,
|
6 as surveillance_id,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'Y') as year_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,c.patdate, tps.collected), 'Y')) as year_data,
|
||||||
niphc0_nphl.get_epi_period(patient.patdate, 'W') as week_data,
|
min(niphc0_nphl.get_epi_period(if(year(tps.collected)=0,c.patdate, tps.collected), 'W')) as week_data,
|
||||||
patient.patage,
|
c.patage,
|
||||||
patient.patsex,
|
c.patsex,
|
||||||
NULL as is_alive,
|
NULL as is_alive,
|
||||||
pro.proname_en
|
pro.proname_en
|
||||||
from niphc0_nphl.sq_batch sqb
|
from niphc0_nphl.sq_batch sqb
|
||||||
inner join niphc0_nphl.sq_sub_batch sqsb on sqsb.bt_id = sqb.bt_id
|
inner join niphc0_nphl.sq_sub_batch sqsb on sqsb.bt_id = sqb.bt_id
|
||||||
inner join niphc0_nphl.labopatients patient on patient.patid = sqsb.patid
|
inner join niphc0_nphl.labopatients c on c.patid = sqsb.patid
|
||||||
inner join niphc0_nphl.laboratory l on l.labid = patient.patsource
|
inner join niphc0_nphl.laboratory l on l.labid = p.patsource
|
||||||
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
inner join niphc0_nphl.test_patsample tps on tps.patientid = c.patid and tps.status = 1
|
||||||
inner join niphc0_nphl.test_patsamtest tpst on tpst.patsmid = tps.sampleid and tpst.patid = tps.patientid
|
inner join niphc0_nphl.test_patsamtest tpst on tpst.patsmid = tps.sampleid and tpst.patid = tps.patientid
|
||||||
left join niphc0_nphl.province pro on pro.proid = patient.frompro
|
left join niphc0_nphl.province pro on pro.proid = c.frompro
|
||||||
where patient.status = 1
|
where c.status = 1
|
||||||
and tpst.labtestid IN ( 659, 662, 666, 667, 668 )
|
and tpst.labtestid IN ( 659, 662, 666, 667, 668 )
|
||||||
" . $cond);
|
" . $cond . "
|
||||||
|
group by
|
||||||
|
c.labcode,
|
||||||
|
c.isnewcase,
|
||||||
|
l.labname_en,
|
||||||
|
l.labaddress_en,
|
||||||
|
c.patage,
|
||||||
|
c.patsex,
|
||||||
|
pro.proname_en;"
|
||||||
|
);
|
||||||
|
|
||||||
$this->insert_surveillance_cases($seq_cases);
|
$this->insert_surveillance_cases($seq_cases);
|
||||||
|
|
||||||
$seq_lab_results = DB::connection('mysql_nphl')
|
$seq_lab_results = DB::connection('mysql_nphl')
|
||||||
->select("
|
->select("
|
||||||
SELECT DISTINCT
|
SELECT
|
||||||
patient.labcode,
|
labcode,
|
||||||
6 as surveillance_id,
|
6 as surveillance_id,
|
||||||
1 is_positive,
|
1 is_positive,
|
||||||
ifnull(sqsb.seqlineage,'N/A') as pathogen_name,
|
ifnull(seqlineage,'N/A') as pathogen_name,
|
||||||
trs.rtitle as subtype,
|
GROUP_CONCAT(seq_result SEPARATOR '') as subtype,
|
||||||
concat('Sequencing Test ', case when patgroup=2 then 'SARI' when patgroup=3 then 'ILI' when patgroup=19 then 'COVID-19' else '' end) as indicator
|
(case
|
||||||
from niphc0_nphl.sq_batch sqb
|
when (Group_concat(influ_result SEPARATOR '')='Negatives' or Group_concat(influ_result SEPARATOR '')='') and Group_concat(covid_result SEPARATOR '')='Positive' then 'Covid-19'
|
||||||
inner join niphc0_nphl.sq_sub_batch sqsb on sqsb.bt_id = sqb.bt_id
|
when (Group_concat(influ_result SEPARATOR '') !='Negatives' and Group_concat(influ_result SEPARATOR '')!='') and Group_concat(covid_result SEPARATOR '')='Negative' then 'Influenza'
|
||||||
inner join niphc0_nphl.labopatients patient on patient.patid = sqsb.patid
|
when (Group_concat(influ_result SEPARATOR '') !='Negatives' and Group_concat(influ_result SEPARATOR '')!='') and Group_concat(covid_result SEPARATOR '')='Positive' then 'Co-infection'
|
||||||
inner join niphc0_nphl.test_patsample tps on tps.patientid = patient.patid
|
else 'N/A'
|
||||||
inner join niphc0_nphl.test_patsamtest tpst on tpst.patsmid = tps.sampleid and tpst.patid = tps.patientid
|
end) as indicator
|
||||||
inner join niphc0_nphl.test_pattestresult tptr on tptr.pstid = tpst.pstid
|
FROM (SELECT
|
||||||
inner join niphc0_nphl.test_resultselect trs on trs.rid = tptr.rsltid
|
c.labcode,
|
||||||
where patient.status = 1
|
( CASE
|
||||||
and tpst.labtestid IN ( 659, 662, 666, 667, 668 )
|
WHEN e1.labtestid IN ( 238, 340, 381 ) THEN e3.rtitle
|
||||||
and trs.rtitle not in ('Inconclusive', 'In Progress')
|
ELSE ''
|
||||||
" . $cond);
|
end ) influ_result,
|
||||||
|
( CASE
|
||||||
|
WHEN e1.labtestid IN ( 650, 651 ) THEN e3.rtitle
|
||||||
|
ELSE ''
|
||||||
|
end ) covid_result,
|
||||||
|
( CASE
|
||||||
|
WHEN e1.labtestid IN ( 668, 659, 666, 667, 662 ) THEN
|
||||||
|
e3.rtitle
|
||||||
|
ELSE ''
|
||||||
|
end ) seq_result,
|
||||||
|
b.seqlineage
|
||||||
|
FROM niphc0_nphl.sq_batch a
|
||||||
|
LEFT JOIN niphc0_nphl.sq_sub_batch b
|
||||||
|
ON a.bt_id = b.bt_id
|
||||||
|
LEFT JOIN niphc0_nphl.labopatients c
|
||||||
|
ON b.patid = c.patid
|
||||||
|
LEFT JOIN niphc0_nphl.laboratory d
|
||||||
|
ON c.patsource = d.labid
|
||||||
|
LEFT JOIN niphc0_nphl.test_patsamtest e1
|
||||||
|
ON c.patid = e1.patid
|
||||||
|
LEFT JOIN niphc0_nphl.test_pattestresult e2
|
||||||
|
ON e1.pstid = e2.pstid
|
||||||
|
LEFT JOIN niphc0_nphl.test_resultselect e3
|
||||||
|
ON e2.rsltid = e3.rid
|
||||||
|
LEFT JOIN niphc0_nphl.ncov_patients e4
|
||||||
|
ON c.patid = e4.patid
|
||||||
|
LEFT JOIN niphc0_nphl.test_patsample e5
|
||||||
|
ON c.patid = e5.patientid
|
||||||
|
AND e5.sampleid = e1.patsmid
|
||||||
|
LEFT JOIN niphc0_nphl.test_patsmpbyunit f
|
||||||
|
ON e5.sampleid = f.patsamid
|
||||||
|
AND c.patid = f.patid
|
||||||
|
WHERE e1.labtestid IN ( 238, 340, 381, 650,
|
||||||
|
651, 668, 659, 666,
|
||||||
|
667, 662 )
|
||||||
|
" . $cond . "
|
||||||
|
) tbl_a
|
||||||
|
GROUP BY labcode,
|
||||||
|
seqlineage
|
||||||
|
HAVING
|
||||||
|
GROUP_CONCAT(seq_result SEPARATOR '') not in ('','Inconclusive', 'In Progress')
|
||||||
|
");
|
||||||
|
|
||||||
$this->insert_surveillance_case_lab_results($seq_lab_results);
|
$this->insert_surveillance_case_lab_results($seq_lab_results);
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ return [
|
|||||||
'name' => env('APP_NAME', 'Laravel'),
|
'name' => env('APP_NAME', 'Laravel'),
|
||||||
|
|
||||||
'lookback_days' => [
|
'lookback_days' => [
|
||||||
'SARI' => 777, //
|
'SARI' => 7, //
|
||||||
'ILI' => 777,
|
'ILI' => 7,
|
||||||
'LBM' => 777,
|
'LBM' => 7,
|
||||||
'AFI' => 777,
|
'AFI' => 7,
|
||||||
'NDS' => 777,
|
'NDS' => 7,
|
||||||
'SEQ' => 200
|
'SEQ' => 7
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
let trendChart;
|
let trendChart;
|
||||||
|
let influenzaSubtypeChart;
|
||||||
|
let covidDistributedByAgeChart;
|
||||||
|
let covidLineageFrequencyChart;
|
||||||
|
let influenzaSubtypeFrequencyChart;
|
||||||
let map;
|
let map;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -30,7 +34,7 @@ function loadSummary() {
|
|||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h6 class="fw-bold">${item.code}</h6>
|
<h6 class="fw-bold">${item.code} Cases</h6>
|
||||||
<h3 class="mb-1">${item.current_total}</h3>
|
<h3 class="mb-1">${item.current_total}</h3>
|
||||||
<small class="text-muted">Last 7 days</small>
|
<small class="text-muted">Last 7 days</small>
|
||||||
</div>
|
</div>
|
||||||
@@ -102,12 +106,15 @@ function loadTrend(periodType, startYear, startWeek, endYear, endWeek) {
|
|||||||
const colors = {
|
const colors = {
|
||||||
SARI: '#2563eb',
|
SARI: '#2563eb',
|
||||||
ILI: '#10b981',
|
ILI: '#10b981',
|
||||||
LBM: '#9333ea'
|
LBM: '#9333ea',
|
||||||
|
AFI: '#fc5741',
|
||||||
|
NDS: '#d59d01',
|
||||||
|
SEQ: '#9ca3af'
|
||||||
};
|
};
|
||||||
|
|
||||||
const datasets = [];
|
const datasets = [];
|
||||||
|
|
||||||
const allowedPrograms = ['SARI', 'ILI', 'LBM'];
|
const allowedPrograms = ['SARI', 'ILI', 'LBM', 'AFI', 'NDS', 'SEQ'];
|
||||||
|
|
||||||
Object.keys(data).forEach(code => {
|
Object.keys(data).forEach(code => {
|
||||||
|
|
||||||
@@ -145,7 +152,10 @@ function loadTrend(periodType, startYear, startWeek, endYear, endWeek) {
|
|||||||
options: {
|
options: {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
plugins: {
|
plugins: {
|
||||||
legend: { position: 'bottom' }
|
legend: { position: 'bottom' },
|
||||||
|
datalabels: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
interaction: {
|
interaction: {
|
||||||
mode: 'index',
|
mode: 'index',
|
||||||
@@ -154,15 +164,499 @@ function loadTrend(periodType, startYear, startWeek, endYear, endWeek) {
|
|||||||
scales: {
|
scales: {
|
||||||
y: {
|
y: {
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
ticks: { stepSize: 1 }
|
ticks: {
|
||||||
|
stepSize: 1
|
||||||
},
|
},
|
||||||
x: { grid: { display: false } }
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Number of Cases'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Surveillance'
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadInfluenzaSubtypeDistribution(periodType, startYear, startWeek, endYear, endWeek) {
|
||||||
|
|
||||||
|
fetch(`/api/dashboard/influenza-subtype-distribution?period_type=${periodType}&start_year=${startYear}&start_week=${startWeek}&end_year=${endYear}&end_week=${endWeek}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
let displayLabels = data.map(item => item.subtype);
|
||||||
|
let dataset = data.map(item => item.total);
|
||||||
|
|
||||||
|
const colors = [
|
||||||
|
'rgba(177,111,243,0.94)'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
if (influenzaSubtypeChart) influenzaSubtypeChart.destroy();
|
||||||
|
influenzaSubtypeChart = new Chart(document.getElementById('influenzaSubtypeDistribution'), {
|
||||||
|
type: 'bar', // you can change to 'pie', 'doughnut', etc.
|
||||||
|
data: {
|
||||||
|
labels: displayLabels,
|
||||||
|
datasets: [{
|
||||||
|
data: dataset,
|
||||||
|
backgroundColor: colors,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
indexAxis: 'y',
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false,
|
||||||
|
position:'right'
|
||||||
|
},
|
||||||
|
datalabels: {
|
||||||
|
color: '#ffffff',
|
||||||
|
backgroundColor: 'rgba(68,76,68,0.31)',
|
||||||
|
borderRadius: 6,
|
||||||
|
z: 1000,
|
||||||
|
padding: {
|
||||||
|
top: 6,
|
||||||
|
bottom: 6,
|
||||||
|
left: 10,
|
||||||
|
right: 10
|
||||||
|
},
|
||||||
|
font: {
|
||||||
|
weight: 'bold',
|
||||||
|
size: 12
|
||||||
|
},
|
||||||
|
formatter: (value) => value,
|
||||||
|
anchor: 'end',
|
||||||
|
align: 'end',
|
||||||
|
offset: 10,
|
||||||
|
clamp: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
stacked: true,
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Number of Positive Influenza Subtypes'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
stacked: true,
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Influenza Subtypes'
|
||||||
|
},
|
||||||
|
grid:{
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [ChartDataLabels]
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCovidDistributedByAgeGroup(periodType, startYear, startWeek, endYear, endWeek) {
|
||||||
|
|
||||||
|
fetch(`/api/dashboard/covid-distributed-by-age-group?period_type=${periodType}&start_year=${startYear}&start_week=${startWeek}&end_year=${endYear}&end_week=${endWeek}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
let displayLabels = data.map(item => item.age_group);
|
||||||
|
let dataset = data.map(item => item.total);
|
||||||
|
|
||||||
|
const colors = [
|
||||||
|
'#84cc16'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (covidDistributedByAgeChart) covidDistributedByAgeChart.destroy();
|
||||||
|
covidDistributedByAgeChart = new Chart(document.getElementById('covidDistributedByAgeGroup'), {
|
||||||
|
type: 'bar', // you can change to 'pie', 'doughnut', etc.
|
||||||
|
data: {
|
||||||
|
labels: displayLabels,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Total Covid-19 Detected',
|
||||||
|
data: dataset,
|
||||||
|
backgroundColor: colors,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false,
|
||||||
|
position:'bottom'
|
||||||
|
},
|
||||||
|
datalabels: {
|
||||||
|
color: '#fff',
|
||||||
|
backgroundColor: 'rgba(68,76,68,0.7)',
|
||||||
|
borderRadius: 6,
|
||||||
|
z: 1000,
|
||||||
|
padding: {
|
||||||
|
top: 6,
|
||||||
|
bottom: 6,
|
||||||
|
left: 10,
|
||||||
|
right: 10
|
||||||
|
},
|
||||||
|
font: {
|
||||||
|
weight: 'bold',
|
||||||
|
size: 12
|
||||||
|
},
|
||||||
|
formatter: (value) => value,
|
||||||
|
anchor: 'end',
|
||||||
|
align: 'end',
|
||||||
|
offset: 10,
|
||||||
|
clamp: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
stacked: true,
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Patient Age Group'
|
||||||
|
},
|
||||||
|
grid:{
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
stacked: true,
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Number of Positive SARS-CoV-2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCovidLineageFrequency(periodType, startYear, startWeek, endYear, endWeek) {
|
||||||
|
|
||||||
|
fetch(`/api/dashboard/covid-lineage-frequency?period_type=${periodType}&start_year=${startYear}&start_week=${startWeek}&end_year=${endYear}&end_week=${endWeek}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
// Extract unique weeks (X-axis)
|
||||||
|
const weeks = [...new Set(data.map(item => item.week))].sort();
|
||||||
|
|
||||||
|
// Extract unique lineages
|
||||||
|
const lineages = [...new Set(data.map(item => item.lineage))];
|
||||||
|
|
||||||
|
// Color palette
|
||||||
|
const colors = [
|
||||||
|
'#84cc16','#22c55e','#06b6d4','#3b82f6',
|
||||||
|
'#6366f1','#a855f7','#ec4899','#ef4444',
|
||||||
|
'#f97316','#eab308'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Build datasets
|
||||||
|
const datasets = lineages.map((lineage, index) => {
|
||||||
|
const lineageData = weeks.map(week => {
|
||||||
|
const found = data.find(
|
||||||
|
item => item.week === week && item.lineage === lineage
|
||||||
|
);
|
||||||
|
return found ? found.total : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: lineage,
|
||||||
|
data: lineageData,
|
||||||
|
fill: true, // area fill
|
||||||
|
tension: 0.4, // smooth curve
|
||||||
|
borderColor: 'transparent', // hide the line
|
||||||
|
borderWidth: 0,
|
||||||
|
pointRadius: 0, // hide points
|
||||||
|
backgroundColor: hexToRGBA(colors[index % colors.length], 0.3),
|
||||||
|
stack: 'total'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Destroy previous chart if exists
|
||||||
|
if (covidLineageFrequencyChart) covidLineageFrequencyChart.destroy();
|
||||||
|
|
||||||
|
const ctx = document.getElementById('covidLineageFrequency').getContext('2d');
|
||||||
|
|
||||||
|
covidLineageFrequencyChart = new Chart(ctx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: weeks,
|
||||||
|
datasets: datasets
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
interaction: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false // hide default legend
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
datalabels: {
|
||||||
|
display: false // hide labels
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
stacked: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Week'
|
||||||
|
},
|
||||||
|
grid:{
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
stacked: true,
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Relative Frequency'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Custom right-side scrollable legend
|
||||||
|
// -------------------------
|
||||||
|
const legendContainer = document.getElementById('legendContainer');
|
||||||
|
legendContainer.innerHTML = ''; // clear old legend
|
||||||
|
|
||||||
|
datasets.forEach((dataset, index) => {
|
||||||
|
const item = document.createElement('div');
|
||||||
|
item.style.display = 'flex';
|
||||||
|
item.style.alignItems = 'center';
|
||||||
|
item.style.marginBottom = '4px';
|
||||||
|
item.style.fontSize = '11px';
|
||||||
|
item.style.cursor = 'pointer';
|
||||||
|
item.innerHTML = `
|
||||||
|
<span style="width:15px;height:15px;background:${dataset.backgroundColor};display:inline-block;margin-right:8px;"></span>
|
||||||
|
${dataset.label}
|
||||||
|
`;
|
||||||
|
|
||||||
|
item.addEventListener('click', () => {
|
||||||
|
const meta = covidLineageFrequencyChart.getDatasetMeta(index);
|
||||||
|
|
||||||
|
// If the clicked dataset is already the only visible one, show all
|
||||||
|
const allHidden = datasets.every((d, i) => covidLineageFrequencyChart.getDatasetMeta(i).hidden || i === index);
|
||||||
|
if (!allHidden) {
|
||||||
|
// Hide all datasets
|
||||||
|
datasets.forEach((d, i) => {
|
||||||
|
covidLineageFrequencyChart.getDatasetMeta(i).hidden = true;
|
||||||
|
});
|
||||||
|
// Show only clicked
|
||||||
|
meta.hidden = false;
|
||||||
|
} else {
|
||||||
|
// Show all datasets
|
||||||
|
datasets.forEach((d, i) => {
|
||||||
|
covidLineageFrequencyChart.getDatasetMeta(i).hidden = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
covidLineageFrequencyChart.update();
|
||||||
|
|
||||||
|
// Update legend opacity
|
||||||
|
Array.from(legendContainer.children).forEach((child, i) => {
|
||||||
|
const metaItem = covidLineageFrequencyChart.getDatasetMeta(i);
|
||||||
|
child.style.opacity = metaItem.hidden ? 0.5 : 1;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
legendContainer.appendChild(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scrollable CSS (in case legend is long)
|
||||||
|
legendContainer.style.maxHeight = '375px';
|
||||||
|
legendContainer.style.overflowY = 'auto';
|
||||||
|
legendContainer.style.padding = '8px';
|
||||||
|
legendContainer.style.borderRadius = '0px';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadInfluenzaSubtypeFrequency(periodType, startYear, startWeek, endYear, endWeek) {
|
||||||
|
|
||||||
|
fetch(`/api/dashboard/influenza-relative-frequency?period_type=${periodType}&start_year=${startYear}&start_week=${startWeek}&end_year=${endYear}&end_week=${endWeek}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
// Extract unique weeks (X-axis)
|
||||||
|
const weeks = [...new Set(data.map(item => item.week))].sort();
|
||||||
|
|
||||||
|
const colors = [
|
||||||
|
'#84cc16','#22c55e','#06b6d4','#3b82f6',
|
||||||
|
'#6366f1','#a855f7','#ec4899','#ef4444',
|
||||||
|
'#f97316','#eab308'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Extract unique lineages
|
||||||
|
const lineages = [...new Set(data.map(item => item.lineage))];
|
||||||
|
// Build datasets
|
||||||
|
const datasets = lineages.map((lineage, index) => {
|
||||||
|
const lineageData = weeks.map(week => {
|
||||||
|
const found = data.find(
|
||||||
|
item => item.week === week && item.lineage === lineage
|
||||||
|
);
|
||||||
|
return found ? found.total : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: lineage,
|
||||||
|
data: lineageData,
|
||||||
|
fill: true, // area fill
|
||||||
|
tension: 0.4, // smooth curve
|
||||||
|
borderColor: 'transparent', // hide the line
|
||||||
|
borderWidth: 0,
|
||||||
|
pointRadius: 0, // hide points
|
||||||
|
backgroundColor: hexToRGBA(colors[index % colors.length], 0.3),
|
||||||
|
stack: 'total'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Destroy previous chart if exists
|
||||||
|
if (influenzaSubtypeFrequencyChart) influenzaSubtypeFrequencyChart.destroy();
|
||||||
|
|
||||||
|
const ctx = document.getElementById('influenzaSubtypeFrequency').getContext('2d');
|
||||||
|
|
||||||
|
influenzaSubtypeFrequencyChart = new Chart(ctx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: weeks,
|
||||||
|
datasets: datasets
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
interaction: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false // hide default legend
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
datalabels: {
|
||||||
|
display: false // hide labels
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
stacked: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Week'
|
||||||
|
},
|
||||||
|
grid:{
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
stacked: true,
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Relative Frequency'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const legendContainer = document.getElementById('legendContainerInfluenzaSubtypeFrequency');
|
||||||
|
legendContainer.innerHTML = ''; // clear old legend
|
||||||
|
|
||||||
|
datasets.forEach((dataset, index) => {
|
||||||
|
const item = document.createElement('div');
|
||||||
|
item.style.display = 'flex';
|
||||||
|
item.style.alignItems = 'center';
|
||||||
|
item.style.marginBottom = '4px';
|
||||||
|
item.style.fontSize = '11px';
|
||||||
|
item.style.cursor = 'pointer';
|
||||||
|
item.innerHTML = `
|
||||||
|
<span style="width:15px;height:15px;background:${dataset.backgroundColor};display:inline-block;margin-right:8px;"></span>
|
||||||
|
${dataset.label}
|
||||||
|
`;
|
||||||
|
|
||||||
|
item.addEventListener('click', () => {
|
||||||
|
const meta = influenzaSubtypeFrequencyChart.getDatasetMeta(index);
|
||||||
|
|
||||||
|
// If the clicked dataset is already the only visible one, show all
|
||||||
|
const allHidden = datasets.every((d, i) => influenzaSubtypeFrequencyChart.getDatasetMeta(i).hidden || i === index);
|
||||||
|
if (!allHidden) {
|
||||||
|
// Hide all datasets
|
||||||
|
datasets.forEach((d, i) => {
|
||||||
|
influenzaSubtypeFrequencyChart.getDatasetMeta(i).hidden = true;
|
||||||
|
});
|
||||||
|
// Show only clicked
|
||||||
|
meta.hidden = false;
|
||||||
|
} else {
|
||||||
|
// Show all datasets
|
||||||
|
datasets.forEach((d, i) => {
|
||||||
|
influenzaSubtypeFrequencyChart.getDatasetMeta(i).hidden = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
influenzaSubtypeFrequencyChart.update();
|
||||||
|
|
||||||
|
// Update legend opacity
|
||||||
|
Array.from(legendContainer.children).forEach((child, i) => {
|
||||||
|
const metaItem = influenzaSubtypeFrequencyChart.getDatasetMeta(i);
|
||||||
|
child.style.opacity = metaItem.hidden ? 0.5 : 1;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
legendContainer.appendChild(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scrollable CSS (in case legend is long)
|
||||||
|
legendContainer.style.maxHeight = '375px';
|
||||||
|
legendContainer.style.overflowY = 'auto';
|
||||||
|
legendContainer.style.padding = '8px';
|
||||||
|
legendContainer.style.borderRadius = '0px';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Helper to convert hex to rgba
|
||||||
|
// -------------------------
|
||||||
|
function hexToRGBA(hex, alpha) {
|
||||||
|
const r = parseInt(hex.slice(1, 3), 16);
|
||||||
|
const g = parseInt(hex.slice(3, 5), 16);
|
||||||
|
const b = parseInt(hex.slice(5, 7), 16);
|
||||||
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||||
|
}
|
||||||
|
|
||||||
function updateAlerts() {
|
function updateAlerts() {
|
||||||
|
|
||||||
if (!window._summaryData || !window._provinceData) return;
|
if (!window._summaryData || !window._provinceData) return;
|
||||||
@@ -380,10 +874,14 @@ function renderAlerts(alerts) {
|
|||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
function getPositivityColor(p) {
|
function getPositivityColor(p) {
|
||||||
if (p > 20) return "#b91c1c";
|
if (p == 'A/H1N1pdm') return "#2563eb";
|
||||||
if (p > 10) return "#ef4444";
|
if (p == 'A/H3N2') return "#11de9d";
|
||||||
if (p > 5) return "#f59e0b";
|
if (p == 'B/Yam') return "#9333ea";
|
||||||
if (p > 0) return "#84cc16";
|
if (p == 'B/Vic') return "#1021b9";
|
||||||
|
if (p == 'A/H9N2') return "#b91081";
|
||||||
|
if (p == 'A/H5N1') return "#ad850d";
|
||||||
|
if (p == 'A/Unsubtypable') return "#047393";
|
||||||
|
if (p == 'B/Unsubtypable') return "#890512";
|
||||||
return "#9ca3af";
|
return "#9ca3af";
|
||||||
}
|
}
|
||||||
function normalizeProvince(name, validSet) {
|
function normalizeProvince(name, validSet) {
|
||||||
@@ -432,13 +930,15 @@ function addPositivityLegend() {
|
|||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div style="background:white;padding:10px 12px;border-radius:6px;
|
<div style="background:white;padding:10px 12px;border-radius:6px;
|
||||||
box-shadow:0 2px 6px rgba(0,0,0,0.2);font-size:12px;">
|
box-shadow:0 2px 6px rgba(0,0,0,0.2);font-size:12px;">
|
||||||
<div style="font-weight:600;margin-bottom:6px;">Positivity</div>
|
<div style="font-weight:600;margin-bottom:6px;">Influenza Subtypes</div>
|
||||||
|
<div><span style="background: #2563eb; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>A/H1N1pdm</div>
|
||||||
<div><span style="border:3px solid #b91c1c;width:12px;height:12px;display:inline-block;margin-right:6px;"></span>> 20%</div>
|
<div><span style="background: #11de9d; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>A/H3N2</div>
|
||||||
<div><span style="border:3px solid #ef4444;width:12px;height:12px;display:inline-block;margin-right:6px;"></span>10–20%</div>
|
<div><span style="background: #b91081; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>A/H9N2</div>
|
||||||
<div><span style="border:3px solid #f59e0b;width:12px;height:12px;display:inline-block;margin-right:6px;"></span>5–10%</div>
|
<div><span style="background: #ad850d; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>A/H5N1</div>
|
||||||
<div><span style="border:3px solid #84cc16;width:12px;height:12px;display:inline-block;margin-right:6px;"></span>0–5%</div>
|
<div><span style="background: #047393; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>A/Unsubtypable</div>
|
||||||
<div><span style="border:3px solid #9ca3af;width:12px;height:12px;display:inline-block;margin-right:6px;"></span>0%</div>
|
<div><span style="background: #9333ea; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>B/Yam</div>
|
||||||
|
<div><span style="background: #1021b9; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>B/Vic</div>
|
||||||
|
<div><span style="background: #890512; border: 2px solid #aa9d9d; width:12px;height:12px;display:inline-block;margin-right:6px; border-radius: 50%;"></span>B/Unsubtypable</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -490,52 +990,42 @@ function loadProvinceMap(startYear, startWeek, endYear, endWeek) {
|
|||||||
const center = layer.getBounds().getCenter();
|
const center = layer.getBounds().getCenter();
|
||||||
|
|
||||||
const rows = data.filter(d => {
|
const rows = data.filter(d => {
|
||||||
if (![1, 2, 3].includes(d.surveillance_id)) return false;
|
|
||||||
|
|
||||||
const name = normalizeProvince(d.patient_province, validProvinces);
|
const name = normalizeProvince(d.patient_province, validProvinces);
|
||||||
return name === province;
|
return name === province;
|
||||||
});
|
});
|
||||||
|
|
||||||
const offsets = { 1: -0.15, 2: 0, 3: 0.15 };
|
if (!rows.length) return;
|
||||||
|
|
||||||
const colors = {
|
// 👉 group by pathogen_name
|
||||||
1: '#2563eb',
|
const pathogens = [...new Set(rows.map(r => r.pathogen_name))];
|
||||||
2: '#10b981',
|
|
||||||
3: '#9333ea'
|
const spacing = 1; //0.12; // adjust spacing between circles
|
||||||
};
|
|
||||||
|
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
|
|
||||||
const percent = row.total
|
// 👉 dynamic offset based on pathogen index
|
||||||
? ((row.positive / row.total) * 100).toFixed(1)
|
const index = pathogens.indexOf(row.pathogen_name);
|
||||||
: 0;
|
const offset = (index - (pathogens.length - 1) / 2) * spacing;
|
||||||
|
|
||||||
const offset = offsets[row.surveillance_id] ?? 0;
|
|
||||||
|
|
||||||
const lat = center.lat;
|
const lat = center.lat;
|
||||||
const lng = center.lng + offset;
|
const lng = center.lng + offset;
|
||||||
|
|
||||||
const programName =
|
|
||||||
row.surveillance_id === 1 ? 'SARI' :
|
|
||||||
row.surveillance_id === 2 ? 'ILI' : 'LBM';
|
|
||||||
|
|
||||||
L.circleMarker([lat, lng], {
|
L.circleMarker([lat, lng], {
|
||||||
radius: getRadius(row.total),
|
radius: getRadius(row.total),
|
||||||
fillColor: colors[row.surveillance_id],
|
fillColor: getColorByPathogen(row.pathogen_name), // 👈 new function
|
||||||
color: getPositivityColor(percent),
|
color: getPositivityColor(row.pathogen_nam),
|
||||||
weight: 2,
|
weight: 2,
|
||||||
fillOpacity: 0.9
|
fillOpacity: 0.9
|
||||||
})
|
})
|
||||||
.bindTooltip(`
|
.bindTooltip(`
|
||||||
<strong>${province}</strong><br>
|
<strong>${province}</strong><br>
|
||||||
${programName}<br>
|
${row.pathogen_name}<br>
|
||||||
Cases: ${row.total}<br>
|
Total Detected: ${row.total}<br>
|
||||||
Positivity: ${percent}%
|
|
||||||
`)
|
`)
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
@@ -544,6 +1034,21 @@ function loadProvinceMap(startYear, startWeek, endYear, endWeek) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getColorByPathogen(name) {
|
||||||
|
const colors = {
|
||||||
|
"A/H1N1pdm": "#2563eb",
|
||||||
|
"A/H3N2": "#11de9d",
|
||||||
|
"B/Yam": "#9333ea",
|
||||||
|
"B/Vic" : "#1021b9",
|
||||||
|
"A/H9N2": "#b91081",
|
||||||
|
"A/H5N1": "#ad850d",
|
||||||
|
"A/Unsubtypable": "#047393",
|
||||||
|
"B/Unsubtypable": "#890512"
|
||||||
|
};
|
||||||
|
|
||||||
|
return colors[name] || "#000000"; // fallback color
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -558,8 +1063,58 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
new DashboardFilter((startYear, startWeek, endYear, endWeek) => {
|
new DashboardFilter((startYear, startWeek, endYear, endWeek) => {
|
||||||
|
|
||||||
loadTrend('week', startYear, startWeek, endYear, endWeek);
|
loadTrend('week', startYear, startWeek, endYear, endWeek);
|
||||||
|
loadInfluenzaSubtypeDistribution('week', startYear, startWeek, endYear, endWeek);
|
||||||
|
loadCovidDistributedByAgeGroup('week', startYear, startWeek, endYear, endWeek);
|
||||||
|
loadInfluenzaSubtypeFrequency('week', startYear, startWeek, endYear, endWeek);
|
||||||
|
loadCovidLineageFrequency('week', startYear, startWeek, endYear, endWeek);
|
||||||
loadProvinceMap(startYear, startWeek, endYear, endWeek);
|
loadProvinceMap(startYear, startWeek, endYear, endWeek);
|
||||||
|
const elements = document.querySelectorAll(".report-period");
|
||||||
|
elements.forEach(el => {
|
||||||
|
el.textContent = 'Week ' + startWeek + ' of '+startYear+' to ' + 'Week ' + endWeek + ' of ' + endYear
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|
||||||
|
let currentSlide = 0;
|
||||||
|
const slides = document.querySelectorAll('.slide');
|
||||||
|
const nextBtn = document.querySelector('.next-btn');
|
||||||
|
const prevBtn = document.querySelector('.prev-btn');
|
||||||
|
|
||||||
|
function showSlide(index) {
|
||||||
|
slides.forEach((slide, i) => {
|
||||||
|
slide.classList.remove('active', 'prev');
|
||||||
|
|
||||||
|
if (i === index) {
|
||||||
|
slide.classList.add('active');
|
||||||
|
} else if (i === index - 1) {
|
||||||
|
slide.classList.add('prev');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextSlide() {
|
||||||
|
currentSlide = (currentSlide + 1) % slides.length;
|
||||||
|
showSlide(currentSlide);
|
||||||
|
}
|
||||||
|
|
||||||
|
function prevSlide() {
|
||||||
|
currentSlide = (currentSlide - 1 + slides.length) % slides.length;
|
||||||
|
showSlide(currentSlide);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button events
|
||||||
|
nextBtn.addEventListener('click', nextSlide);
|
||||||
|
prevBtn.addEventListener('click', prevSlide);
|
||||||
|
|
||||||
|
// Auto slide every 1 minute
|
||||||
|
let slideInterval = 2 * (60 * 1000);
|
||||||
|
setInterval(nextSlide, slideInterval);
|
||||||
|
|
||||||
|
// Init
|
||||||
|
showSlide(currentSlide);
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div id="custom_range_container" style="display:none;" class="align-items-center gap-1">
|
<div id="custom_range_container" style="display:none;" class="align-items-center gap-1">
|
||||||
|
|
||||||
<select id="start_year" class="form-select"></select>
|
<select id="start_year" class="form-select"></select>
|
||||||
<select id="start_week" class="form-select"></select>
|
<select id="start_week" class="form-select"></select>
|
||||||
|
|
||||||
@@ -28,88 +27,155 @@
|
|||||||
|
|
||||||
<select id="end_year" class="form-select"></select>
|
<select id="end_year" class="form-select"></select>
|
||||||
<select id="end_week" class="form-select"></select>
|
<select id="end_week" class="form-select"></select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Summary Cards -->
|
<!-- Summary Cards -->
|
||||||
<div class="row flex-grow-1" id="summary_cards"></div>
|
<div class="row flex-grow-1 mb-2" id="summary_cards"></div>
|
||||||
|
|
||||||
|
<!-- SLIDESHOW -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8">
|
||||||
|
|
||||||
<div class="row flex-grow-1">
|
<div class="slide-wrapper">
|
||||||
|
|
||||||
<!-- LEFT COLUMN -->
|
<!-- SLIDE 1 -->
|
||||||
<div class="col-lg-8 d-flex flex-column">
|
<div class="slide active">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 d-flex flex-column">
|
||||||
|
|
||||||
<!-- Trend Chart -->
|
<div class="card shadow-sm mb-3" style="height:60vh;">
|
||||||
<div class="card shadow-sm mb-3 flex-grow-1">
|
|
||||||
<div class="card-body" >
|
<div class="card-body" >
|
||||||
|
|
||||||
<div class="mb-3">
|
<h5 class="fw-bold">Epidemic Trend</h5>
|
||||||
<h5 class="fw-bold mb-1">Epidemic Trend</h5>
|
<p class="text-muted small report-period">
|
||||||
<p class="text-muted small mb-0">
|
|
||||||
(based on selected epiweek range)
|
(based on selected epiweek range)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
|
|
||||||
<canvas id="trendChart" height="90"></canvas>
|
<canvas id="trendChart" height="90"></canvas>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Alerts -->
|
</div>
|
||||||
<div class="card shadow-sm flex-grow-1">
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- SLIDE 2 -->
|
||||||
|
<div class="slide">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 d-flex flex-column">
|
||||||
|
<div class="card shadow-sm" style="height:60vh;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<h5 class="fw-bold">Influenza Subtypes Distribution</h5>
|
||||||
|
<p class="text-muted small report-period">
|
||||||
|
(based on selected epiweek range)
|
||||||
|
</p>
|
||||||
|
|
||||||
<h5 class="fw-bold">Recent Alerts & Notifications</h5>
|
<canvas id="influenzaSubtypeDistribution" style="max-width: 100%; max-height:40vh; float: left;"></canvas>
|
||||||
|
|
||||||
<ul id="alertsList" class="list-group list-group-flush mt-3"></ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- SLIDE 3 -->
|
||||||
|
<div class="slide">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 d-flex flex-column">
|
||||||
|
<div class="card shadow-sm" style="height:60vh;">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="fw-bold">SARS-CoV-2 Detected Distribute by Age Group</h5>
|
||||||
|
<p class="text-muted small report-period">
|
||||||
|
(based on selected epiweek range)
|
||||||
|
</p>
|
||||||
|
<canvas id="covidDistributedByAgeGroup" style="max-width: 100%; max-height:40vh; float: left;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- RIGHT COLUMN -->
|
</div>
|
||||||
<div class="col-lg-4 d-flex flex-column">
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- SLIDE 3 -->
|
||||||
|
<div class="slide">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 d-flex flex-column">
|
||||||
|
<div class="card shadow-sm" style="height:60vh; display: flex">
|
||||||
|
<div class="card-body" >
|
||||||
|
<h5 class="fw-bold">SARS-CoV-2 Lineage Relative Frequencies Over Time</h5>
|
||||||
|
<p class="text-muted small report-period">
|
||||||
|
(based on selected epiweek range)
|
||||||
|
</p>
|
||||||
|
<canvas id="covidLineageFrequency" style=" flex:1; max-width: 90%; max-height:45vh; float: left;"></canvas>
|
||||||
|
<div id="legendContainer" style="
|
||||||
|
width:10%;
|
||||||
|
margin-left:20px;
|
||||||
|
max-height:375px;
|
||||||
|
overflow-y:auto;
|
||||||
|
padding:8px;
|
||||||
|
|
||||||
|
"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- SLIDE 3 -->
|
||||||
|
<div class="slide">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 d-flex flex-column">
|
||||||
|
<div class="card shadow-sm" style="height:60vh; display: flex">
|
||||||
|
<div class="card-body" >
|
||||||
|
<h5 class="fw-bold">Influenza Subtypes Relative Frequencies Over Time</h5>
|
||||||
|
<p class="text-muted small report-period">
|
||||||
|
(based on selected epiweek range)
|
||||||
|
</p>
|
||||||
|
<canvas id="influenzaSubtypeFrequency" style=" flex:1; max-width: 90%; max-height:45vh; float: left;"></canvas>
|
||||||
|
<div id="legendContainerInfluenzaSubtypeFrequency" style="
|
||||||
|
width:10%;
|
||||||
|
margin-left:20px;
|
||||||
|
max-height:375px;
|
||||||
|
overflow-y:auto;
|
||||||
|
padding:8px;
|
||||||
|
|
||||||
|
"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CONTROLS -->
|
||||||
|
<button class="slide-btn prev-btn">❮</button>
|
||||||
|
<button class="slide-btn next-btn">❯</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 d-flex flex-column">
|
||||||
|
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
<h5 class="fw-bold">Total Cases by Provinces</h5>
|
<h5 class="fw-bold">Influenza Subtypes Detected by Province</h5>
|
||||||
<p class="text-muted small">(based on selected epiweek range)</p>
|
<p class="text-muted small report-period">(based on selected epiweek range)</p>
|
||||||
|
|
||||||
<div id="provinceMap" style="height:50vh;"></div>
|
<div id="provinceMap" style="height:40vh;"></div>
|
||||||
|
|
||||||
<div class="d-flex justify-content-center align-items-center gap-4 mt-4 small">
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
style="display:inline-block;width:10px;height:10px;background:#2563eb;border-radius:50%;margin-right:6px;"></span>
|
|
||||||
SARI
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
style="display:inline-block;width:10px;height:10px;background:#10b981;border-radius:50%;margin-right:6px;"></span>
|
|
||||||
ILI
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
style="display:inline-block;width:10px;height:10px;background:#9333ea;border-radius:50%;margin-right:6px;"></span>
|
|
||||||
LBM
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>NRML Dashboard</title>
|
<title>NRML Dashboard</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0"></script>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||||||
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
|
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
|
||||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||||
|
|
||||||
@@ -16,11 +19,8 @@
|
|||||||
<script src="/js/dashboard/charts.js"></script>
|
<script src="/js/dashboard/charts.js"></script>
|
||||||
<script src="/js/dashboard/export.js"></script>
|
<script src="/js/dashboard/export.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body { margin: 0; }
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-navbar {
|
.top-navbar {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
.brand-title {
|
.brand-title {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
color: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-bar {
|
.nav-bar {
|
||||||
@@ -44,8 +45,6 @@
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
background: white;
|
|
||||||
border-bottom: 1px solid #dcdcdc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-theme-outline {
|
.btn-theme-outline {
|
||||||
@@ -56,7 +55,6 @@
|
|||||||
|
|
||||||
.btn-theme-outline:hover {
|
.btn-theme-outline:hover {
|
||||||
background-color: #cce0d4;
|
background-color: #cce0d4;
|
||||||
color: #0B8F3C;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item {
|
.nav-item {
|
||||||
@@ -68,9 +66,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover {
|
.nav-item:hover { background: #cce0d4; }
|
||||||
background: #cce0d4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-tab {
|
.active-tab {
|
||||||
color: #0B8F3C;
|
color: #0B8F3C;
|
||||||
@@ -78,27 +74,10 @@
|
|||||||
background: #e5efe8;
|
background: #e5efe8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-area {
|
|
||||||
padding: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand-title {
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-area {
|
.content-area {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
min-height: calc(100vh - 60px);
|
min-height: calc(100vh - 110px);
|
||||||
}
|
|
||||||
|
|
||||||
.brand-logo {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
object-fit: contain;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
@@ -106,13 +85,13 @@
|
|||||||
border: 1px solid #E5E7EB;
|
border: 1px solid #E5E7EB;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card h3 {
|
.form-select { border-radius: 0px !important; }
|
||||||
color: #0B8F3C;
|
.shadow-sm { box-shadow: none !important; }
|
||||||
}
|
|
||||||
|
|
||||||
.export-control {
|
.card h3 { color: #0B8F3C; }
|
||||||
position: relative;
|
|
||||||
}
|
/* EXPORT */
|
||||||
|
.export-control { position: relative; }
|
||||||
|
|
||||||
#exportItems {
|
#exportItems {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -132,7 +111,6 @@
|
|||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.export-modal {
|
.export-modal {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -149,19 +127,49 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SLIDE FEATURE (from master) */
|
||||||
|
.slide-wrapper {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide.active { left: 0; opacity: 1; z-index: 2; }
|
||||||
|
.slide.prev { left: -100%; opacity: 0; }
|
||||||
|
|
||||||
|
.slide-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
background: rgba(0,128,0,0.43);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prev-btn { right: 75px; }
|
||||||
|
.next-btn { right: 25px; }
|
||||||
|
|
||||||
|
.slide-btn:hover {
|
||||||
|
background: rgba(7,120,24,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
#floatingExport {
|
#floatingExport { display: none !important; }
|
||||||
display: none !important;
|
.nav-bar, .top-navbar { display: none !important; }
|
||||||
}
|
.card { page-break-inside: avoid; }
|
||||||
|
|
||||||
.nav-bar,
|
|
||||||
.top-navbar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
page-break-inside: avoid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -169,15 +177,12 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="top-navbar">
|
<div class="top-navbar">
|
||||||
|
|
||||||
<div class="brand-title">
|
<div class="brand-title">
|
||||||
National Reference Medical Laboratory Surveillance Dashboard
|
National Reference Medical Laboratory Surveillance Dashboard
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ms-auto small">
|
<div class="ms-auto small">
|
||||||
Last update: 12:05 | 2026-03-15
|
Last update: 12:05 | 2026-03-15
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav-bar">
|
<div class="nav-bar">
|
||||||
@@ -186,16 +191,8 @@
|
|||||||
Overview
|
Overview
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- @foreach($programs as $program)
|
|
||||||
<a href="/dashboard/{{ strtolower($program->code) }}"
|
|
||||||
class="nav-item {{ request()->is('dashboard/' . strtolower($program->code)) ? 'active-tab' : '' }}">
|
|
||||||
{{ $program->code }}
|
|
||||||
</a>
|
|
||||||
@endforeach -->
|
|
||||||
@foreach($programs as $program)
|
@foreach($programs as $program)
|
||||||
|
|
||||||
@if($program->code === 'SEQ')
|
@if($program->code === 'SEQ')
|
||||||
|
|
||||||
<a href="/dashboard/seq" class="nav-item {{ request()->is('dashboard/seq') ? 'active-tab' : '' }}">
|
<a href="/dashboard/seq" class="nav-item {{ request()->is('dashboard/seq') ? 'active-tab' : '' }}">
|
||||||
SEQ
|
SEQ
|
||||||
</a>
|
</a>
|
||||||
@@ -205,12 +202,11 @@
|
|||||||
{{ $program->code }}
|
{{ $program->code }}
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<div class="ms-auto d-flex align-items-center gap-2 pe-3">
|
<div class="ms-auto d-flex align-items-center gap-2 pe-3">
|
||||||
|
|
||||||
<button type="button" onclick="reloadDataSource()" class="btn btn-sm btn-theme-outline">
|
<button onclick="reloadDataSource()" class="btn btn-sm btn-theme-outline">
|
||||||
Refresh Data
|
Refresh Data
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -221,14 +217,12 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div id="exportItems" class="align-items-center gap-2">
|
<div id="exportItems" class="align-items-center gap-2">
|
||||||
|
|
||||||
<button class="btn btn-sm btn-light" onclick="openChartSelector()">Charts</button>
|
<button class="btn btn-sm btn-light" onclick="openChartSelector()">Charts</button>
|
||||||
<button class="btn btn-sm btn-light" onclick="exportFullDashboard()">Screen</button>
|
<button class="btn btn-sm btn-light" onclick="exportFullDashboard()">Screen</button>
|
||||||
<button class="btn btn-sm btn-light" onclick="window.print()">Print</button>
|
<button class="btn btn-sm btn-light" onclick="window.print()">Print</button>
|
||||||
|
|
||||||
<button class="btn btn-sm btn-outline-secondary" id="exportClose">✕</button>
|
<button class="btn btn-sm btn-outline-secondary" id="exportClose">✕</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="chartModal" class="export-modal">
|
<div id="chartModal" class="export-modal">
|
||||||
<div class="export-content">
|
<div class="export-content">
|
||||||
<h5>Select Charts</h5>
|
<h5>Select Charts</h5>
|
||||||
@@ -248,25 +242,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
|
|
||||||
<div class="content-area">
|
<div class="content-area">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@yield('scripts')
|
@yield('scripts')
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener("click", (e) => {
|
window.addEventListener("click", (e) => {
|
||||||
const modal = document.getElementById("chartModal");
|
const modal = document.getElementById("chartModal");
|
||||||
|
if (e.target === modal) modal.style.display = "none";
|
||||||
if (e.target === modal) {
|
|
||||||
modal.style.display = "none";
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function reloadDataSource() {
|
function reloadDataSource() {
|
||||||
fetch(`/api/dashboard/reload`)
|
fetch(`/api/dashboard/reload`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
@@ -275,5 +263,4 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -7,6 +7,10 @@ Route::get('/dashboard/summary', [DashboardController::class, 'summary']);
|
|||||||
Route::get('/dashboard/trend', [DashboardController::class, 'trend']);
|
Route::get('/dashboard/trend', [DashboardController::class, 'trend']);
|
||||||
Route::get('/dashboard/program', [DashboardController::class, 'program']);
|
Route::get('/dashboard/program', [DashboardController::class, 'program']);
|
||||||
Route::get('/dashboard/province-circles', [DashboardController::class, 'provinceCircles']);
|
Route::get('/dashboard/province-circles', [DashboardController::class, 'provinceCircles']);
|
||||||
|
Route::get('/dashboard/influenza-subtype-distribution', [DashboardController::class, 'influenzaSubtypeDetected']);
|
||||||
|
Route::get('/dashboard/covid-distributed-by-age-group', [DashboardController::class, 'covidDistributedByAgeGroup']);
|
||||||
|
Route::get('/dashboard/covid-lineage-frequency', [DashboardController::class, 'covidLineageRelativeOverTime']);
|
||||||
|
Route::get('/dashboard/influenza-relative-frequency', [DashboardController::class, 'influenzaRelativeOverTime']);
|
||||||
Route::get('/dashboard/sentinel-map', [DashboardController::class, 'sentinelMap']);
|
Route::get('/dashboard/sentinel-map', [DashboardController::class, 'sentinelMap']);
|
||||||
Route::get('/dashboard/reload', [DashboardController::class, 'fetchSourceData']);
|
Route::get('/dashboard/reload', [DashboardController::class, 'fetchSourceData']);
|
||||||
Route::get('/dashboard/sequencing', [DashboardController::class, 'sequencing']);
|
Route::get('/dashboard/sequencing', [DashboardController::class, 'sequencing']);
|
||||||
|
|||||||
Reference in New Issue
Block a user