fedarko / MetagenomeScope

Hierarchical scaffold/assembly graph web visualization tool. As of August 9, 2017, the official repository for this has moved to MarBL! Use that repository instead :)
http://github.com/marbl/MetagenomeScope
GNU General Public License v3.0
0 stars 0 forks source link

Directly draw edges to/from child nodes via B-Spline Extension #150

Closed fedarko closed 7 years ago

fedarko commented 7 years ago

Currently, during backfilling (#80), edges are drawn to/from the node groups themselves rather than the individual child node(s) in particular. The resulting control points are then used in Cytoscape.js for the actual edges to child nodes, resulting in some inaccuracy/odd-looking edges.

For edges to child nodes: I'm thinking we can rectify this problem by adding 3 more control points (creating another "bezier curve" on the B-spline) -- one starting at the last control point of the previous B-spline, another one halfway to the child node target, and another one at the child node target. We could apply the same logic for edges from child nodes, and we could apply both approaches for edges to/from child nodes (e.g. an edge that starts and originates in two different node groups).

fedarko commented 7 years ago

So I sorta implemented some code that does this for at least interior source nodes, and it seemed to produce invalid B-splines (Cytoscape.js won't render the edges as beziers, at least). I'm guessing this is because my code just linearly extends control points, which isn't really a valid thing to do?

Here's my code right now (to find where it belongs in collate.py, search for the first line given here (if source_id != e[0]) --

        if source_id != e[0]:
            # TODO
            # Add control points from source to the first current control pt.
            # The first new control point is at the "tailport" of the source
            tailx = source.xdot_x + (source.xdot_width / 2)
            taily = source.xdot_y + (source.xdot_height / 2)
            new_points = "%g %g" % (tailx, taily)
            dx3 = (coord_list[0] - tailx) / 3.0
            dy3 = (coord_list[1] - taily) / 3.0
            # Add two more control points, one 1/3 of the distance
            # and another 2/3 of the distance
            for i in range(1, 3):
                new_x = tailx + (i * dx3)
                new_y = taily + (i * dy3)
                new_points += " %g %g" % (new_x, new_y)
            new_points += " "
            # Update the current edge's attributes accordingly
            curr_edge.xdot_ctrl_pt_str= new_points + curr_edge.xdot_ctrl_pt_str
            new_point_coord_list = [float(c) for c in new_points.split()]
            coord_list = new_point_coord_list + coord_list
            curr_edge.xdot_ctrl_pt_count += 3
fedarko commented 7 years ago

A possible workaround: see this paper.

Update: actually, after doing some digging, this paper (by Shetty and White) seems to present a simpler solution? Update again -- never mind, that auto-generates the control points to extend to via reflection. Looks like the approach of the first-mentioned paper here is what we should go with.

fedarko commented 7 years ago

WAIT never mind, so it turns out my code used inches (via the .xdot_height variable) where points should have been used. Fixing the values makes things alright, and produces ostensibly valid B-splines or at least control points that form acceptable cubic Beziers.

fedarko commented 7 years ago

And it's actually valid + a lot easier than the method shown in the code above to just change the initial control point to just be the tail/head position of the interior node in question. At least from testing this out on the salmonella and simplified Shakya assembly graphs, this produces nicer, more natural-looking edges.

fedarko commented 7 years ago

TODOs left: clean up code, apply this approach to target, test, commit changes then close this

fedarko commented 7 years ago

This works with targets now. It looks a lot better -- screenshots of before/after (for component 2 of the simplified Shakya assembly graph):

before

after