hyper-vis
A Opal Ruby wrapper for Vis.js with Ruby-Hyperloop Components. Implements the complete API for:
Includes vis.js version 4.21.0
Demo
Reactive hyper-vis in action:
Quality
Tests
Finished in 2 minutes 39.7 seconds (files took 3.18 seconds to load)
132 examples, 0 failures, 15 pending
To run Tests
Clone repo, then:
bundle update
cd spec/test_app
bundle update
cd ../..
bundle exec rspec
Installation
for a Rails app:
gem 'hyper-vis'
and bundle update
.
hyper-vis depends on hyper-component
from Ruby-Hyperloop but can be used without it.
vis.js is automatically imported for Ruby-Hyperloop. If you get vis.js with webpacker, you may need to cancel the import in your config/intializers/hyperloop.rb
config.cancel_import 'vis/source/vis.js'
The wrapper expects a global vis
(not Vis
) to be availabe in javascript.
For Vis to function as expected, the stylesheets must be included.
For a Rails app, the asset path is automatically added.
In your application.css
add:
*= require vis.css
For other frameworks vis.js, stylesheets and images are available in the gems lib/vis/source/
directory.
Usage
The wrapper follows vis.js 1 to 1, conforming to ruby standards, instead of setSize
in javascript, you would use set_size
. Also see specs in the specs
directory for usage or the vis documentation (linked above).
All arguments or return values are 'rubyfied' as much as possible, so you can just use ruby.
The Vis part
dataset = Vis::DataSet.new([{id: 1, name: 'foo'}, {id: 2, name: 'bar'}, {id: 3, name: 'pub'}])
edge_dataset = Vis::DataSet.new([{from: 1, to: 2}, {from: 2, to: 3}])
dom_node = Vis::Network.test_container
net = Vis::Network.new(dom_node, {nodes: dataset, edges: edge_dataset})
xy = net.canvas_to_dom({x: 10, y: 10})
# there also are
Vis::Graph2d
Vis::Graph3d
Vis::Timeline
The Component part
The Components takes care about all the things necessary to make Vis.js play nice with React.
The Components also provide a helper to access the document: document
.
Vis::Network::Mixin
Vis::Network can be used within the render_with_dom_node.
class MyVisNetworkComponent
include Hyperloop::Vis::Network::Mixin
# the component automatically calls the render_with_dom_node block every
# time new data or options are received
# however
# setting automatic_refresh false turns that off ...
# (default is true, so this is optional):
automatic_refresh false
# ... and with automatic_refresh false refresh can
# be handled in the before_receive_props callback
# for example (this is also optional):
before_receive_props do |new_props|
# data can be accessed using the helper vis_data
if new_props[:vis_data] != vis_data
@net.set_data(new_props[:vis_data])
end
end
render_with_dom_node do |dom_node, data, options|
# its important to use the data as passed in as 'data' argument
# to get the latests passed data for each new render
@net = Vis::Network.new(dom_node, data, options)
# data is also atomatically saved and available using the helper
vis_data
# example of using the document helper
canvas = document.JS.querySelector('canvas')
end
end
class AOuterComponent < Hyperloop::Component
render do
received_data = []
# example of using a callback in the options
options = { manipulation: {
edit_node: proc { |node_data, callback| received_data << node_data }
}}
# initialize a dataset
data = Vis::DataSet.new([{id: 1, name: 'foo'}, {id: 2, name: 'bar'}, {id: 3, name: 'pub'}])
# call the component
DIV { MyVisNetworkComponent(vis_data: data, otions: options)}
end
end
Vis::Graph3d::Mixin
Works the same as Vis::Network::Mixin
Vis::Timeline::Mixin
Similar to Vis::Network, mostly params and helpers are different:
class MyVisTimelineComponent
include Hyperloop::Vis::Timeline::Mixin
# the component automatically calls the render_with_dom_node block every
# time new data or options are received
# however
# setting automatic_refresh false turns that off ...
# (default is true, so this is optional):
automatic_refresh false
# ... and with automatic_refresh false refresh can
# be handled in the before_receive_props callback
# for example (this is also optional):
before_receive_props do |new_props|
# data can be accessed using the helpers:
items
groups
options
end
render_with_dom_node do |dom_node, items, groups, options|
# its important to use the data as passed in as 'data' argument
# to get the latests passed data for each new render
@net = Vis::Timeline.new(dom_node, items, groups, options)
# data is also atomatically saved and available using the helpers
items
groups
options
end
end
class AOuterComponent < Hyperloop::Component
render do
options = { align: 'left' }
# initialize a dataset
data = Vis::DataSet.new([
{id: 1, content: 'item 1', start: '2013-04-20'},
{id: 2, content: 'item 2', start: '2013-04-14'},
{id: 3, content: 'item 3', start: '2013-04-18'},
{id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19'},
{id: 5, content: 'item 5', start: '2013-04-25'},
{id: 6, content: 'item 6', start: '2013-04-27'}
])
# call the component
DIV { MyVisTimelineComponent(items: data, otions: options)}
end
end
Vis::Graph2d::Mixin
Works the same as Vis::Timeline::Mixin