Giter Site home page Giter Site logo

d3trees.jl's Introduction

D3Trees

Build Status Code Coverage

Flexible interactive visualization for large trees using D3.js.

Tree

Installation

Pkg.add("D3Trees")

Basic Usage

There are two ways to create a D3Tree object described below:

1) With AbstractTrees

Any object that implements the interface from AbstractTrees can be given to the constructor: D3Tree(object).

See the docstring (julia> ?D3Tree) for information on how to control the style.

2) Without AbstractTrees

The structure of a D3Tree is specified with lists of children for each node stored in a Vector of Int Vectors. For example,

D3Tree([[2,3], [], [4], []])

creates a tree with four nodes. Nodes 2 and 3 are children of node 1, and node 4 is the only child of node 3. Nodes 2 and 4 are childless.

Displaying Trees

In an IJulia notebook, the tree will automatically be displayed using D3.js. To get an interactive display in a chrome browser from the repl or a script, you can use the inchrome function. The blink function can also open it in a standalone window using the Blink.jl package.

children = [[2,3], [4,5], [6,7], [8,9], [1], [], [], [], []]
t = D3Tree(children)

inchrome(t)
inbrowser(t, "firefox")

By clicking on the nodes, you can expand it to look like the image at the top of the page.

Style Control

Optional arguments control other aspects of the style (use julia> ?D3Tree for a complete list), for example,

children = [[2,3], [], [4], []]
text = ["one\n(second line)", "2", "III", "four"]
style = ["", "fill:red", "r:14px", "opacity:0.7"]
link_style = ["", "stroke:blue", "", "stroke-width:10px"]
tooltip = ["pops", "up", "on", "hover"]
t = D3Tree(children,
           text=text,
           style=style,
           tooltip=tooltip,
           link_style=link_style,
           title="My Tree",
           init_expand=10)

inchrome(t)

will yield

Expanded tree with style

or, see examples/hello.ipynb

Lazy loading trees

Deep trees can be expanded on demand from the visualization by clicking on unexpanded nodes. For example, see examples/LazyLoadDeepTrees.ipynb

The lazy loading can be controlled through two main keyword arguments:

  • lazy_expand_after_depth which controls the initial expansion depth of the tree, before being sent as json to the visualization,
  • lazy_subtree_depth which determines the depth of on-demand expanded subtrees.
# very deep tree
ldroot = LimitedDepthTree()
# launches visualization and click some nodes
D3Tree(ldroot, lazy_expand_after_depth=0,  lazy_subtree_depth=1)

returns Expanded tree with style

Text output

D3Trees also supports basic text output. This can be achieved by writing to an io object with the text/plain mime. This format is the automatic output if a D3Tree is created in the REPL:

julia> children = [[2,3], [4,5], [6,7], [8,9], [1], [], [], [], []];

julia> t = D3Tree(children)
1
├──2
│  ├──4
│  │  ├──8 (0 children)
│  │  └──9 (0 children)
│  └──5
│     └──1 (2 children)
└──3
   ├──6
   └──7

Browser compatibility

This package works best in the Google chrome or chromium browser.

Limitations

  • This will not work offline because it downloads the D3 library on the fly (#10)

d3trees.jl's People

Contributors

bozenkhaa avatar ebalaban avatar juliendehos avatar mossr avatar mykelk avatar rejuvyesh avatar zsunberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3trees.jl's Issues

Compatibility with directed Graphs.jl

Is there any reason why this wouldn't play with DiGraphs ?
If you are interested I can push a branch with a constructor D3Tree(::DiGraph)
I will actually just transform the Graph in an AbstractTree implementation, where the directed edges lead to children.
Maybe some constraints need to apply (e.g. only graphs that can be transformed to trees).
I don't know what would happen to the library if there was to be cyclic graphs and multiple parents per node.
I am not familiar with the original javascript library.

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Tooltip text not working with AbstractTrees

The problem is with lines 105-106 of D3Trees.jl. Once take!(iob) is called on line 105, iob is reset, so the second call on line 106 pushes an empty string into t.tooltip. For now, I simply fixed it on my end as

 str = String(take!(iob))
 push!(t.text, str)
 push!(t.tooltip, str)

Happy to create a pull request. It may be good to make this a bit more flexible down the road and allow different text for t.text and t.tooltip. If we stick with the same AbstractTrees.printnode interface, perhaps the two pieces of text can be separated by a delimiter within the input string (no delimiter: use the same text for both). In general, this tooltip feature is very useful for larger, denser trees.

Save the D3Tree as html file (improvement?).

It will be great to have an example of how to store a D3Tree in HTML.

For example, instead of:
inchrome(D3Tree(info[:tree], init_expand=0, title="TreeStep-$c" ))

Something like:

saveTree(D3Tree(info[:tree], init_expand=0, title="TreeStep-$c" ), pathHTLMOutputFile)

So the tree can later be inspected using a particular browser.

Specify CSS

It would be nice to be able to give the tree some css to change the style for all the nodes in addition to the per-node styling that is done now.

Specifying attributes as functions

@mykelk had the idea of specifying the attributes of each node as a function, i.e.

f(i) = isodd(i) ? "fill:blue" : "fill:red"
D3Tree(children, style=f)

I don't think this is necessary right now because it's easy enough to do

D3Tree(children, style=[f(i) for i in 1:length(children)])

but we could add it if people want it. I just want to maintain as little code as possible.

Circle size in Firefox

Firefox doesn't allow css styling of svg circle elements, so it is not currently possible to set the size of the nodes. It probably also doesn't work in safari. It works fine in chrome.

Image output

It would be cool to be able to output these trees as images. The challenge is that the javascript actually has to be run to display the tree.

https://wkhtmltopdf.org/ might be a good place to start.

Offline

Right now the package downloads d3 on the fly, so it will not work without the internet, as I found out painfully in a presentation. I guess we should download d3 into deps

Testing on Windows

No one has made sure this works on windows yet - especially the inchrome function.

Support custom attributes for trees created via the AbstractTrees interface

Right now there is no way to specify tree attributes (such as init_expand, title, etc) if one is using the D3Tree(node; detect_repeat=true) constructor, i.e., the AbstractTrees interface. To help with my own debugging, I went ahead and implemented this functionality and created a pull request for it: #19.

In it, the D3Tree(node; ...) constructor will now take the same keyword arguments as D3Tree(children, <keyword arguments>), in addition to detect_repeat. Some of the arguments won't be very useful for the AbstractTrees interface (text, tooltip, style, and link_style), but that's probably not a big deal.

Additionally, I'd like to suggest two new D3Trees API functions, style() and link_style(), that can help set node and link attributes:

style(node)::String = ""
link_style(node1, node2)::String = ""

Alternatively, we could propose adding them to the AbstractTrees API. What do you think?

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.