DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Data
  4. Network Visualization Using Cypher and D3.JS

Network Visualization Using Cypher and D3.JS

Max De Marzi user avatar by
Max De Marzi
·
Feb. 13, 12 · Interview
Like (0)
Save
Tweet
Share
6.70K Views

Join the DZone community and get the full member experience.

Join For Free

we’ve seen some pretty nice visualizations of nodes and their immediate neighbors, but we want to be able to visualize more. so we’re going to prepare a 200 node network, use cypher to extract the data we want and visualize it with d3.js .

i’m not going to type in the names of 200 people, so we’ll create a method to generate some random text.

def generate_text(length=8)
  chars = 'abcdefghjkmnpqrstuvwxyz'
  name = ''
  length.times { |i| name << chars[rand(chars.length)] }
  name
end

we are once again going to use our the batch command. we are creating 200 nodes with random names, and randomly connecting them to 0-9 other nodes. this is going to send between 500 and 1000 commands in one batched transaction. this is as big as we want to go for one batch command, if you wanted to create a bigger graph, breaking it up into multiple batches of 1000 commands would be best.

def create_graph
  neo = neography::rest.new
  graph_exists = neo.get_node_properties(1)
  return if graph_exists && graph_exists['name']

  names = 200.times.collect{|x| generate_text}

  commands = names.map{ |n| [:create_node, {"name" => n}]}
  names.each_index do |x| 
    follows = names.size.times.map{|y| y}
    follows.delete_at(x)
    follows.sample(rand(10)).each do |f|
      commands << [:create_relationship, "follows", "{#{x}}", "{#{f}}"]    
    end
  end

  batch_result = neo.batch *commands
end

i want this visualization to be a little more dynamic than the last one, so when you take a look you’ll randomly see the network of one of the nodes. with cypher we’ll parametrize the node and pass it a random number to serve as our node_id. if you’ve been following along you’ll notice this query looks pretty similar to when we used cypher to get friends of friends . we are just taking it up a notch by going to friends of friends of friends and also getting the count of others.

def follower_matrix
  neo = neography::rest.new
  cypher_query =  " start me = node({node_id})"
  cypher_query << " match (me)-[?:follows]->(friends)-[?:follows]->(fof)-[?:follows]->(fofof)-[?:follows]->others"
  cypher_query << " return me.name, friends.name, fof.name, fofof.name, count(others)"
  cypher_query << " order by friends.name, fof.name, fofof.name, count(others) desc"
  neo.execute_query(cypher_query, {:node_id => 1 + rand(200)})["data"]
end  

when we get our data it is going to be an array of arrays with the count of others at the end. you are basically looking at paths without the relationships.

[["max", "ben", "rob", "james", 5],
 ["max", "ben", "rob", "peter", 2],
 ["max", "ben", "musannif", "pramod", 2]
]

our visualization is looking for a json object that looks more like this:

{"name":"max",
 "children":[{"name":"ben",
               "children":[{"name":"rob",
                            "children":[{"name":"james",
                                         "size":2},
                                        {"name":"peter",
                                         "size":5}
                                       ]},
                           {"name":"musannif",
                            "children":[{"name":"pramod",
                                         "size":2}
                                       ]}
                           ]},
            ]
}

we will do this in two steps. the first is to create a variable called data and fill it with a nested hash of our array of arrays.

get '/followers' do
  data = follower_matrix.inject({}) {|h,i| t = h; i.each {|n| t[n] ||= {}; t = t[n]}; h}
  with_children(data).to_json
end

we could have created a nice nested hash class, or used one of the existing gems that deal with trees, but ruby is nice enough to let us do it on one line. don’t let that one liner freak you out, it is an just an old ruby trick.

we need a way to turn this nested hash into the final format with children arrays and such, so we’ll write that method as follows:

def with_children(node)
  if node[node.keys.first].keys.first.is_a?(integer)
    { "name" => node.keys.first,
      "size" => 1 + node[node.keys.first].keys.first 
     }
  else
    { "name" => node.keys.first, 
      "children" => node[node.keys.first].collect { |c| 
        with_children(hash[c[0], c[1]]) } 
    }
  end
end

we are going to use the size variable to figure out how big to make our leaf nodes. we start with 1 and add the count of others, because if there are zero others, our leaf node would have a zero size and we don’t want that.

our visualization is about 120 lines long, so i won’t dump it all here. if you want to see it check it out on github .

it follows the d3 force collapsible example, but adds a little color using the size attribute so it won’t look so bland:

var colorscale = d3.scale.category10();

function color(d) {
  return d._children ? "#3182bd" : d.children ? "#c6dbef" : colorscale(d.size);
}

ee it live on heroku at http://evening-mountain-5731.herokuapp.com/index.html and make sure to refresh the page to see different results.



source: http://maxdemarzi.com/2012/02/13/visualizing-a-network-with-cypher/

Visualization (graphics) Network D3.js

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • [DZone Survey] Share Your Expertise and Take our 2023 Web, Mobile, and Low-Code Apps Survey
  • Spring Cloud
  • Apache Kafka Is NOT Real Real-Time Data Streaming!
  • Cucumber.js Tutorial With Examples For Selenium JavaScript

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: