extensions/net.sf.basedb.meludi/trunk/resources/libprep/dna_protocol.js

Code
Comments
Other
Rev Date Author Line
3449 28 Jul 15 olle 1 var Protocol = function()
3449 28 Jul 15 olle 2 {
3449 28 Jul 15 olle 3   var protocol = {};
3449 28 Jul 15 olle 4   var debug = 0;
3449 28 Jul 15 olle 5   
3449 28 Jul 15 olle 6   var LOW_QUANTITY_WARNING_FACTOR = 2;
3449 28 Jul 15 olle 7
3449 28 Jul 15 olle 8   // Page initialization
3449 28 Jul 15 olle 9   protocol.initPage = function()
3449 28 Jul 15 olle 10   {
3449 28 Jul 15 olle 11     var pageId = Doc.getPageId();
3449 28 Jul 15 olle 12 //alert("dna_protocol.js::initPage(): pageId = " + pageId);
3449 28 Jul 15 olle 13     if (pageId == 'protocol')
3449 28 Jul 15 olle 14     {
3449 28 Jul 15 olle 15       Buttons.addClickHandler('print-button', Wizard.goPrint);  
3449 28 Jul 15 olle 16
3449 28 Jul 15 olle 17       var dnaPlateId = Data.int('page-data', 'dna-plate');
3449 28 Jul 15 olle 18 alert("dna_protocol.js::initPage(): dnaPlateId = " + dnaPlateId);
3449 28 Jul 15 olle 19
3449 28 Jul 15 olle 20 /*
3449 28 Jul 15 olle 21       var url = '../MRna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 22       url += '&cmd=GetMRnaInfoForPlate&bioplate='+mrnaPlateId;    
3449 28 Jul 15 olle 23       Wizard.showLoadingAnimation('Loading mRNA bioplate information...');
3449 28 Jul 15 olle 24 */
3449 28 Jul 15 olle 25       var url = '../Dna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 26       url += '&cmd=GetDnaInfoForPlate&bioplate='+dnaPlateId;    
3449 28 Jul 15 olle 27       Wizard.showLoadingAnimation('Loading DNA bioplate information...');
3449 28 Jul 15 olle 28       Wizard.asyncJsonRequest(url, protocol.initializeProtocol);
3449 28 Jul 15 olle 29     }
3449 28 Jul 15 olle 30     else
3449 28 Jul 15 olle 31     {
3449 28 Jul 15 olle 32       Events.addEventHandler('bioplate', 'change', protocol.bioplateOnChange);
3449 28 Jul 15 olle 33       Events.addEventHandler('listview', 'click', protocol.viewProtocol);
3449 28 Jul 15 olle 34       Events.addEventHandler('plateview', 'click', protocol.viewProtocol);
3449 28 Jul 15 olle 35       Events.addEventHandler('stratageneConc', 'keypress', Events.numberOnly);
3449 28 Jul 15 olle 36
3449 28 Jul 15 olle 37 /*
3449 28 Jul 15 olle 38       var url = '../Dna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 39       url += '&cmd=GetUnprocessedPlates&plateType=DNA';
3449 28 Jul 15 olle 40 */
3449 28 Jul 15 olle 41       var url = '../LibPrep.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 42       url += '&cmd=GetLibraryPlatesForLibPrep';
3449 28 Jul 15 olle 43       Wizard.showLoadingAnimation('Loading DNA plates...');
3449 28 Jul 15 olle 44       Wizard.asyncJsonRequest(url, protocol.initializeStep1);
3449 28 Jul 15 olle 45     }
3449 28 Jul 15 olle 46   }
3449 28 Jul 15 olle 47
3449 28 Jul 15 olle 48
3449 28 Jul 15 olle 49   protocol.initializeStep1 = function(response)
3449 28 Jul 15 olle 50   {
3449 28 Jul 15 olle 51     var frm = document.forms['meludi'];  
3449 28 Jul 15 olle 52
3449 28 Jul 15 olle 53     var bioplates = response.bioplates;
3449 28 Jul 15 olle 54     var plates = frm.bioplate;
3449 28 Jul 15 olle 55     if (bioplates.length > 0)
3449 28 Jul 15 olle 56     {
3449 28 Jul 15 olle 57       for (var i=0; i < bioplates.length; i++)
3449 28 Jul 15 olle 58       {
3449 28 Jul 15 olle 59         var bioplate = bioplates[i];
3449 28 Jul 15 olle 60         var name = bioplate.name;
3449 28 Jul 15 olle 61         if (bioplate.AutoProcessing == 'PreNormalizeRNA')
3449 28 Jul 15 olle 62         {
3449 28 Jul 15 olle 63           name += ' (pre-normalized)';
3449 28 Jul 15 olle 64         }
3449 28 Jul 15 olle 65         else if (bioplate.DilutionDate)
3449 28 Jul 15 olle 66         {
3449 28 Jul 15 olle 67           name += ' (diluted ' + Meludi.reformatDate(bioplate.DilutionDate) + ')';
3449 28 Jul 15 olle 68         }
3449 28 Jul 15 olle 69         var option = new Option(name, bioplate.id);
3449 28 Jul 15 olle 70         option.bioplate = bioplate;
3449 28 Jul 15 olle 71         plates.options[plates.length] = option;
3449 28 Jul 15 olle 72       }
3449 28 Jul 15 olle 73       bioplateIsValid = true;
3449 28 Jul 15 olle 74       
3449 28 Jul 15 olle 75       protocol.bioplateOnChange();
3449 28 Jul 15 olle 76       protocol.loadStratageneConc();
3449 28 Jul 15 olle 77     }
3449 28 Jul 15 olle 78     else
3449 28 Jul 15 olle 79     {
3449 28 Jul 15 olle 80       Wizard.setFatalError('No DNA bioplates available for processing.');
3449 28 Jul 15 olle 81       return;
3449 28 Jul 15 olle 82     }
3449 28 Jul 15 olle 83
3449 28 Jul 15 olle 84     Doc.show('step-1');
3449 28 Jul 15 olle 85     Doc.show('gonext');
3449 28 Jul 15 olle 86   }
3449 28 Jul 15 olle 87   
3449 28 Jul 15 olle 88   
3449 28 Jul 15 olle 89   // Add pools to the pools list based on the bioplate selection
3449 28 Jul 15 olle 90   protocol.bioplateOnChange = function()
3449 28 Jul 15 olle 91   {
3449 28 Jul 15 olle 92     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 93     var bioplate = frm.bioplate[frm.bioplate.selectedIndex].bioplate;
3449 28 Jul 15 olle 94     Doc.element('comments').innerHTML = Strings.encodeTags(bioplate.comments);
3449 28 Jul 15 olle 95     frm.poolSchema.value = bioplate.poolSchema;
3449 28 Jul 15 olle 96   }
3449 28 Jul 15 olle 97   
3449 28 Jul 15 olle 98   protocol.saveStratageneConc = function()
3449 28 Jul 15 olle 99   {
3449 28 Jul 15 olle 100     if (!window.localStorage) return;
3449 28 Jul 15 olle 101     
3449 28 Jul 15 olle 102     var frm = document.forms['meludi'];  
3449 28 Jul 15 olle 103     var stratageneInfo = new Object();
3449 28 Jul 15 olle 104     stratageneInfo.conc = frm.stratageneConc.value;
3449 28 Jul 15 olle 105     window.localStorage.setItem('meludi.stratagene-info', JSON.stringify(stratageneInfo));
3449 28 Jul 15 olle 106   }
3449 28 Jul 15 olle 107
3449 28 Jul 15 olle 108   protocol.loadStratageneConc = function()
3449 28 Jul 15 olle 109   {
3449 28 Jul 15 olle 110     if (!window.localStorage) return;
3449 28 Jul 15 olle 111     var frm = document.forms['meludi'];  
3449 28 Jul 15 olle 112     
3449 28 Jul 15 olle 113     var stratageneInfo = JSON.parse(window.localStorage.getItem('meludi.stratagene-info'));
3449 28 Jul 15 olle 114     if (stratageneInfo)
3449 28 Jul 15 olle 115     {
3449 28 Jul 15 olle 116       frm.stratageneConc.value = stratageneInfo.conc;
3449 28 Jul 15 olle 117     }
3449 28 Jul 15 olle 118   }
3449 28 Jul 15 olle 119
3449 28 Jul 15 olle 120   protocol.viewProtocol = function(event)
3449 28 Jul 15 olle 121   {
3449 28 Jul 15 olle 122 /*
3449 28 Jul 15 olle 123     protocol.saveStratageneConc();
3449 28 Jul 15 olle 124 */
3449 28 Jul 15 olle 125     
3449 28 Jul 15 olle 126     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 127     if (frm.bioplate && !frm.bioplate.disabled)
3449 28 Jul 15 olle 128     {
3449 28 Jul 15 olle 129       frm.view.value = Data.get(event.currentTarget, 'protocol-type');
3449 28 Jul 15 olle 130       frm.submit();
3449 28 Jul 15 olle 131     }
3449 28 Jul 15 olle 132   }
3449 28 Jul 15 olle 133
3449 28 Jul 15 olle 134   
3449 28 Jul 15 olle 135   protocol.initializeProtocol = function(response)
3449 28 Jul 15 olle 136   {
3449 28 Jul 15 olle 137 alert("dna_protocol.js::initializeProtocol(): Start");
3449 28 Jul 15 olle 138     var plate = response.plate;
3449 28 Jul 15 olle 139     if (plate.DilutionDate)
3449 28 Jul 15 olle 140     {
3449 28 Jul 15 olle 141       Doc.element('dilution-date').innerHTML = Meludi.reformatDate(plate.DilutionDate);
3449 28 Jul 15 olle 142       Doc.element('dilution-operator').innerHTML = Strings.encodeTags(plate.DilutionOperator);
3449 28 Jul 15 olle 143     }
3449 28 Jul 15 olle 144     
3449 28 Jul 15 olle 145     var list = response.dna;
3449 28 Jul 15 olle 146     var stratageneConc = Data.float('page-data', 'stratagene-conc');
3449 28 Jul 15 olle 147     
3449 28 Jul 15 olle 148     // Pre-process the return DNA items
3449 28 Jul 15 olle 149     var allPreNormalized = true;
3449 28 Jul 15 olle 150 alert("dna_protocol.js::initializeProtocol(): list.length = " + list.length);
3449 28 Jul 15 olle 151     for (var i = 0; i < list.length; i++)
3449 28 Jul 15 olle 152     {
3449 28 Jul 15 olle 153 alert("dna_protocol.js::initializeProtocol(): i = " + i);
3449 28 Jul 15 olle 154 alert("dna_protocol.js::initializeProtocol(): list[" + i + "].dna.name = " + list[i].dna.name);
3449 28 Jul 15 olle 155 /*
3449 28 Jul 15 olle 156       allPreNormalized &= list[i].rna.preNormalized;
3449 28 Jul 15 olle 157 */
3449 28 Jul 15 olle 158       allPreNormalized &= list[i].dna.preNormalized;
3449 28 Jul 15 olle 159       protocol.checkAndPreProcessDna(list[i], stratageneConc);
3449 28 Jul 15 olle 160     }
3449 28 Jul 15 olle 161     
3449 28 Jul 15 olle 162     var view = Data.get('page-data', 'view');
3449 28 Jul 15 olle 163     if (view == 'list')
3449 28 Jul 15 olle 164     {
3449 28 Jul 15 olle 165       protocol.viewAsList(list);
3449 28 Jul 15 olle 166     }
3449 28 Jul 15 olle 167     else
3449 28 Jul 15 olle 168     {
3449 28 Jul 15 olle 169       protocol.viewAsPlate(plate, list)
3449 28 Jul 15 olle 170     }
3449 28 Jul 15 olle 171     if (allPreNormalized)
3449 28 Jul 15 olle 172     {
3449 28 Jul 15 olle 173       Doc.element('dilution-date').innerHTML = 'PreNormalized';
3449 28 Jul 15 olle 174     }
3449 28 Jul 15 olle 175   }
3449 28 Jul 15 olle 176   
3449 28 Jul 15 olle 177   protocol.checkAndPreProcessDna = function(mrna, stratageneConc)
3449 28 Jul 15 olle 178   {
3449 28 Jul 15 olle 179     var rna = mrna.rna;
3449 28 Jul 15 olle 180     // Set the 'stratagene' flag
3449 28 Jul 15 olle 181     rna.stratagene = Meludi.isStratagene(rna.name);
3449 28 Jul 15 olle 182     rna.external = Meludi.isExternal(rna.name);
3449 28 Jul 15 olle 183     
3449 28 Jul 15 olle 184     // Set the 'QC' flag 
3449 28 Jul 15 olle 185     rna.qc = mrna.UseForQC;
3449 28 Jul 15 olle 186     
3449 28 Jul 15 olle 187     if (stratageneConc > 0)
3449 28 Jul 15 olle 188     {
3449 28 Jul 15 olle 189       if (rna.stratagene && !rna.NDConc) rna.NDConc = stratageneConc;
3449 28 Jul 15 olle 190     }
3449 28 Jul 15 olle 191     
3449 28 Jul 15 olle 192     // Calculate volume to use and water to add based on concentration
3449 28 Jul 15 olle 193     var remarks = [];
3449 28 Jul 15 olle 194     if (rna.NDConc && rna.usedQuantity)
3449 28 Jul 15 olle 195     {
3449 28 Jul 15 olle 196       rna.volume = Math.ceil(10000*rna.usedQuantity/rna.NDConc) / 10; // µl
3449 28 Jul 15 olle 197       if (rna.preNormalized)
3449 28 Jul 15 olle 198       {
3449 28 Jul 15 olle 199         rna.water = 0;
3449 28 Jul 15 olle 200       }
3449 28 Jul 15 olle 201       else
3449 28 Jul 15 olle 202       {
3449 28 Jul 15 olle 203         var totalVolume = mrna.DilutionConc ? 1000 * rna.usedQuantity / mrna.DilutionConc : 50;
3449 28 Jul 15 olle 204         rna.water = totalVolume-rna.volume;
3449 28 Jul 15 olle 205         if (totalVolume > 50)
3449 28 Jul 15 olle 206         {
3449 28 Jul 15 olle 207           remarks[remarks.length] = 'Large mix; Use 50µl';
3449 28 Jul 15 olle 208         }
3449 28 Jul 15 olle 209       }
3449 28 Jul 15 olle 210     }
3449 28 Jul 15 olle 211     
3449 28 Jul 15 olle 212     // check for some issues that may indicate problems
3449 28 Jul 15 olle 213     if (rna.qc) remarks[remarks.length] = 'QC';
3449 28 Jul 15 olle 214     if (!rna.stratagene && !rna.external)
3449 28 Jul 15 olle 215     {
3449 28 Jul 15 olle 216       if (!rna.bioWell && !rna.preNormalized)
3449 28 Jul 15 olle 217       {
3449 28 Jul 15 olle 218         remarks[remarks.length] = 'No location';
3449 28 Jul 15 olle 219       }
3449 28 Jul 15 olle 220       if (!rna.remainingQuantity)
3449 28 Jul 15 olle 221       {
3449 28 Jul 15 olle 222         remarks[remarks.length] = 'No quantity';
3449 28 Jul 15 olle 223       }
3449 28 Jul 15 olle 224       else if (rna.remainingQuantity < rna.usedQuantity)
3449 28 Jul 15 olle 225       {
3449 28 Jul 15 olle 226         remarks[remarks.length] = 'Not enough RNA';
3449 28 Jul 15 olle 227       }
3449 28 Jul 15 olle 228       else if (rna.remainingQuantity < rna.usedQuantity * LOW_QUANTITY_WARNING_FACTOR && !rna.preNormalized)
3449 28 Jul 15 olle 229       {
3449 28 Jul 15 olle 230         remarks[remarks.length] = 'Low quantity';
3449 28 Jul 15 olle 231       }
3449 28 Jul 15 olle 232       if (!rna.NDConc)
3449 28 Jul 15 olle 233       {
3449 28 Jul 15 olle 234         remarks[remarks.length] = 'No NDConc value';
3449 28 Jul 15 olle 235       }
3449 28 Jul 15 olle 236     }
3449 28 Jul 15 olle 237     else if (rna.stratagene)
3449 28 Jul 15 olle 238     {
3449 28 Jul 15 olle 239       if (!rna.NDConc && rna.usedQuantity) 
3449 28 Jul 15 olle 240       {
3449 28 Jul 15 olle 241         remarks[remarks.length] = 'Use ' + Numbers.formatNumber(rna.usedQuantity, 2) + ' µg RNA';
3449 28 Jul 15 olle 242       }
3449 28 Jul 15 olle 243     }
3449 28 Jul 15 olle 244     else if (rna.external)
3449 28 Jul 15 olle 245     {
3449 28 Jul 15 olle 246       remarks[remarks.length] = 'Use ' + Numbers.formatNumber(rna.usedQuantity, 2) + ' µg RNA';
3449 28 Jul 15 olle 247     }
3449 28 Jul 15 olle 248     if (mrna.comment) remarks[remarks.length] = mrna.comment;
3449 28 Jul 15 olle 249     rna.remarks = remarks;
3449 28 Jul 15 olle 250   }
3449 28 Jul 15 olle 251
3449 28 Jul 15 olle 252   protocol.viewAsPlate = function(plate, list)
3449 28 Jul 15 olle 253   {
3449 28 Jul 15 olle 254 alert("dna_protocol.js::viewAsPlate(): Start");    
3449 28 Jul 15 olle 255     var schema = PoolSchema.getById(plate.poolSchema);
3449 28 Jul 15 olle 256     Plate.init(plate.rows, plate.columns, schema, WellPainter);
3449 28 Jul 15 olle 257
3449 28 Jul 15 olle 258 alert("dna_protocol.js::viewAsPlate(): list.length = " + list.length);    
3449 28 Jul 15 olle 259     for (var i = 0; i < list.length; i++)
3449 28 Jul 15 olle 260     {
3449 28 Jul 15 olle 261       var mrna = list[i];
3449 28 Jul 15 olle 262 alert("dna_protocol.js::viewAsPlate(): i = " + i + " mrna = " + JSON.stringify(mrna));    
3449 28 Jul 15 olle 263       var well = mrna.bioWell;
3449 28 Jul 15 olle 264       Plate.getWell(well.row, well.column).setExtract(mrna);
3449 28 Jul 15 olle 265     }
3449 28 Jul 15 olle 266
3449 28 Jul 15 olle 267     Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 268     PoolSchema.buildPoolTableRow(schema, plate.columns);
3449 28 Jul 15 olle 269     Doc.show('all-protocol');
3449 28 Jul 15 olle 270   }
3449 28 Jul 15 olle 271
3449 28 Jul 15 olle 272   protocol.viewAsList = function(list)
3449 28 Jul 15 olle 273   {
3449 28 Jul 15 olle 274 alert("dna_protocol.js::viewAsList(): Start");    
3449 28 Jul 15 olle 275 alert("dna_protocol.js::viewAsList(): list.length = " + list.length);    
3449 28 Jul 15 olle 276     for (var i = 0; i < list.length; i++)
3449 28 Jul 15 olle 277     {
3449 28 Jul 15 olle 278       var mrna = list[i];
3449 28 Jul 15 olle 279       var rna = mrna.rna;
3449 28 Jul 15 olle 280       var idSuffix = mrna.bioWell.column + '.' + mrna.bioWell.row;
3449 28 Jul 15 olle 281       var tableRow = Doc.element('row.'+idSuffix);
3449 28 Jul 15 olle 282       
3449 28 Jul 15 olle 283       Doc.removeClass(tableRow, 'empty');
3449 28 Jul 15 olle 284       if (rna.external) Doc.addClass(tableRow, 'external');
3449 28 Jul 15 olle 285       if (rna.stratagene) Doc.addClass(tableRow, 'stratagene');
3449 28 Jul 15 olle 286       Doc.element('rna.'+idSuffix).innerHTML = Strings.encodeTags(rna.external && mrna.externalId ? mrna.externalId : rna.name);
3449 28 Jul 15 olle 287       Doc.element('box.'+idSuffix).innerHTML = Strings.encodeTags(protocol.getPlateCoordinate(rna, true));
3449 28 Jul 15 olle 288       Doc.element('ndconc.'+idSuffix).innerHTML = Numbers.formatNumber(rna.NDConc, 2);
3449 28 Jul 15 olle 289       Doc.element('remain.'+idSuffix).innerHTML = Numbers.formatNumber(rna.remainingQuantity, 2);
3449 28 Jul 15 olle 290       Doc.element('volume.'+idSuffix).innerHTML = Numbers.formatNumber(rna.volume, 1);
3449 28 Jul 15 olle 291       Doc.element('water.'+idSuffix).innerHTML = rna.preNormalized ? '—' : Numbers.formatNumber(rna.water, 1);
3449 28 Jul 15 olle 292       Doc.element('remarks.'+idSuffix).innerHTML = rna.remarks.join('; ');
3449 28 Jul 15 olle 293     }
3449 28 Jul 15 olle 294     
3449 28 Jul 15 olle 295     Doc.show('all-protocol');
3449 28 Jul 15 olle 296   }
3449 28 Jul 15 olle 297   
3449 28 Jul 15 olle 298   
3449 28 Jul 15 olle 299   protocol.getPlateCoordinate = function(rna, includePlateName)
3449 28 Jul 15 olle 300   {
3449 28 Jul 15 olle 301     var c = '';
3449 28 Jul 15 olle 302     if (rna.bioWell)
3449 28 Jul 15 olle 303     {
3449 28 Jul 15 olle 304       if (includePlateName) c += rna.bioWell.bioPlate.name;
3449 28 Jul 15 olle 305       c += ' ' + Meludi.wellToAlpha(rna.bioWell.row) + (rna.bioWell.column+1);
3449 28 Jul 15 olle 306     }
3449 28 Jul 15 olle 307     else if (rna.preNormalized)
3449 28 Jul 15 olle 308     {
3449 28 Jul 15 olle 309       c = 'PreNorm.';
3449 28 Jul 15 olle 310     }
3449 28 Jul 15 olle 311     else
3449 28 Jul 15 olle 312     {
3449 28 Jul 15 olle 313       c = ' ';
3449 28 Jul 15 olle 314     }
3449 28 Jul 15 olle 315     return c;
3449 28 Jul 15 olle 316   }
3449 28 Jul 15 olle 317
3449 28 Jul 15 olle 318     
3449 28 Jul 15 olle 319   return protocol;
3449 28 Jul 15 olle 320 }();
3449 28 Jul 15 olle 321
3449 28 Jul 15 olle 322 Doc.onLoad(Protocol.initPage);
3449 28 Jul 15 olle 323
3449 28 Jul 15 olle 324
3449 28 Jul 15 olle 325 var WellPainter = function()
3449 28 Jul 15 olle 326 {
3449 28 Jul 15 olle 327   var painter = {};
3449 28 Jul 15 olle 328   
3449 28 Jul 15 olle 329   painter.getClassNameForWell = function(well)
3449 28 Jul 15 olle 330   {
3449 28 Jul 15 olle 331     var cls = '';
3449 28 Jul 15 olle 332     var mrna = well.extract;
3449 28 Jul 15 olle 333     if (mrna)
3449 28 Jul 15 olle 334     {
3449 28 Jul 15 olle 335       var rna = mrna.rna;
3449 28 Jul 15 olle 336       if (rna.qc) cls += ' qc';
3449 28 Jul 15 olle 337       if (rna.external) cls += ' external';
3449 28 Jul 15 olle 338       if (rna.stratagene) cls += ' stratagene';
3449 28 Jul 15 olle 339     }
3449 28 Jul 15 olle 340     return cls;
3449 28 Jul 15 olle 341   }
3449 28 Jul 15 olle 342   
3449 28 Jul 15 olle 343   painter.getWellText = function(well)
3449 28 Jul 15 olle 344   {
3449 28 Jul 15 olle 345     var text = '';
3449 28 Jul 15 olle 346     var mrna = well.extract;
3449 28 Jul 15 olle 347     if (mrna)
3449 28 Jul 15 olle 348     {
3449 28 Jul 15 olle 349       var rna = mrna.rna;
3449 28 Jul 15 olle 350       var name = rna.external && mrna.externalId ? mrna.externalId : rna.name;
3449 28 Jul 15 olle 351       text += '<div class="rna">'+name+'</div>';
3449 28 Jul 15 olle 352       text += '<div class="box">'+Strings.encodeTags(Protocol.getPlateCoordinate(rna, true))+'</div>';
3449 28 Jul 15 olle 353       text += '<div class="remain">'+Numbers.formatNumber(rna.remainingQuantity, 2, 'µg')+'</div>';
3449 28 Jul 15 olle 354       text += '<div class="ndconc">'+Numbers.formatNumber(rna.NDConc, 2, 'ng/µl') + '</div>';
3449 28 Jul 15 olle 355
3449 28 Jul 15 olle 356       if (rna.volume >= 0 && rna.water >= 0)
3449 28 Jul 15 olle 357       {
3449 28 Jul 15 olle 358         text += '<div><span class="volume">'+Numbers.formatNumber(rna.volume, 1)+'µl</span>';
3449 28 Jul 15 olle 359         text += '<span class="water">'+(rna.preNormalized ? '—' : Numbers.formatNumber(rna.water, 1)+'µl')+'</span></div>';
3449 28 Jul 15 olle 360       }
3449 28 Jul 15 olle 361       text += '<div class="remarks">'+ rna.remarks.join('; ') + '</div>';
3449 28 Jul 15 olle 362     }
3449 28 Jul 15 olle 363     return text;
3449 28 Jul 15 olle 364   }
3449 28 Jul 15 olle 365
3449 28 Jul 15 olle 366   return painter;
3449 28 Jul 15 olle 367 }();
3449 28 Jul 15 olle 368