Idea

When Chrome dropped the NPAPI support in 2015, integration of Java applets with Chrome browser becomes a hurdle (only as a web start software).
This results in lesser integration of a widely used Archaeopteryx Java applet for around 70% of the users.
This project was about to bring the similar functionalities using the latest web technologies.
Using D3.js to creating a phylogram is quite simple as we saw in d3.phylogram.js.
But we found currently existing web-applications for visualization of phylogenetic trees not up to the task.
So we've created phyD3.

Features list

Supported formats

Extended phyloXML

The current phyloXML XSD permits inserting other (non-standard) tags, which are used here to describe taxonomy colors, domain colors as well as node label and node graphs.
  1. Taxonomy information

    You can specify the taxonomy name, color and URL in the <taxonomies> section of extended phyloXML.
    These information will be displayed on the tree, in node infobox as well as used for taxonomy colorization.
    The taxonomy codes must match ones used in phylogeny. Use HEX values for colors (0xRRGGBB). Use full URL for links (starting with http://).
    See the code below and also working example.
    <phyloxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.phyloxml.org"
              xsi:schemaLocation="http://www.phyloxml.org http://www.phyloxml.org/1.10/phyloxml.xsd">
        <phylogeny rooted="true">
            <clade>
                <taxonomy>
                    <code>mdo</code>
                </taxonomy>
                ...
            </clade>
            ...
        </phylogeny>
        <taxonomies>
          <taxonomy code="mdo">
             <color>0x40FF00</color>
             <name>Malus domestica</name>
             <url>https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=3750</url>
          </taxonomy>
          ...
        </taxonomies>
        ...
    </phyloxml>
  2. Domain information

    You can specify domain description, color and URL in the <domains> section of extended phyloXML.
    These information will be displayed on the tree, in node infobox as well as used for domain colorization.
    The domain codes must match ones used in phylogeny. Use HEX values for colors (0xRRGGBB). Use full URL for links (starting with http://).
    See the code below and also working example.
    <phyloxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.phyloxml.org"
              xsi:schemaLocation="http://www.phyloxml.org http://www.phyloxml.org/1.10/phyloxml.xsd">
        <phylogeny rooted="true">
            <clade>
                <sequence>
                    <domain_architecture length="402">
                        <domain confidence="3.7E-6" from="135" to="212">IPR011992</domain>
                        <domain confidence="8.879" from="181" to="216">IPR002048</domain>
                        ...
                    </domain_architecture>
                </sequence>
                ...
            </clade>
            ...
        </phylogeny>
        <domains>
            <domain name="IPR011992">
                <color>0x12C6D7</color>
                <description>Pyruvate dehydrogenase</description>
                <url>http://www.example.com</url>
            </domain>
            <domain name="IPR002048">
                <color>0xFAF38C</color>
                <description>Protein kinase</description>
                <url>http://www.example.com</url>
            </domain>
            ...
        </domains>
        ...
    </phyloxml>
  3. Node labels

    It is possible to display on the tree additional node labels. Those labels can be created from existing node properties or other tags.
    There are two kinds of labels: text labels and color labels.
    To specify which properties to show use <labels> section in extended phyloXML. Type can be either text or color. Data tag and ref must match the intended clade property to be displayed. Use HEX values for colors (0xRRGGBB). Only text labels can be displayed for inner nodes of the tree.
    See the code below and also working example.
    <phyloxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.phyloxml.org"
              xsi:schemaLocation="http://www.phyloxml.org http://www.phyloxml.org/1.10/phyloxml.xsd">
        <phylogeny rooted="true">
            <clade>
                <events>
                    <duplications>1</duplications>
                </events>
                <property applies_to="clade" datatype="xksd:string" ref="Resistance score">0xA3B523</property>
                ...
            </clade>
            ...
        </phylogeny>
        <labels>
          <label type="text">
             <name show="0">Duplications</name>
             <data tag="events" ref="duplications"></data>
          </label>
          <label type="color">
             <name show="1">Resistance</name>
             <data tag="property" ref="Resistance score"></data>
          </label>
          ...
        </labels>
        ...
    </phyloxml>
  4. Node graphs

    You can also include the graphs specifications and the graph data, that should be displayed next to the node (clade).
    On the internal nodes pie or binary graphs can be drawn. For leaf nodes you can choose between 5 graph types: multibar (normal/stacked), pie, binary, heatmap, boxplot. Each referenced clade needs to have an id tag defined in the phylogeny.
    For complete graph specification you need three things:
    1. name - graph name, that will be displayed in detailed node information popup
    2. legend - for each value series of your data, you need to specify the legend field; for each field you need to put field name (which will be displayed to the user in legend and infobox popup), color that will be used to draw this series (for all graph types besides heatmap) and for binary graph also a symbol shape (one of circle); additionally for heatmap you need to specify which gradient spec to use (name & classes following the ColorBrewer2)
    3. data - for each clade id you wish to display the graph for, you need to include data values, ordered in series defined in legend; you can also use existing tags or properties from phylogeny tree, referencing them by tag and ref attributes of data tag; to turn single values into pie charts use min and max tags inside data tag.
    See the code below and also working examples of leaf node graphs or inner node graphs.
    <phyloxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.phyloxml.org"
              xsi:schemaLocation="http://www.phyloxml.org http://www.phyloxml.org/1.10/phyloxml.xsd">
        <phylogeny rooted="true">
            <clade>
                <id>10</id>
                <events>
                    <duplications>1</duplications>
                </events>
                <clade>
                    <id>11</id>
                    <property applies_to="clade" datatype="xksd:double" ref="duplication consistency score:">0.6923</property>
                    ...
                </clade>
                <clade>
                    <id>12</id>
                    <property applies_to="clade" datatype="xksd:double" ref="duplication consistency score:">0.6923</property>
                    ...
                </clade>
                ...
            </clade>
            <clade>
                <id>13</id>
                <events>
                    <duplications>1</duplications>
                </events>
                ...
            </clade>
            ...
        </phylogeny>
        <graphs>
            <graph type="multibar">
                <name>Multibar test graph</name>
                <legend show="0">
                    <field>
                        <name>bar1</name>
                        <color>0x8986BF</color>
                    </field>
                    <field>
                        <name>bar2</name>
                        <color>0x9D4FB0</color>
                    </field>
                    <field>
                        <name>bar3</name>
                        <color>0xF7BE81</color>
                    </field>
                </legend>
                <data>
                    <values for="10">
                        <value>12</value>
                        <value>61</value>
                        <value>34</value>
                    </values>
                    <values for="11">
                        <value>57</value>
                        <value>37</value>
                        <value>8</value>
                    </values>
                    <values for="12">
                        <value>23</value>
                        <value>27</value>
                        <value>14</value>
                    </values>
                    <values for="13">
                        <value>23</value>
                        <value>27</value>
                        <value>14</value>
                    </values>
                    ...
                </data>
            </graph>
            <graph type="multibar">
                <name>Stacked multibar test graph</name>
                <legend show="1" stacked="1">
                    <field>
                        <name>barA</name>
                        <color>0x8986BF</color>
                    </field>
                    <field>
                        <name>barB</name>
                        <color>0x9D4FB0</color>
                    </field>
                    <field>
                        <name>barC</name>
                        <color>0xF7BE81</color>
                    </field>
                </legend>
                <data>
                    <values for="10">
                        <value>21</value>
                        <value>16</value>
                        <value>43</value>
                    </values>
                    <values for="11">
                        <value>75</value>
                        <value>73</value>
                        <value>8</value>
                    </values>
                    <values for="12">
                        <value>32</value>
                        <value>72</value>
                        <value>41</value>
                    </values>
                    <values for="13">
                        <value>32</value>
                        <value>72</value>
                        <value>41</value>
                    </values>
                    ...
                </data>
            </graph>
            <graph type="boxplot">
                <name>Boxplot test graph</name>
                <legend show="1">
                    <field>
                        <color>0x8986BF</color>
                    </field>
                    <field>
                        <color>0x9D4FB0</color>
                    </field>
                </legend>
                <data>
                    <values for="10">
                        <value>12</value>
                        <value>21</value>
                        <value>34</value>
                        <value>49</value>
                        <value>58</value>
                    </values>
                    <values for="11">
                        <value>17</value>
                        <value>27</value>
                        <value>38</value>
                        <value>46</value>
                        <value>57</value>
                    </values>
                    <values for="12">
                        <value>13</value>
                        <value>27</value>
                        <value>34</value>
                        <value>43</value>
                        <value>56</value>
                    </values>
                    ...
                </data>
            </graph>
            <graph type="binary">
                <name>Binary test graph1</name>
                <legend show="1">
                    <field>
                        <name>binary1</name>
                        <color>0xf03b20</color>
                        <shape>circle</shape>
                    </field>
                    <field>
                        <name>binary2</name>
                        <color>0x2c7fb8</color>
                        <shape>cross</shape>
                    </field>
                    <field>
                        <name>binary3</name>
                        <color>0x37BA49</color>
                        <shape>diamond</shape>
                    </field>
                </legend>
                <data>
                    <values for="10">
                        <value>1</value>
                        <value>1</value>
                        <value>0</value>
                    </values>
                    ...
                </data>
            </graph>
            <graph type="heatmap">
                <name>Heatmap test graph with fields</name>
                <legend show="0">
                    <field>
                        <name>heat1</name>
                    </field>
                    <field>
                        <name>heat2</name>
                    </field>
                    <field>
                        <name>heat3</name>
                    </field>
                    <field>
                        <name>heat4</name>
                    </field>
                    <field>
                        <name>heat5</name>
                    </field>
                    <field>
                        <name>heat6</name>
                    </field>
                    <field>
                        <name>heat7</name>
                    </field>
                    <field>
                        <name>heat8</name>
                    </field>
                    <field>
                        <name>heat9</name>
                    </field>
                    <gradient>
                        <name>YlOrRd</name>
                        <classes>9</classes>
                    </gradient>
                </legend>
                <data>
                    <values for="10">
                        <value>64</value>
                        <value>38</value>
                        <value>84</value>
                        <value>9</value>
                        <value>74</value>
                        <value>33</value>
                        <value>82</value>
                        <value>37</value>
                        <value>12</value>
                    </values>
                    ...
                </data>
            </graph>
            <graph type="pie">
                <name>Duplication</name>
                <legend>
                    <field>
                        <name>Consistency score</name>
                        <color>0xFF0000</color>
                    </field>
                </legend>
                <data tag="property" ref="duplication consistency score:">
                    <min>0</min>
                    <max>1</max>
                </data>
            </graph>
            <graph type="binary">
                <name>Speciations</name>
                <legend>
                    <field>
                        <name>Speciations</name>
                        <color>0x00FF00</color>
                        <shape>circle</shape>
                    </field>
                </legend>
                <data tag="events" ref="duplications">
                </data>
            </graph>
            ...
        </graphs>
    </phyloxml>

Usage

  1. Running the example with Node.js

    Download the PhyD3 source code from: https://github.com/vibbits/phyd3/.
    In the PhyD3 folder issue the following commands:
    # npm install
    ...
    # node phyd3.js
    Listening on 127.0.0.1:8080...
    Open your browser and point to your local PhyD3 copy under http://127.0.0.1:8080/.
  2. Embedding the widget

    In the dist/ folder you will find minified js & css files. The required jQuery, Bootstrap and D3 libraries are not included. You will need to link all the libraries and phyD3 on your website.
    There are two parsers of tree formats available: Newick phyd3.newick.parse() and phyloXML phyd3.phyloxml.parse(). Once you have parsed your tree you can use phyd3.phylogram.build(id, tree, opts) function to display the PhyD3 viewer.
    See the example below.
    <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="https://d3js.org/d3.v3.min.js"></script>
        <link rel="stylesheet" href="css/phyd3.min.css" />
        <script src="js/phyd3.min.js"></script>
        <script>
            function load() {
                d3.xml("sample.xml", function(xml) {
                    var tree = phyd3.phyloxml.parse(xml);
                    phyd3.phylogram.build("#phyd3", tree, {});
                });
            };
        </script>
        </head>
        <body onload="load()">
            <div id="phyd3"></div>
        </body>
    </html>
    In dist/ folder there are also index.html and sample.xml files to help you get started.
  3. Widget configuration

    The third parameter of the build function is a options object. It helps you customise the viewer look and behaviour. Available options are listed below.
    Property name Default value Description
    backgroundColor white color used to paint SVG background and node infobox popup background
    domainLevel 1 only domains which confidence is lower than specified value will be shown on domain architecture graph
    domainLevelStep 10 multiplied factor in the domain level when changing the threshold
    domainWidth 100 width of the domain architecture graph
    domainWidthStep 100 added factor in the domain architecture graph when zooming
    dynamicHide false when true, hides all the overlapping node names, graphs and domain architecture and support lines
    pinnedNodes [] array of node IDs that should be always visible, independently of dynamic hide setting
    foregroundColor black color used to pain fonts, lines, outlines & borders
    graphWidth 20 width of the multibar graph
    graphWidthStep 10 added factor in the multibar graph width when zooming
    height 800 height of the viewer SVG area
    invertColors false when true, uses the foreground color as background and vice versa
    lineupNodes true when true, nodes are lined up to the furthest node and support lines are drawn
    margin 20 margin in the viewer SVG area
    nanColor white Color for undefined values in heatmaps
    nodeHeight 6 height of the node (node size, text font-size, radius of pie & binary graphs, height of multibar & domain graphs)
    nodeHeightStep 1 added factor in the node height when changing the node size
    outline 0.3 font stroke outline for displaying node names
    popupAction renderPopup callback function to handle click event on a node, by default displays the node infobox
    popupWidth 500 width of the node infobox popup
    scaleStep 0.3 multiplied factor in the tree height and width when zooming
    scaleX 1 SVG scale on X axis
    scaleY 1 SVG scale on Y axis
    showDomains true when true, shows the domain architecture graph
    showDomainNames false when true, shows the domain names on the domain architecture graph
    showDomainColors true when true, sets the colors of the domains on the domain architecture graph accordingly to xml
    showFullTaxonomy false when true, shows the full taxonomy names instead of taxonomy codes on the tree
    showGraphs true when true, shows the graphs next to nodes
    showGraphLegend true when true, shows the legend on top of the graphs
    showLabels true when true, shows the labels next to nodes
    showLengthValues false when true, shows the branch length values next to nodes
    maxDecimalsLengthValues 2 number of decimals the branch length values will be rounded to
    branchLengthColor red font color when displaying branch length values
    showSupportValues false when true, shows the clade support values next to nodes
    maxDecimalsSupportValues 0 number of decimals the support values will be rounded to
    supportValuesColor blue font color when displaying clade support values
    showNodeNames true when true, shows the node names next to nodes
    showNodesType only leaf shows the names and taxonomy only for specified subset of nodes, available options are: 'all', 'only leaf', 'only inner'
    showPhylogram false when true, shows phylogram instead of dendrogram
    showTaxonomy true when true, shows the taxonomy codes next to nodes
    showTaxonomyColors true when true, sets the colors of node names and taxonomy names to the taxonomy color specified in xml
    textLength 100 width in pixels reserved for node text
    translateX 0 initial SVG translation on X axis
    translateY 0 initial SVG translation on Y axis
    treeWidth auto override default tree width calculations; useful with large number of node graphs
  4. Widget controls

    You can allow the users to control the display of the tree by providing them with form controls with the appropriate id. The full list of controls can be found below.
    Control ID Type Description
    graphWidth text displays the current multibar graph width
    graphWidthLower button decreases the multibar graph width by graphWidthStep
    graphWidthHigher button increases the multibar graph width by graphWidthStep
    domainWidth text displays the current domain architecture graph width
    domainWidthLower button decreases the domain architecture graph width by domainWidthStep
    domainWidthHigher button increases the domain architecture graph width by domainWidthStep
    nodeHeight text displays the current node height
    nodeHeightLower button decreases the node height by nodeHeightStep
    nodeHeightHigher button increases the node height by nodeHeightStep
    dynamicHide checkbox toggles the dynamic hide mechanism on and off
    invertColors checkbox toggles the inversion of colors on and off
    lineupNodes checkbox toggles the line up of the nodes on and off
    phylogram checkbox toggles between dendrogram and phylogram tree
    lengthValues checkbox toggles the display of branch length values on and off
    maxDecimalsLengthValues input specifies the number of decimals the length values will be rounded to
    supportValues checkbox toggles the display of clade support vlaues on and off
    maxDecimalsSupportValues input specifies the number of decimals the length values will be rounded to
    nodeNames checkbox toggles the display of node names on and off
    taxonomy checkbox toggles the display of taxonomy names on and off
    taxonomyColors checkbox toggles the colorization of nodes according to their taxonomy on and off
    domains checkbox toggles the display of the domain architecture graph on and off
    domainNames checkbox toggles the display of the domain names on and off
    domainColors checkbox toggles the colors of the domains on and off
    graphs checkbox toggles the display of graphs on and off
    graphLegend checkbox toggles the display of graph legend on and off
    nodesType select changes the displayed node types, possible options are 'all', 'only leaf', 'only inner'
    zoominY button zooms in the tree on Y axis
    zoomoutY button zooms out the tree on Y axix
    zoominX button zooms in the tree on X axis
    zoomoutX button zooms out the tree on X axis
    resetZoom button resets the zoom to the defaul level on both X and Y axes
    linkSVG button downloads the current tree as SVG file
    linkPNG button downloads the current tree as PNG file

License

phyD3, phylogenetic tree viewer based on D3.js
Copyright (c) BITS VIB 2016

This program 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 any later version.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
This program 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.

Full license text can be found here

You can obtain the source code from:
https://github.com/vibbits/phyd3/

Contact us

For any questions, remarks, issues, etc., send an email to bits@vib.be