citf-malaysia / citf-public Goto Github PK
View Code? Open in Web Editor NEWOfficial data on Malaysia's National Covid-19 Immunisation Programme (PICK). Powered by MySejahtera.
License: Other
Official data on Malaysia's National Covid-19 Immunisation Programme (PICK). Powered by MySejahtera.
License: Other
Lets do 'windows'?
i add your team as under 'MG'
just a development group
👍🏻
add me under yours, i'll help build the trackers for home assesment
but i have 1 problem now, my pc hardware are having problem and no budget for fix it(serious)
Hi,
Would like to ask if the state data is using PPV's address or the person's address to determine the state?
Just curious since this affects the accuracy of the data.
As of 20-7-2021, the total number of registration in W.P. Kuala Lumpur is 1,801,763 but the total number of first dose administered is 1,835,737 (+33,974). Is this caused by walk-ins? Or is there any other explanation? Just curious.
Suggestion:
Rather than committing the contribution codes directly into this repository, use a text list linking all contributor's project repositories instead.
This would eliminate the need to constantly review pull requests and the liability of having 3rd party codes under CTIF's official repository. This also eliminates the need to introduce a pull request every time a 3rd party updates their code.
IMO, latest update (CSV) should put on top (ordered by latest date):
on the new data structure, try to derive of those have completed the dose2, that from dose1.
from the data:
checked against the data, taking 18th Aug as example,
that means, 1-dose is not started, right? since column x is not there also.
when 1-dose started, with current data structure, will have problem to derive those have completed dose2 from dose1, since daily _full or cumul_full are sum of dose2 and 1-dose. also cannot derive those pending for dose2 that have completed dose1.
i presumed the population static data only referring to Malaysia citizens, while registration and vaccination including none Malaysians as well, am i right? just want to get it clear, as i did not see any clarification on this.
For example:
This will be useful for us to help to compare the data with other countries as well and perhaps improve the data structure to be more standardised
If CDC is using this data as well, that'll be great too.
We all know what the daily rate of vaccines being given is thanks to you sharing that data.
But let us see how effective you are, by also sharing the "burn down" of vaccine shots available versus shots given in arms.
This corpus of data only needs to be updated when arrivals of vaccines come. Provide historical data too, to ensure that we really did ramp up effectively.
E.g. Today the USA donated some Pfizer vaccines. This should be in the file. We need to know what's donated, what's paid for, what arrived, when it arrived, and how quickly they're going into arms.
Main reason is if we are to achieve phase two or three, with a vaccine component thrown into the mix (silly, but this is what it is), this data is crucial to share.
Also, share projections. Can't always blame the EU or First world for holding vaccines back. If you ordered something and it was delayed, the data will tell us all, rather than the "Vaccine Tsar" just shooting his mouth off.
https://alexandereric995.github.io/citf-public/mask.htm
adding left click function to branch sample at CL web link
daily_partial should be
daily_partial = sinovac1 + pfyzer1 + astra1
Some are not same;
2021-08-06 W.P. Labuan
daily_partial = 177
sinovac1 = 9
pfyzer1 = 125
Astra = 0
2021-08-16 W.P. Putrajaya
daily_partial = 623
sinovac1 = 5
pfyzer1 = 594
astra1 = 0
I believe some developers would appreciate being able to make GET requests for the data from their website. Creating a project site for this repo with GitHub Pages can be a quick way to achieve that, and it only takes a couple of clicks from the repo's settings tab.
After GitHub Pages is enabled, one can get the data by making a request to https://citf-malaysia.github.io/citf-public/<path to file>
Another thing that some may find nice to have is JSON-formatted data.
Note:
The downside of serving the data with GitHub Pages is that we can't have robust APIs that can, for example, filter the data by date, etc. However, it is a quick way for us to have APIs for the data.
Any particular reason why daily_partial calculated without cansino while cum_partial calculated with cansino? Seems inconsistent
Its not clear if the total from cumul_full includes the total from cumul_full_child, and likewise for the cumul_partial figures, can the README clarify this?
on data for selangor state, since 23rd july, the total registration, is more than adult population of 4,747,900. for example, on 23rd july, total registration is 4,778,443, on 21st aug, is 5,416,791.
Same issue happens on johor, melaka, n.sembilan, pulau pinang, kuala lumpur and putrajaya data.
saya forked dan lakukan kaedah PF terhadap web pihak tuan;puan.
Currently there are no data available for number of people who have taken their vaccination overseas, such as in Singapore, UK, Australia, etc. If this data is available, it will be a better gauge of the % of vaccinated population that is currently in Malaysia.
This data could be collected via voluntary submission of proof by citizens overseas.
The latest date should be at the top for vax_malaysia and vax_state so that it is more easier to read, instead of scrolling to the bottom to get the latest details
document.addEventListener('DOMContentLoaded', function () {
/**
|--------------------------------------------------------------------------
| params
|--------------------------------------------------------------------------
*/
// video canvas size(4:3)
const video_canvas_w = 640; // default 640
const video_canvas_h = Math.round(video_canvas_w * (3 / 4)); // default 480
// 顔画像キャプチャー先canvasのサイズ係数
const cliped_size_factor = 1.0;
/**
|--------------------------------------------------------------------------
| 前処理
|--------------------------------------------------------------------------
*/
let ctracker = new clm.tracker();
// video
let video = document.getElementById('camera');
video.width = video_canvas_w;
video.height = video_canvas_h;
// canvas
let video_canvas = document.getElementById('from-video');
let video_canvas_ctx = video_canvas.getContext('2d');
video_canvas.width = video_canvas_w;
video_canvas.height = video_canvas_h;
let cliped_canvas = document.getElementById('cliped');
let cliped_canvas_ctx = cliped_canvas.getContext('2d');
let dummy_canvas = document.getElementById('dummy');
let dummy_canvas_ctx = dummy_canvas.getContext('2d');
// dummy wrapper
let dummy_box = document.getElementById('dummy-box');
// video constraints
const video_constraints_for_front = {video: {facingMode : "user"}};
const video_constraints_for_rear = {video: {facingMode : {exact : "environment"}}};
let video_track = null;
// カメラ切り替え
const facing_mode = document.getElementById('facing-mode');
let is_front = facing_mode.value !== "0";
facing_mode.addEventListener('change', function(e){
is_front = this.checked;
if (video_track) {
video_track.stop();
}
video_track = null;
video.srcObject = null;
// Reload video
load();
});
// グレースケール変換
const for_grayscale = document.getElementById('to-grayscale');
let switch_grayscale = for_grayscale.value !== "0";
for_grayscale.addEventListener('change', function(e){
switch_grayscale = this.checked;
});
// debug用
const for_debug = document.getElementById('debug');
let is_debug = for_debug.value !== "0";
for_debug.addEventListener('change', function(e){
is_debug = this.checked;
});
// 顔部分のマージン設定
let scale; // 顔の長さを10等分する場合 1/10, 5等分の場合 1/5,,,
let margin_of_top_scale; // 顔部分の何%分上にマージンを取るか(margin_of_bottom_scaleとの調整が必要)
let margin_of_bottom_scale; // 顔部分の何%分下にマージンを取るか(margin_of_top_scaleとの調整が必要)
let margin_of_left_scale; // 顔部分の何%分左にマージンを取るか(margin_of_right_scaleとの調整が必要)
let margin_of_right_scale; // 顔部分の何%分右にマージンを取るか(margin_of_left_scaleとの調整が必要)
// @lenk https://beiznotes.org/input-range-show-value/
// スライダーの値
const range_elem = document.getElementsByClassName('range');
const apply_range_val = function(elem, target) {
return function(evt) {
setting_face_margin(elem.id);
apply_scale_val(elem.id, elem.value);
target.innerHTML = calc_range_val(elem.id, elem.value);
}
}
function calc_range_val(id_name, value) {
if (id_name !== 'scale') {
return value;
}
const _scale = parseInt(value, 10);
if (_scale <= 0) {
return 0;
}
return Math.round( (1 / _scale) * 1000 ) / 10;
}
function apply_scale_val(id_name, value) {
if (id_name !== 'scale') {
return;
}
document.getElementById('scale-val').innerHTML = value;
}
function setting_face_margin(id_name) {
if (id_name === 'scale') {
const _scale = parseInt(document.getElementById(id_name).value, 10);
scale = _scale > 0 ? 1 / _scale : 0;
}
// @link https://blog.sushi.money/entry/2017/04/19/114028
Array.from(range_elem, function(range) {
const bar = range.querySelector('input');
switch (bar.id) {
case 'margin_of_top_scale':
margin_of_top_scale = scale * bar.value;
break;
case 'margin_of_bottom_scale':
margin_of_bottom_scale = scale * bar.value;
break;
case 'margin_of_left_scale':
margin_of_left_scale = scale * bar.value;
break;
case 'margin_of_right_scale':
margin_of_right_scale = scale * bar.value;
break;
}
});
}
// transform: scaleX(-1); により逆転する
function switch_margin_label() {
const l = document.getElementById('range-margin-left');
const r = document.getElementById('range-margin-right');
if (is_front === true) {
l.innerHTML = 'margin-right';
r.innerHTML = 'margin-left';
} else {
l.innerHTML = 'margin-left';
r.innerHTML = 'margin-right';
}
}
function init_face_margin() {
setting_face_margin('scale');
for(let i = 0, len = range_elem.length; i < len; i++){
let range = range_elem[i];
let bar = range.querySelector('input');
let target = range.querySelector('span > span.range-val');
bar.addEventListener('input', apply_range_val(bar, target));
apply_scale_val(bar.id, bar.value);
target.innerHTML = calc_range_val(bar.id, bar.value);
}
}
/**
|--------------------------------------------------------------------------
| start
|--------------------------------------------------------------------------
*/
init_face_margin();
// Load video
load();
function load() {
const constraints = is_front ? video_constraints_for_front : video_constraints_for_rear;
swith_scaleX();
switch_margin_label();
navigator.mediaDevices.getUserMedia(constraints)
.then(load_success)
.catch(load_fail);
}
function load_success(stream) {
video_track = stream.getVideoTracks()[0];
video.srcObject = stream;
}
function load_fail(err) {
alert(err);
console.log(err);
}
function swith_scaleX() {
const scale_x_val = is_front ? -1 : 1;
video_canvas.style.transform = `scaleX(${scale_x_val})`;
cliped_canvas.style.transform = `scaleX(${scale_x_val})`;
dummy_canvas.style.transform = `scaleX(${scale_x_val})`;
}
// 動画再生のイベント監視
let tracking_started = false;
video.addEventListener('playing', function(){
if (tracking_started === true) {
return;
}
adjust_proportions();
init_ctracker();
draw_loop();
video.onresize = function() {
adjust_proportions();
ctracker.stop();
ctracker.reset();
ctracker.start(video);
}
tracking_started = true;
});
function init_ctracker() {
ctracker.init();
ctracker.start(video);
}
function adjust_proportions() {
// resize overlay and video if proportions of video are not 4:3
// keep same height, just change width
const proportion = video.videoWidth / video.videoHeight;
const video_width = Math.round(video.height * proportion);
video.width = video_width;
video_canvas.width = video_width;
dummy_canvas.width = video_width;
}
function draw_loop() {
requestAnimationFrame(draw_loop);
let w = video_canvas.width;
let h = video_canvas.height;
video_canvas_ctx.clearRect(0, 0, w, h);
video_canvas_ctx.drawImage(video, 0, 0, w, h);
dummy_canvas.width = w;
dummy_canvas.height = h;
dummy_canvas_ctx.clearRect(0, 0, w, h);
dummy_canvas_ctx.drawImage(video, 0, 0, w, h);
ctracker.draw(video_canvas);
const positions = ctracker.getCurrentPosition();
if (positions !== false) {
render_cliped_canvas(positions);
} else {
clear_cliped_canvas();
}
_stats();
}
/**
* render cliped_canvas
*/
function render_cliped_canvas(p) {
// 顔領域の矩形座標を求める
// @link http://blog.phalusamil.com/entry/2016/07/09/150751
const index_of_min_x = [0, 1, 2, 3, 4, 5, 6, 7, 19, 20];
const index_of_min_y = [0, 1, 2, 12, 13, 14, 15, 16, 19, 20];
const index_of_max_x = [7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
const index_of_max_y = [3, 4, 5, 6, 7, 8, 9, 10, 11];
let min = {'x': 100000, 'y': 100000};
let max = {'x': 0, 'y': 0};
for (let i = 0; i < index_of_min_x.length; i++) {
let k = index_of_min_x[i];
min.x = min.x > p[k][0] ? p[k][0] : min.x;
}
for (let i = 0; i < index_of_min_y.length; i++) {
let k = index_of_min_y[i];
min.y = min.y > p[k][1] ? p[k][1] : min.y;
}
for (let i = 0; i < index_of_max_x.length; i++) {
let k = index_of_max_x[i];
max.x = max.x < p[k][0] ? p[k][0] : max.x;
}
for (let i = 0; i < index_of_max_y.length; i++) {
let k = index_of_max_y[i];
max.y = max.y < p[k][1] ? p[k][1] : max.y;
}
const min_x = Math.round(min.x);
const min_y = Math.round(min.y);
const max_x = Math.round(max.x);
const max_y = Math.round(max.y);
const face_w = max.x - min.x;
const face_h = max.y - min.y;
const face_margin = Math.round(face_h * scale);
// 顔検出部分の面積調整(少し広めにしたりとか)
// transform: scaleX(-1); している場合sxとswの関係性が逆転します
let sx = min_x - (face_w * margin_of_left_scale);
let sy = min_y - (face_h * margin_of_top_scale);
let sw = face_w + (face_w * margin_of_right_scale);
let sh = face_h + (face_h * margin_of_bottom_scale);
const vcw = video_canvas.width;
const vch = video_canvas.height;
// 画面上に顔切り取り部分が見切れた場合
if (sy < 0) {
sy += Math.abs(sy);
}
// 画面下に顔切り取り部分が見切れた場合
const assigned_margin_bottom = Math.round((margin_of_bottom_scale - margin_of_top_scale) * 10);
const margin_of_bottom = face_margin * assigned_margin_bottom;
if (max_y + margin_of_bottom > vch) {
sy -= (max_y + margin_of_bottom) - vch;
}
// 画面左に顔切り取り部分が見切れた場合
const assigned_margin_left = Math.round((margin_of_right_scale - margin_of_left_scale) * 10);
const margin_of_left = face_margin * assigned_margin_left;
if (max_x + margin_of_left > vcw) {
sx -= (max_x + margin_of_left) - vcw;
}
// 画面右に顔切り取り部分が見切れた場合
if (sx < 0) {
sx += Math.abs(sx);
}
// 顔が見切れた場合
if (max_x > vcw || max_y > vch || min_x < 0 || min_y < 0) {
// clear_cliped_canvas();
return;
}
const w = Math.round(sw * cliped_size_factor);
const h = Math.round(sh * cliped_size_factor);
cliped_canvas.width = w;
cliped_canvas.height = h;
cliped_canvas_ctx.clearRect(0, 0, w, h);
cliped_canvas_ctx.drawImage(
dummy_canvas,
Math.round(sx),
Math.round(sy),
Math.round(sw),
Math.round(sh),
0,
0,
w,
h
);
if (switch_grayscale === true) {
to_grayscale(cliped_canvas, cliped_canvas_ctx);
}
// -- debug --
if (is_debug === true) {
if (scale <= 0) {
render_debug(dummy_canvas_ctx, 'rgba(0, 255, 0, 1)', min_x, min_y, face_w, face_h);
after_render_debug();
return;
}
// -- 顔部分マージン付き --
for (let margin=0, _sh=sh;_sh>=0;_sh-=face_h * scale) {
render_debug(dummy_canvas_ctx, 'rgba(255, 0, 0, 1)', sx, sy, sw, sh - margin);
margin += face_h * scale;
}
// -- 顔部分 --
for (let _scale=0;_scale<=1.0;_scale+=scale) {
render_debug(dummy_canvas_ctx, 'rgba(0, 255, 0, 1)', min_x, min_y, face_w, face_h - (face_h * _scale));
}
after_render_debug();
} else {
dummy_box.style.display = 'none';
}
}
function render_debug(ctx, ss, x, y, w, h) {
ctx.beginPath();
ctx.strokeStyle = ss;
ctx.lineWidth = 3;
ctx.strokeRect(x, y, w, h);
ctx.stroke();
}
function after_render_debug() {
dummy_box.style.display = 'block';
}
/**
* グレースケール変換
* @link https://www.html5canvastutorials.com/advanced/html5-canvas-grayscale-image-colors-tutorial/
*/
function to_grayscale(canvas, context) {
let image_data = context.getImageData(0, 0, canvas.width, canvas.height);
let data = image_data.data;
for(let i = 0; i < data.length; i += 4) {
let brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// red
data[i] = brightness;
// green
data[i + 1] = brightness;
// blue
data[i + 2] = brightness;
}
// overwrite original image
context.putImageData(image_data, 0, 0);
}
/**
* clear cliped_canvas
*/
function clear_cliped_canvas() {
cliped_canvas.width = 0;
cliped_canvas.height = 0;
cliped_canvas_ctx.clearRect(0, 0, cliped_canvas.width, cliped_canvas.height);
}
/******** stats ********/
function _stats() {
body.dispatchEvent(event);
}
const body = document.querySelector('body');
// Create the event.
const event = document.createEvent('Event');
// Define that the event name is 'build'.
event.initEvent('draw_loop', true, true);
const stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
body.appendChild(stats.domElement);
// Update stats on every iteration.
document.addEventListener('draw_loop', function(event) {
stats.update();
}, false);
});
since vaccination for 12 to 17yo starts on middle of september, for up-to-date data, has included those 12-17 already, or still only the adult only (18 and above)?
pada bot bantuan untuk isu covid dan vaksin, adakah lebih baik ditukar kepada live chat? saya cadangkan sebagai live chat features untuk pihak admin mampu menjawab soalan orang awam jika ditanyakkan terus ke live chat centre?
Is it possible to get data on the number of pax vaccinated based on the registration data? At the moment, I believe the number of pax vaccinated is taken from the location of the PPV
The data schema in this repo, i.e. the columns in CSVs change over time as the pandemic response evolves. Example: commit a6ccca9 renames columns for dose1
and dose2
to daily_partial
and daily_full
, to incorporate the rollout of single-dose vaccines. Although this is natural for pandemic data collection, it can be disruptive to downstream data consumers, who had to modify their applications to keep up with the changed data schema.
I'm keeping track of the data schema changes at https://gist.github.com/tnwei/6b1e974ff0fa5463933c94964a831dd0, which is updated regularly. Would like to suggest linking to my list in the README, so data consumers can see the lineage of data schema changes.
I'll put in a PR if @CITF-Malaysia is onboard. TQ for your tireless data updates!
Edit: Related suggestion in MOH data repo: MoH-Malaysia/covid19-public#179
Please provide vaccinated age group and preferably to group it by state.
Thanks!
the % of vaccinated by population(overall and by state) won't be correct with the data in the repository. These are the data needed for correct calculation
total population (malaysian) , population (non malaysian) , population > 18 (malaysian) , population >18 (non malaysian)
total vaccitated 1st dose (malaysian) , vaccitated 1st dose (non malaysian) , fully vaccitated (malaysian) fully vaccitated (non malaysian)
*fully vaccinated must include those given single-dose vaccines ( Sinopharm and Johnson & Johnson)
Also, it is much approachable if can get data of vaccination by the vaccine ( Pfizer, Sinivac, AZ, Sinopharm, and Johnson & Johnson)
With these data, we can have a better view of the vaccinated %
Boleh saya tahu kenapa kebanyakkan jurutera pihak tuan menggunakan .csr? biasanya .xml untuk maklumat
might need to review back your method
daily_partial = dose 1 for double dose
daily_full = dose 2 for double dose + cansino
cumul_partial = daily_partial + cansino
cumul_full = daily_full + cumul_full for the day before
cumul = cumul_partial + cumul_full
First you add cansino into cumul_partial. cumul_partial now has cansino.
Next you add cumul_full from the day before with daily_full. daily_full already has cansino in it.
Then for cumul, you calculate cumul_partial with cumul_full.
Question: Didnt this mean cansino calculated twice?
as per subject
Berikut adalah ReadMe yang saya edit sedikit:
https://github.com/my-mg/citf-public/blob/main/README.md
Population for W.P Kuala Lumpur is listed as 1773700
On 19/07/21, dose1_cumul is recorded as 1791880
What could be the reasons for this?
Anything else to take into account?
contoh cara untuk melakukan sub-cl:
https://alexandereric995.github.io/citf-public/mask.htm
tahniah, jika bekerjasama, Malaysia boleh jadi industri atas talian yang besar
👍🏻
daily_full: 2nd doses (for single-dose vaccines) and 1-dose vaccines (e.g. Cansino) delivered between 0000 and 2359 on date.
should be
daily_full: 2nd doses (for double-dose vaccines) and 1-dose vaccines (e.g. Cansino) delivered between 0000 and 2359 on date.
what i want for isues here are 'big mistakes' that had been happen. Do differenciate between Asthma;SARS and poisons by Desmondus rotundus.
thanks.
if you deal with real situations and real data about covid isues, might want for consider that facts.
Missed out the Selangor and KL statistic data for Vaccination https://covidnow.moh.gov.my/vaccinations/kvy
Different data on 15 July 2021 Total_Daily with JKJAV one
On their Twitter they stated 460158 but on this repo Total_daily it was 460123
seems like the problem is on dose1_daily , JKJAV stated 304807 but on this repo it was 304772.
Is there any glitch on this data?
Source : https://twitter.com/JKJAVMY/status/1415833970118258690/photo/1
Will a more specified (i.e districts, municipals) version of data for vaccine administration / vaccine registration be available? Will be useful to see which area have problems on vaccinations.
Hi All,
Regarding to vaxreg_malaysia.csv, all the variables x
value are cumulative data.
But I realized that the cumulative data is decreasing between 19th July and 20th July for call
and web
variables.
As we can see there's less 63 from 19th July to 20th July for call
variable.
Appreciated that could resolve my concern about this.
Thanks a lot!
Can you include data of daily cases based on categories of Covid19
disease just like this KKM graphics? Its also very nice if this data can be specific by states also, so that everyone can see
deeply on Covid19 disease effecting us. (https://www.facebook.com/kementeriankesihatanmalaysia/photos/a.390879946236/10158074729016237/)
i think you should add new column for cansino like other brand e.g pfizer1 & 2, astra1 & 2, sinovac1 & 2.
i believe it would help people know how many were vaccinated by cansino in a day.
please add a license, this is public data, it should be public domain licensed for others to use. the unlicense works pretty well for this.
#mapDiv {
position: absolute;
z-index:1;
top:0;
bottom:0;
right:0;
left:0;
overflow:hidden;
background-color:red;
}
See https://www.vaksincovid.gov.my/en/statistics/
W.P. Kuala Lumpur @ 1,773,700 versus JKJAV's 1,610,305
For example:
You can close this issue if you think otherwise.
but personally, for raw data, total_daily
, dose1_cumul
, dose2_cumul
, and total_cumul
may not be needed as those are calculated/generated from dose1_daily
and dose2_daily
.
If you're following specific standards, please mention it on the readme file for our reference.
Does the first column (pop) indicate the total population for sum of adult (18+) and elderly (60+) population at the state level? If so, any reason why the differences between the sum and the value input in the pop column vary around 9-24% across the states? Might be something I missed out in my analysis.
I'm aware that the section on Data Request is non-promissory but hopefully, there could be updates on whether each data request is either being reviewed, work in progress, or is rejected for a reason. Thanks.
CONTRIB.md uses numbered lists, which means that people wanting to update CONTRIB.md will all add their entries in the next available number. Thus, nearly all PRs will have merge conflicts as everyone adds their entry to the next available number on master branch. In current state, only the next immediate PR accepted can be merged cleanly.
I suggest changing the numbered lists in CONTRIB to unordered lists, using "+" or "-" as bulletpoints instead. As long as everyone only adds their own line in their PRs, all future PRs can be merged cleanly. As for the current outstanding PRs, merging is no issue once people update their PRs accordingly to match the format.
Just to be explicit with what I mean, here is the before:
1) [[Git repo]](https://github.com/aminhusni/project_kururugi_offline)
[[Live Version]](https://kururugi.blob.core.windows.net/kururugi/index.html)
Project Kururugi, by Amin Husni. Analysis and plotting of vaccination data.
2) [[Git repo]](https://github.com/leeliwei930/citf-express-api)
CITF Express API server, by [Li Wei Lee](https://techrino.net). A RestFUL API server written in NodeJS to parse the CSV-formatted data into JSON format, allowing for a variety of query via HTTP requests.
3) [[Live Version]](https://twitter.com/MYVaccineCount)
Malaysia Vaccine Tracker Twitter Bot, by [Henry Lim](https://twitter.com/henrylim96). Auto-tweets daily COVID-19 vaccination progress for the country, as well as each state.
And here is the after:
+ [[Git repo]](https://github.com/aminhusni/project_kururugi_offline)
[[Live Version]](https://kururugi.blob.core.windows.net/kururugi/index.html)
Project Kururugi, by Amin Husni. Analysis and plotting of vaccination data.
+ [[Git repo]](https://github.com/leeliwei930/citf-express-api)
CITF Express API server, by [Li Wei Lee](https://techrino.net). A RestFUL API server written in NodeJS to parse the CSV-formatted data into JSON format, allowing for a variety of query via HTTP requests.
+ [[Live Version]](https://twitter.com/MYVaccineCount)
Malaysia Vaccine Tracker Twitter Bot, by [Henry Lim](https://twitter.com/henrylim96). Auto-tweets daily COVID-19 vaccination progress for the country, as well as each state.
A similar changed has been proposed in the COVID data repo, which has been accepted: MoH-Malaysia/covid19-public#157
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.