neo-viz 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.gitignore +9 -0
  2. data/.livereload +20 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +3 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +19 -0
  7. data/README.md +120 -0
  8. data/Rakefile +12 -0
  9. data/bin/neo-viz +12 -0
  10. data/config.ru +35 -0
  11. data/lib/neo-viz.rb +185 -0
  12. data/lib/neo-viz/version.rb +6 -0
  13. data/neo-viz.gemspec +37 -0
  14. data/public/coffeescripts/app_context.coffee +89 -0
  15. data/public/coffeescripts/canvas_util.coffee +68 -0
  16. data/public/coffeescripts/event_broker.coffee +16 -0
  17. data/public/coffeescripts/filters.coffee +113 -0
  18. data/public/coffeescripts/main.coffee.erb +132 -0
  19. data/public/coffeescripts/neo4j.coffee +90 -0
  20. data/public/coffeescripts/renderer.coffee +141 -0
  21. data/public/coffeescripts/space.coffee +81 -0
  22. data/public/images/ajax-loader.gif +0 -0
  23. data/public/javascripts/data.js +45 -0
  24. data/public/javascripts/data2.js +1287 -0
  25. data/public/javascripts/main.sprockets.js +9 -0
  26. data/public/lib/arbor/arbor-tween.js +86 -0
  27. data/public/lib/arbor/arbor.js +67 -0
  28. data/public/lib/jQuery/jquery-1.6.1.min.js +18 -0
  29. data/public/lib/jasmine-1.1.0/MIT.LICENSE +20 -0
  30. data/public/lib/jasmine-1.1.0/jasmine-html.js +190 -0
  31. data/public/lib/jasmine-1.1.0/jasmine.css +166 -0
  32. data/public/lib/jasmine-1.1.0/jasmine.js +2476 -0
  33. data/public/lib/jasmine-1.1.0/jasmine_favicon.png +0 -0
  34. data/public/lib/stdlib/stdlib.js +115 -0
  35. data/public/lib/sylvester-0.1.3/CHANGELOG.txt +29 -0
  36. data/public/lib/sylvester-0.1.3/sylvester.js +1 -0
  37. data/public/lib/sylvester-0.1.3/sylvester.js.gz +0 -0
  38. data/public/lib/sylvester-0.1.3/sylvester.src.js +1254 -0
  39. data/public/scss/main.scss +152 -0
  40. data/public/scss/mixins.scss +37 -0
  41. data/spec/coffeescripts/canvas_util_spec.coffee +4 -0
  42. data/spec/coffeescripts/filters_spec.coffee +37 -0
  43. data/spec/coffeescripts/neo4j_spec.coffee +76 -0
  44. data/spec/neo_viz_spec.rb +48 -0
  45. data/spec/spec_helper.rb +17 -0
  46. data/spec/support/struct_matcher.rb +117 -0
  47. data/views/_filters.haml +22 -0
  48. data/views/_partial.haml +39 -0
  49. data/views/embedded.haml +15 -0
  50. data/views/index.haml +19 -0
  51. data/views/jasmine_specs_runner.haml +50 -0
  52. metadata +236 -0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ db
2
+ vendor
3
+ .bundle
4
+ .sass-cache
5
+ spec/coffeescripts/*.js
6
+ views/coffeescript/*.js
7
+ pkg
8
+ Gemfile.lock
9
+
data/.livereload ADDED
@@ -0,0 +1,20 @@
1
+ # Lines starting with pound sign (#) are ignored.
2
+
3
+ # additional extensions to monitor
4
+ config.exts << 'scss'
5
+ config.exts << 'haml'
6
+
7
+ # exclude files with NAMES matching this mask
8
+ #config.exclusions << '~*'
9
+ # exclude files with PATHS matching this mask (if the mask contains a slash)
10
+ #config.exclusions << '/excluded_dir/*'
11
+ # exclude files with PATHS matching this REGEXP
12
+ #config.exclusions << /somedir.*(ab){2,4}.(css|js)$/
13
+
14
+ # reload the whole page when .js changes
15
+ #config.apply_js_live = false
16
+ # reload the whole page when .css changes
17
+ #config.apply_css_live = false
18
+
19
+ # wait 100ms for more changes before reloading a page
20
+ #config.grace_period = 0.1
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format p d
data/.rvmrc ADDED
@@ -0,0 +1,3 @@
1
+ rvm use jruby-1.6.5
2
+
3
+
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in neo-viz.gemspec
4
+ gemspec
5
+
6
+
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 AmanziTel
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # Neo-Viz
2
+
3
+ Neo-Viz is a tool for visualizing Neo data in the browser. It is
4
+ a Sinatra application that uses Neo4j.rb to read data from a Neo
5
+ database directory. It shows the data using Javascript in a browser.
6
+
7
+
8
+ ## Installing
9
+
10
+ The visualizer can be used stand-alone or embedded in a Rails application.
11
+
12
+ ### External Dependencies
13
+
14
+ The visualizer has an external dependency on coffee-script. It can be
15
+ installed by:
16
+
17
+ # OS X
18
+ $ brew install coffee-script
19
+
20
+ # Linux
21
+ $ apt-get install coffee-script
22
+
23
+
24
+
25
+ ### Standalone
26
+
27
+ To use it standalone you must first get the code from the repository.
28
+
29
+ $ git clone git@github.com:AmanziTel/neo-viz.git
30
+ $ cd neo-viz
31
+
32
+ # To use it as is
33
+ $ rackup
34
+ [2011-06-23 07:48:34] INFO WEBrick 1.3.1
35
+ [2011-06-23 07:48:34] INFO ruby 1.8.7 (2011-05-23) [java]
36
+ [2011-06-23 07:48:34] INFO WEBrick::HTTPServer#start: pid=64743 port=9292
37
+
38
+
39
+ # To install it as a gem
40
+ $ rake install
41
+ neo-viz 1.0.0 built to pkg/neo-viz-1.0.0.gem
42
+ neo-viz (1.0.0) installed
43
+
44
+ $ neo-viz
45
+ [2011-06-23 07:51:10] INFO WEBrick 1.3.1
46
+ [2011-06-23 07:51:10] INFO ruby 1.8.7 (2011-05-23) [java]
47
+ [2011-06-23 07:51:10] INFO WEBrick::HTTPServer#start: pid=64864 port=1666
48
+
49
+ ### Embedding in Rails
50
+
51
+ To embed the visualizer in Rails, you first have to add it to your `Gemfile`.
52
+
53
+ # Gemfile
54
+ gem 'neo-viz', :git => 'git@github.com:AmanziTel/neo-viz.git'
55
+
56
+ Then you have to mount the route in `routes.rb`
57
+
58
+ # config/routes.rb
59
+ mount Neo::Viz::App => '/neo-viz'
60
+
61
+ You can now access it at e.g. http://localhost:3000/neo-viz.
62
+
63
+ ## Neo4j Database
64
+
65
+ The standalone version expects a `db` directory containing the usual
66
+ Neo4j database files.
67
+
68
+ The embedded version uses the Neo4j database that has been configured
69
+ for the embedding project.
70
+
71
+ ## Known issues
72
+
73
+ There is a problem running the Jasmine specs (/run-specs) on Windows if the "therubyrhino" gem is installed
74
+ and you are using JRuby. On Windows we want to use the built-in JScript runtime but ExecJS chooses Rhino if it
75
+ is installed.
76
+
77
+ Typical errors returned over HTTP when requesting a .coffee file:
78
+
79
+ throw Error("NativeException: org.mozilla.javascript.JavaScriptException:
80
+ Error: too many ) on line 2 (<eval>#8)\n (in c:/..../neo-viz/public/coffeescripts/canvas_util.coffee)")
81
+
82
+ A workaround is to uninstall the therubyrhino gem, but ofcourse it will be re-installed on every call to bundle.
83
+ I can't figure out how to tell bundler not to load a specific gem when I'm on JRuby and Windows.
84
+
85
+ ## To do
86
+
87
+ ### Server
88
+
89
+ * Make it possible to choose where that data comes from
90
+ * Implement a command line interface for starting the server and
91
+ selecting the data source.
92
+
93
+
94
+ ### Client
95
+
96
+ * Group nodes, if there are too many to show.
97
+ * bind and trigger with custom events
98
+
99
+
100
+ ### License
101
+
102
+ MIT, see LICENSE file
103
+
104
+ ### Changes
105
+
106
+ * 2011-09-28 Added relationship filter
107
+ * 2001-09-28 Enabled embedding from AJAX-call (/embedded)
108
+ * 2011-06-23 Changed the namespace.
109
+ * 2011-06-23 Added depth to the traversal algorithm
110
+ * 2011-06-20 A query protocol for selecting only the relevant nodes
111
+ * 2011-06-20 Query protocol editor to select the relevant nodes to ask
112
+ * 2011-06-16 Views for showing only the relevant properties.
113
+ * 2011-06-16 Node filter
114
+ * 2011-06-16 Select number of nodes to show.
115
+ * 2011-06-14 Click to show detailed information.
116
+ * Connect with the Server to get the data.
117
+ * Fetch new data from the Server when a node is selected.
118
+ * Limit the amount of nodes shown on the screen.
119
+ * Show the properties of the nodes and relations.
120
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ begin
5
+ require 'jasmine'
6
+ load 'jasmine/tasks/jasmine.rake'
7
+ rescue LoadError
8
+ task :jasmine do
9
+ abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
10
+ end
11
+ end
12
+
data/bin/neo-viz ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rack'
4
+
5
+ rackup_file = File.expand_path('../../config.ru', __FILE__)
6
+
7
+ ARGV.concat(["-p", "1666"]) unless ARGV.include?("-p")
8
+ ARGV.concat(["-E", "production"]) unless ARGV.include?("-E")
9
+ ARGV << rackup_file unless ARGV.include?(/\.ru/)
10
+
11
+ Rack::Server.start
12
+
data/config.ru ADDED
@@ -0,0 +1,35 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/views'
3
+
4
+ require 'sprockets'
5
+ require 'neo-viz'
6
+ require 'find'
7
+
8
+ map '/' do
9
+ run Neo::Viz::App
10
+ end
11
+
12
+ map '/assets' do
13
+ environment = Sprockets::Environment.new
14
+
15
+ # map all dirs under /public to /assets
16
+ Find.find(File.join(Neo::Viz.install_path, "public")) do |path|
17
+ environment.append_path(path) if FileTest.directory?(path)
18
+ end
19
+
20
+ environment.instance_eval do
21
+ @context_class.instance_eval do
22
+ define_method :root_url do
23
+ '.'
24
+ end
25
+ end
26
+ end
27
+
28
+ run environment
29
+ end
30
+
31
+ map '/specs' do
32
+ environment = Sprockets::Environment.new
33
+ environment.append_path 'spec/coffeescripts'
34
+ run environment
35
+ end
data/lib/neo-viz.rb ADDED
@@ -0,0 +1,185 @@
1
+ require 'sinatra/base'
2
+
3
+ require 'haml'
4
+ require 'sass'
5
+ require 'coffee-script'
6
+ require 'neo4j'
7
+ require 'sprockets'
8
+ require 'execjs'
9
+
10
+ module Neo; module Viz; end; end
11
+
12
+
13
+ module Neo::Viz
14
+
15
+ def self.install_path
16
+ return File.expand_path('../..', __FILE__)
17
+ end
18
+
19
+ class App < Sinatra::Base
20
+
21
+ include Neo4j
22
+
23
+ configure do
24
+ set :public, File.expand_path('../../public/', __FILE__)
25
+ set :views, File.expand_path('../../views/', __FILE__)
26
+ end
27
+
28
+ configure(:development) do
29
+ require 'sinatra/reloader'
30
+ register Sinatra::Reloader
31
+ also_reload "lib/**/*.rb"
32
+ end
33
+
34
+ get '/' do
35
+ redirect to('/index')
36
+ end
37
+
38
+ get '/index' do
39
+ @assets_url_prefix = ''
40
+ haml :index
41
+ end
42
+
43
+ # Consumers of /embedded have to redefine this method inside
44
+ # the Sprockets environment. See config.ru.
45
+ def root_url
46
+ '.'
47
+ end
48
+
49
+ get '/embedded' do
50
+ @assets_url_prefix = request.env["rack.mount.prefix"] || ''
51
+ haml :embedded
52
+ end
53
+
54
+ get '/node-count' do
55
+ Neo4j.management.get_number_of_node_ids_in_use.to_s
56
+ end
57
+
58
+ get '/tree' do
59
+ Neo4j.ref_node.rels.map { |rel| rel.end_node.attributes }.inspect
60
+ end
61
+
62
+ get '/env' do
63
+ #p ExecJS::runtime
64
+ p request.env
65
+ request.env.inspect
66
+ end
67
+
68
+ get '/run-specs' do
69
+ haml :jasmine_specs_runner
70
+ end
71
+
72
+ get '/eval' do
73
+ code = params[:code]
74
+ p code
75
+ ret = eval_code code, depth
76
+ if node_data?(ret)
77
+ ret.to_json
78
+ else
79
+ # Hallberg: is seems 'to_s' does not alias 'inspect' for Hash and Array
80
+ # on JRuby 1.6.4 on Windows. Instead {:foo => :bar}.to_s = "foobar".
81
+ # So special case them here.
82
+ if ret.kind_of?(Hash) || ret.kind_of?(Array)
83
+ { :result => ret.inspect}.to_json
84
+ else
85
+ { :result => "#{ret}" }.to_json
86
+ end
87
+ end
88
+ end
89
+
90
+
91
+ private
92
+
93
+ def node_data?(ret)
94
+ ret.kind_of?(Hash) && ret.length == 2 && ret.key?(:nodes) && ret.key?(:rels)
95
+ end
96
+
97
+ def depth
98
+ params[:depth].try(:to_i) || 1
99
+ end
100
+
101
+ def eval_code(code, depth)
102
+ code = underscore code
103
+
104
+ begin
105
+ $Depth = depth
106
+ tx = Neo4j::Transaction.new
107
+ begin
108
+ result = eval <<-EOT
109
+ #{code}
110
+ EOT
111
+ rescue SyntaxError => e
112
+ return e
113
+ end
114
+ tx.success
115
+ result
116
+ rescue => e
117
+ e
118
+ ensure
119
+ tx.finish
120
+ end
121
+
122
+ end
123
+
124
+ # This changes the code to use the internal versions that
125
+ # don't use classes, but just pure nodes and relations.
126
+ def underscore code
127
+ code.
128
+ gsub(/\bload\b/, '_load').
129
+ gsub(/\brels\b/, '_rels').
130
+ gsub(/\bnode\b/, '_node')
131
+ end
132
+
133
+ def viz(*args)
134
+ depth = $Depth
135
+ data = { :nodes => [], :rels => [] }
136
+ args.each do |arg|
137
+ data_for(data, arg, depth)
138
+ end
139
+ data
140
+ end
141
+
142
+ def data_for(data, obj, depth)
143
+ if obj.class.to_s == 'Neo4j::Relationship'
144
+ populate_data(data, arg.start_node, depth, [])
145
+ elsif obj.class.to_s == 'Neo4j::Node'
146
+ populate_data(data, obj, depth, [])
147
+ elsif obj.respond_to? :each
148
+ obj.each do |o|
149
+ data_for(data, o, depth)
150
+ end
151
+ end
152
+ data
153
+ end
154
+
155
+ def populate_data(data, node, depth, navigatedRels)
156
+ data[:nodes] << node_data(node)
157
+ return if depth == 0
158
+ node._rels.each do |rel|
159
+ # Make sure we don't walk the same rel path more than once
160
+ if !navigatedRels.include?(rel)
161
+ data[:rels] << rel_data(rel)
162
+ navigatedRels << rel
163
+ populate_data(data, rel._other_node(node), depth-1, navigatedRels)
164
+ end
165
+ end
166
+ end
167
+
168
+ def node_data(node)
169
+ {
170
+ :id => node.props['_neo_id'],
171
+ :data => node.props,
172
+ }
173
+ end
174
+
175
+ def rel_data(rel)
176
+ {
177
+ :id => rel.props['_neo_id'],
178
+ :start_node => rel._start_node.props['_neo_id'],
179
+ :end_node => rel._end_node.props['_neo_id'],
180
+ :data => rel.props.merge(:rel_type => rel.rel_type)
181
+ }
182
+ end
183
+ end
184
+
185
+ end
@@ -0,0 +1,6 @@
1
+ module Neo
2
+ module Viz
3
+ VERSION = "1.0.1"
4
+ end
5
+ end
6
+