jsPhyloSVG leverages the SVG rendering library, Raphael. This library to be included in your HTML (included in the source zip).
Here is an example of an HTML skeleton with the includes:
<html> <head> <script type="text/javascript" src="js/raphael/raphael-min.js" ></script> <script type="text/javascript" src="js/jsphylosvg-min.js"></script> </head> <body> <div id="svgCanvas"> </div> </body> </html>
Because you want to be sure that the dependencies have been loaded before you begin building the tree off it, you can use YUI's ability to load the tree once the document has finished loading.
Put this in the HTML <head>, and your tree will load once everything is registered:
window.onload = function(){
YUI().use('oop', 'json-stringify', 'io-base', 'event', 'event-delegate', function(Y){
phylocanvas = new Smits.PhyloCanvas(
dataObject,
'svgCanvas',
1000, 1000
);
});
};
Here is an example of code to render a simple tree from the Newick file format. Because we include the Newick inline, the tree will load without requiring any internet connectivity!
<html>
<head>
<script type="text/javascript" src="/js/raphael/raphael-min.js" ></script>
<script type="text/javascript" src="/js/jsphylosvg-min.js"></script>
<script type="text/javascript">
window.onload = function(){
var dataObject = { newick: '(((Espresso:2,(Milk Foam:2,Espresso Macchiato:5,((Steamed Milk:2,Cappuccino:2,(Whipped Cream:1,Chocolate Syrup:1,Cafe Mocha:3):5):5,Flat White:2):5):5):1,Coffee arabica:0.1,(Columbian:1.5,((Medium Roast:1,Viennese Roast:3,American Roast:5,Instant Coffee:9):2,Heavy Roast:0.1,French Roast:0.2,European Roast:1):5,Brazilian:0.1):1):1,Americano:10,Water:1);' };
phylocanvas = new Smits.PhyloCanvas(
dataObject,
'svgCanvas',
500, 500
);
};
</script>
</head>
<body>
<div id="svgCanvas"> </div>
</body>
</html>
(see source (YUI), source (jQuery), coffee.xml)
Suppose you have a bunch of trees from your project. You've already got a bunch of XML trees generated, and all you want to do is have a simple way to view them. Enter Ajax. You can now load up the trees asynchronously from your domain or a public database of trees.
There are a number of popular javascript libraries that might be used to perform these Ajax requests. We have included examples for using YUI and jQuery.
Here's an example of using Ajax for loading your trees:
var uri = "/path/to/my/tree.xml";
function complete(id, o, args) {
var data = o.responseXML; // Response data.
var dataObject = {
phyloxml: data, // If using phyloXML, need to tell us - or else we assume it is Newick
fileSource: true // Need to indicate that it is from a file for us to process it correctly
};
phylocanvas = new Smits.PhyloCanvas(
dataObject,
'svgCanvas',
800, 800,
'circular'
);
};
Y.on('io:complete', complete, Y);
var request = Y.io(uri);
Because jsPhyloSVG accepts numerous file formats and parses everything within the browser, you will need to define the format of the data you are providing and the data itself to the parser. The first parameter to be passed to instantiate a tree is an object containing this information.
An example of designating the source data being in Newick format:
phylocanvas = new Smits.PhyloCanvas(
{ newick: data },
'svgCanvas',
800, 800
);
You will notice that in other examples we create an object called "dataObject" and pass that as a first parameter. This is essentially the same thing, and is based on one's preference.
The simple Newick format is supported by jsPhyloSVG. Branch names, lengths and internal labels are all scraped and available for rendering.
You need to pass an object with the property "newick" and assign the Newick string as its value. An example:
phylocanvas = new Smits.PhyloCanvas(
{
newick: '(((Espresso:2,(Milk Foam:2,Espresso Macchiato:5,((Steamed Milk:2,Cappuccino:2,(Whipped Cream:1,Chocolate Syrup:1,Cafe Mocha:3):5):5,Flat White:2):5):5):1,Coffee arabica:0.1,(Columbian:1.5,((Medium Roast:1,Viennese Roast:3,American Roast:5,Instant Coffee:9):2,Heavy Roast:0.1,French Roast:0.2,European Roast:1):5,Brazilian:0.1):1):1,Americano:10,Water:1);'
},
'svgCanvas',
800, 800
);
Find more information about the phyloXML format here. It is likely that you will find it simplest to acquire the XML data by utilizing an AJAX request to assign the contents of a file to a variable. In the following example we assume you have assigned the XML to the variable "data".
Here is an example of code for rendering a tree from phyloXML:
phylocanvas = new Smits.PhyloCanvas(
{
phyloxml: data,
fileSource: true
},
'svgCanvas',
800, 800
);
(see Tree1 source, Tree2 source; both trees use the same NeXML file: nexml.xml)
Find more information about the NeXML format here. Here is an example of the simplest format to render a tree from NeXML. We assume you have assigned the XML to the variable "data" as we did for the phyloXML example above.
phylocanvas = new Smits.PhyloCanvas(
{
nexml: data,
fileSource: true
},
'svgCanvas',
800, 800
);
Because you can include numerous trees within one NeXML formatted file, we give you the option to designate which tree you would like to render with the property "tree". If you do not supply this property, it is assumed that you wish to render the first tree defined in the file.
Here is an example of rendering the third tree from NeXML:
phylocanvas = new Smits.PhyloCanvas(
{
nexml: data,
tree: 3,
fileSource: true
},
'svgCanvas',
800, 800
);
(see source, 3-coffee.xml)
Now that we have the tree loading, let's take a closer look at the tree XML. For more in-depth information, see phyloXML. If you already export your trees in this format, you're in luck - everything is already setup for you. Otherwise, take a look at how descriptions and hyperlink references to other pages are set.
The following is an example of how both the description and hyperlinks are set:
<clade>
<name>Espresso</name>
<branch_length>2.0</branch_length>
<annotation>
<desc>Base of many coffees</desc>
<uri>http://en.wikipedia.org/wiki/Espresso</uri>
</annotation>
</clade>
(see source, 4-coffee.xml)
You can style your chart from within your XML directly by overriding the defaults. In order to override any of the default settings (shown below), simply add a <parameters> element with the name of the parameter you wish to override. If the parameter is specific to a certain chart type, you must also specify this, as demonstrated in the example below.
To override the amount of space left outside of the inner circular tree (for charting):
<render> <parameters> <circular> <bufferRadius>0.4</bufferRadius> </circular> </parameters> </render>
Here are some of the defaults (found in render-parameters.js) that can be overridden:
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
},
/* 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 : [],
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
(see source, 2-coffee.xml)
You can also style from within your javascript itself. This may be desireable in order to maintain a consistent style across one's site. We encourage content providers to render trees the way the original authors' have marked-up their trees. That being said, there are scenarios in which it is aesthetically pleasing to maintain some degree of stylistic control on one's site. jsPhyloSVG plays nice, and allows one to override trees that are already styled within their XML specifications. All attributes that are currently assigned, and can be possibly set with Raphaeljs can be manipulated.
As an example, the colors of the lines of a tree and font size can be controlled within the javascript:
Smits.PhyloCanvas.Render.Style.line.stroke = 'rgb(0,0,255)'; // Color lines blue Smits.PhyloCanvas.Render.Style.text["font-size"] = 16; // Increase font size to 16pt
Similar to "Parameters" (described in 3.2), currently-set render styles are described in render-style.js. The following is an excerpt of possible options:
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'
}
}
(see source, 5-coffee.xml)
Charting is simple in jsPhyloSVG. Follow these simple steps:
<charts> <component type="binary" thickness="10" /> </charts>
<styles> <caffeine fill='#A93' stroke='#DDD' /> <other fill='#333' stroke='#DDD' /> </styles>
<clade> <name>Espresso</name> <branch_length>2.0</branch_length> <annotation> <desc>Base of many coffees</desc> <uri>http://en.wikipedia.org/wiki/Espresso</uri> </annotation> <chart> <component>caffeine</component> </chart> </clade>
(see source, 6-coffee.xml)
You may add as many tracks as desireable to the tree. Simply continue to add elements to <chart> within each node. In order to have it viewable, ensure that you also declare the chart in <render><charts>.
<charts> <component type="binary" thickness="10" /> <colored type="binary" disjointed="1" /> </charts>
Another consideration to make if using the circular chart style and adding a significant amount of charting, is that you may need to increase the default bufferRadius ratio as illustrated in the "Parameters" example.
(see source, 12-coffee.xml)
Internal charts appear within the inner circle of the tree instead of outside. Just add isInternal="true" to the chart definition in order for them to appear internally.
An example:
<charts> <acidity type="binary" thickness="10" isInternal="true" bufferInner="0" /> </charts>
(see source, 7-coffee.xml)
Bar charts follow the same structre that is observed in Binary Charts. You may use your own naming convention for elements, and then refer to the elements within the <chart> element. You may add styling characteristics the same way you would for the Binary Charts.
This example includes a Binary Chart (named component) and a Bar Chart (name content):
<charts> <component type="binary" thickness="10" /> <content type="bar" fill="#666" width="0.2" /> </charts>
(see source, 8-coffee.xml)
Highlighting the labels with different backgrounds is simplified with the "styles" approach. Simply add the property bgStyle to your <name> element, specifying your defined style.
This is an example of a styled label:
<name bgStyle="sweet">Cafe Mocha</name>
This is an example of defining the style:
<styles> <sweet fill="#d7e3bc" stroke="#d7e3bc" /> </styles>
(see source, 10-coffee.xml)
Adding a gradient to the background of labels on circular phylograms follows the established styles design pattern. In short, it can be implemented much like highlighting labels. Also note that gradients are only supported by SVG-based browsers.
This is an example of a styled label (no change from that above):
<name bgStyle="sweet">Cafe Mocha</name>
This is an example of defining the style:
<styles> <sweet type="radialGradient" > <stop offset="0%" style="stop-color:#d7e3bc; stop-opacity:0"/> <stop offset="93%" style="stop-color:#d7e3bc; stop-opacity:1"/> <stop offset="100%" style="stop-color:#BED192; stop-opacity:1"/> </sweet> </styles>
(see source, 11-coffee.xml)
Ribbons can be integrated within the label backgrounds of circular trees, and are formatted similar to how bar charts are implemented.
Integrated ribbons are first defined within <chart>:
<chart> <group type="integratedBinary" thickness="10" /> </chart>
You may style the integrated ribbons within <styles>:
<styles> <markgroup fill="#000" stroke="#000" opacity="0.7" /> </styles>
Again, similar to other charting components, the defined chart style is defined within the node:
<clade> <name bgStyle="highlight_bold">Espresso</name> <branch_length>2.0</branch_length> <chart> <group>markgroup</group> </chart> </clade>
(see source, 12-coffee.xml)
Integrated ribbons can also have labels assigned. In order to label the ribbons, add your label as a property to the definition of the ribbon (don't forget to also define a style for your labels using the "styles" method previously described.
Here is an example of both marked groups and the label styles being defined:
<styles> <markgroupA fill="#000" stroke="#000" opacity="0.7" label="PEETS" labelStyle="sectorHighlightText" /> <markgroupB fill="#000" stroke="#000" opacity="0.7" label="STARBUCKS" labelStyle="sectorHighlightText" /> <sectorHighlightText font-family="Verdana" font-size="10" font-weight="bold" fill="#FFFFFF" rotate="90" /> </styles>
(see source, 8-coffee.xml)
In browsers which support SVG, we render a SVG tree image. Since everything is done browser-side, we can provide the SVG markup to the client within javascript. We give you access to this with a simple method called getSvgSource().
An example of accessing the SVG source:
phylocanvas = new Smits.PhyloCanvas(
{ newick: data },
'svgCanvas',
800, 800
);
var svgSource = phylocanvas.getSvgSource(); // Put SVG source into the svgSource variable
In the posted example, we put this SVG source into a link, and allow the user to download the source.