PageRenderTime 62ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/opencga/ui-widgets/result-widget.js

https://github.com/aaleman/jsorolla
JavaScript | 1025 lines | 762 code | 132 blank | 131 comment | 121 complexity | 3c1eb90acb2d0f12a86dc857cb664990 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0
  1. /*
  2. * Copyright (c) 2012 Francisco Salavert (ICM-CIPF)
  3. * Copyright (c) 2012 Ruben Sanchez (ICM-CIPF)
  4. * Copyright (c) 2012 Ignacio Medina (ICM-CIPF)
  5. *
  6. * This file is part of JS Common Libs.
  7. *
  8. * JS Common Libs is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * JS Common Libs is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with JS Common Libs. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. function ResultWidget(args){
  22. var _this = this;
  23. this.id = "ResultWidget"+ Math.round(Math.random()*10000);
  24. this.targetId = null;
  25. if (args != null){
  26. if (args.targetId!= null){
  27. this.targetId = args.targetId;
  28. }
  29. if (args.application!= null){
  30. this.application = args.application;
  31. }
  32. if (args.app!= null){
  33. this.app = args.app;
  34. }
  35. }
  36. this.adapter = new OpencgaManager();
  37. this.adapter.onJobResult.addEventListener(function (sender, data){
  38. // console.log(data);
  39. _this.data = JSON.parse(data);
  40. Ext.getBody().unmask();
  41. _this.panel.setLoading(false);
  42. _this.render();
  43. });
  44. this.panelId=null;
  45. this.networkViewerId = null;
  46. this.genomeMapsId = null;
  47. this.resultTables = new Object();
  48. this.resultHistograms = new Object();
  49. this.resultGCharts = new Object();
  50. this.variantFiles = new Object();
  51. // this.onRendered = new Event();
  52. this.onViewRendered = new Event();
  53. this.onViewRendered.addEventListener(function (sender, targetId){
  54. _this.drawTables();
  55. _this.drawHistograms();
  56. _this.drawGCharts();
  57. _this.drawApplicationItems();
  58. });
  59. };
  60. ResultWidget.prototype.draw = function (sid, record){
  61. // console.log(record.data);
  62. this.record = record;
  63. this.jobId = this.record.data.id;
  64. this.id = this.jobId+this.id;
  65. this.panelId = "ResultWidget_"+this.jobId;
  66. this.networkViewerId = this.panelId+"_CellBrowserId";
  67. this.genomeMapsId = this.panelId+"_GenomeMapsId";
  68. this.panel = Ext.getCmp(this.panelId);
  69. if(this.panel==null){
  70. this.panel = Ext.create('Ext.panel.Panel', {
  71. id :this.panelId,
  72. border: 0,
  73. title: this.record.data.name,
  74. closable:true,
  75. autoScroll:true
  76. // html: this.tpl.applyTemplate(outputItems)
  77. });
  78. Ext.getCmp(this.targetId).add(this.panel);
  79. Ext.getCmp(this.targetId).setActiveTab(this.panel);
  80. this.panel.setLoading("Loading job info...");
  81. Ext.getBody().mask();
  82. //this.adapter.jobResult(this.jobId, "json", sid);
  83. //accountId, sessionId, bucketname, jobId, format
  84. this.adapter.jobResult($.cookie("bioinfo_account"), sid, this.jobId, "json");
  85. //this.adapter.jobResult(this.jobId, "json", sid);
  86. }else{
  87. // this.panel.setLoading(false);
  88. Ext.getCmp(this.targetId).setActiveTab(this.panel);
  89. }
  90. };
  91. ResultWidget.prototype.render = function (){
  92. var _this=this;
  93. console.log(this.application);
  94. debugger
  95. if(this.data.outputItems.length != 0){
  96. var outputItems = this.data.inputItems.concat(this.data.outputItems);
  97. //obtener todos los grupos quitando los repetidos
  98. var obj = {};
  99. for(var i = 0; i < outputItems.length; i++){
  100. var group = outputItems[i].group;
  101. if(group != "" ){ //no meter items con grupo distinto a ""
  102. if(group.indexOf(".")!=-1){//comprobar si alguno tiene un subgrupo
  103. var parent_group = group.split(".")[0];
  104. var sub_group = group.split(".")[1];
  105. if(obj[parent_group]==null) {
  106. obj[parent_group]={};
  107. }
  108. if(obj[parent_group][sub_group]==null){
  109. obj[parent_group][sub_group]=[];
  110. }
  111. //ESTE if quita los resultados para los pvalue = 0.005, 0.01, 0.1, deja solo los 0.05
  112. if(this.checkPValue(outputItems[i].title)){
  113. obj[parent_group][sub_group].push(outputItems[i]);
  114. }
  115. }else {
  116. if(obj[group]==null){
  117. obj[group]={};
  118. obj[group]["items"]=[];
  119. }
  120. //QUITAR la cadena de texto ${pvalue} si existe y la sustituye por 0.05
  121. this.renamePValue(outputItems[i]);
  122. obj[group]["items"].push(outputItems[i]);
  123. }
  124. }
  125. }
  126. if(this.application == 'renato' || this.application == 'variant'){
  127. obj["Interactive Results"]={items:[]};
  128. }
  129. console.log(obj);
  130. var topLink = Ext.create('Ext.container.Container', {html:'<a name="'+this.jobId+'top"></a>'});
  131. var info = Ext.create('Ext.container.Container', {
  132. margin: "15 0 5 15",
  133. html:'<p >The job named <span class="info">'+this.record.data.name+' </span>'+
  134. 'was launched on <span class="err">'+this.record.data.date+' </span>'+
  135. //'and has been visited <span class="dis">'+this.record.data.visites+' times</span></p>'+
  136. //'You can download the job results by pressing the <b>download</b> button.'
  137. '<br>'
  138. });
  139. var result = [];
  140. //Solo grupos juntos al principio
  141. var i=1;
  142. for (key in obj){
  143. var groupId = this.jobId+key.replace(/\s/g, '_')+"group";
  144. var groupBox = Ext.create('Ext.container.Container', {
  145. padding:"0 0 2 15",
  146. width:(key.length*14),
  147. //html:'<p class="s110 emph">'+i+'. <a href="#'+key+'">'+key+'</a></p>'
  148. groupId:groupId,
  149. html:'<span class="s110 emph">'+i+'. '+key+'</span>',
  150. listeners:{
  151. afterrender:function(){
  152. this.getEl().addClsOnOver("ssel u");
  153. this.getEl().addCls("dedo");
  154. var groupId = this.groupId;
  155. //inlineblock
  156. this.getEl().on("click",function(){
  157. var pos = $('#'+groupId).position().top;
  158. $(_this.panel.getEl().dom).children().scrollTop(pos);
  159. });
  160. }
  161. }
  162. });
  163. result.push(groupBox);
  164. i++;
  165. }
  166. //Grupos con resultados a continuacion
  167. var i=1;
  168. for (key in obj){
  169. //Grupo
  170. var infoId = (this.jobId+key+"info").replace(/ /gi, "");
  171. var groupId = this.jobId+key.replace(/\s/g, '_')+"group";
  172. var groupBox = Ext.create('Ext.container.Container', {
  173. infoId:infoId,
  174. groupName:key,
  175. padding:"60 15 5 15",
  176. //html:'<p class="panel-border-bottom"><span class="s140 emph">'+i+'. <a name="'+key+'" href="#'+this.jobId+'top">'+key+'</a>'+
  177. //' </span><span class="info" id="'+infoId+'"></span></p>',
  178. html:'<p id="'+groupId+'" class="panel-border-bottom"><span class="s140 emph">'+i+'. '+key+' &nbsp;&nbsp; &uarr;'+
  179. ' </span><span class="info" id="'+infoId+'"></span></p>',
  180. listeners:{
  181. afterrender:function(){
  182. this.getEl().addClsOnOver("ssel");
  183. this.getEl().addCls("dedo");
  184. this.getEl().on("click",function(){
  185. $(_this.panel.getEl().dom).children().scrollTop(0);
  186. });
  187. var text = _this.getInfo(this.groupName);
  188. if(text!=""){
  189. $("#"+this.infoId).html("+info");
  190. var infoTip = Ext.create('Ext.tip.Tip',{
  191. html:text,
  192. listeners:{
  193. show:function(){
  194. var este = this;
  195. this.getEl().on("mouseleave",function(){
  196. este.hide();
  197. });
  198. }
  199. }
  200. });
  201. $("#"+this.infoId).mouseover(function(ev){
  202. $(this).css({cursor:"pointer"});
  203. infoTip.showAt(ev.clientX,ev.clientY);
  204. });
  205. $("#"+this.infoId).click(function(){
  206. infoTip.hide();
  207. });
  208. }
  209. }
  210. }
  211. });
  212. result.push(groupBox);
  213. //Resultados - se le pasa el array de items
  214. result.push(this.getResults(obj[key].items));
  215. //Comprobamos si tiene subgrupos 1 - nivel solo
  216. var c = 1;
  217. for(clave in obj[key]){
  218. if (clave != "items"){
  219. //Grupo
  220. var groupBox = Ext.create('Ext.container.Container', {
  221. padding:"15 15 5 30",
  222. cls:"inlineblock",
  223. html:'<p class="panel-border-bottom s120 emph">'+i+'.'+c+' '+clave+'</p>'
  224. });
  225. //si la clave es Your annotation tratarlo de otra manera... para mas adelante
  226. // console.log(clave)
  227. result.push(groupBox);
  228. // debugger
  229. //Resultados - se le pasa el array de items
  230. result.push(this.getResults(obj[key][clave]));
  231. c++;
  232. }
  233. }//subgrupos
  234. i++;
  235. }
  236. var downloadButton = Ext.create('Ext.button.Button', {
  237. text: 'Download',
  238. margin: "0 0 25 15",
  239. handler: function (){
  240. _this.adapter.download(_this.jobId, $.cookie('bioinfo_sid'));
  241. }
  242. });
  243. var deleteJobButton = Ext.create('Ext.button.Button', {
  244. text: 'Delete',
  245. margin: "0 0 25 30",
  246. handler: function (){
  247. Ext.Msg.confirm("Delete job", "Are you sure you want to delete this job?", function (btnClicked){
  248. // console.log(btnClicked);
  249. if(btnClicked == "yes") {
  250. _this.adapter.onDeleteJob.addEventListener(function (sender, data){
  251. var msg = "";
  252. if(data.response.indexOf("OK") != -1) {
  253. Ext.getCmp(_this.targetId).getActiveTab().close();
  254. msg = "The job has been succesfully deleted.";
  255. }
  256. else {
  257. msg = "ERROR: could not delete job.";
  258. }
  259. Ext.Msg.alert("Delete job", msg);
  260. });
  261. // console.log("Job id: "+_this.jobId+" Cookie: "+$.cookie('bioinfo_sid'));
  262. _this.adapter.deleteJob(_this.jobId, $.cookie('bioinfo_sid'));
  263. }
  264. });
  265. }
  266. });
  267. this.panel.add(topLink);
  268. this.panel.add(info);
  269. //this.panel.add(downloadButton);
  270. //this.panel.add(deleteJobButton);
  271. this.panel.add(result);
  272. _this.onViewRendered.notify();
  273. }//else
  274. };
  275. ResultWidget.prototype.getResults = function (items){
  276. //Resultados
  277. var boxes = [];
  278. for (var j = 0; j < items.length; j++){
  279. var item = items[j];
  280. //Obtener el container con el resultado
  281. var itemBox = this.showInfo(item);
  282. boxes.push(itemBox);
  283. //A帽adir el container para resultados adicionales segun el type y el tag si procede
  284. var container = this.showTypeInfo(item);
  285. if(container){
  286. boxes.push(container);
  287. }
  288. var container = this.showTagInfo(item);
  289. if(container!=null){
  290. boxes.push(container);
  291. }
  292. }
  293. var itemsBox = Ext.create('Ext.container.Container', {
  294. layout: {type: 'table',columns: 1, tableAttrs: {style: {width: '100%'}}},
  295. items:boxes
  296. });
  297. return itemsBox;
  298. };
  299. ResultWidget.prototype.showInfo = function (item){
  300. var _this=this;
  301. var itemTpl = new Ext.XTemplate(
  302. // '<tpl for="tags">',
  303. // '<span class="ok">{.} </span>:: ',
  304. // '</tpl>',
  305. // '<span class="err">{type} </span>',
  306. '<span class="key">{title} </span>',
  307. '<span class="{[ this.setCSS(values) ]}">{value}</span><br>'
  308. ,
  309. {
  310. // XTemplate configuration:
  311. disableFormats: true,
  312. // member functions:
  313. setCSS: function(item){
  314. switch(item.type){
  315. case 'FILE':
  316. return 'file';
  317. break;
  318. case 'MESSAGE':
  319. //Setting species code
  320. if (item.name == "species"){
  321. _this.species=item.value;
  322. }
  323. return 'message';
  324. break;
  325. }
  326. }
  327. });
  328. //fin template
  329. return itemBox = Ext.create('Ext.container.Container', {
  330. data:item,
  331. datos:item,
  332. margin:"0 10 0 20",
  333. padding:5,
  334. tpl:itemTpl,
  335. cls:"inlineblock",
  336. listeners:{
  337. afterrender:function(){
  338. var datos = this.datos;
  339. if(this.datos.type == 'FILE'){
  340. this.getEl().addClsOnOver("encima");
  341. this.getEl().addCls("whiteborder");
  342. if(_this.application=="variant" && datos.title.toLowerCase().indexOf("filter")!=-1){
  343. _this.filteredVcfFile=datos.value;
  344. }
  345. this.getEl().on("click",function(){
  346. console.log(datos);
  347. var value = datos.value.trim();
  348. _this.adapter.poll($.cookie('bioinfo_account'),$.cookie('bioinfo_sid'), _this.jobId, value, true);
  349. });
  350. }
  351. }
  352. }
  353. });
  354. };
  355. ResultWidget.prototype.showTypeInfo = function (item){
  356. var _this=this;
  357. var box = Ext.create('Ext.container.Container',{
  358. margin:"0 10 0 10",
  359. padding:5
  360. });
  361. switch(item.type){
  362. case 'IMAGE':
  363. /*width="400" height="200" */
  364. var filename = item.value.trim();
  365. box.html = '<div><img src="'+_this.adapter.pollurl($.cookie('bioinfo_account'),$.cookie('bioinfo_sid'), _this.jobId,filename)+'"></div>';
  366. return box;
  367. break;
  368. default: return null;
  369. }
  370. };
  371. ResultWidget.prototype.showTagInfo = function (item){
  372. var _this=this;
  373. var box = Ext.create('Ext.container.Container',{
  374. margin:"0 10 0 10",
  375. flex:1,
  376. padding:5,
  377. html:""
  378. });
  379. for(var i = 0; i < item.tags.length ; i++){
  380. switch(item.tags[i]){
  381. case 'TABLE':
  382. var value = item.value.trim();
  383. var id = _this.jobId+value+item.tags;
  384. _this.resultTables[id] = new ResultTable (_this.jobId, value, item.tags,{targetId:'resultTable_'+id});
  385. // _this.resultTables[id].onRendered.
  386. box.html += '<div id="resultTable_'+id+'" style="padding:5px;"></div>';
  387. return box;
  388. break;
  389. case 'HISTOGRAM':
  390. var id = "histogram_"+_this.jobId+item.value+item.tags;
  391. _this.resultHistograms[id] = item.value;
  392. box.html = '<div id="'+id+'" style="padding:5px;"></div>';
  393. return box;
  394. break;
  395. case 'GCHART':
  396. var id = 'gchart_'+item.name;
  397. _this.resultGCharts[id] = item.value;
  398. box.html = '<div id="'+id+'"></div>';
  399. return box;
  400. break;
  401. case 'CONSEQUENCE_TYPE_VARIANTS':
  402. this.variantFiles[item.name] = item.title;
  403. break;
  404. }
  405. }
  406. return null;
  407. };
  408. ResultWidget.prototype.drawTables = function (){
  409. // console.log(this.resultTables);
  410. for(id in this.resultTables){
  411. this.resultTables[id].draw();
  412. }
  413. };
  414. ResultWidget.prototype.drawHistograms = function (){
  415. //se dibujan todas las tablas
  416. // console.log(this.resultHistograms);
  417. for(id in this.resultHistograms){
  418. var adapterPoll = new OpencgaManager();
  419. adapterPoll.onPoll.addEventListener(function(sender,data){
  420. if(data!=""){
  421. var lines = data.split("\n");
  422. var fields=[];
  423. var names=[];
  424. var values=[];
  425. var normValues=[];
  426. var total = 0;
  427. for ( var i = 0; i < lines.length; i++) {
  428. fields.push(lines[i].split("\t"));
  429. if(fields[i][0]!=""){
  430. names.push(fields[i][0]);
  431. }
  432. if(fields[i][1]!=null){
  433. total = total + parseFloat(fields[i][1]);
  434. values.push(fields[i][1]);
  435. }
  436. }
  437. for ( var i = 0; i < values.length; i++) {
  438. normValues.push(Math.round(parseFloat(values[i])/total*100));
  439. }
  440. names = names.toString().replace(/,/gi,"|");
  441. var img = '<img src="https://chart.googleapis.com/chart?cht=p&chs=600x300&chd=t:'+normValues+'&chl='+names+'&chtt=Consequence+types&chts=000000,14.5">';
  442. document.getElementById(id).innerHTML=img;
  443. }
  444. });
  445. //adapterPoll.poll(this.jobId,this.resultHistograms[id],false,$.cookie('bioinfo_sid'));
  446. adapterPoll.poll($.cookie("bioinfo_account"), $.cookie('bioinfo_sid'), this.jobId, this.resultHistograms[id], false);
  447. }
  448. };
  449. ResultWidget.prototype.drawGCharts = function (){
  450. for(id in this.resultGCharts){
  451. drawChart(id, this.resultGCharts[id]);
  452. }
  453. };
  454. ResultWidget.prototype.drawApplicationItems = function (){
  455. var _this=this;
  456. var viewerContainer = Ext.create('Ext.container.Container', {
  457. id:this.application+this.id+"Container",
  458. border: true,
  459. margin:"50 50 0 50",
  460. html:'<div class="greyborder" id="'+this.id+'Container"></div><div style="height:40px"></div>'
  461. });
  462. switch (this.application){
  463. case "variant":
  464. viewerContainer.on("afterrender",function(){
  465. _this.createGenomeViewer(_this.id+"Container");
  466. });
  467. break;
  468. case "renato":
  469. //***********bar
  470. var pbar = Ext.create('Ext.ProgressBar', {id:this.id+'pbar',margin:"5 0 0 50",width: 500});
  471. // Wait for 5 seconds, then update the status el (progress bar will auto-reset)
  472. pbar.wait({
  473. interval: 500, //bar will move fast!
  474. duration: 50000,
  475. increment: 15,
  476. text: 'Getting database information and drawing the network, please wait...',
  477. scope: this,
  478. fn: function(){
  479. pbar.updateText('Done!');
  480. }
  481. });
  482. //Add de bar to the main panel
  483. this.panel.add(pbar);
  484. /*************************/
  485. viewerContainer.on("afterrender",function(){
  486. _this.createCellBrowser(_this.id+"Container");
  487. });
  488. break;
  489. default: return null;
  490. }
  491. this.panel.add(viewerContainer);
  492. };
  493. ResultWidget.prototype.createGenomeViewer = function (targetId){
  494. var _this = this;
  495. var width = Ext.getCmp(this.application+targetId).getWidth();
  496. var height = Ext.getCmp(this.application+targetId).getHeight();
  497. //var genomeViewer = new GenomeViewer(targetId, AVAILABLE_SPECIES[0],{
  498. //version:"",
  499. //zoom:75,
  500. //width:width-2,
  501. //height:height-2
  502. //});
  503. //genomeViewer.setMenuBar(this.getGenomeViewerResultBar(genomeViewer));
  504. genomeViewer = new GenomeViewer(targetId, DEFAULT_SPECIES,{
  505. sidePanelCollapsed:true,
  506. width:width-2,
  507. height:700-2
  508. });
  509. genomeViewer.afterRender.addEventListener(function(sender,event){
  510. _this.app.setTracks(genomeViewer);
  511. genomeViewer.addSidePanelItems();
  512. var variantFilterWidget = new VariantFilterWidget(_this.jobId,{
  513. width:width-2,
  514. targetId:_this.application+targetId,
  515. viewer:genomeViewer,
  516. fileNames:_this.variantFiles
  517. });
  518. });
  519. genomeViewer.draw();
  520. var adapter = new OpencgaManager();
  521. adapter.onPoll.addEventListener(function(sender, data){
  522. if(data.indexOf("ERROR")!=1){
  523. console.error(data);
  524. }
  525. var vcfDataAdapter = new VCFDataAdapter(new StringDataSource(data),{async:false,species:genomeViewer.species});
  526. var vcfTrack = new TrackData("VCF file",{
  527. adapter: vcfDataAdapter
  528. });
  529. genomeViewer.addTrack(vcfTrack,{
  530. id:"VCF file",
  531. featuresRender:"MultiFeatureRender",
  532. histogramZoom:50,
  533. height:150,
  534. visibleRange:{start:0,end:100},
  535. featureTypes:FEATURE_TYPES
  536. });
  537. //var feature = vcfDataAdapter.featureCache.getFirstFeature();
  538. //genomeViewer.region.load(feature);
  539. //genomeViewer.setRegion({sender:""});
  540. // genomeViewer.setZoom(75);
  541. });
  542. // console.log(this.filteredVcfFile)
  543. if(this.filteredVcfFile != null){
  544. adapter.poll($.cookie("bioinfo_account"), $.cookie('bioinfo_sid'), _this.jobId, this.filteredVcfFile, false);
  545. //adapter.poll(_this.jobId, this.filteredVcfFile, false, $.cookie('bioinfo_sid'));
  546. }else{
  547. console.log("No filtered VCF file.");
  548. }
  549. };
  550. var mostSignificativesFeatures = new Array();
  551. ResultWidget.prototype.createCellBrowser = function (targetId){
  552. var _this = this;
  553. record = this.record;
  554. //hide network-viewer, all nodes mut be rendered before show
  555. Ext.getCmp(this.application+targetId).disable();
  556. var width = Ext.getCmp(this.application+targetId).getWidth();
  557. var height = Ext.getCmp(this.application+targetId).getHeight();
  558. //Pako creating cellBrowser
  559. this.networkViewer = new NetworkViewer(targetId,this.getSpeciesItem(this.species),{
  560. width:width-2,
  561. height:height-2
  562. });
  563. // this.networkViewer.setSpeciesMenu(AVAILABLE_SPECIES);
  564. this.networkViewer.draw();
  565. //setting a empty data and format, nodes will be draw later using the interface
  566. var dataset = new GraphDataset();
  567. var layout = new LayoutDataset();
  568. var formatter = new NetworkDataSetFormatter({
  569. "defaultFormat": {"type":"LineEdgeNetworkFormatter","opacity":1, "fill":"#000000", "radius":"5", "strokeWidth":"1", "stroke":"#000000", "size":"2", "title":{"fontSize":10, "fill":"#000000"}},
  570. "selected": {"opacity":0.9, "fill":"#FF0000", "radius":"5", "stroke":"#000000", "size":"2"},
  571. "over": {"opacity":1, "fill":"#DF0101", "radius":"5", "stroke":"#000000", "size":"2", "strokeWidth":"1"}
  572. },
  573. {
  574. "defaultFormat": { "opacity":0.8,"stroke":"#000000", "strokeWidth":"1", "strokeOpacity":0.5, "title":{"fontSize":6, "fontColor":"#000000"}},
  575. "selected": {"stroke":"#DF0101", "fill":"#FF0000"},
  576. "over": { "stroke":"#DF0101","strokeOpacity":1, "strokeWidth":"4"}
  577. },
  578. // { "labeled":false, "height":height,"width":this.width,"right":this.width,"backgroundColor":"#FFFFFF", "balanceNodes":false, "nodesMaxSize":4, "nodesMinSize":2});
  579. { "labeled":false, "backgroundColor":"#FFFFFF", "balanceNodes":false, "nodesMaxSize":4, "nodesMinSize":2});
  580. formatter.dataBind(dataset);
  581. layout.dataBind(dataset);
  582. formatter.setHeight(height - 140);
  583. formatter.setWidth(width-2-13);
  584. this.networkViewer.drawNetwork(dataset, formatter, layout);
  585. //Getting significant_your_annotation_0.05.txt
  586. var adapter2 = new WumRestAdapter();
  587. adapter2.onPoll.addEventListener(function(sender, data){
  588. var lines = data.split("\n");
  589. var significativesFeatures = new Array();
  590. for ( var i = 1; i < lines.length; i++) {
  591. var column = 13;
  592. if(record.data.toolName == "fatiscan"){
  593. if(lines[i].split("\t").length==7){
  594. //we are in the case of logistic model
  595. column = 6;
  596. }
  597. }
  598. var significativeValue = lines[i].split("\t")[column];
  599. if(significativeValue < 1000000){
  600. significativesFeatures.push(lines[i].split("\t")[0]);
  601. }
  602. }
  603. console.log('significativesFeatures.length: '+significativesFeatures.length);
  604. /** TFBS **/
  605. var adapter3 = new WumRestAdapter();
  606. adapter3.onPoll.addEventListener(function(sender, data){
  607. var genes = data.split("\n");
  608. /** Para elminar la linea en blanco: Gorrion Rules! **/
  609. genes.pop();
  610. console.log('genes.length: '+genes.length);
  611. _this.loadNetworkOnCellBrowser(genes, significativesFeatures, targetId);
  612. });
  613. var file = "clean_list1.txt";
  614. if(record.data.toolName == "fatiscan")
  615. file = "id_list.txt";
  616. adapter3.poll(_this.jobId, file, false, $.cookie('bioinfo_sid'));
  617. });
  618. adapter2.poll(this.jobId, "significant_your_annotation_0.05.txt", false, $.cookie('bioinfo_sid'));
  619. //END getting significant_your_annotation_0.05.txt
  620. // By Nacho
  621. // getting 50 most significant genes
  622. console.log('getting ranked_list...');
  623. var cleanListWumAdapater = new WumRestAdapter();
  624. cleanListWumAdapater.onPoll.addEventListener(function(sender, data) {
  625. var lines = data.split("\n");
  626. var numGenes = lines.length;
  627. var cont = 0;
  628. console.log('getting top clean_list...');
  629. for(var i = 0; cont < 50 && i < numGenes; i++) {
  630. if(lines[i].indexOf('#') < 0) {
  631. // console.log('getting top ranked_list... '+lines[i]);
  632. // console.log('getting top ranked_list... '+lines[i].split("\t")[0]);
  633. mostSignificativesFeatures[lines[i].split("\t")[0]] = true;
  634. cont++;
  635. }
  636. }
  637. cont = 0;
  638. console.log('getting bottom clean_list...');
  639. for(var i = numGenes-1; cont < 50 && i > 0; i--) {
  640. if(lines[i].indexOf('#') < 0) {
  641. mostSignificativesFeatures[lines[i].split("\t")[0]] = true;
  642. cont++;
  643. }
  644. }
  645. });
  646. cleanListWumAdapater.poll(this.jobId, "clean_list1.txt", false, $.cookie('bioinfo_sid'));
  647. // END getting 50 most significant genes
  648. // getting ranked_list
  649. console.log('getting ranked_list...');
  650. var rankedListWumAdapater = new WumRestAdapter();
  651. rankedListWumAdapater.onPoll.addEventListener(function(sender, data) {
  652. var lines = data.split("\n");
  653. var numGenes = lines.length;
  654. var cont = 0;
  655. console.log('getting top ranked_list...');
  656. for(var i = 0; cont < 50 && i < numGenes; i++) {
  657. if(lines[i].indexOf('#') < 0) {
  658. mostSignificativesFeatures[lines[i].split("\t")[0]] = true;
  659. cont++;
  660. }
  661. }
  662. cont = 0;
  663. console.log('getting bottom ranked_list...');
  664. for(var i = numGenes-1; cont < 50 && i > 0; i--) {
  665. if(lines[i].indexOf('#') < 0) {
  666. mostSignificativesFeatures[lines[i].split("\t")[0]] = true;
  667. cont++;
  668. }
  669. }
  670. });
  671. rankedListWumAdapater.poll(this.jobId, "ranked_list.txt", false, $.cookie('bioinfo_sid'));
  672. //END getting ranked_list
  673. };
  674. ResultWidget.prototype.loadNetworkOnCellBrowser = function (genes, tfbs, targetId){
  675. var _this = this;
  676. //tfbs and mirna nodes are rendered
  677. //2 indicates that mirna and tfbs are done
  678. var nodesRendered = 0;
  679. //Getting tfbs by gene
  680. var cellBaseManager = new CellBaseManager(this.networkViewer.species);
  681. cellBaseManager.success.addEventListener(function (evt, response){
  682. var data_tfbs = response.result;
  683. var tfbsByGene = new Object();
  684. for (var i = 0; i < data_tfbs.length; i++){
  685. for ( var j = 0; j < data_tfbs[i].length; j++) {
  686. if(tfbs.toString().indexOf(data_tfbs[i][j].tfName) != -1){
  687. if (tfbsByGene[data_tfbs[i][j].tfName] == null){
  688. tfbsByGene[data_tfbs[i][j].tfName] = new Object();
  689. }
  690. if(tfbsByGene[data_tfbs[i][j].tfName][genes[i]] == null){
  691. tfbsByGene[data_tfbs[i][j].tfName][genes[i]] = true;
  692. }
  693. }
  694. }
  695. }
  696. console.log(tfbsByGene);
  697. console.log(data_tfbs.length);
  698. console.log('contando TFBSs...');
  699. // check the number of elemts to be rendered
  700. // if there are more than 500 then select the most significant
  701. var numElements = 0;
  702. for ( var tf in tfbsByGene) {
  703. if(numElements > 500) {
  704. break;
  705. }
  706. for ( var gene in tfbsByGene[tf]) {
  707. numElements++;
  708. }
  709. }
  710. console.log('menos de 500: '+numElements);
  711. for ( var tf in tfbsByGene) {
  712. _this.networkViewer.networkWidget.getDataset().addNode(tf, {type:"tf"});
  713. var verticeId = _this.networkViewer.networkWidget.getDataset().getVerticesCount() - 1;
  714. _this.networkViewer.networkWidget.getFormatter().getVertexById(verticeId).getDefault().setFill("#DF0101");
  715. // console.log(tfbsByGene[tf]);
  716. // console.log(_this.networkViewer.networkWidget.getFormatter().getVertexById(verticeId));
  717. for ( var gene in tfbsByGene[tf]) {
  718. if(numElements < 500 || mostSignificativesFeatures[gene] == true) {
  719. // console.log(gene);
  720. /** Conecto los tfbs con sus genes **/
  721. if(_this.networkViewer.networkWidget.getDataset().getVertexByName(gene).length == 0){
  722. _this.networkViewer.networkWidget.getDataset().addNode(gene, {type:"gene"});
  723. }
  724. // console.log(_this.networkViewer.networkWidget.getDataset());
  725. // getVertexByName returns an array
  726. var vertexGeneId = _this.networkViewer.networkWidget.getDataset().getVertexByName(gene)[0].id;
  727. var vertexTfbsId = _this.networkViewer.networkWidget.getDataset().getVertexByName(tf)[0].id;
  728. _this.networkViewer.networkWidget.getDataset().addEdge("tfbs_" + vertexGeneId + "_" + vertexTfbsId, vertexTfbsId, vertexGeneId);
  729. _this.networkViewer.networkWidget.getFormatter().getVertexById(vertexGeneId).getDefault().setFill("#0000FF");
  730. }
  731. }
  732. }
  733. _this.networkViewer.networkWidget.getLayout().getLayout("neato");
  734. _this.networkViewer.networkWidget.getLayout().layoutDone.addEventListener(function (evt){
  735. nodesRendered++;
  736. if(nodesRendered==2){
  737. Ext.getCmp(_this.id+'pbar').destroy();
  738. Ext.getCmp(_this.application+targetId).enable();
  739. }
  740. });
  741. });
  742. if(genes.length>0){
  743. cellBaseManager.get("feature", "gene", genes, "tfbs");
  744. }
  745. //getting mirna target by gene
  746. var cellBaseManagerMirna = new CellBaseManager(this.networkViewer.species);
  747. cellBaseManagerMirna.success.addEventListener(function (evt, response){
  748. var data_tfbs = response.result;
  749. var tfbsByGene = new Object();
  750. for (var i = 0; i < data_tfbs.length; i++){
  751. for ( var j = 0; j < data_tfbs[i].length; j++) {
  752. if(tfbs.toString().indexOf(data_tfbs[i][j].mirbaseId) != -1){
  753. if (tfbsByGene[data_tfbs[i][j].mirbaseId] == null){
  754. tfbsByGene[data_tfbs[i][j].mirbaseId] = new Object();
  755. }
  756. if(tfbsByGene[data_tfbs[i][j].mirbaseId][genes[i]] == null){
  757. tfbsByGene[data_tfbs[i][j].mirbaseId][genes[i]] = true;
  758. }
  759. }
  760. }
  761. }
  762. console.log(tfbsByGene);
  763. console.log(data_tfbs.length);
  764. console.log('contando miRNAs...');
  765. // check the number of elemts to be rendered
  766. // if there are more than 500 then select the most significant
  767. var numElements = 0;
  768. for ( var tf in tfbsByGene) {
  769. if(numElements > 500) {
  770. break;
  771. }
  772. for ( var gene in tfbsByGene[tf]) {
  773. numElements++;
  774. }
  775. }
  776. console.log('menos de 500: '+numElements);
  777. for ( var mirna in tfbsByGene) {
  778. _this.networkViewer.networkWidget.getDataset().addNode(mirna, {type:"mirna"});
  779. var verticeId = _this.networkViewer.networkWidget.getDataset().getVerticesCount() - 1;
  780. _this.networkViewer.networkWidget.getFormatter().getVertexById(verticeId).getDefault().setFill("red");
  781. for ( var gene in tfbsByGene[mirna]) {
  782. if(numElements < 500 || mostSignificativesFeatures[gene] == true) {
  783. // console.log(gene);
  784. if(_this.networkViewer.networkWidget.getDataset().getVertexByName(gene).length == 0){
  785. // if(_this.networkViewer.networkWidget.getDataset().getVertexByName(gene) == null) {
  786. _this.networkViewer.networkWidget.getDataset().addNode(gene, {type:"gene"});
  787. }
  788. var vertexGeneId = _this.networkViewer.networkWidget.getDataset().getVertexByName(gene)[0].id;
  789. var vertexTfbsId = _this.networkViewer.networkWidget.getDataset().getVertexByName(mirna)[0].id;
  790. _this.networkViewer.networkWidget.getDataset().addEdge("tfbs_" + vertexGeneId + "_" + vertexTfbsId, vertexTfbsId, vertexGeneId);
  791. _this.networkViewer.networkWidget.getFormatter().getVertexById(vertexGeneId).getDefault().setFill("blue");
  792. var edgeId = _this.networkViewer.networkWidget.getDataset().getEdgesCount() - 1;
  793. _this.networkViewer.networkWidget.getFormatter().changeEdgeType(edgeId, "CutDirectedLineEdgeNetworkFormatter");
  794. }
  795. }
  796. }
  797. _this.networkViewer.networkWidget.getLayout().getLayout("neato");
  798. _this.networkViewer.networkWidget.getLayout().layoutDone.addEventListener(function (evt){
  799. nodesRendered++;
  800. if(nodesRendered==2){
  801. Ext.getCmp(_this.id+'pbar').destroy();
  802. Ext.getCmp(_this.application+targetId).enable();
  803. }
  804. });
  805. });
  806. if(genes.length>0){
  807. cellBaseManagerMirna.get("feature", "gene", genes, "mirna_target");
  808. }else{
  809. Ext.getCmp(_this.id+'pbar').destroy();
  810. Ext.getCmp(_this.application+targetId).enable();
  811. }
  812. };
  813. ResultWidget.prototype.getGenomeViewerResultBar = function(genomeViewer) {
  814. var _this=this;
  815. switch (this.application){
  816. case "variant":
  817. var toolbarMenu = Ext.create('Ext.container.Container', {
  818. cls:'bio-toolbar',
  819. defaults:{margin:'1 0 0 2'},
  820. layout:'vbox',
  821. height:27,
  822. items : [
  823. {xtype:'button',text:'<span class="info">Variant filter tool...</span>',handler:function(){
  824. var variantFilterWidget = new VariantFilterWidget(_this.jobId,{viewer:genomeViewer,fileNames:_this.variantFiles});
  825. // variantFilterWidget.draw();
  826. // variantFilterWidget.parseData(data);
  827. // var wumRestAdapter = new WumRestAdapter();
  828. // wumRestAdapter.onPoll.addEventListener(function(sender, data){
  829. // });
  830. // wumRestAdapter.poll(_this.jobId, "variant.txt", false, $.cookie('bioinfo_sid'));
  831. }
  832. }
  833. ]
  834. });
  835. return toolbarMenu;
  836. break;
  837. default: return null;
  838. }
  839. };
  840. ResultWidget.prototype.getSpeciesItem = function(species) {
  841. //selecciona el objeto AVAILABLE_SPECIES segun el species code
  842. for ( var i = 0; i < AVAILABLE_SPECIES.length; i++) {
  843. if(AVAILABLE_SPECIES[i].species==species){
  844. return AVAILABLE_SPECIES[i];
  845. }
  846. }
  847. };
  848. //Quita los resultados para your annotation
  849. ResultWidget.prototype.checkPValue = function(str) {
  850. //return false si es 0.005, 0.01 贸 0.1
  851. if(str.indexOf("pvalue<0.005")!= -1 ||
  852. str.indexOf("pvalue<0.01")!= -1 ||
  853. str.indexOf("pvalue<0.1")!= -1
  854. ){
  855. return false;
  856. }
  857. return true;
  858. };
  859. //Quita los resultados para your annotation
  860. ResultWidget.prototype.renamePValue = function(item) {
  861. //reemplaza la cadena ${pvalue} por 0.05
  862. if(item.value.indexOf("${pvalue}") != -1){
  863. item.value = item.value.replace(/\$\{pvalue\}/gi, "0.05");
  864. }
  865. };
  866. //XXX no se usa por ahora...Para mas adelante
  867. ResultWidget.prototype.setPValue = function(value) {
  868. console.log(this.id);
  869. var divId="#pvalue"+this.id;
  870. $(divId).html(value);
  871. };
  872. //Quita los resultados para your annotation
  873. ResultWidget.prototype.getInfo = function(groupName) {
  874. switch (this.application){
  875. case "renato":
  876. switch (groupName){
  877. case "Input data": return "This section is a reminder of the parameters or settings you have submitted to run the analysis.";
  878. case "Summary": return "<p>This section shows the number of genes annotated to each database in each list.</p><br><p>Gene list: contains three elements, the number of genes in your gene list annotated in the database over the total number of genes remaining in your gene list after the duplicates management, a percentage of genes in your gene list annotated in the database and the ratio of regulators per gene.<br> Genome: the same structure explained above but applied to the whole genome (TFBS or miRNA) or Your Annotations after the duplicates management.</p>";
  879. case "Significant Results": return "<p>We consider a significant enrichment after correcting the results by a multiple testing correction method. Enrichment p-values are corrected applying the False discovery rate (FDR) method (Benjamini et al., 1995; Storey andTibshirani, 2003). The threshold of signification applied to the correction has been set to 0.05.</p><br><p>The table provided summarizes the information about the enrichment test for each of the significant regulatory elements that have an Adjusted p-value < 0.05. The table is originally sorted by adjusted p-value and can be sorted up and down by clicking in any of the other column headings. When the number of significant results in a table is higher than five, results are split into different pages. You can move forward or backward in the page list using the arrow buttons.</p>";
  880. case "All results": return "This section contains a downloadable individual text file containing all results for all significant and not significant regulators. This file follows the same structure described above.";
  881. case "Annotation files": return "<p>When significant results are obtained, we can suppose that there is one or several regulatory elements behaving different when comparing groups. The list of genes included in the analysis have pointed to a significantly over-represented set of common regulators to these genes. The interpretation of the results will be different in the case of TFs (transcription factors) and miRNAs given that (generally) the first are positive regulators and the latter are negative regulators.</p><br><p>TFs generally bind to the promoter region of their target genes to assist and promote the transcription. miRNAs, on the other hand, bind to transcript products preventing them from being translated. Significant TF and miRNAs can be pointed to be responsible for the differential expression of the genes observed in the list. We must take special care in the interpretation of over-expressed or under-expressed genes in a functional analysis. In the case of TFs, if we are working with the list of over-expressed genes, the significant results makes reference to active TFs in one condition with respect to the other; while significant results of under-expressed genes makes reference to inactive TFs. In miRNAs, significant results of over-expressed genes will point to inactive miRNAs, while significant results of under-expressed genes will point to active miRNAs when comparing conditions.</p>";
  882. default: return "";
  883. }
  884. break;
  885. case "variant":
  886. switch (groupName){
  887. case "Variants by Consequence Type": return "Click this link: <a class='ok' target='_blank' href='http://docs.bioinfo.cipf.es/projects/variant/wiki/Output_columns'>Output columns</a>";
  888. default: return "";
  889. }
  890. break;
  891. default: return "";
  892. }
  893. };