Where will blood run short first, and which ICUs feel it?
Days of stock per state and blood group, projected forward and set against ICU pressure. Filter by state or group, or stress the system with the surge simulator.
Stress-test the next 7 days
Extra ICU beds opened. Occupancy drops, but more patients treated means more transfusions.
Which states' critical care is most exposed
0–100. Weighs ICU occupancy (45%), ventilator load (15%) and projected blood cover at the horizon (40%). Faint bars show the no-scenario baseline.
18 major state hospitals
Marker size follows ICU occupancy under the current scenario. Tap one for details; markers outside your filters fade.
Top 5 critical zones
Highest ICU pressure relative to available blood supply. Donors are needed here most today.
Localized donor alerts
Auto-generated from critical-quadrant hospitals.
ICU occupancy vs. blood supply, per hospital
Dashed lines are the medians that split the four quadrants. Blood index is on a log scale because Kuala Lumpur collects about 6× any other state. Tap a dot for details.
Projected days of stock
What to do this week
Supply share vs. demand benchmark
All hospitals
Ranked by vulnerability ratio. Click a column to sort, or a row for details. Red edge marks the national top 5.
| # |
|---|
Turn insight into action
Every critical zone on the dashboard needs real donors. Below is a directory of Malaysia's fixed blood donation venues, with real addresses and coordinates, plus how to find this week's mobile blood drives, which change too often to publish as a fixed list.
Most urgent right now
This week's mobile blood drives
PDN posts a new mobile-drive schedule (malls, offices, community centres) on its own channels about once a week. That changes too often for a static list here, so go straight to the source:
- pdn.gov.my, the official site. Look for "Lokasi Derma Darah Bergerak" (mobile donation locations).
- PDN's official Facebook page. Search "Pusat Darah Negara"; new locations are posted weekly.
- Call PDN: 03-2613 2688
What this dashboard does
It maps regional blood supply against ICU demand to surface localized critical zones: hospitals where high ICU pressure coincides with a thin extrapolated blood supply. Donation campaigns and blood-bank logistics can then be aimed at the places and blood types that need them most, instead of relying on general awareness appeals. The surge simulator lets planners test how floods, trauma events, outbreaks and extra ICU beds would move those numbers over the next 3 to 28 days — long enough to run a full ~4-week Ramadan dip end to end.
Data sources
| Dataset | Status in this app | Source |
|---|---|---|
| Blood donations by state & blood type | Real, rolling 7-day average, as of . Fetched live on page load via /api/blood-stock, which re-parses this same source file server-side; a baked-in snapshot is shown until that resolves and stays if it fails (see the badge in the header). | storage.data.gov.my/healthcare/blood_donations_state.parquet |
| ICU / ventilator occupancy | Illustrative baseline (state-level 2024 snapshot + per-hospital jitter) | Public hospital-bed-utilisation dashboard, data.moh.gov.my |
| Hospital facility list (name, district, lat/lng, beds) | Sample of 18 major MoH state hospitals | Assumed reference file. No public facility-level GPS registry is confirmed available. |
| Days of stock | Modelled from donations, ICU pressure and the ABO benchmark | No public blood-bank inventory feed exists; see the stock-flow model below |
| Malaysia coastline | Real, static (not live) | Natural Earth 1:50m admin-0 boundaries, via world-atlas TopoJSON |
| Donation venues | Real, static addresses and coordinates | PDN and MoH hospital blood banks |
Pipeline steps
- 1. Ingest. Fetch state-level blood donations (by A/B/AB/O) and hospital bed/ICU data; merge with the facility master list (name, district, lat/lng, beds).
- 2. Clean. Compute each state's rolling 7-day average donation total, overall and per blood type. Compute ICU and ventilator occupancy % per hospital. Fill Perlis, Putrajaya and Labuan with scaled proxies.
- 3. Extrapolate (gravity model). Distribute each state's blood pool to its hospitals, weighted by hospital size and inverse distance from the state capital.
- 4. Score. Compute the vulnerability ratio, classify each hospital into one of four quadrants, and identify its most-needed blood type.
- 5. Project. Run the stock-flow model per state × blood group to get days of stock over the forecast horizon, then the state ICU vulnerability index.
- 6. Alert & recommend. Generate a plain-language donor alert for every critical-quadrant hospital, plus donor-drive, transfer and ICU-capacity recommendations.
- 7. Serve. Export as JSON; a FastAPI backend serves the dashboard via
/api/health-index,/api/critical-zones,/api/quadrants,/api/alerts,/api/states/{state}, and the forecast routes/api/v1/stock,/api/v1/vulnerability,/api/v1/forecastandPOST /api/v1/simulate.
Formulas
Gravity-model blood availability score
Each hospital's pull on its state's blood pool grows with its bed count and shrinks with distance from the state capital, where the main blood bank sits:
decay_km defaults to 80 km, so hospitals further from the capital receive proportionally less of the state's pool. The same weight share is applied per blood type to get a type-level breakdown. Under a scenario, the score is multiplied by the collection factor and divided by the demand multiplier.
Vulnerability ratio (hospital)
Higher means more critical: high ICU pressure relative to how much blood reaches that hospital. It ranks the Top 5 critical zones and the all-hospitals table.
Four-quadrant classification
ICU occupancy and blood availability are each split at the median of the baseline dataset, not at a fixed clinical threshold:
- Critical zone: high ICU, low blood availability
- Stable high-demand: high ICU, high blood availability
- Watch: low ICU, low blood availability
- Healthy: low ICU, high blood availability
This is the vulnerability matrix on the dashboard; tap any dot for that hospital's detail.
Most-needed blood type
The benchmark is Malaysia's approximate population-wide ABO distribution (O ≈ 44%, A ≈ 26%, B ≈ 23%, AB ≈ 7%), a commonly cited clinical estimate rather than an official figure. The most under-supplied type drives the alert text for critical-zone hospitals.
Days of stock (stock-flow model)
No public inventory feed exists, so stock is modelled per state s and group g:
Demand is anchored to each state's own collection volume (collection networks are sized to local usage), raised where ICU pressure is above the 65% reference and shifted by the ABO benchmark. Status bands: critical < 3 d, low 3–5 d, adequate 5–7 d, healthy ≥ 7 d.
ICU vulnerability index (state)
Tiers: critical ≥ 70, elevated 55–69, stable < 55.
Surge simulator
Opening surge beds lowers occupancy, but more patients then reach an ICU bed, so blood demand rises. The simulator shows that trade-off directly.
| Scenario | ICU load | Blood demand | Collection lost | States (weight) |
|---|
Map
The coastline is Malaysia's real geometry (Peninsular, Sabah and Sarawak, plus Penang, Langkawi, Tioman and a few smaller islands), projected with a simple equirectangular fit to Malaysia's bounding box and drawn as inline SVG. Hospital markers use the same projection, so they land in the right place relative to the coastline. Live raster tiles such as OpenStreetMap aren't used because the published-page policy blocks remote image and tile requests. A self-hosted Next.js deployment can use Leaflet with OSM tiles instead.
From prototype to production
This version runs entirely client-side, with data baked in at build time. The production layout (see ) splits it into:
pipeline/: the daily ETL and training job described above, run as a cron job or GitHub Actions workflowapp/main.py: a FastAPI backend serving the endpoints listed in step 7app/dashboard/page.tsxandHospitalMap.tsx: a Next.js + Leaflet frontend with real OSM tiles
Swapping in a real hospital-level ICU/ventilator feed only needs a column mapping in the ingest step; the rest of the pipeline accepts it unchanged.
Limitations
- Days of stock are modelled from donation flow, not read from blood-bank inventory. Rh factor, component type (red cells, platelets, plasma) and expiry are not modelled.
- ICU occupancy is an illustrative baseline, so hospital rankings show the method working, not today's real ward state.
- Perlis, W.P. Putrajaya and W.P. Labuan are estimates, not reported figures. They're a fixed share of their nearest tracked state (Kedah, Selangor and Sabah respectively — 15%, 5% and 3%), applied equally to every blood group. Group O's share of donations varies from about 40% to 48% across states, so a proxy state's true type mix can differ from its parent's; treat these three states' per-group numbers, and anything downstream of them (most-needed type, donor alerts), as approximate.
- Scenario parameters are planning assumptions, not calibrated epidemiological estimates. The Ramadan donor dip is the one exception: its ~30% figure (95% range −36% to −24%, narrower check −32%) comes directly from the donation data.