From: <lol...@us...> - 2011-08-01 20:18:16
|
Revision: 935 http://treebase.svn.sourceforge.net/treebase/?rev=935&view=rev Author: loloyohe Date: 2011-08-01 20:18:08 +0000 (Mon, 01 Aug 2011) Log Message: ----------- Updated the jsphylosvg-min.js with the most recent version hoping to see what happens with the tree visualizer. Modified Paths: -------------- trunk/treebase-web/src/main/webapp/scripts/jsphylosvg-min.js Modified: trunk/treebase-web/src/main/webapp/scripts/jsphylosvg-min.js =================================================================== --- trunk/treebase-web/src/main/webapp/scripts/jsphylosvg-min.js 2011-07-27 21:58:58 UTC (rev 934) +++ trunk/treebase-web/src/main/webapp/scripts/jsphylosvg-min.js 2011-08-01 20:18:08 UTC (rev 935) @@ -1,2505 +1,75 @@ -Smits = {};Smits.Common = { - nodeIdIncrement : 0, - activeNode: 0, - - /* Rounds float to a defined number of decimal places */ - roundFloat : function(num, digits){ - var i = 0, - dec = 1; - while(i < digits){ - dec *= 10; - i++; - } - return Math.round(num*dec)/dec; - }, - - /* Copies properties from one object to another */ - apply : function(obj, extObj){ - if (obj && typeof extObj == 'object') { - for (var key in extObj) { - obj[key] = extObj[key]; - } - } - return obj; - }, - - addEventHandler : function(el, eventType, fn, paramsObj){ - try{ - el.addEventListener( - eventType, - (function(fn, args){ - return( - function(e,o) { - var params = paramsObj; - params.e = e; - fn(params); - } - ); - }(fn, paramsObj)), - false - ); - } catch (err){} - }, - - isInteger : function(s) { - return !isNaN(parseInt(s)); - }, - - isXMLSerializerAvailable : function(){ - if (typeof(XMLSerializer) == "function"){ - return true; - } else { - return false; - } - }, - - createSvgEl : function (el, attr) { - el = document.createElementNS("http://www.w3.org/2000/svg", el); - if (attr) { - for (var key in attr) { - if (attr.hasOwnProperty(key)) { - el.setAttribute(key, String(attr[key])); - } - } - } - return el; - }, - - createGradientEl : function(name, obj, coords){ - if(obj.type != "radialGradient") return false; - - var radialEl = Smits.Common.createSvgEl("radialGradient", { - id: name, - gradientUnits:"userSpaceOnUse", - cx: coords[0], - cy: coords[1], - r: coords[2], - fx: coords[0], - fy: coords[1] - }); - - if(obj.stop){ - var stop = obj.stop; - for(var i = 0; i < stop.length; i++){ - var stopObj = stop[i]; - if(stopObj['@attributes']){ - radialEl.appendChild(Smits.Common.createSvgEl("stop", stopObj['@attributes'])); - } else { - if(stopObj['_attributes']) delete stopObj['_attributes']; - if(stopObj['_children']) delete stopObj['_children']; - if(stopObj['__proto__']) delete stopObj['__proto__']; - radialEl.appendChild(Smits.Common.createSvgEl("stop", stopObj)); - } - } - } - - return radialEl; - }, - - setCssStyle : function(selector, rule) { - var stylesheet = document.styleSheets[0]; - if( stylesheet.addRule ){ - stylesheet.addRule(selector, rule); - } else if( stylesheet.insertRule ){ - stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length); - } - } - -};Smits.PhyloCanvas = function(){ - var phylogram, - divId, - newickObject, - svg, - dataObject; - - return function(inputFormat, sDivId, canvasWidth, canvasHeight, type){ - /* Privileged Methods */ - this.getNewickObject = function(){ - return newickObject; - }; - this.clear = function(){ - - }; - this.scale = function(multiplier){ - svg.svg.scale(multiplier); - }; - this.getSvg = function(){ - return svg; - }; - this.getPhylogram = function(){ - return phylogram; - }; - this.getSvgSource = function(){ - if(Raphael.svg && Smits.Common.isXMLSerializerAvailable()){ - var serialize = new XMLSerializer(); - return serialize.serializeToString(svg.svg.canvas); - } else { - return false; - } - } - - /* CONSTRUCTOR */ - - // Process dataset -- assume newick format, else needs to provide format - if(typeof inputFormat === "object"){ - if(inputFormat.xml){ // default xml format is phyloXML - if(!inputFormat.fileSource){ - var xj = XMLObjectifier.textToXML(inputFormat.xml); // assume we need to clean it up - } else { - var xj = inputFormat.xml; - } - xj = XMLObjectifier.xmlToJSON(xj); - dataObject = new Smits.PhyloCanvas.PhyloxmlParse(xj); - } else if(inputFormat.phyloxml){ - if(!inputFormat.fileSource){ - var xj = XMLObjectifier.textToXML(inputFormat.phyloxml); // assume we need to clean it up - } else { - var xj = inputFormat.phyloxml; - } - xj = XMLObjectifier.xmlToJSON(xj); - dataObject = new Smits.PhyloCanvas.PhyloxmlParse(xj); - } else if(inputFormat.nexml){ - if(!inputFormat.fileSource){ - var xj = XMLObjectifier.textToXML(inputFormat.nexml); // assume we need to clean it up - } else { - var xj = inputFormat.nexml; - } - xj = XMLObjectifier.xmlToJSON(xj); - dataObject = new Smits.PhyloCanvas.NexmlParse(xj, inputFormat) - } else if(inputFormat.json){ - dataObject = new Smits.PhyloCanvas.PhyloxmlParse(inputFormat.json); - } else if(inputFormat.newick){ - dataObject = new Smits.PhyloCanvas.NewickParse(inputFormat.newick); - } else if(inputFormat.nexmlJson){ - dataObject = new Smits.PhyloCanvas.NexmlJsonParse(inputFormat); - } else { - alert('Please set the format of input data'); - } - } else { - dataObject = new Smits.PhyloCanvas.NewickParse(inputFormat); - } - - divId = sDivId; - svg = new Smits.PhyloCanvas.Render.SVG( divId, canvasWidth, canvasHeight ); - - /* FACTORY */ - if(type == "circular"){ - phylogram = new Smits.PhyloCanvas.Render.CircularPhylogram( - svg, - dataObject - ); - } else { - phylogram = new Smits.PhyloCanvas.Render.Phylogram( - svg, - dataObject - ); - } - - } - -}(); - -Smits.PhyloCanvas.prototype = { -};Smits.PhyloCanvas.Node = function(){ - - /** - * Node Class - * Allows objects to be traversed across children - * - */ - return function(o, parentInstance){ - // initiate object - this.id = Smits.Common.nodeIdIncrement += 1; - this.level = 0; - this.len = 0; - this.newickLen = 0; - this.name = ''; - this.type = ''; - this.chart = {}; - this.img = []; - - if(o) Smits.Common.apply(this, o); - - this.children = new Array(); - - if(parentInstance){ - parentInstance.children.push(this); - } - } -}(); - - -Smits.PhyloCanvas.Node.prototype = { - - getCountAllChildren : function(){ - var nodeCount = 0; - - for (var key in this.children) { - if(Smits.Common.isInteger(key)){ - var child = this.children[key]; - if(child.children && child.children.length > 0){ - nodeCount += child.getCountAllChildren(); - } else { - nodeCount ++; - } - } - } - return nodeCount; - }, - - getCountImmediateChildren : function(){ - var nodeCount = 0; - - for (var key in this.children) { - var child = this.children[key]; - nodeCount += child.length; - } - return nodeCount; - }, - - getMidbranchPosition : function(){ - var y = [0,0]; // bounds - - for (var i = 0; i < this.children.length; i++) { - var child = this.children[i]; - - if(child.children && child.children.length > 0){ - if(i == 0){ - y[0] = child.getMidbranchPosition(); - y[1] += child.getCountAllChildren(); - } else if (i == this.children.length - 1){ - y[1] += child.getMidbranchPosition(); - } else { - y[1] += child.getCountAllChildren(); - } - } else { - if(i == 0){ - y[0] = 1; - y[1] += 1; - } else if (i == this.children.length - 1){ - y[1] += 1; - } else { - y[1] += 1; - } - } - } - - return y[1] >= y[0] ? ((y[1] - y[0]) / 2) + y[0] : y[0]; - } - -};Smits.PhyloCanvas.NewickParse = function(){ - - var text, - ch, - pos, - mLevel = 0, - mNewickLen = 0, - root, - validate, - - object = function (parentNode) { - var node = new Smits.PhyloCanvas.Node(); - - while (ch !== ')' && ch !== ',') { - if (ch === ':'){ - next(); - node.len = Smits.Common.roundFloat(string(), 4); // round to 4 decimal places - if(node.len == 0){ - node.len = 0.0001; - } - } else if (ch === "'" || ch === '"'){ - node.type = "label"; - node.name = quotedString(ch); - } else { - node.type = "label"; - node.name = string(); - } - } - node.level = parentNode.level + 1; - return node; - }, - - objectIterate = function(parentNode){ - var node = new Smits.PhyloCanvas.Node(); - if(parentNode){ - node.level = parentNode.level + 1; - } - - while( ch !== ')' ){ - next() - if( ch === '(' ) { - node.children.push(objectIterate(node)); - } else { - node.children.push(object(node)); - } - } - - next(); - if(ch !== ':' && ch !== ')' && ch !== ',' && ch !== ';'){ - node.type = "label"; - node.name = string(); - } - if(ch === ':'){ - next(); - node.len = Smits.Common.roundFloat(string(), 4); - if(node.len == 0){ - node.len = 0.0001; - } - node.type = "stem"; - - } - return node; - }, - - string = function(){ - var string = ''; - - while (ch !== ':' && ch !== ')' && ch !== ',' && ch !== ';'){ - string += ch; - next(); - } - return string; - }, - - quotedString = function(quoteType){ - var string = ''; - - while (ch !== quoteType){ - string += ch; - next(); - } - return string; - }, - - next = function() { - ch = text.charAt(pos); - pos += 1; - return ch; - }, - - recursiveProcessRoot = function(node, parentNode){ - - if(node.children && node.children.length){ - for( var i = 0; i < node.children.length; i++ ){ - var child = node.children[i]; - if(child.len === 0) { // Dendogram - child.len = 1; - } - child.newickLen = Smits.Common.roundFloat(child.len + node.newickLen, 4); - if(child.level > mLevel) mLevel = child.level; - if(child.newickLen > mNewickLen) mNewickLen = child.newickLen; - if(child.children.length > 0){ - recursiveProcessRoot(child, node); - } - } - } - return node; - }; - - return function(parseText){ - /* Privileged Methods */ - this.getRoot = function(){ - return root; - }; - this.getLevels = function(){ - return mLevel; - }; - this.getNewickLen = function(){ - return mNewickLen; - }; - this.getValidate = function(){ - return validate; - }; - - - /* CONSTRUCTOR */ - text = parseText; - pos = 0; - - next(); - root = objectIterate(); - root = recursiveProcessRoot(root); - } - -}(); - -Smits.PhyloCanvas.NewickParse.prototype = { - -};Smits.PhyloCanvas.PhyloxmlParse = function(){ - - var mLevel = 0, - mNewickLen = 0, - root, - validate, - - recursiveParse = function(clade, parentNode){ - var node = new Smits.PhyloCanvas.Node(); - if(parentNode){ - node.level = parentNode.level + 1; - } - - if(clade.clade && clade.clade.length){ - for(var i = 0; i < clade.clade.length; i++){ - var thisClade = clade.clade[i]; - node.children.push(recursiveParse(thisClade, node)); - } - } - if(clade.branch_length){ // Branches can be attributes or own element - if(typeof clade.branch_length === 'object'){ - clade.branch_length = clade.branch_length[0].Text; - } - - node.len = Smits.Common.roundFloat(clade.branch_length, 4); // round to 4 decimal places - if(node.len == 0){ - node.len = 0.0001; - } - } - if(clade.name){ - node.type = 'label'; - node.name = clade.name[0].Text; - if(clade.name[0] && clade.name[0].style){ - node.style = clade.name[0].style; - } - if(clade.name[0] && clade.name[0].bgStyle){ - node.bgStyle = clade.name[0].bgStyle; - } - } else if(clade.confidence){ - node.name = clade.confidence[0].Text; - } - - /* Collect further info that might be used as a label */ - if (clade.sequence && clade.sequence[0] && clade.sequence[0].name && clade.sequence[0].name[0] && clade.sequence[0].name[0].Text){ - node.sequenceName = clade.sequence[0].name[0].Text; - } - if (clade.taxonomy && clade.taxonomy[0]){ - if(clade.taxonomy[0].scientific_name && clade.taxonomy[0].scientific_name[0] && clade.taxonomy[0].scientific_name[0].Text){ - node.taxonomyScientificName = clade.taxonomy[0].scientific_name[0].Text; - } - if (clade.taxonomy[0].common_name && clade.taxonomy[0].common_name[0] && clade.taxonomy[0].common_name[0].Text){ - node.taxonomyCommonName = clade.taxonomy[0].common_name[0].Text; - } - } - if (clade.sequence && clade.sequence[0] && clade.sequence[0].accession && clade.sequence[0].accession[0] && clade.sequence[0].accession[0].Text){ - node.sequenceAccession = clade.sequence[0].accession[0].Text; - } - if (clade.point ){ - node.LatLong = [clade.point[0].lat[0].Text, clade.point[0]['long'][0].Text]; - } - - - /* Prioritization of Label */ - if(!node.name){ - if(node.sequenceName){ - node.name = node.sequenceName; - } else if (node.taxonomyScientificName){ - node.name = node.taxonomyScientificName; - } else if (node.taxonomyCommonName){ - node.name = node.taxonomyCommonName; - } else if (node.sequenceAccession){ - node.name = node.sequenceAccession; - } - if(node.name){ // if name is now set, type is 'label' - node.type = 'label'; - } - } - - if(clade.annotation){ - if(clade.annotation[0] && clade.annotation[0].desc && clade.annotation[0].desc[0] && clade.annotation[0].desc[0].Text){ - node.description = clade.annotation[0].desc[0].Text; - } - if(clade.annotation[0] && clade.annotation[0].uri && clade.annotation[0].uri[0] && clade.annotation[0].uri[0].Text){ - node.uri = clade.annotation[0].uri[0].Text; - } - if(clade.annotation[0] && clade.annotation[0].img){ - for(var i in clade.annotation[0].img){ - if(Smits.Common.isInteger(i)){ - node.img[i] = clade.annotation[0].img[i].Text; - } - } - } - } - if(clade.chart){ - if(clade.chart[0]){ - for(var i in clade.chart[0]){ - if(i != 'Text' && i != '_children'){ - node.chart[i] = clade.chart[0][i][0].Text; - } - } - } - - } - - // Validation - if(node && node.level > 1){ - if(!node.len){ - validate = 'Error. Please include Branch Lengths - we only draw rooted phylogenetic trees.'; - } - } - - return node; - }, - - recursiveProcessRoot = function(node, parentNode){ - if(node.children && node.children.length){ - for( var i = 0; i < node.children.length; i++){ - var child = node.children[i]; - child.newickLen = Math.round( (child.len + node.newickLen) *10000)/10000; - if(child.level > mLevel) mLevel = child.level; - if(child.newickLen > mNewickLen) mNewickLen = child.newickLen; - if(child.children.length > 0){ - recursiveProcessRoot(child, node); - } - } - } - return node; - }, - - recursiveProcessParameters = function(parametersEl, treeType){ - for (var i in parametersEl){ - if(i != '_children' && i != 'Text'){ - if(i == 'rectangular' || i == 'circular'){ - recursiveProcessParameters(parametersEl[i][0], i); - } else { - if(!Smits.PhyloCanvas.Render.Parameters[i]) { Smits.PhyloCanvas.Render.Parameters[i] = {}; }; - Smits.PhyloCanvas.Render.Parameters.set(i, parametersEl[i][0].Text, treeType); - } - } - } - return; - }; - - return function(jsonString){ - /* Privileged Methods */ - this.getRoot = function(){ - return root; - }; - this.getLevels = function(){ - return mLevel; - }; - this.getNewickLen = function(){ - return mNewickLen; - }; - this.getValidate = function(){ - return validate; - }; - - - /* CONSTRUCTOR */ - if(jsonString.phylogeny && jsonString.phylogeny[0] && jsonString.phylogeny[0].clade){ - root = recursiveParse(jsonString.phylogeny[0].clade[0]); - } - - if(jsonString.phylogeny && jsonString.phylogeny[0] && jsonString.phylogeny[0].render && jsonString.phylogeny[0].render[0]){ - var render = jsonString.phylogeny[0].render[0]; - - // Custom Styles - if(render && render.styles){ - var styles = render.styles[0]; - for (var i in styles){ - if(i != '_children' && i != 'Text'){ - if(styles[i][0]['type'] && styles[i][0]['type'] == "radialGradient" && Raphael.svg){ - // radialGradient only supported by SVG - styles[i][0]['name'] = i; - Smits.PhyloCanvas.Render.Style[i] = styles[i][0]; - if(!Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList']) { Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList'] = [] }; - Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList'].push(i); - } else { - if(!Smits.PhyloCanvas.Render.Style[i]) { Smits.PhyloCanvas.Render.Style[i] = {}; }; - for(var j in styles[i][0]){ - if(j != '_attributes' && j != '_children' && j != 'type'){ - Smits.PhyloCanvas.Render.Style[i][j.replace('_', '-')] = styles[i][0][j]; // This is quite painful, as xml does not allow dashes - } - } - } - - } - } - } - - // Custom Parameters - if(render && render.parameters){ - recursiveProcessParameters(render.parameters[0]); - } - - // Charts - if(render && render.charts){ - var charts = render.charts[0]; - for (var i in charts){ - if(i != '_children' && i != 'Text'){ - for(var j in charts[i]){ - if(charts[i][j].type == "binary"){ - charts[i][j].chart = i; - Smits.PhyloCanvas.Render.Parameters.binaryCharts.push(charts[i][j]); - } else if (charts[i][j].type == "integratedBinary"){ - charts[i][j].chart = i; - Smits.PhyloCanvas.Render.Parameters.integratedBinaryCharts.push(charts[i][j]); - } else if (charts[i][j].type == "bar"){ - charts[i][j].chart = i; - Smits.PhyloCanvas.Render.Parameters.barCharts.push(charts[i][j]); - } - } - } - } - } - - } - - root = recursiveProcessRoot(root); - - } - -}(); - -Smits.PhyloCanvas.PhyloxmlParse.prototype = { - -};Smits.PhyloCanvas.NexmlParse = function(){ - - var mLevel = 0, - mNewickLen = 0, - root, - validate, - nexEdges, - nexNodes, - - recursiveParse = function(nexnode, nexlen, parentNode){ - var node = new Smits.PhyloCanvas.Node(); - if(parentNode){ - node.level = parentNode.level + 1; - } - - for(var i = 0; i < nexEdges.length; i++){ - if(nexEdges[i].source == nexnode.id){ - for(var j = 0; j < nexNodes.length; j++){ - if(nexEdges[i].target == nexNodes[j].id){ - node.children.push(recursiveParse(nexNodes[j], nexEdges[i].length, node)); - } - } - } - } - - if(nexlen) { - node.len = Smits.Common.roundFloat(nexlen, 4); // round to 4 decimal places - if(node.len == 0){ - node.len = 0.0001; - } - } - - if(nexnode.label){ - node.type = 'label'; - node.name = nexnode.label; - if(nexnode.style){ - node.style = nexnode.style; - } - } - - - // Validation - if(node && node.level > 1){ - if(!node.len){ - validate = 'Error. Please include Branch Lengths - we only draw rooted phylogenetic trees.'; - } - } - - return node; - }, - - recursiveProcessRoot = function(node, parentNode){ - if(node.children && node.children.length){ - for( var i = 0; i < node.children.length; i++){ - var child = node.children[i]; - child.newickLen = Math.round( (child.len + node.newickLen) *10000)/10000; - if(child.level > mLevel) mLevel = child.level; - if(child.newickLen > mNewickLen) mNewickLen = child.newickLen; - if(child.children.length > 0){ - recursiveProcessRoot(child, node); - } - } - } - return node; - }, - recursiveProcessParameters = function(parametersEl, treeType){ - for (var i in parametersEl){ - if(i != '_children' && i != 'Text'){ - if(i == 'rectangular' || i == 'circular'){ - recursiveProcessParameters(parametersEl[i][0], i); - } else { - if(!Smits.PhyloCanvas.Render.Parameters[i]) { Smits.PhyloCanvas.Render.Parameters[i] = {}; }; - Smits.PhyloCanvas.Render.Parameters.set(i, parametersEl[i][0].Text, treeType); - } - } - } - return; - }; - - return function(jsonString, inputFormat){ - /* Privileged Methods */ - this.getRoot = function(){ - return root; - }; - this.getLevels = function(){ - return mLevel; - }; - this.getNewickLen = function(){ - return mNewickLen; - }; - this.getValidate = function(){ - return validate; - }; - - - if(inputFormat.tree && jsonString.trees[0] && jsonString.trees[0].tree[(inputFormat.tree-1)]){ - nexEdges = jsonString.trees[0].tree[(inputFormat.tree-1)].edge; - nexNodes = jsonString.trees[0].tree[(inputFormat.tree-1)].node; - } else { - nexEdges = jsonString.trees[0].tree[0].edge; - nexNodes = jsonString.trees[0].tree[0].node; - } - - // RAV: it is more robust to search for the root by the tree topology - // then by looking for a @root attribute. Valid NeXML tree structures - // always have one node without normal edges pointing into it. The - // root attribute is used to indicate that this tree is actually rooted. - // Compare this with nexus/newick: newick strings are always implicitly - // rooted, even if the tree is called a utree or the [&U] token is used. - for(i = 0; i < nexNodes.length; i++){ - for(i = 0; i < nexNodes.length; i++) { - var targetCount = 0; - for(j = 0; j < nexEdges.length; j++) { - if(nexEdges[j].target == nexNodes[i].id) { - targetCount++; - } - } - if ( targetCount == 0 ) { - root = nexNodes[i]; - } - } - } - - if(root){ - root = recursiveParse(root); - - root = recursiveProcessRoot(root); - } else { - validate = 'Error. Currently, only rooted NeXML trees are supported.'; - } - - }; - -}(); - -Smits.PhyloCanvas.NexmlParse.prototype = { - -};Smits.PhyloCanvas.NexmlJsonParse = function(){ - - var mLevel = 0, - mNewickLen = 0, - root, - validate, - nexEdges = [], nexNodes = [], - - recursiveParse = function(nexnode, nexlen, parentNode){ - var node = new Smits.PhyloCanvas.Node(); - if(parentNode){ - node.level = parentNode.level + 1; - } - - for(var i = 0; i < nexEdges.length; i++){ - if(nexEdges[i].source == nexnode.id){ - for(var j = 0; j < nexNodes.length; j++){ - if(nexEdges[i].target == nexNodes[j].id){ - node.children.push(recursiveParse(nexNodes[j], nexEdges[i].length, node)); - } - } - } - } - - if(nexlen) { - node.len = Smits.Common.roundFloat(nexlen, 4); // round to 4 decimal places - if(node.len == 0){ - node.len = 0.0001; - } - } - - if(nexnode.label){ - node.type = 'label'; - node.name = nexnode.label; - if(nexnode.accession){ - node.accession = nexnode.accession; - } - if(nexnode.style){ - node.style = nexnode.style; - } - if(nexnode.bgStyle){ - node.bgStyle = nexnode.bgStyle; - } - } - - if(nexnode.chart){ - node.chart = nexnode.chart; - } - - // Validation - if(node && node.level > 1){ - if(!node.len){ - validate = 'Error. Please include Branch Lengths - we only draw rooted phylogenetic trees.'; - } - } - - return node; - }, - - recursiveProcessRoot = function(node, parentNode){ - if(node.children && node.children.length){ - for( var i = 0; i < node.children.length; i++){ - var child = node.children[i]; - child.newickLen = Math.round( (child.len + node.newickLen) *10000)/10000; - if(child.level > mLevel) mLevel = child.level; - if(child.newickLen > mNewickLen) mNewickLen = child.newickLen; - if(child.children.length > 0){ - recursiveProcessRoot(child, node); - } - } - } - return node; - }, - - recursiveProcessParameters = function(parametersEl, treeType){ - for (var i in parametersEl){ - if(i != '_children' && i != 'Text'){ - if(i == 'rectangular' || i == 'circular'){ - recursiveProcessParameters(parametersEl[i], i); - } else { - if(!Smits.PhyloCanvas.Render.Parameters[i]) { Smits.PhyloCanvas.Render.Parameters[i] = {}; }; - Smits.PhyloCanvas.Render.Parameters.set(i, parametersEl[i], treeType); - } - } - } - return; - }; - - return function(inputFormat){ - /* Privileged Methods */ - this.getRoot = function(){ - return root; - }; - this.getLevels = function(){ - return mLevel; - }; - this.getNewickLen = function(){ - return mNewickLen; - }; - this.getValidate = function(){ - return validate; - }; - - var jsonString = inputFormat.nexmlJson.nexml; - - - /* RENDER STYLES */ - var render = jsonString.render; - - // Custom Styles - if(render && render.styles){ - var styles = render.styles; - for (var i in styles){ - if(i != '_children' && i != 'Text'){ - if(styles[i]['@attributes']['type'] && styles[i]['@attributes']['type'] == "radialGradient" && Raphael.svg){ - // radialGradient only supported by SVG - styles[i]['name'] = i; - styles[i]['type'] = styles[i]['@attributes']['type']; - Smits.PhyloCanvas.Render.Style[i] = styles[i]; - if(!Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList']) { Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList'] = [] }; - Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList'].push(i); - } else { - if(!Smits.PhyloCanvas.Render.Style[i]) { Smits.PhyloCanvas.Render.Style[i] = {}; }; - for(var j in styles[i]['@attributes']){ - if(j != '_attributes' && j != '_children' && j != 'type'){ - Smits.PhyloCanvas.Render.Style[i][j.replace('_', '-')] = styles[i]['@attributes'][j]; // This is quite painful, as xml does not allow dashes - } - } - } - } - } - } - // Custom Parameters - if(render && render.parameters){ - recursiveProcessParameters(render.parameters); - } - - // Charts - if(render && render.charts){ - var charts = render.charts; - for (var i in charts){ - charts[i]['@attributes'].chart = i; - if(charts[i]['@attributes'].type == "binary"){ - Smits.PhyloCanvas.Render.Parameters.binaryCharts.push(charts[i]['@attributes']); - } else if(charts[i]['@attributes'].type == "integratedBinary"){ - Smits.PhyloCanvas.Render.Parameters.integratedBinaryCharts.push(charts[i]['@attributes']); - } else if(charts[i]['@attributes'].type == "bar"){ - Smits.PhyloCanvas.Render.Parameters.barCharts.push(charts[i]['@attributes']); - } - } - } - - if(inputFormat.tree && jsonString.trees[0] && jsonString.trees[0].tree[(inputFormat.tree-1)]){ - nexEdges = jsonString.trees[0].tree[(inputFormat.tree-1)].edge; - nexNodes = jsonString.trees[0].tree[(inputFormat.tree-1)].node; - } else { - for(var i = 0; i < jsonString.trees.tree.edge.length; i++){ - nexEdges.push(jsonString.trees.tree.edge[i]['@attributes']); - } - for(var i = 0; i < jsonString.trees.tree.node.length; i++){ - var node = jsonString.trees.tree.node[i]['@attributes']; - if(node.label){ - node.chart = jsonString.trees.tree.node[i].chart; - } - nexNodes.push(node); - } - } - - for(var i = 0; i < nexNodes.length; i++){ - if(nexNodes[i].root && nexNodes[i].root == "true"){ - root = nexNodes[i]; - } - } - - if(root){ - root = recursiveParse(root); - - root = recursiveProcessRoot(root); - } else { - validate = 'Error. Currently, only rooted NeXML trees are supported.'; - } - - }; - -}(); - -Smits.PhyloCanvas.NexmlParse.prototype = { - -};Smits.PhyloCanvas.Render = {};Smits.PhyloCanvas.Render.Style = { - - /* Default Styles */ - - line: { - "stroke": 'rgb(0,0,0)', - "stroke-width": 1 - }, - - text: { - "font-family": 'Verdana', - "font-size": 12, - "text-anchor": 'start' - }, - - path: { - "stroke": 'rgb(0,0,0)', - "stroke-width": 1 - }, - - connectedDash : { - "stroke": 'rgb(200,200,200)', - "stroke-dasharray": ". " - }, - - textSecantBg : { - "fill": '#EEE', - "stroke": '#DDD' - }, - - highlightedEdgeCircle : { - "fill": 'red' - }, - - barChart : { - fill: '#003300', - stroke: '#DDD' - }, - - getStyle : function(requestStyle, fallbackStyle){ - if(this[requestStyle]){ - return this[requestStyle]; - } else { - return this[fallbackStyle]; - } - - } - - - -};Smits.PhyloCanvas.Render.Parameters = { - - /* DEFAULT PARAMETERS */ - jsOverride: 0, // If set, js will override chart's file setting - - /** Phylogram parameters are separated because they behave very differently **/ - - /* Rectangular Phylogram */ - Rectangular : { - bufferX : 200, // Reduces the available canvas space for tree branches, allowing - // for more space for the textual/charting components - bufferY : 40, - bufferInnerLabels : 10, // Pixels - bufferOuterLabels : 5, // Pixels - minHeightBetweenLeaves : 10, // Should probably set pretty low, as clipping may occur if it needs to be implemented - - alignPadding : 0, // Pixels to push the labels out by - this extension should be - // compensated by an increase in bufferX too - alignRight : false, - - showScaleBar : false // (STRING, e.g. "0.05") Shows a scale bar at the bottom of the tree - }, - - /* Circular Phylogram */ - Circular : { - bufferRadius : 0.33, // Margins of Tree Circle - // If > 1, it is in pixels - // If < 1, it is a percentage of the full canvas size - bufferAngle : 20, // controls split size in circle - initStartAngle : 160, - innerCircleRadius : 0, - minHeightBetweenLeaves : 5, - - /* Labels */ - bufferInnerLabels : 2, // Pixels - bufferOuterLabels : 5 // Pixels - }, - - /* Charts */ - binaryCharts : [], - integratedBinaryCharts : [], - barCharts : [], - - /* Binary Defaults */ - binaryChartBufferInner : 5, - binaryChartBufferSiblings : 0.01, - binaryChartThickness : 15, - binaryChartDisjointed : false, - - /* Bar Defaults */ - barChartBufferInner : 3, - barChartHeight : 50, - barChartWidth : 0.5, // If > 1, it is in pixels - // If < 1, it is a percentage of the node width - - /* - Rollover Events - At minimum, the params object has the following properties: - .svg - .node - .x - .y - .textEl - */ - mouseRollOver : function(params) { - if(params.node.edgeCircleHighlight){ - params.node.edgeCircleHighlight.show(); - } else { - var circleObject = params.svg.draw( - new Smits.PhyloCanvas.Render.Circle( - params.x, params.y, 5, - { attr: Smits.PhyloCanvas.Render.Style.highlightedEdgeCircle } - ) - ); - params.node.edgeCircleHighlight = circleObject[0]; - } - params.textEl.attr({ fill: 'red' }); - }, - mouseRollOut : function(params) { - params.node.edgeCircleHighlight.hide(); - params.textEl.attr({ fill: '#000' }); - }, - - set : function(param, value, treeType){ - if(!this.jsOverride){ - if(treeType){ - if(treeType == 'circular'){ - this['Circular'][param] = parseFloat(value); - } else if (treeType == 'rectangular'){ - this['Rectangular'][param] = parseFloat(value); - } - } else { - this[param] = parseFloat(value); - } - } - } -};Smits.PhyloCanvas.Render.Line = function(){ - - return function(x1, x2, y1, y2, params){ - /* Defaults */ - this.type = 'line'; - this.attr = Smits.PhyloCanvas.Render.Style.line; - - this.x1 = x1; - this.x2 = x2; - this.y1 = y1; - this.y2 = y2; - - if(params) { - Smits.Common.apply(this, params); - if(params.attr) this.attr = params.attr; - } - - } -}();Smits.PhyloCanvas.Render.Text = function(){ - - return function(x, y, text, params){ - /* Defaults */ - this.type = 'text'; - this.attr = Smits.PhyloCanvas.Render.Style.text; - - this.x = x; - this.y = y; - this.text = text; - - if(params) { - Smits.Common.apply(this, params); - if(params.attr) this.attr = params.attr; - } - } -}();Smits.PhyloCanvas.Render.Path = function(){ - var attr = Smits.PhyloCanvas.Render.Style.path; - - return function(path, params){ - /* Defaults */ - this.type = 'path'; - this.attr = Smits.PhyloCanvas.Render.Style.path; - - this.path = path; - if(params) { - Smits.Common.apply(this, params); - if(params.attr) this.attr = params.attr; - } - - } -}();Smits.PhyloCanvas.Render.Circle = function(){ - - return function(x, y, radius, params){ - /* Defaults */ - this.type = 'circle'; - - this.x = x; - this.y = y; - this.radius = radius; - - if(params) { - Smits.Common.apply(this, params); - if(params.attr) this.attr = params.attr; - } - - } -}();Smits.PhyloCanvas.Render.SVG = function(){ - var divId, - canvasSize; - - return function(sDivId, canvasWidth, canvasHeight){ - - /* CONSTRUCTOR */ - divId = sDivId; - this.canvasSize = [canvasWidth, canvasHeight]; - - this.svg = Raphael(sDivId, this.canvasSize[0], this.canvasSize[1]); - - } - -}(); - -Smits.PhyloCanvas.Render.SVG.prototype = { - - render : function(){ - var instructs = this.phylogramObject.getDrawInstructs(); - - for (var i = 0; i < instructs.length; i++) { - if(instructs[i].type == 'line'){ - var line = this.svg.path(["M", instructs[i].x1, instructs[i].y1, "L", instructs[i].x2, instructs[i].y2]).attr(Smits.PhyloCanvas.Render.Style.line); - } else if(instructs[i].type == 'path'){ - var path = this.svg.path(instructs[i].path).attr(instructs[i].attr); - } else if(instructs[i].type == 'circle'){ - var path = this.svg.circle(instructs[i].x, instructs[i].y, instructs[i].radius).attr({ - "stroke": 'red' - }); - } else { - var text = this.svg.text(instructs[i].x, instructs[i].y, instructs[i].text).attr(Smits.PhyloCanvas.Render.Style.text); - if(instructs[i].attr){ - text.attr(instructs[i].attr); - } - if(instructs[i].rotate){ - text.rotate(instructs[i].rotate); - } - - var bbox = text.getBBox(); - var hyp = Math.sqrt( (bbox.height * bbox.height) + (bbox.width * bbox.width) ); // get hypotenuse - - } - } - }, - - draw : function(instruct){ - var obj, - param; - if(instruct.type == 'line'){ - obj = this.svg.path(["M", instruct.x1, instruct.y1, "L", instruct.x2, instruct.y2]).attr(Smits.PhyloCanvas.Render.Style.line); - } else if(instruct.type == 'path'){ - obj = this.svg.path(instruct.path).attr(instruct.attr); - } else if(instruct.type == 'circle'){ - obj = this.svg.circle(instruct.x, instruct.y, instruct.radius).attr({ - "stroke": 'red' - }); - } else if(instruct.type == 'text'){ - obj = this.svg.text(instruct.x, instruct.y, instruct.text).attr(Smits.PhyloCanvas.Render.Style.text); - if(instruct.attr){ - obj.attr(instruct.attr); - } - if(instruct.rotate){ - obj.rotate(instruct.rotate); - } - - var bbox = obj.getBBox(); - param = Math.sqrt( (bbox.height * bbox.height) + (bbox.width * bbox.width) ); // get hypotenuse - } - - return [obj, param]; - } - -};Smits.PhyloCanvas.Render.Phylogram = function(){ - - var svg, - sParams = Smits.PhyloCanvas.Render.Parameters.Rectangular, // Easy Reference - canvasX, canvasY, - scaleX, scaleY, maxBranch, - minHeightBetweenLeaves, - firstBranch = true, - absoluteY = 0, maxLabelLength = 0, - outerX, outerY, outerRadius, - x1, x2, y1, y2, - positionX, positionY, - bufferX, bufferY, labelsHold = [], - - textPadding = function (y){ - return y + Math.round(y / 4); - }, - - rectLinePathArray = function (x1, y1, x2, y2){ - return ["M", x1, y1, "L", x2, y1, "L", x2, y2, "L", x1, y2, "Z"]; - }, - - recursiveCalculateNodePositions = function (node, positionX){ - if(node.len){ - if(firstBranch){ - firstBranch = false; - } else { - if(node.children.length == 0) absoluteY = Smits.Common.roundFloat(absoluteY + scaleY, 4); - } - } - - if(node.children.length > 0){ - var nodeCoords = [], x1,x2,y1,y2; - if(node.len){ // draw stem - x1 = positionX; - x2 = positionX = Smits.Common.roundFloat(positionX + (scaleX * node.len), 4); - y1 = absoluteY + (node.getMidbranchPosition() * scaleY); - y2 = y1; - - svg.draw(new Smits.PhyloCanvas.Render.Line(x1, x2, y1, y2)); - } - - if(node.name){ // draw bootstrap values - var attr = {}; - attr = Smits.PhyloCanvas.Render.Style.getStyle('bootstrap', 'text'); - if(node.uri) { attr.href = node.uri }; - if(node.description) {attr.title = node.description }; - if(node.level == 0){ - var innerX2 = 2; - var innerY2 = absoluteY + (node.getMidbranchPosition() * scaleY); - } else { - var innerX2 = x2; - var innerY2 = y2; - } - - svg.draw( - new Smits.PhyloCanvas.Render.Text( - innerX2 + 5, innerY2, - node.name, - { - attr: attr - } - ) - ); - //svg.draw(new Smits.PhyloCanvas.Render.Text(x2 + 5, y2, node.name)); - } - - if(node.children && node.children.length){ - for(var i = 0; i < node.children.length; i++){ - var child = node.children[i]; - nodeCoords.push(recursiveCalculateNodePositions(child, positionX)); - } - } - - var flatNodeCoords = []; // establish vertical bounds - for ( var i = 0; i < nodeCoords.length; i++ ){ - if(nodeCoords[i][0]) flatNodeCoords.push(nodeCoords[i][0]); - if(nodeCoords[i][1]) flatNodeCoords.push(nodeCoords[i][1]); - } - var verticalY1 = Math.min.apply(null, flatNodeCoords ); - var verticalY2 = Math.max.apply(null, flatNodeCoords); - - // draw vertical - // hack: little elbows at ends in order to prevent stair-effects at edges - svg.draw( - new Smits.PhyloCanvas.Render.Path( - [ - "M", positionX + 0.0001, verticalY1, - "L", positionX, verticalY1, - "L", positionX, verticalY2, - "L", positionX + 0.0001, verticalY2 - ], - { attr : Smits.PhyloCanvas.Render.Style.line } - ) - ); - - } else { - // label - x1 = positionX; - x2 = Smits.Common.roundFloat(positionX + (scaleX * node.len), 2); - y1 = absoluteY; - y2 = absoluteY; - - // preserve for later processing - node.y = absoluteY; - labelsHold.push(node); - - svg.draw(new Smits.PhyloCanvas.Render.Line(x1, x2, y1, y2)); - if(sParams.alignRight){ - svg.draw( - new Smits.PhyloCanvas.Render.Path( - ["M", x2, y1, "L", sParams.alignPadding + maxBranch, y2], - { attr : Smits.PhyloCanvas.Render.Style.connectedDash } - ) - ); - } - - if(node.name){ - var attr = {}; - if(node.style){ - attr = Smits.PhyloCanvas.Render.Style.getStyle(node.style, 'text'); - } - attr["text-anchor"] = 'start'; - if(node.uri) { attr.href = node.uri }; - if(node.description) {attr.title = node.description }; - - var draw = svg.draw( - new Smits.PhyloCanvas.Render.Text( - sParams.alignRight ? maxBranch + sParams.bufferInnerLabels + sParams.alignPadding : x2 + sParams.bufferInnerLabels, y2, - node.name, - { - attr: attr - } - ) - ); - if(node.style){ - console.log([node, attr]); - } - maxLabelLength = Math.max(draw[1], maxLabelLength); - - // Rollover, Rollout and Click Events - if(Smits.PhyloCanvas.Render.Parameters.mouseRollOver){ - Smits.Common.addEventHandler( - draw[0].node, - 'mouseover', - Smits.PhyloCanvas.Render.Parameters.mouseRollOver, - { svg: svg, node: node, x: x2, y: y2, textEl: draw[0] } - ); - } - if(Smits.PhyloCanvas.Render.Parameters.mouseRollOut){ - Smits.Common.addEventHandler( - draw[0].node, - 'mouseout', - Smits.PhyloCanvas.Render.Parameters.mouseRollOut, - { svg: svg, node: node, x: x2, y: y2, textEl: draw[0] } - ); - } - if(Smits.PhyloCanvas.Render.Parameters.onClickAction){ - Smits.Common.addEventHandler( - draw[0].node, - 'click', - Smits.PhyloCanvas.Render.Parameters.onClickAction, - { svg: svg, node: node, x: x2, y: y2, textEl: draw[0] } - ); - } - } - - } - - return [y1, y2]; - - }, - - drawScaleBar = function (){ - y = absoluteY + scaleY; - x1 = 0; - x2 = sParams.showScaleBar * scaleX; - svg.draw(new Smits.PhyloCanvas.Render.Line(x1, x2, y, y)); - svg.draw(new Smits.PhyloCanvas.Render.Text( - (x1+x2)/2, - y-8, - sParams.showScaleBar) - ); - }, - - renderBinaryChart = function(x, groupName, params){ - var bufferInner = (params && params.bufferInner ? params.bufferInner : 0) | Smits.PhyloCanvas.Render.Parameters.binaryChartBufferInner, - bufferSiblings = (params && params.bufferSiblings ? params.bufferSiblings * scaleY : 0) | (Smits.PhyloCanvas.Render.Parameters.binaryChartBufferSiblings < 1 ? scaleY * Smits.PhyloCanvas.Render.Parameters.binaryChartBufferSiblings : Smits.PhyloCanvas.Render.Parameters.binaryChartBufferSiblings), - thickness = (params && params.thickness ? params.thickness : 0) | Smits.PhyloCanvas.Render.Parameters.binaryChartThickness, - beginY; - - for(var i = 0; i < labelsHold.length; i++){ - var node = labelsHold[i]; - svg.draw( - new Smits.PhyloCanvas.Render.Path( - rectLinePathArray( - x + bufferInner, - node.y - (scaleY/2) + (bufferSiblings/2), - x + bufferInner + thickness, - node.y + (scaleY/2) - (bufferSiblings/2) - ), - { attr: Smits.PhyloCanvas.Render.Style.getStyle(node.chart[groupName], 'textSecantBg') } - ) - ); - } - return x + bufferInner + thickness; - }, - - renderBarChart = function(x, groupName, params){ - var allValues = [], maxValue, - bufferInner = params && params.bufferInner ? params.bufferInner : 0 | Smits.PhyloCanvas.Render.Parameters.barChartBufferInner, - height = params && params.height ? params.height : 0 | Smits.PhyloCanvas.Render.Parameters.barChartHeight, - width = params && params.width ? (params.width < 1 ? scaleY * params.width : params.width ) : 0 | (Smits.PhyloCanvas.Render.Parameters.barChartWidth < 1 ? scaleY * Smits.PhyloCanvas.Render.Parameters.barChartWidth : Smits.PhyloCanvas.Render.Parameters.barChartWidth), - scaleHeight = 0; - - // Need to get max value - for(var i = 0; i < labelsHold.length; i++){ - allValues.push(labelsHold[i].chart[groupName]); - } - maxValue = Math.max.apply(null, allValues); - scaleHeight = Smits.Common.roundFloat(height / maxValue, 4); - - for(var i = 0; i < labelsHold.length; i++){ - var node = labelsHold[i]; - svg.draw( - new Smits.PhyloCanvas.Render.Path( - rectLinePathArray( - x + bufferInner, - node.y - (width/2), - x + bufferInner + (scaleHeight * node.chart[groupName]), - node.y + (width/2) - ), - { attr: Smits.PhyloCanvas.Render.Style.getStyle(node.chart[groupName], 'barChart') } - ) - ); - } - - return x + bufferInner + height; - }; - - return function(sSvg, dataObject){ - absoluteY = 0; - - /* Privileged Methods */ - this.getCanvasSize = function(){ - return [canvasX, canvasY]; - }; - this.getRoot = function(){ - return dataObject.getRoot(); - }; - - /* CONSTRUCTOR */ - if(dataObject.getValidate()){ // Validate - svg.draw(0,0, dataObject.getValidate()); - } - - svg = sSvg; - var node = dataObject.getRoot(); - var mNewickLen = dataObject.getNewickLen(); - - canvasX = svg.canvasSize[0]; // Full Canvas Width - canvasY = svg.canvasSize[1]; // Full Canvas Height - - bufferX = sParams.bufferX; - bufferY = sParams.bufferY; - minHeightBetweenLeaves = sParams.minHeightBetweenLeaves; - - scaleX = Math.round((canvasX - bufferX) / mNewickLen); - scaleY = Math.round((canvasY - bufferY) / (sParams.showScaleBar ? node.getCountAllChildren() + 1 : node.getCountAllChildren()) ); - if(scaleY < minHeightBetweenLeaves){ - scaleY = minHeightBetweenLeaves; - } - maxBranch = Math.round( canvasX - bufferX ); - - if(Smits.PhyloCanvas.Render.Parameters.binaryCharts.length || Smits.PhyloCanvas.Render.Parameters.barCharts.length){ - sParams.alignRight = true; - } - - recursiveCalculateNodePositions(node, 0); - - // Draw Scale Bar - if(sParams.showScaleBar){ - drawScaleBar(); - } - - outerX = maxBranch + maxLabelLength + sParams.bufferInnerLabels; - // Draw secant highlights - if(Smits.PhyloCanvas.Render.Parameters.binaryCharts.length){ - var binaryCharts = Smits.PhyloCanvas.Render.Parameters.binaryCharts; - for(var i in binaryCharts){ - outerX = renderBinaryChart(outerX, binaryCharts[i].chart, binaryCharts[i]); - } - } - - // Draw Bar Chart - if(Smits.PhyloCanvas.Render.Parameters.barCharts.length){ - var barCharts = Smits.PhyloCanvas.Render.Parameters.barCharts; - for(var i in barCharts){ - outerRadius = renderBarChart(outerX, barCharts[i].chart, barCharts[i]); - } - } - - } -}(); - -Smits.PhyloCanvas.Render.Phylogram.prototype = { - -};Smits.PhyloCanvas.Render.CircularPhylogram = (function(){ - - var svg, - sParams = Smits.PhyloCanvas.Render.Parameters.Circular, // Easy Reference - canvasX, canvasY, canvasMinEdge, - scaleRadius, scaleAngle, - minHeightBetweenLeaves, - innerCircleRadius, - firstBranch = true, - absoluteY = 0, cx, cy, maxBranch, - labelsHold = [], bgLabelsHold = [], - bufferRadius, bufferAngle, outerRadius, - maxLabelLength = 0, - initStartAngle, - rad = (Math.PI / 180); - - function secPosition(r, deg){ - deg += initStartAngle; - return [ - Smits.Common.roundFloat(cx + r * Math.sin(deg * rad), 4), - Smits.Common.roundFloat(cy + r * Math.cos(deg * rad), 4) - ]; // x,y - }; - function rotateTextByY(yCoord){ - var rotateAngle = normalizeAngle( 90 - yCoord - initStartAngle ); - - if(rotateAngle > 90 && rotateAngle < 270){ - rotateAngle += 180; - var alignment = "end"; - } else { - var alignment = "start"; - } - - return [rotateAngle, alignment]; - }; - function secant(r, startAngle, endAngle, params){ - var startPos = secPosition(r, startAngle); - var endPos = secPosition(r, endAngle); - var arr = [], - n, inv = 0; - - if(Math.abs(normalizeAngle(endAngle-startAngle)) > 180) { - n = 1; - } else { - n = -1; - } - - // Parameter changes - if(params && params.invertSecant){ - n *= -1; - inv = 1; - } - if(params && params.noMove){ - } else { - arr.push('M'); - } - - arr.push(startPos[0], startPos[1], "A", r, r, 0, n < 1 ? 0 : 1, inv, endPos[0], endPos[1]); - return arr; - }; - function secLinePath(deg, x1, x2, params){ - var arr = []; - var startPos = secPosition(x1, deg); - var endPos = secPosition(x2, deg); - if(params && params.noMove){ - } else { - arr.push('M'); - } - arr.push(startPos[0], startPos[1], "L", endPos[0], endPos[1]); - return arr; - }; - function normalizeAngle(ang){ - while(ang > 360 || ang < 0){ - if(ang > 360){ - ang -= 360; - } else if (ang < 0){ - ang += 360; - } - } - return ang; - }; - function sector(r1, r2, y1, y2){ - if(!r2 && r1.length > 1){ - var y2 = r1[3]; - var y1 = r1[2]; - var r2 = r1[1]; - var r1 = r1[0]; - } - var arr = array_merge( "M", - secant( - r1, - y1, - y2, - { noMove: 1, invertSecant: 0} - ), "L", - secant( - r2, - y2, - y1, - { noMove: 1, invertSecant: 1} - ), - 'Z' - ); - return arr; - }; - - function recursiveCalculateNodePositions(node, positionX){ - positionX = positionX; - - if(node.len){ // If first branch, pad only margin - if(firstBranch){ - absoluteY = bufferAngle || 1; // Has to be at least 1 - firstBranch = false; - } else { - if(node.children.length == 0) absoluteY = Smits.Common.roundFloat(absoluteY + scaleAngle, 4); - } - } - - if(node.children.length > 0){ - var nodeCoords = [], x1,x2,y1,y2; - x1 = positionX; - x2 = positionX += Smits.Common.roundFloat(scaleRadius * node.len, 4); - - - if(node.name){ // draw bootstrap values - - } - - if(node.children && node.children.length){ - for(var i = 0; i < node.children.length; i++){ - var child = node.children[i]; - var y = recursiveCalculateNodePositions(child, positionX); - if(y > 0) nodeCoords.push(y); - } - } - - var minAngle = Smits.Common.roundFloat(Math.min.apply(null, nodeCoords ), 4); - var maxAngle = Smits.Common.roundFloat(Math.max.apply(null, nodeCoords ), 4); - - // hack: little elbows at ends in order to prevent stair-effects at edges - svg.draw( - new Smits.PhyloCanvas.Render.Path( - array_merge( - "M", secPosition(positionX + 0.01, minAngle), - "L", secant(positionX, minAngle, maxAngle, {noMove: true}), - "L", secPosition(positionX + 0.01, maxAngle) - ) - ) - ); - - if(node.len){ // draw stem - y1 = Smits.Common.roundFloat( minAngle + (maxAngle-minAngle)/2, 4 ); - svg.draw(new Smits.PhyloCanvas.Render.Path(secLinePath(y1, x1, x2))); - } - - } else { - // LABEL - - // preserve for later processing - node.y = absoluteY; - labelsHold.push(node); - - x1 = positionX; - x2 = positionX = Smits.Common.roundFloat(positionX + (scaleRadius * node.len)); - y1 = absoluteY; - - svg.draw(new Smits.PhyloCanvas.Render.Path(secLinePath(y1, x1, x2))); - svg.draw( - new Smits.PhyloCanvas.Render.Path( - secLinePath(y1, x2, maxBranch), - { attr : Smits.PhyloCanvas.Render.Style.connectedDash } - ) - ); - - - - if(node.name){ - var pos = secPosition(maxBranch + sParams.bufferInnerLabels, y1); - var rotateParam = rotateTextByY(y1); - var rotateAngle = rotateParam[0]; - var alignment = rotateParam[1]; - - var attr = {}; - if(node.style){ - Smits.Common.apply(attr, Smits.PhyloCanvas.Render.Style.getStyle(node.style, 'text')); - } - attr["text-anchor"] = alignment; - if(node.uri) { attr.href = node.uri }; - if(node.description) {attr.title = node.description }; - - var draw = svg.draw( - new Smits.PhyloCanvas.Render.Text( - pos[0], pos[1], - node.name, - { - attr: attr, - rotate: [rotateAngle, pos[0], pos[1]] - } - ) - ); - - // Background Style - if(node.bgStyle){ - bgLabelsHold.push([node.bgStyle, y1]); - } - - // Rollover, Rollout and Click Events - var pos = secPosition(x2, y1); - if(Smits.PhyloCanvas.Render.Parameters.mouseRollOver){ - Smits.Common.addEventHandler( - draw[0].node, - 'mouseover', - Smits.PhyloCanvas.Render.Parameters.mouseRollOver, - { svg: svg, node: node, x: pos[0], y: pos[1], textEl: draw[0] } - ); - } - if(Smits.PhyloCanvas.Render.Parameters.mouseRollOut){ - Smits.Common.addEventHandler( - draw[0].node, - 'mouseout', - Smits.PhyloCanvas.Render.Parameters.mouseRollOut, - { svg: svg, node: node, x: pos[0], y: pos[1], textEl: draw[0] } - ); - } - if(Smits.PhyloCanvas.Render.Parameters.onClickAction){ - Smits.Common.addEventHandler( - draw[0].node, - 'click', - Smits.PhyloCanvas.Render.Parameters.onClickAction, - { svg: svg, node: node, x: pos[0], y: pos[1], textEl: draw[0] } - ); - } - - maxLabelLength = Math.max(draw[1], maxLabelLength); - } - } - return y1; - }; - - - function array_merge(arr) { - var merged = arr; - for (var i = 1; i < arguments.length; i++) { - merged = merged.concat(arguments[i]); - } - return merged; - }; - - function renderBackground(){ - var arr = []; - - // Highlighted Labels - if(bgLabelsHold.length > 0){ - - // Setup Gradients if defined - if(Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList']){ - for(var i = 0; i < Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList'].length; i++){ - var gradientName = Smits.PhyloCanvas.Render.Style['jsphylosvgGradientList'][i]; - var radialEl = Smits.Common.createGradientEl(gradientName, Smits.PhyloCanvas.Render.Style[gradientName], [cx, cy, maxBranch + maxLabelLength + sParams.bufferOuterLabels]); - svg.svg.defs.appendChild(radialEl); - } - } - - for(var i = 0; i < bgLabelsHold.length; i++){ - if(i != bgLabelsHold.length - 1 && bgLabelsHold[i][0] == bgLabelsHold[(i+1)][0]){ - bgLabelsHold[(i+1)][2] = bgLabelsHold[i][2] ? bgLabelsHold[i][2] : bgLabelsHold[i][1]; - continue; - } - - var arr = sector( - maxBranch, - maxBranch + maxLabelLength + sParams.bufferOuterLabels, - bgLabelsHold[i][2] ? bgLabelsHold[i][2] - scaleAngle/2 : bgLabelsHold[i][1] - scaleAngle/2, - bgLabelsHold[i][1] + scaleAngle/2 - ); - var attr = Smits.PhyloCanvas.Render.Style.getStyle(bgLabelsHold[i][0], 'textSecantBg'); - var bgObj = svg.draw( - new Smits.PhyloCanvas.Render.Path( - arr, - { attr: attr.type ? {} : attr} - ) - ); - //if(attr.type && attr.type == "radialGradient") { bgObj[0].node.setAttribute('class', 'jsphylosvg-' + attr.name); }; - if(attr.type && attr.type == "radialGradient") { bgObj[0].node.setAttribute('fill', 'url(#' + attr.name + ')'); }; - if(attr.type && attr.type == "radialGradient") { bgObj[0].node.setAttribute('stroke', 'none'); }; - bgObj[0].toBack(); // Put it behind the labels - } - } - - // Neutral Background - var arr = sector( - maxBranch, - maxBranch + maxLabelLength + sParams.bufferOuterLabels, - (bufferAngle || 1) + (scaleAngle/2), - 360 + (scaleAngle/2) - ); - var bgObj = svg.draw( - new Smits.PhyloCanvas.Render.Path( - arr, - { attr: Smits.PhyloCanvas.Render.Style.textSecantBg } - ) - ); - - bgObj[0].toBack(); // Put it behind the labels - - return maxBranch + maxLabelLength + sParams.bufferOuterLabels; - }; - - function renderBinaryChart(outerRadius, groupName, params){ - var bufferInner = (params && params.bufferInner) ? parseFloat(params.bufferInner) : Smits.PhyloCanvas.Render.Parameters.binaryChartBufferInner, - bufferSiblings = (params && params.bufferSiblings ? params.bufferSiblings * scaleAngle : 0) | (Smits.PhyloCanvas.Render.Parameters.binaryChartBufferSiblings < 1 ? scaleAngle * Smits.PhyloCanvas.Render.Parameters.binaryChartBufferSiblings : Smits.PhyloCanvas.Render.Parameters.binaryChartBufferSiblings), - thickness = (params && params.thickness) ? parseFloat(params.thickness) : Smits.PhyloCanvas.Render.Parameters.binaryChartThickness, - disjointed = (params && params.disjointed ? params.disjointed : false) | Smits.PhyloCanvas.Render.Parameters.binaryChartDisjointed, - isInternal = (params && params.isInternal) ? params.isInternal : false, - isFirst = true, - beginY; - - - for(var i = 0; i < labelsHold.length; i++){ - var node = labelsHold[i]; - if( (!labelsHold[i+1] || node.chart[groupName] !== labelsHold[i+1].chart[groupName] || disjointed) && node.chart[groupName] != "none" ){ - var attr = Smits.PhyloCanvas.Render.Style.getStyle(node.chart[groupName], 'textSecantBg'); - if(isInternal){ - var sectorCoords = [ - maxBranch - bufferInner - thickness, - maxBranch - bufferInner, - (beginY ? beginY : node.y) - (scaleAngle/2) + (isFirst && !disjointed ? 0 : (bufferSiblings/2)), - node.y + (scaleAngle/2) - (i == labelsHold.length-1 && !disjointed ? 0 : (bufferSiblings/2)) - ]; - } else { - var sectorCoords = [ - outerRadius + bufferInner, - outerRadius + bufferInner + thickness, - (beginY ? beginY : node.y) - (scaleAngle/2) + (isFirst && !disjointed ? 0 : (bufferSiblings/2)), - node.y + (scaleAngle/2) - (i == labelsHold.length-1 && !disjointed ? 0 : (bufferSiblings/2)) - ]; - } - - if(attr.label){ - var textAttr = Smits.PhyloCanvas.Render.Style.getStyle(attr.labelStyle, 'text'); - var pos = secPosition( (sectorCoords[0] + sectorCoords[1]) / 2, (sectorCoords[2] + sectorCoords[3]) / 2 ); - var rotateParam = rotateTextByY((sectorCoords[2] + sectorCoords[3]) / 2); - var rotateLabelBy = normalizeAngle(rotateParam[0] + (textAttr["rotate"] ? parseFloat(textAttr["rotate"]) : 0)); - - var rotateAngle = normalizeAngle( 90 - (sectorCoords[2] + sectorCoords[3])/2 - initStartAngle ); - if(rotateAngle > 90 && rotateAngle < 270){ - rotateLabelBy += 180; - } - - if(!textAttr["text-anchor"]){ - textAttr["text-anchor"] = "middle"; - } - - var binText = svg.draw( - new Smits.PhyloCanvas.Render.Text( - pos[0], - pos[1], - attr.label, - { - attr: textAttr, - rotate: rotateLabelBy - } - ) - ); - binText[0].toBack(); - } - - if(attr.borderStyle){ - var borderAttr = Smits.PhyloCanvas.Render.Style.getStyle(attr.borderStyle, 'textSecantBg'); - var borderSectorCoords = [ - maxBranch, - borderAttr.fullsize ? sectorCoords[1] : sectorCoords[0], - sectorCoords[2], - sectorCoords[3] - ]; - var binBorder = svg.draw( - new Smits.PhyloCanvas.Render.Path( - sector( - borderSectorCoords - ), - { attr: borderAttr } - ) - ); - binBorder[0].toBack(); - } - - var binObj = svg.draw( - new Smits.PhyloCanvas.Render.Path( - sector( - sectorCoords - ), - { attr: attr } - ) - ); - binObj[0].toBack(); - - beginY = 0; - isFirst = false; - } else { - if(!beginY){ beginY = node.y; } - if(node.chart[groupName] == "none"){ - beginY = 0; - } - } - isFirst = false; - } - return isInternal ? outerRadius : outerRadius + bufferInner + thickness; - }; - - function renderBarChart(outerRadius, groupName, params){ - var allValues = [], maxValue, - bufferInner = params && params.bufferInner ? parseFloat(params.bufferInner) : Smits.PhyloCanvas.Render.Parameters.barChartBufferInner, - height = params && params.height ? parseFloat(params.height) : (Smits.PhyloCanvas.Render.Parameters.barChartHeight ? Smits.PhyloCanvas.Render.Parameters.barChartHeight : 0), - width = params && params.width ? (parseFloat(params.width) < 1 ? scaleAngle * parseFloat(params.width) : parseFloat(params.width) ) : 0 | (Smits.PhyloCanvas.Render.Parameters.barChartWidth < 1 ? scaleAngle * Smits.PhyloCanvas.Render.Parameters.barChartWidth : Smits.PhyloCanvas.Render.Parameters.barChartWidth), - scaleHeight = 0; - - // Need to get max value - for(var i = 0; i < labelsHold.length; i++){ - allValues.push(labelsHold[i].chart[groupName]); - } - maxValue = Math.max.apply(null, allValues); - scaleHeight = Smits.Common.roundFloat(height / maxValue, 4); - - for(var i = 0; i < labelsHold.length; i++){ - var node = labelsHold[i]; - if(node.chart[groupName] > 0){ - svg.draw( - new Smits.PhyloCanvas.Render.Path( - sector( - outerRadius + bufferInner, - outerRadius + bufferInner + (scaleHeight * node.chart[groupName]), - node.y - (width/2), - node.y + (width/2) - ), - { attr: Smits.PhyloCanvas.Render.Style.getStyle(node.chart[groupName], 'barChart') } - ) - ); - } - } - - return outerRadius + bufferInner + height; - }; - - return function(sSvg, dataObject, bufferRadius){ - /* Privileged Methods */ - this.getCanvasSize = function(){ - return [canvasX, canvasY]; - }; - this.getRoot = function(){ - return dataObject.getRoot(); - }; - - /* CONSTRUCTOR */ - // Validation - if(dataObject.getValidate()){ - sSvg.draw({type: 'text', x: 0, y: sSvg.canvasSize[1] / 3, text: dataObject.getValidate() }); - return - } - - // Properties Setup - svg = sSvg; - var node = dataObject.getRoot(); - var mNewickLen = dataObject.getNewickLen(); - canvasX = svg.canvasSize[0]; // Full Canvas Width - canvasY = svg.canvasSize[1]; // Full Canvas Height - cx = canvasX / 2; // Set Center Position - cy = canvasY / 2; - canvasMinEdge = Math.min.apply(null, [canvasX,canvasY]); - - bufferRadius = (sParams.bufferRadius > 1) ? sParams.bufferRadius : Smits.Common.roundFloat(canvasMinEdge * sParams.bufferRadius, 4); - bufferAngle = sParams.bufferAngle; // controls split size in circle - innerCircleRadius = sParams.innerCircleRadius; - minHeightBetweenLeaves = sParams.minHeightBetweenLeaves; - initStartAngle = sParams.initStartAngle; // Angle at which the entire tree is rotated - - maxBranch = Math.round( (canvasMinEdge - bufferRadius - innerCircleRadius) / 2); // maximum branch length - scaleRadius = (maxBranch - innerCircleRadius) / mNewickLen; // scale multiplier to use - scaleAngle = Smits.Common.roundFloat( (360 - bufferAngle) / node.getCountAllChildren(), 4 ); - - // Draw Nodes and Labels - recursiveCalculateNodePositions(node, innerCircleRadius); - outerRadius = maxBranch + maxLabelLength + sParams.bufferOuterLabels; - - // Draw integrated secant highlights - if(Smits.PhyloCanvas.Render.Parameters.integratedBina... [truncated message content] |