Playing with the HTML5 File API: translating a Fasta file.
In the current post, I'm using the new HTML5 File Api. This new API can read the content of a file on the client side without needing a remote server. Let me repeat this:
YOU DO NOT NEED A SERVER
YOU DO NOT NEED TO COPY AND PASTE THE CONTENT OF THE FILE IN A TEXTAREA
.YOU DO NOT NEED TO COPY AND PASTE THE CONTENT OF THE FILE IN A TEXTAREA
As an example, the following code reads a whole DNA fasta file stored on your computer and translate each DNA sequence to a protein. When the user selects a new file, a FileReader object is created and a callback function translating the DNA is invoked when the fasta file has been loaded.
Test (your browser must support HTML5)
Source code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
</head> | |
<body> | |
<form> | |
<label for="ZmlsZXMKfiles">Select a FASTA file</label>:<input type="file" id="ZmlsZXMKfiles" multiple="true"/> | |
</form> | |
<script type="application/ecmascript"> | |
var GENETIC_CODE="FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"; | |
function base2index(c) | |
{ | |
switch(c) | |
{ | |
case 'T':case 't': return 0; | |
case 'C':case 'c': return 1; | |
case 'A':case 'a': return 2; | |
case 'G':case 'g': return 3; | |
default: return -1; | |
} | |
} | |
function translate(dna) | |
{ | |
var prot=""; | |
for(var i=0;i+2 < dna.length;i+=3) | |
{ | |
var base1= base2index(dna[i+0]); | |
var base2= base2index(dna[i+1]); | |
var base3= base2index(dna[i+2]); | |
if(base1==-1 || base2==-1 || base3==-1) | |
{ | |
prot+='?'; | |
} | |
else | |
{ | |
prot+=GENETIC_CODE[base1*16+base2*4+base3]; | |
} | |
} | |
return prot; | |
} | |
function readingFasta(evt) | |
{ | |
if (!evt.lengthComputable) return; | |
var loaded = (evt.loaded / evt.total); | |
if (loaded > 1) return; | |
var pre=document.getElementById('ZmlsZXMKtext'); | |
while(pre.hasChildNodes()) pre.removeChild( pre.firstChild ); | |
pre.appendChild(document.createTextNode("Reading "+Math.round(loaded*100)+"%")); | |
} | |
function endReadFasta(e) | |
{ | |
var pre=document.getElementById('ZmlsZXMKtext'); | |
while(pre.hasChildNodes()) pre.removeChild( pre.firstChild ); | |
var lines=e.target.result.split("\n"); | |
var dna=""; | |
var i=0; | |
var line; | |
for(;;) | |
{ | |
if(i==lines.length || (line=lines[i].replace(/^\s+|\s+$/g,""))[0]=='>') | |
{ | |
if(dna.length > 0) | |
{ | |
var prot=translate(dna); | |
var j=0; | |
while(j < prot.length) | |
{ | |
pre.appendChild(document.createTextNode(prot.substring(j,j+50))); | |
pre.appendChild(document.createElement("br")); | |
j+=50; | |
} | |
} | |
if(i===lines.length) break; | |
pre.appendChild(document.createTextNode(line)); | |
pre.appendChild(document.createElement("br")); | |
dna=""; | |
} | |
else | |
{ | |
dna+=line; | |
} | |
++i; | |
} | |
} | |
function handleFileSelect(evt) | |
{ | |
var files = evt.target.files; // FileList object | |
if(files.length!=1) return; | |
var reader = new FileReader(); | |
reader.onprogress=readingFasta; | |
reader.onloadend=endReadFasta; | |
var pre=document.getElementById('ZmlsZXMKtext'); | |
while(pre.hasChildNodes()) pre.removeChild( pre.firstChild ); | |
pre.appendChild(document.createTextNode("Reading "+files[0].name+"...")); | |
reader.readAsText(files[0]); | |
} | |
document.getElementById('ZmlsZXMKfiles').addEventListener('change', handleFileSelect, false); | |
</script> | |
<pre id="ZmlsZXMKtext"></pre> | |
</body> | |
</html> |
That's it,
Pierre
1 comment:
Awesome! I did a lot of web programming in a former life, but I haven't kept up with the latest developments. It will be interesting to see how new web technologies impact bioinformatics!
Post a Comment