patrickfuller / jgraph

An embeddable webGL graph visualization library.
http://patrickfuller.github.io/jgraph
MIT License
133 stars 31 forks source link

Real-time updating #5

Closed patrickfuller closed 9 years ago

patrickfuller commented 9 years ago

From Uros Platise:

This I am curious: in the JS case would it possible to update connections and locations in time? i.e. that JS keeps updating latest changes without 'refreshing' the JS view but while surfing with the camera. My vision is to run on-going simulations and basically I could watch the progress.

patrickfuller commented 9 years ago

Real-time javascript interaction is a little awkward through the current igraph API. I don't want to complicate igraph, so real-time visualization will require some javascript in the notebook.

I got real time working by 1. editing the igraph html to make the relevant js variable global, and 2. using that variable to clear and draw updates.

out

Here's the code.

import igraph
graph = {
    'nodes': {
        'ross': {'color': 0xffaaaa, 'size': 2.0, 'location': [10, 0, 0]},
        'joey': {'size': 0.5, 'location': [0, 10, 0]},
        'chandler': {'color': 0x2222ff, 'size': 1.25, 'location': [0, 0, 10]},
        'phoebe': {'color': 0x22ff22, 'location': [10, 10, 10]},
        'rachel': {'location': [10, 10, 0]},
        'monica': {'location': [10, 0, 10]},
    },
    'edges': [
        {'source': 'chandler', 'target': 'ross'},
        {'source': 'monica', 'target': 'ross'},
        {'source': 'ross', 'target': 'rachel'},
        {'source': 'ross', 'target': 'joey'},
        {'source': 'ross', 'target': 'phoebe'},
        {'source': 'monica', 'target': 'rachel'},
        {'source': 'chandler', 'target': 'phoebe'}
    ]
}
from IPython.display import display, HTML, Javascript

# This converts the data into an HTML string without rendering it.
html = igraph.draw(graph, optimize=False, display_html=False)

# This mess moves a javascript variable `$d` into the global scope by moving a line up.
# I'm editing the string directly as a proof of concept.
# You'll need to improve upon it if you want e.g. multiple real-time graphs.
html_split = html.splitlines()
html_split.insert(2, html_split[5].strip())
del html_split[6]
html = '\n'.join(html_split)

def refresh(graph):
    """Redraws the contents of an igraph canvas. Uses a global `$d` selector."""
    display(Javascript('$d.igraph.clear(); $d.igraph.draw(%s);' % igraph.to_json(graph)))
from random import random
from time import sleep

# Renders the HTML
display(HTML(html))

for _ in range(100):
    sleep(0.25)
    # Random updates to the graph structure
    graph['nodes']['ross']['size'] = 0.1 + random() * 5.0
    graph['nodes']['chandler']['location'] = [random() * 40.0, random() * 40.0, random() * 40.0]
    # Redraws
    refresh(graph)
platise commented 9 years ago

This is just great, I am able to change edges sizes, colors, etc.

Thanks a lot.