The parser reads in the newick strings, and it is found in org.phylowidget.tree.TreeIO.java
public static RootedTree parseNewickString(RootedTree tree, String s)
parses through all the notation, handles determining the different levels of the tree and the parent-child relationships.
When it's created a string of text it considers the label, it calls:
PhyloNode curNode = newNode(tree, curLabel, nhx, poorMans);
static PhyloNode newNode(RootedTree t, String s, boolean useNhx, boolean poorMan)
...deals with NHX annotation stuff, then...
s = parseNexusLabel(s);
(removes single quotes and replaces underscores with spaces)
t.addVertex(v);
t.setLabel(v, s);
(self explanatory)
So that was pretty exciting, because it allowed me to understand how labels are created and stored in tree nodes, which will be useful since I plan to be able to intercept those labels before render time and change them. In practice, the idea is to display common names in place of scientific names for the organisms in the tree.
Then I went on to find the renderer. The class LabelRender is found inside NodeRenderer.java. In the method render(), we have
canvas.text(tree.getLabel(n), offX - curTextSize / 3 - s, offY - s - curTextSize / 3);
n is a PhyloNode and tree is a RootedTree so getLabel(vertex) is in RootedTree.java
that calls
vertex.getLabel() which is in PhyloNode.java (extends CachedVertex which extends DefaultVertex)
It is at this point that I intercept the label and change the return value so that the rendered label name is different than the stored one. I created a wrapper class for HashMap called NameLookup, which for testing purposes just stores mappings from each capital letter of the alphabet to the corresponding number, from 1 to 26.
I created a NameLookup object called map in
PhyloNode.java and updated the getLabel() method to look up the value in the map and return the resulting string (in this case a number). Any label that is mapped to null in the NameLookup map is changed to the string "Hi Val". The replacement label string gets passed along all the way back to the render.
For the tree:((A,B),(C,D),(E,F,G,H,'*'),I,J); we end up with the following image

No comments:
Post a Comment