tripal_phylogeny.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* phylotree d3js graphs */
  2. (function ($) {
  3. var height = 0; // will be dynamically sized
  4. $(document).ready( function () {
  5. var nodeSize = function(d) {
  6. var size;
  7. if (d.cvterm_name == "phylo_root") {
  8. size = treeOptions['root_node_size'];
  9. }
  10. if (d.cvterm_name == "phylo_interior") {
  11. size = treeOptions['interior_node_size'];
  12. }
  13. if (d.cvterm_name == "phylo_leaf") {
  14. size = treeOptions['leaf_node_size'];
  15. }
  16. return size;
  17. }
  18. // function to generate color based on the organism genus and species
  19. // on graph node d
  20. var organismColor = function(d) {
  21. var color = null;
  22. if (d.fo_genus) {
  23. color = organismColors[d.fo_genus + ' ' + d.fo_species];
  24. }
  25. if (color) { return color; }
  26. else { return 'grey'; }
  27. };
  28. // callback for mouseover event on graph node d
  29. var nodeMouseOver = function(d) {
  30. var el =$(this);
  31. el.attr('cursor', 'pointer');
  32. var circle = el.find('circle');
  33. // highlight in yellow no matter if leaf or interior node
  34. circle.attr('fill', 'yellow');
  35. if(! d.children) {
  36. // only leaf nodes have descriptive text
  37. var txt = el.find('text');
  38. txt.attr('font-weight', 'bold');
  39. }
  40. };
  41. // callback for mouseout event on graph node d
  42. var nodeMouseOut = function(d) {
  43. var el = $(this);
  44. el.attr('cursor', 'default');
  45. var circle = el.find('circle');
  46. if(! d.children) {
  47. // restore the color based on organism id for leaf nodes
  48. circle.attr('fill', organismColor(d));
  49. var txt = el.find('text');
  50. txt.attr('font-weight', 'normal');
  51. }
  52. else {
  53. // restore interior nodes to white
  54. circle.attr('fill', 'white');
  55. }
  56. };
  57. // callback for mousedown/click event on graph node d
  58. var nodeMouseDown = function(d) {
  59. var el = $(this);
  60. var dialog = $('#phylonode_popup_dialog');
  61. var title = (! d.children ) ? d.name : 'interior node ' + d.phylonode_id;
  62. if(d.children) {
  63. // interior node
  64. if(d.phylonode_id) {
  65. var link = $('#phylonode_context_link');
  66. // eventually, this link will be replaced with something internal to the site; note that the trailing slash is somewhat important to avoid apparent hanging due to the way django handles url pattern matching
  67. link.attr('href', 'http://comparative-legumes.org/chado/context_viewer/' + d.phylonode_id + '/');
  68. link.text('View Genomic Contexts for genes in this subtree');
  69. link.show();
  70. }
  71. else {
  72. // this shouldn't happen but ok
  73. $('#phylonode_context_link').hide();
  74. }
  75. // show dialog content relevant for interior node
  76. // go_link not ready for prime time
  77. // $('#phylonode_go_link').show();
  78. $('#phylonode_go_link').hide();
  79. $('#phylonode_context_link').show();
  80. // hide dialog content which is only applicable to leaf nodes
  81. $('#phylonode_organism_link').hide();
  82. $('#phylonode_feature_link').hide();
  83. }
  84. else {
  85. // leaf node
  86. // show dialog content relevant for leaf node
  87. $('#phylonode_organism_link').show();
  88. $('#phylonode_feature_link').show();
  89. // hide dialog content which is only applicable to interior nodes
  90. $('#phylonode_go_link').hide();
  91. $('#phylonode_context_link').hide();
  92. if(d.feature_node_id) {
  93. var link = $('#phylonode_feature_link');
  94. link.attr('href', '?q=node/' + d.feature_node_id);
  95. link.text('view feature: ' + d.feature_name);
  96. link.show();
  97. }
  98. else {
  99. // this shouldn't happen but ok
  100. $('#phylonode_feature_link').hide();
  101. }
  102. if (d.feature_name) {
  103. var link = $('#phylonode_gene_linkout');
  104. //FIXME: hack depending on typical naming conventions. we can certainly do better
  105. var transcript = d.feature_name.replace(/^.....\./, "");
  106. var gene = transcript.replace(/\.\d+$/, "");
  107. if (d.fo_genus == 'Glycine' && d.fo_species == 'max') {
  108. link.attr('href', 'http://www.soybase.org/sbt/search/search_results.php?category=FeatureName&search_term=' + gene);
  109. //link.attr('href', 'http://www.soybase.org/gb2/gbrowse/gmax2.0/?q=' + gene + ';dbid=gene_models_wm82_a2_v1');
  110. link.text('view at SoyBase: ' + gene);
  111. link.show();
  112. }
  113. else if (d.fo_genus == 'Phaseolus' && d.fo_species == 'vulgaris') {
  114. link.attr('href', 'http://phytozome.jgi.doe.gov/pz/portal.html#!gene?organism=Pvulgaris&searchText=locusName:' + gene);
  115. link.text('view at Phytozome: ' + gene);
  116. link.show();
  117. }
  118. else if (d.fo_genus == 'Medicago' && d.fo_species == 'truncatula') {
  119. link.attr('href', 'http://medicago.jcvi.org/medicago/jbrowse/?data=data%2Fjson%2Fmedicago&loc='+transcript+'&tracks=DNA%2Cgene_models&highlight=');
  120. link.text('view at JCVI: ' + transcript);
  121. link.show();
  122. }
  123. else if (d.fo_genus == 'Arachis' && d.fo_species == 'duranensis') {
  124. //link.attr('href', 'http://peanutbase.org/gb2/gbrowse/Aradu1.0/?q=' + gene);
  125. //link.attr('href', 'http://peanutbase-stage.agron.iastate.edu/gb2/gbrowse/Aradu1.0/?q=' + gene);
  126. link.attr('href', 'http://peanutbase.org/gb2/gbrowse/Aradu1.0/?q=' + gene + ';dbid=gene_models');
  127. //link.attr('href', 'http://peanutbase-stage.agron.iastate.edu/gb2/gbrowse/Aradu1.0/?q=' + gene + ';dbid=gene_models');
  128. link.text('view at PeanutBase: ' + gene);
  129. link.show();
  130. }
  131. else if (d.fo_genus == 'Arachis' && d.fo_species == 'ipaensis') {
  132. //link.attr('href', 'http://peanutbase.org/gb2/gbrowse/Araip1.0/?q=' + gene);
  133. //link.attr('href', 'http://peanutbase-stage.agron.iastate.edu/gb2/gbrowse/Araip1.0/?q=' + gene);
  134. link.attr('href', 'http://peanutbase.org/gb2/gbrowse/Araip1.0/?q=' + gene + ';dbid=gene_models');
  135. //link.attr('href', 'http://peanutbase-stage.agron.iastate.edu/gb2/gbrowse/Araip1.0/?q=' + gene + ';dbid=gene_models');
  136. link.text('view at PeanutBase: ' + gene);
  137. link.show();
  138. }
  139. else if (d.fo_genus == 'Arabidopsis' && d.fo_species == 'thaliana') {
  140. link.attr('href', ' http://www.araport.org/locus/' + gene);
  141. link.text('view at Arabidopsis Information Portal: ' + gene);
  142. link.show();
  143. }
  144. else {
  145. link.hide();
  146. }
  147. }
  148. if(d.fo_organism_id) {
  149. var link = $('#phylonode_organism_link');
  150. link.attr('href', d.fo_organism_node_id ?
  151. '?q=node/' + d.fo_organism_node_id : '#');
  152. link.text('view organism: ' + d.fo_genus + ' '+
  153. d.fo_species + ( d.fo_common_name ? ' (' + d.fo_common_name + ')' : '' ) );
  154. link.show();
  155. }
  156. else {
  157. // there should always be an organism id, but degrade gracefully
  158. $('#phylonode_organism_link').hide();
  159. }
  160. }
  161. dialog.dialog( {
  162. title : title,
  163. closeOnEscape : false,
  164. modal : false,
  165. position : { my : 'center center', at : 'center center', of : el },
  166. show : { effect: 'blind', direction: 'down', duration: 200 }
  167. });
  168. };
  169. $.getJSON(phylotreeDataURL, function(treeData) {
  170. displayData(treeData);
  171. $('.phylogram-ajax-loader').remove();
  172. });
  173. function displayData(treeData) {
  174. height = graphHeight(treeData);
  175. d3.phylogram.build('#phylogram', treeData, {
  176. 'width' : treeOptions['phylogram_width'],
  177. 'height' : height,
  178. 'fill' : organismColor,
  179. 'size' : nodeSize,
  180. 'nodeMouseOver' : nodeMouseOver,
  181. 'nodeMouseOut' : nodeMouseOut,
  182. 'nodeMouseDown' : nodeMouseDown
  183. });
  184. d3.phylogram.buildRadial('#phylotree-radial-graph', treeData, {
  185. 'width' : treeOptions['dendrogram_width'], // square graph
  186. 'fill' : organismColor,
  187. 'size' : nodeSize,
  188. 'nodeMouseOver' : nodeMouseOver,
  189. 'nodeMouseOut' : nodeMouseOut,
  190. 'nodeMouseDown' : nodeMouseDown
  191. });
  192. organismBubblePlot('#phylotree-organisms', treeData, {
  193. 'height' : treeOptions['bubble_width'], // square graph
  194. 'width' : treeOptions['bubble_width'],
  195. 'fill' : organismColor,
  196. 'nodeMouseOver' : nodeMouseOver,
  197. 'nodeMouseOut' : nodeMouseOut,
  198. 'nodeMouseDown' : nodeMouseDown
  199. });
  200. }
  201. /* graphHeight() generate graph height based on leaf nodes */
  202. function graphHeight(data) {
  203. function countLeafNodes(node) {
  204. if(! node.children) {
  205. return 1;
  206. }
  207. var ct = 0;
  208. node.children.forEach( function(child) {
  209. ct+= countLeafNodes(child);
  210. });
  211. return ct;
  212. }
  213. var leafNodeCt = countLeafNodes(data);
  214. return 22 * leafNodeCt;
  215. }
  216. });
  217. })(jQuery);