Graph Visualization and Neo4j

So far we’ve learned how to get Neo4j up and running with Neography, how to find friends of friends and degrees of separation with the Neo4j REST API and a little bit of the Gremlin and Cypher languages. However, all we’ve seen is text output. We haven’t really “seen” a graph yet, but that’s about to change.

Vouched holds a graph of skill specific recommendations people have made to each other and visualizes it. I extracted the visualization, and hosted it on github as neovigator. You can get your very own visualization up and running or take a look at this instance running on Heroku.


Let’s get it up and running and then we’ll go through some pieces of the code.

git clone git@github.com:maxdemarzi/neovigator.git
cd neovigator
bundle install
rake neo4j:install
rake neo4j:start
rackup

Then visit localhost:9292 to see it running.

The website is a Sinatra Application with only two routes. The home page, and a resources route that returns a JSON object of one node and all his “next node neighbours”.

The JSON object we create will have this structure:

{"details_html":"Information which replaces the side panel",
 "data":{
         "id":"the id of the current node",
         "name":"the name of the current node",
         "attributes":[{"id":"id of 1st relationship type",
                        "name":"name of 1st relationship type",
                        "values":[{"id":"the id of our 1st neighbour",
                                   "name":"the name of our 1st neighbour"},
                                  {"id":"the id of our 2nd neighbour",
                                   "name":"the name of our 2nd neighbour"}]},
                       {"id":"id of 2nd relationship type",
                        "name":"name of 2nd relationship type",
                        "values":[{"id":"the id of our 3rd neighbour",
                                   "name":"the name of our 3rd neighbour"},
                                  {"id":"the id of our 4th neighbour",
                                   "name":"the name of our 4th neighbour"}]}]
        }
}

When we fill this JSON object and pass it to the visualization, this is what we get:

We create a route in Sinatra and set it to return JSON.

  get '/resources/show' do
    content_type :json

From our starting node, we are going to traverse the graph to a depth of 1, and get everything but our starting node.

  neighbours =
    {"order"         => "depth first",
     "uniqueness"    => "none",
     "return filter" => {"language" => "builtin", "name" => "all_but_start_node"},
     "depth"         => 1}

Then we get our node and traverse the graph using the “fullpath” option which gives us the nodes and relationships.

    node = neo.get_node(params[:id])
    connections = neo.traverse(node, "fullpath", neighbours)

We are going to split up our incoming and outgoing relationships and get the ids of the “other node” so we can link to it.

    incoming = Hash.new{|h, k| h[k] = []}
    outgoing = Hash.new{|h, k| h[k] = []}

    connections.each do |c|
       c["nodes"].each do |n|
         nodes[n["self"]] = n["data"]
       end
       rel = c["relationships"][0]

       if rel["end"] == node["self"]
         incoming["Incoming:#{rel["type"]}"] << {:values => nodes[rel["start"]].
                                                            merge({:id => node_id(rel["start"]) }) 
                                                }
       else
         outgoing["Outgoing:#{rel["type"]}"] << {:values => nodes[rel["end"]].
                                                            merge({:id => node_id(rel["end"]) }) 
                                                }
       end
    end

We then merge them together to create our neighbours array and put them in the attributes piece of our JSON object.

incoming.merge(outgoing).each_pair do |key, value|
  attributes << {:id => key.split(':').last, 
                 :name => key, 
                 :values => value.collect{|v| v[:values]} 
                 }
end

We then load our JSON object with a few more details, like the node id, name, and some of its properties.

{:details_html => "<h2>Neo ID: #{node_id(node)}</h2>#{get_properties(node)}",
 :data => {:attributes => attributes,
           :name => node["data"]["name"],
           :id => node_id(node)}
 }.to_json
end

I will go over more details of how the visualization was done at FOSDEM 2012 in the Graph Processing Room on February 5th, 2012 at at 3:20 PM in the AW building room 1.125.

Update! Here are the FOSDEM Slides:

Credits
Processing is an open source programming language and environment for people who want to create images, animations, and interactions. Processing.js takes processing to the browser. It is written in JavaScript and uses HTML5’s canvas element. Michael Aufreiter adapted a motion tweening library for use with processing.js and built a radial navigator (Donut) for the project ASKKEN. Michael has given permission to use Donut as you’d like, checkout his amazing work with Substance.

Tagged , , , , , ,

6 thoughts on “Graph Visualization and Neo4j

  1. [...] Graph Visualization and Neo4j « Max De Marzi Processing.js takes processing to the browser. It is written in JavaScript and uses HTML5′s canvas element. Michael Aufreiter adapted a motion tweening library for use with processing.js and built a radial navigator ( Donut ) for the project ASKKEN . [...]

    • Kaye says:

      at 40:30 in the video, will that tarverser traverse all KNOWS relationships before it stops? even though only one LOVES was found ?that seems like a sound yes …Then maybe, can we make a tarverser that parses all LOVES relationships ? seems less operations to be done, at least in that example

  2. [...] work from the Gremlin shell and put it on the web using the Heroku Neo4j add-on and altering the Neovigator project for our use case. Heroku has a great article on how to get an example Neo4j application up [...]

  3. Rachit says:

    Hiii .. this is an awesome work. I need to do the same thing… i am using an neo4j embedded in my javaee application . Since i program in java .. i think i don’t need to install neography.
    I can directly send a JSON reply to the javascript request.
    This means i don’t need all the applications you mentioned in the post .. like sintara , neography..
    Am i right ? Please give me a big picture of visualization for graphs stored in neo4j.

    • maxdemarzi says:

      Yes Rachit. You can use any Neo4j REST Client or use Java directly with the embedded server option. All you need to do is produce the JSON required by the visualizations.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 1,678 other followers

%d bloggers like this: