Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

GetCommitInfo.m

Blame
  • DrawTree.js 7.42 KiB
    /*****************************************************************************/
    //
    //    Copyright 2015 Andrew Cohen
    //
    //     This file is part of CloneView - the tool for displaying stem cell lineaging in a webpage.
    //
    //     CloneView is free software: you can redistribute it and/or modify
    //     it under the terms of the GNU General Public License as published by
    //     the Free Software Foundation, either version 3 of the License, or
    //     (at your option) any later version.
    //
    //     CloneView is distributed in the hope that it will be useful,
    //     but WITHOUT ANY WARRANTY; without even the implied warranty of
    //     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    //     GNU General Public License for more details.
    //
    //     You should have received a copy of the GNU General Public License
    //     along with CloneView in file "gnu gpl v3.txt".  If not, see
    //     <http://www.gnu.org/licenses/>.
    //
    /*****************************************************************************/
    
    // recursively set the x location for every node
    function InitTree(tree,idx) {
    	
    	if (tree[idx].LeftChild>0) {
    		tree=InitTree(tree,tree[idx].LeftChild);
    		tree=InitTree(tree,tree[idx].RightChild);
    		tree[idx].xLocation= (tree[tree[idx].LeftChild].xLocation + tree[tree[idx].RightChild].xLocation)/2;
    		tree[idx].depth=Math.max(tree[tree[idx].LeftChild].depth,tree[tree[idx].RightChild].depth)+1;
    		// deeper node goes to the left!
    		if (tree[tree[idx].LeftChild].depth<tree[tree[idx].RightChild].depth) {
    			var tmp = tree[idx].LeftChild;
    			tree[idx].LeftChild=tree[idx].RightChild;
    			tree[idx].RightChild=tmp;
    		}
    	}
    	else {
    		tree[idx].xLocation = tree.glastX;
    		tree[idx].depth=0;
    		tree.glastX++;
    	}
    	if (tree[idx].EndTime>tree.gmaxTime)
    		tree.gmaxTime=tree[idx].EndTime;
    
    
    		
    	return tree;
    } //InitTree
    
    
    function nodeFromID(tree,id) {
    	var i;
    	
    	if (0==id)
    		return 0;
    		
    	for (i=0;i<tree.length;i++)
    		if (tree[i].TrackID==id)
    			return i;
    	
    	console.log('nodeFromID not found!\n');
    	return 0; 	
    }
    function remapTreeNodes(tree) {
    	for (var i=0;i<tree.length;i++) {
    		tree[i].LeftChild = nodeFromID(tree,tree[i].LeftChild);
    		tree[i].RightChild = nodeFromID(tree,tree[i].RightChild);
    		tree[i].Parent = nodeFromID(tree,tree[i].Parent);
    	}
    	return tree;
    }
    
    function DrawTree(canvas,tree) {
    	var context = canvas.getContext("2d");
    	var sx,sy; // scale factor
    	
    	tree.glastX=0.0; // x coordinate of farthest right child
    	tree.gmaxTime = 0.0; // y coordinate of oldest child
    
    	tree=remapTreeNodes(tree);
    	// run init tree twice! first time sets most prolific to the left
    	tree=InitTree(tree,0); 
    	tree.glastX=0.0; // x coordinate of farthest right child
    	tree.gmaxTime = 0.0; // y coordinate of oldest child
    	// 2nd time sets x locations
    	tree=InitTree(tree,0);
    	
    	// now draw!
    	sx = 0.95*canvas.width/tree.glastX;
    	sy = 0.95*canvas.height/tree.gmaxTime;
    	for (var i=0;i<tree.length;i++) {
    		tree[i].xLocation+=1;
    		tree[i].StartTime+=1;
    		tree[i].EndTime+=1;
    	}
    		
    	context.strokeStyle='black';
    	context.beginPath();
    	context.fillStyle='white';
    	for (var i=0;i<tree.length;i++) {
    		
    		context.moveTo(tree[i].xLocation*sx,tree[i].StartTime*sy);
    		context.lineTo(tree[i].xLocation*sx,tree[i].EndTime*sy);
    		// children? if so, draw horizontal
    		if (tree[i].LeftChild) {
    		
    			context.moveTo(tree[tree[i].LeftChild].xLocation*sx,tree[tree[i].LeftChild].StartTime*sy);
    			context.lineTo(tree[tree[i].RightChild].xLocation*sx,tree[tree[i].RightChild].StartTime*sy );
    		}		
    		
    		if (undefined != tree[i].Phenotype) {
    		
    			// 1==dead, 2,3==ambiguous >=4 actual pheno marker
    			if (1==tree[i].Phenotype.ID) {
    			
    				// make an 'x'
    				var lineStep=2;
    				
    				context.moveTo(tree[i].xLocation*sx-lineStep,tree[i].EndTime*sy-lineStep);
    				context.lineTo(tree[i].xLocation*sx+lineStep,tree[i].EndTime*sy+lineStep);
    				context.moveTo(tree[i].xLocation*sx+lineStep,tree[i].EndTime*sy-lineStep);
    				context.lineTo(tree[i].xLocation*sx-lineStep,tree[i].EndTime*sy+lineStep);
    				
    			}
    			else if (tree[i].Phenotype.ID<4) {
    				// have to flush drawing q so i can fill on top for circles
    				context.stroke();
    				context.beginPath();
    				context.arc(tree[i].xLocation*sx,tree[i].EndTime*sy, 2, 0, 2 * Math.PI,false);
    				context.fill(); // draw this arc
    				context.stroke();
    				context.beginPath(); // set up next draw
    			}
    		}
    	}
    	context.stroke();
    	context.fill();	
    	return tree;
    	
    
    } // DrawTree
    
    
    function DrawTreeFluorescent(canvas,tree) {
    	var context = canvas.getContext("2d");
    	var sx,sy; // scale factor
    	
    	tree.glastX=0.0; // x coordinate of farthest right child
    	tree.gmaxTime = 0.0; // y coordinate of oldest child
    
    	tree=remapTreeNodes(tree);
    	// run init tree twice! first time sets most prolific to the left
    	tree=InitTree(tree,0); 
    	tree.glastX=0.0; // x coordinate of farthest right child
    	tree.gmaxTime = 0.0; // y coordinate of oldest child
    	// 2nd time sets x locations
    	tree=InitTree(tree,0);
    	tree.glastX+=1;
    	// now draw!
    	sx = 0.95*canvas.width/tree.glastX;
    	sy = 0.95*canvas.height/tree.gmaxTime;
    	for (var i=0;i<tree.length;i++) {
    		tree[i].xLocation+=1;
    		tree[i].StartTime+=1;
    		tree[i].EndTime+=1;
    	}
    		
    	context.strokeStyle='LightGray';
    	context.lineWidth=1;
    	context.beginPath();
    	context.fillStyle='white';
    	for (var i=0;i<tree.length;i++) {
    		
    		context.moveTo(tree[i].xLocation*sx,tree[i].StartTime*sy);
    		context.lineTo(tree[i].xLocation*sx,tree[i].EndTime*sy);
    		context.stroke();
    		// draw fluorescent curves
    		context.strokeStyle='green';
    		//context.lineWidth=2;
    		context.beginPath();
    		for (var f=0;f<tree[i].GreenStats.length-1;f++) {
    			fval1 = tree[i].GreenStats[f];
    			fval1 = Math.min(fval1,0.95);
    			fval2 = tree[i].GreenStats[f+1];
    			fval2 = Math.min(fval2,0.95);
    			context.moveTo((tree[i].xLocation+ fval1)*sx,(tree[i].StartTime+f)*sy);
    			context.lineTo((tree[i].xLocation+ fval2)*sx,(tree[i].StartTime+f+1)*sy);
    		}
    		context.stroke();
    		context.beginPath();
    		context.strokeStyle='red';
    		for (var f=0;f<tree[i].RedStats.length-1;f++) {
    			fval1 = tree[i].RedStats[f];
    			fval1 = Math.min(fval1,0.95);
    			fval2 = tree[i].RedStats[f+1];
    			fval2 = Math.min(fval2,0.95);
    			context.moveTo((tree[i].xLocation+ fval1)*sx,(tree[i].StartTime+f)*sy);
    			context.lineTo((tree[i].xLocation+ fval2)*sx,(tree[i].StartTime+f+1)*sy);
    		}
    		context.stroke();
    		context.lineWidth=1;
    		context.strokeStyle='LightGray';
    		context.beginPath();
    
    		// children? if so, draw horizontal
    		if (tree[i].LeftChild) {
    		
    			context.moveTo(tree[tree[i].LeftChild].xLocation*sx,tree[tree[i].LeftChild].StartTime*sy);
    			context.lineTo(tree[tree[i].RightChild].xLocation*sx,tree[tree[i].RightChild].StartTime*sy );
    		}		
    		
    		if (undefined != tree[i].Phenotype) {
    		
    			// 1==dead, 2,3==ambiguous >=4 actual pheno marker
    			if (1==tree[i].Phenotype.ID) {
    			
    				// make an 'x'
    				var lineStep=2;
    				
    				context.moveTo(tree[i].xLocation*sx-lineStep,tree[i].EndTime*sy-lineStep);
    				context.lineTo(tree[i].xLocation*sx+lineStep,tree[i].EndTime*sy+lineStep);
    				context.moveTo(tree[i].xLocation*sx+lineStep,tree[i].EndTime*sy-lineStep);
    				context.lineTo(tree[i].xLocation*sx-lineStep,tree[i].EndTime*sy+lineStep);
    				
    			}
    			else if (tree[i].Phenotype.ID<4) {
    				// have to flush drawing q so i can fill on top for circles
    				context.stroke();
    				context.beginPath();
    				context.arc(tree[i].xLocation*sx,tree[i].EndTime*sy, 2, 0, 2 * Math.PI,false);
    				context.fill(); // draw this arc
    				context.stroke();
    				context.beginPath(); // set up next draw
    			}
    		}
    	}
    	context.stroke();
    	context.fill();	
    	return tree;
    	
    
    } // DrawTreeFluorescent