As a little project, I am trying to create a simple online hematology differential counter.The physical counters (which are no more than glorified calculators) run labs in excess of $1000 per device. Small labs and labs in underdeveloped countries cannot afford this cost, so an online solution would be valuable.
HTML
<h1>Use the number pad to count cells</h1>
<textarea id="textarea"></textarea>
<br>Cells counted:
<br>
<input type=text id="counter" size=5><br>
Blasts:<br><input type=text id="bl_num" size=5><br>
Blasts%:<br><input type=text id="bl_pct" size=5><br>
Segmented and band neutrophils:<br><input type=text id="segs_num" size=5><br>
Segmented and band neutrophils%:<br><input type=text id="segs_pct" size=5><br>
Lymphocytes:<br><input type=text id="lymph_num" size=5><br>
Lymphocytes%:<br><input type=text id="lymph_pct" size=5><br>
Metamyelocytes/myelocytes:<br><input type=text id="meta_num" size=5><br>
Metamyelocytes/myelocytes%:<br><input type=text id="meta_pct" size=5><br>
Promyelocytes:<br><input type=text id="pro_num" size=5><br>
Promyelocytes%:<br><input type=text id="pro_pct" size=5><br>
Monocytes:<br><input type=text id="mono_num" size=5><br>
Monocytes%:<br><input type=text id="mono_pct" size=5><br>
Nrbc:<br><input type=text id="nrbc_num" size=5><br>
Nrbc%:<br><input type=text id="nrbc_pct" size=5><br>
Eosinophils:<br><input type=text id="eos_num" size=5><br>
Eosinophils%:<br><input type=text id="eos_pct" size=5><br>
Plasma cells:<br><input type=text id="plasma_num" size=5><br>
Plasma cells%:<br><input type=text id="plasma_pct" size=5><br>
Basophils:<br><input type=text id="baso_num" size=5><br>
Basophils%:<br><input type=text id="baso_pct" size=5><br>
Atypical cells:<br><input type=text id="atyp_num" size=5><br>
Atypical cells%:<br><input type=text id="atyp_pct" size=5><br>
my script:
$(window).load(function(){
$("#textarea").keyup(function () {
var box = $(this).val();
var len = box.length;
if (len < 201) {
$('#counter').val(len);
// count blasts
var _blast = box.match(/8/g).length;
var _blast_pct = (_blast / len) * 100;
$('#bl_num').val(_blast);
$('#bl_pct').val(_blast_pct);
// count segs
var _segs = box.match(/3/g).length;
var _segs_pct = (_segs / len) * 100;
$('#segs_num').val(_segs);
$('#segs_pct').val(_segs_pct);
// count meta/myelo
var _meta = box.match(/7/g).length;
var _meta_pct = (_meta / len) * 100;
$('#meta_num').val(_meta);
$('#meta_pct').val(_meta_pct);
// count pros
var _pro = box.match(/5/g).length;
var _pro_pct = (_pro / len) * 100;
$('#pro_num').val(_pro);
$('#pro_pct').val(_pro_pct);
// count lymphs
var _lym = box.match(/2/g).length;
var _lym_pct = (_lym / len) * 100;
$('#lymph_num').val(_lym);
$('#lymph_pct').val(_lym_pct);
// count nrbcs
var _nrbc = box.match(/9/g).length;
var _nrbc_pct = (_nrbc / len) * 100;
$('#nrbc_num').val(_nrbc);
$('#nrbc_pct').val(_nrbc_pct);
// count eos
var _eos = box.match(/4/g).length;
var _eos_pct = (_eos / len) * 100;
$('#eos_num').val(_eos);
$('#eos_pct').val(_eos_pct);
// count mono
var _mono = box.match(/1/g).length;
var _mono_pct = (_mono / len) * 100;
$('#mono_num').val(_mono);
$('#mono_pct').val(_mono_pct);
// count plasma
var _plasma = box.match(/6/g).length;
var _plasma_pct = (_plasma / len) * 100;
$('#plasma_num').val(_plasma);
$('#plasma_pct').val(_plasma_pct);
// count basos
var _baso = box.match(/\+/g).length;
var _baso_pct = (_baso / len) * 100;
$('#baso_num').val(_baso);
$('#baso_pct').val(_baso_pct);
// count atypcal cells
var _atyp = box.match(/\-/g).length;
var _atyp_pct = (_atyp / len) * 100;
$('#atyp_num').val(_atyp);
$('#atyp_pct').val(_atyp_pct);
} else {
alert("You have counted 200 cells");
}
});
});
I have this crude example working (see here:http://jsfiddle.net/xpMTE/), but I don't understand why the character frequency data don't populate in real time? When the user uses the number pad to count cells they see in the microscope, the counter seems to wait for certain instances to happen fist, before populating the rest of the graph. This is not an ideal condition.
Okay, I think I figured it out. My console log was highlighting an error such that if my .match statement did not find any matches, it would return null, thus a null.length was invalid.
So, I took the .match arguments outside of the initial if statement, and instead added a series of if statements such that:
// count blasts
if (box.match(/8/g) !== null) {
var _blast = box.match(/8/g).length;
var _blast_pct = (_blast / len) * 100;
$('#bl_num').val(_blast);
$('#bl_pct').val(_blast_pct);
}
and so on for each keypress match.
Now, the boxes populate in realtime.
see here: http://jsfiddle.net/xpMTE/1/