Giter VIP home page Giter VIP logo

Comments (10)

spond avatar spond commented on August 17, 2024 2

Dear @pschwien82,

Not the prettiest solution, but should get your started: http://bl.ocks.org/spond/707878838762cb57d892a5d8e774d4e0

The idea is to use the callback invoked when each node is drawn (node_styler) and add the desired graphical elements (in the example : 3 colored boxes) to the SVG element that is the node.

@stephenshank : if you look at the example, it exposes some of the limitations of the node styler callback, which we should discuss how to remedy. For example, there should be no need to manually handle rotations and shifts for radial layouts, and there needs to be a mechanism to request layout space for node labels to accommodate arbitrary elements.

Best,
Sergei

from phylotree.js.

carlotta-93 avatar carlotta-93 commented on August 17, 2024 1

I am working on this topic as well as part of a project for the university and I am interested in future updates.

what I managed to do so far is something like this:
linear_data
radial_data

I have three different categories of data and this is where I got so far.
I didn't use the node_styler but just append new svg elements at the end of the labels. I see now that the solution presented here might solve me a lot of effort actually.
So thank you very much :) and looking forward to new updates or examples

from phylotree.js.

pschwientek avatar pschwientek commented on August 17, 2024

Thank you Sergei,
this was a super fast response, I appreciate it.
We will try the code sample out in the next few days!

Best,
Patrick

from phylotree.js.

carlotta-93 avatar carlotta-93 commented on August 17, 2024

Hello again,
I used the code example for my project but I have some issues I cannot manage to solve.
My issue is on the resizing of the svg. More precisely, when I add "longer shapes" (so instead of the three squares presented in the code I want to bind "barplots", each bar on each node, showing a quantitative type of data) the issue I have is that on the linear layout the svg gets resized too small to show the whole "length" of the shapes.
I tried playing a bit with your example and maybe I didn't really understand how the
'left-right-spacing' and 'top-bottom-spacing' options work.
This is the code I am using:
`<script>
var example_tree = "(((glp1r_human:0.03295,g1sgd4_rabit:0.01369):0.30976,glr_human:0.27221):0.47235,(crfr1_human:0.64018,(grm1_human:0.10097,grm5_human:0.17333):3.05238):0.10081,calcr_human:0.71265);";
// tree from Yokoyama et al http://www.ncbi.nlm.nih.gov/pubmed/18768804
var tree = d3.layout.phylotree()
// create a tree layout object
.svg(d3.select("#tree_display")).align_tips(true).radial(true);
// render to this SVG element
var attribute_to_color = d3.scale.category10();
var standard_label = tree.branch_name();

tree.branch_name(function (node) {
    return standard_label(node) + "             ";
});
tree(d3.layout.newick_parser(example_tree));
tree.size([400, 400]);
var tree_attributes = {};

/* the following loop just populates an object with key : value pairs like
    leaf_name -> [a,b,c], where a,b,c are random numbers in {0,1,2,3,4}
*/

var maximum_length = 0;

tree.traverse_and_compute (function (node) {
    if (d3.layout.phylotree.is_leafnode (node)) {
        tree_attributes[node.name] = [0,0,0].map (function () {return Math.floor(Math.random() * 5);});
        maximum_length = maximum_length < node.name.length ? node.name.length : maximum_length;
    }
});


tree.style_nodes(function (element, node_data) {
    if (node_data.name in tree_attributes) {   // see if the node has attributes

        var node_label = element.select("text");
        var font_size  = parseFloat(node_label.style("font-size"));

        var annotation = element.selectAll("rect").data(tree_attributes[node_data.name]);
        annotation.enter().append("rect");
        annotation.attr ("width", font_size)
            .attr ("height", font_size)
            .attr ("y", -font_size/2).style ("fill", function(d, i) {
            return attribute_to_color(d);
        });

        var move_past_label =  maximum_length * 0.75 * font_size;

        if (tree.radial ()) {
            var shifter = tree.shift_tip(node_data)[0];
            annotation.attr("transform", "rotate (" + node_data.text_angle + ")")
                .attr ("x", function (d, i) { return   shifter > 0 ? shifter + font_size * i + move_past_label : shifter - font_size * (i+1) - move_past_label;})
        } else {
            var x_shift = tree.shift_tip (node_data)[0] + move_past_label;
            annotation.attr ("transform", null).attr ("x", function (d, i) { return  x_shift + font_size * i;});
        }

    }
});

tree.options({
    'show-scale': true
    'left-right-spacing': "fit-to-size",
    // fit to given size top-to-bottom
    'top-bottom-spacing': "fit-to-size"
    // fit to given size left-to-right
    //'selectable': false,
    // make nodes and branches not selectable
    //'collapsible': false,
    // turn off the menu on internal nodes
    //'transitions': false
    // turn off d3 animations
})

$("#layout").on ("click", function (e) {
    tree.radial ($(this).prop ("checked")).placenodes().update ();
});

// parse the Newick into a d3 hierarchy object with additional fields
tree.layout();`

The first output looks like this:
lay1
which is how the tree is supposed to look like.
When i switch view it looks like this:
lay2
Which is good. But when I switch again to radial, the tree changes and looks like this:
lay3
So, this is the issue I don't understand. Could you explain why this happens??

This project I am working on is part of an exam that I'll have in late June and if the output of the project will be functional then it might end up being used as an official tool on this website:
http://gpcrdb.org/
Therefore I am highly interested in solving the issue hereby presented.

Thanks for your help.

from phylotree.js.

spond avatar spond commented on August 17, 2024

Dear @carlotta-93,

I think both radial trees are the same, just that the second one uses an "annular" display near the center to space things out a bit differently. I will make a note to track down why the layout changes between the two iterations (it should be stable), but the tree is not wrong in either case.

I'll update this thread when I have a solution for stable rendering.

Best,
Sergei

from phylotree.js.

carlotta-93 avatar carlotta-93 commented on August 17, 2024

Hi @spond,
Thanks for your reply. I understand that now but the weird part is that the "annular" is not added when "fixed-size" is chosen instead of "fit-to-size".

For stable rendering you mean when "longer" shapes are added ? Shall I add some pictured to make the problem more clear ?

Thank you very much for your help.

from phylotree.js.

spond avatar spond commented on August 17, 2024

Dear @carlotta-93,

Yes, more pictures would be helpful. By stable rendering I mean that when you switch between radial and linear views, you should get the same renderings for each mode regardless of how many switches occur.

Best,
Sergei

from phylotree.js.

carlotta-93 avatar carlotta-93 commented on August 17, 2024

All right,
Firstly, I am using these options:
tree.options({ 'show-scale': true //'left-right-spacing': "fixed-step", // fit to given size top-to-bottom //'top-bottom-spacing': "fixed-step" // fit to given size left-to-right //'selectable': false, // make nodes and branches not selectable //'collapsible': false, // turn off the menu on internal nodes //'transitions': false // turn off d3 animations })
so the spacings are default to "fixed-step". And the tree is built with the same code as the example for the metadata. (there is option for width neither in the HTML nor the .js)
The problem with the "longer shapes" I have is the following
First layout:
lay1
Here the size of the svg is "arbitrary chosen" and everything is fine.
When I add "barplots" to show quantitative data this is what happens in radial layout:
lay2
So, some of the shapes are cut out from the svg (which mantains the same size)
If I switch to linear layout, this is what happens:
lay3
And the size of the svg is "resized" but it is too small in width.
If I change the size from the "inspection" board I get to see my barplots entirely:
lay4

What I would like to understand is why this happens and if there is a way to solve it.
I tries using "fit-to-size" with tree.size([800, 800]) exactly the same happens.

Thanks for your time

from phylotree.js.

spond avatar spond commented on August 17, 2024

Dear @carlotta-93,

It looks like you are toggling bar plots on and off. In order to understand what phylotree is doing at that moment, can you provide the code for your event handler for when the annotations are added?

Best,
Sergei

from phylotree.js.

carlotta-93 avatar carlotta-93 commented on August 17, 2024

Hi @spond,
Here is the code:
` function draw_quantitative_data(select_data, data_type){

tree.align_tips(true);

var maximum_length = 0;

var receptor_coverage = {}; // create object of GPCR_classes to bind to element

tree.get_nodes().forEach(function (node) {
    if (d3.layout.phylotree.is_leafnode(node)) {
        select_data.forEach(function (receptor) {
            if(node.name === receptor.name){
                receptor_coverage[node.name] = [0].map(function () {
                    return receptor.coverage
                });
            }
        });
        maximum_length = maximum_length < node.name.length ? node.name.length : maximum_length;
    }
});

var coverage_tooltip = d3.select("body").append("div")
    .attr("class", "coverage_tooltip")
    .style("opacity", 0);

var max_rect_h = 30;

var yScale_radial = d3.scale.linear() // scale to draw the quantities relative to the max_rect_h
    .domain([1, 0]) // change to max and min values from the type
    .range([max_rect_h, 0]);

tree.style_nodes(function (element, node_data) {

    if (node_data.name in receptor_coverage) {   // see if the node has attributes
        var node_label = element.select("text");
        var font_size  = parseFloat(node_label.style("font-size"));

        var annotation = element.selectAll("rect").data(receptor_coverage[node_data.name]);

        annotation.enter().append("rect").attr("class", "receptor_coverage");
        annotation
            .attr ("height", font_size)
            .attr("width", function (d) {
                return yScale_radial(d)
            })
            .attr ("y", -font_size/2)
            .style("fill", "#DBB1CD")

            .on("mouseover", function(d) { // add tooltip
                coverage_tooltip.transition()
                    .style("opacity", .9);
                coverage_tooltip.html(function(){
                    return ("Coverage: " + d)
                })
                    .style("left", (d3.event.pageX) + "px")
                    .style("top", (d3.event.pageY - 28) + "px");
            })

            .on("mouseout", function() {
                coverage_tooltip.transition().duration(100)
                    .style("opacity", 0);
            });

        var move_past_label = maximum_length * 0.65 * font_size;

        if (tree.radial ()) {
            var shifter = tree.shift_tip(node_data)[0];
            annotation.attr("transform", "rotate (" + node_data.text_angle + ")")
                .attr ("x", function (d, i) { return   shifter > 0 ? shifter + font_size * i + move_past_label : shifter - font_size * (i+1) - move_past_label;})
        } else {
            var x_shift = tree.shift_tip (node_data)[0] + move_past_label;
            annotation.attr ("transform", null).attr ("x", function (d, i) { return  x_shift + font_size * i;});
        }

    }

});

tree.layout();`

The select_data arguments is an array of dictionaries as follows:
{ "name":"glr_human", "GPCR_class":"C (Glutamate)", "selectivity":["Gi/Go family", "Gq/G11 family", "Gs family"], "ligand_type":"Protein receptors", "coverage":0.6, "receptor_page":"http://gpcrdb.org/protein/glr_human/" },
Where coverage is a random number between 0 and 1

from phylotree.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.