sigma-rails 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +37 -0
  4. data/lib/sigma/rails.rb +8 -0
  5. data/lib/sigma/rails/version.rb +5 -0
  6. data/vendor/assets/javascripts/sigma.js +8723 -0
  7. data/vendor/assets/javascripts/sigma.layout.forceAtlas2/README.md +12 -0
  8. data/vendor/assets/javascripts/sigma.layout.forceAtlas2/sigma.layout.forceAtlas2.js +1051 -0
  9. data/vendor/assets/javascripts/sigma.parsers.gexf/README.md +29 -0
  10. data/vendor/assets/javascripts/sigma.parsers.gexf/gexf-parser.js +548 -0
  11. data/vendor/assets/javascripts/sigma.parsers.gexf/sigma.parsers.gexf.js +108 -0
  12. data/vendor/assets/javascripts/sigma.parsers.json/README.md +29 -0
  13. data/vendor/assets/javascripts/sigma.parsers.json/sigma.parsers.json.js +88 -0
  14. data/vendor/assets/javascripts/sigma.plugins.animate/README.md +8 -0
  15. data/vendor/assets/javascripts/sigma.plugins.animate/sigma.plugins.animate.js +165 -0
  16. data/vendor/assets/javascripts/sigma.plugins.dragNodes/README.md +8 -0
  17. data/vendor/assets/javascripts/sigma.plugins.dragNodes/sigma.plugins.dragNodes.js +135 -0
  18. data/vendor/assets/javascripts/sigma.plugins.neighborhoods/README.md +24 -0
  19. data/vendor/assets/javascripts/sigma.plugins.neighborhoods/sigma.plugins.neighborhoods.js +186 -0
  20. data/vendor/assets/javascripts/sigma.renderers.customShapes/README.md +55 -0
  21. data/vendor/assets/javascripts/sigma.renderers.customShapes/shape-library.js +145 -0
  22. data/vendor/assets/javascripts/sigma.renderers.customShapes/sigma.renderers.customShapes.js +112 -0
  23. metadata +121 -0
@@ -0,0 +1,108 @@
1
+ ;(function(undefined) {
2
+ 'use strict';
3
+
4
+ if (typeof sigma === 'undefined')
5
+ throw 'sigma is not declared';
6
+
7
+ // Initialize package:
8
+ sigma.utils.pkg('sigma.parsers');
9
+
10
+ // Just a basic ID generator:
11
+ var _id = 0;
12
+ function edgeId() {
13
+ return 'e' + (_id++);
14
+ }
15
+
16
+ /**
17
+ * If the first arguments is a valid URL, this function loads a GEXF file and
18
+ * creates a new sigma instance or updates the graph of a given instance. It
19
+ * is possible to give a callback that will be executed at the end of the
20
+ * process. And if the first argument is a DOM element, it will skip the
21
+ * loading step and parse the given XML tree to fill the graph.
22
+ *
23
+ * @param {string|DOMElement} target The URL of the GEXF file or a valid
24
+ * GEXF tree.
25
+ * @param {object|sigma} sig A sigma configuration object or a
26
+ * sigma instance.
27
+ * @param {?function} callback Eventually a callback to execute
28
+ * after having parsed the file. It will
29
+ * be called with the related sigma
30
+ * instance as parameter.
31
+ */
32
+ sigma.parsers.gexf = function(target, sig, callback) {
33
+ var i,
34
+ l,
35
+ arr,
36
+ obj;
37
+
38
+ function parse(graph) {
39
+ // Adapt the graph:
40
+ arr = graph.nodes;
41
+ for (i = 0, l = arr.length; i < l; i++) {
42
+ obj = arr[i];
43
+
44
+ obj.id = obj.id;
45
+ if (obj.viz && typeof obj.viz === 'object') {
46
+ if (obj.viz.position && typeof obj.viz.position === 'object') {
47
+ obj.x = obj.viz.position.x;
48
+ obj.y = obj.viz.position.y;
49
+ }
50
+ obj.size = obj.viz.size;
51
+ obj.color = obj.viz.color;
52
+ }
53
+ }
54
+
55
+ arr = graph.edges;
56
+ for (i = 0, l = arr.length; i < l; i++) {
57
+ obj = arr[i];
58
+
59
+ obj.id = typeof obj.id === 'string' ? obj.id : edgeId();
60
+ obj.source = '' + obj.source;
61
+ obj.target = '' + obj.target;
62
+
63
+ if (obj.viz && typeof obj.viz === 'object') {
64
+ obj.color = obj.viz.color;
65
+ obj.size = obj.viz.thickness;
66
+ }
67
+
68
+ // Weight over viz.thickness?
69
+ obj.size = obj.weight;
70
+ }
71
+
72
+ // Update the instance's graph:
73
+ if (sig instanceof sigma) {
74
+ sig.graph.clear();
75
+
76
+ arr = graph.nodes;
77
+ for (i = 0, l = arr.length; i < l; i++)
78
+ sig.graph.addNode(arr[i]);
79
+
80
+ arr = graph.edges;
81
+ for (i = 0, l = arr.length; i < l; i++)
82
+ sig.graph.addEdge(arr[i]);
83
+
84
+ // ...or instanciate sigma if needed:
85
+ } else if (typeof sig === 'object') {
86
+ sig.graph = graph;
87
+ sig = new sigma(sig);
88
+
89
+ // ...or it's finally the callback:
90
+ } else if (typeof sig === 'function') {
91
+ callback = sig;
92
+ sig = null;
93
+ }
94
+
95
+ // Call the callback if specified:
96
+ if (callback) {
97
+ callback(sig || graph);
98
+ return;
99
+ } else
100
+ return graph;
101
+ }
102
+
103
+ if (typeof target === 'string')
104
+ gexf.fetch(target, parse);
105
+ else if (typeof target === 'object')
106
+ return parse(gexf.parse(target));
107
+ };
108
+ }).call(this);
@@ -0,0 +1,29 @@
1
+ sigma.parsers.json
2
+ ==================
3
+
4
+ Plugin developed by [Alexis Jacomy](https://github.com/jacomyal).
5
+
6
+ ---
7
+
8
+ This plugin provides a single function, `sigma.parsers.json()`, that will load a JSON encoded file, parse it, eventually instanciate sigma and fill the graph with the `graph.read()` method. The main goal is to avoid using jQuery only to load an external JSON file.
9
+
10
+ The most basic way to use this helper is to call it with a path and a sigma configuration object. It will then instanciate sigma, but after having added the graph into the config object.
11
+
12
+ ````javascript
13
+ sigma.parsers.json(
14
+ 'myGraph.json',
15
+ { container: 'myContainer' }
16
+ );
17
+ ````
18
+
19
+ It is also possible to update an existing instance's graph instead.
20
+
21
+ ````javascript
22
+ sigma.parsers.json(
23
+ 'myGraph.json',
24
+ myExistingInstance,
25
+ function() {
26
+ myExistingInstance.refresh();
27
+ }
28
+ );
29
+ ````
@@ -0,0 +1,88 @@
1
+ ;(function(undefined) {
2
+ 'use strict';
3
+
4
+ if (typeof sigma === 'undefined')
5
+ throw 'sigma is not declared';
6
+
7
+ // Initialize package:
8
+ sigma.utils.pkg('sigma.parsers');
9
+ sigma.utils.pkg('sigma.utils');
10
+
11
+ /**
12
+ * Just an XmlHttpRequest polyfill for different IE versions.
13
+ *
14
+ * @return {*} The XHR like object.
15
+ */
16
+ sigma.utils.xhr = function() {
17
+ if (window.XMLHttpRequest)
18
+ return new XMLHttpRequest();
19
+
20
+ var names,
21
+ i;
22
+
23
+ if (window.ActiveXObject) {
24
+ names = [
25
+ 'Msxml2.XMLHTTP.6.0',
26
+ 'Msxml2.XMLHTTP.3.0',
27
+ 'Msxml2.XMLHTTP',
28
+ 'Microsoft.XMLHTTP'
29
+ ];
30
+
31
+ for (i in names)
32
+ try {
33
+ return new ActiveXObject(names[i]);
34
+ } catch (e) {}
35
+ }
36
+
37
+ return null;
38
+ };
39
+
40
+ /**
41
+ * This function loads a JSON file and creates a new sigma instance or
42
+ * updates the graph of a given instance. It is possible to give a callback
43
+ * that will be executed at the end of the process.
44
+ *
45
+ * @param {string} url The URL of the JSON file.
46
+ * @param {object|sigma} sig A sigma configuration object or a sigma
47
+ * instance.
48
+ * @param {?function} callback Eventually a callback to execute after
49
+ * having parsed the file. It will be called
50
+ * with the related sigma instance as
51
+ * parameter.
52
+ */
53
+ sigma.parsers.json = function(url, sig, callback) {
54
+ var graph,
55
+ xhr = sigma.utils.xhr();
56
+
57
+ if (!xhr)
58
+ throw 'XMLHttpRequest not supported, cannot load the file.';
59
+
60
+ xhr.open('GET', url, true);
61
+ xhr.onreadystatechange = function() {
62
+ if (xhr.readyState === 4) {
63
+ graph = JSON.parse(xhr.responseText);
64
+
65
+ // Update the instance's graph:
66
+ if (sig instanceof sigma) {
67
+ sig.graph.clear();
68
+ sig.graph.read(graph);
69
+
70
+ // ...or instanciate sigma if needed:
71
+ } else if (typeof sig === 'object') {
72
+ sig.graph = graph;
73
+ sig = new sigma(sig);
74
+
75
+ // ...or it's finally the callback:
76
+ } else if (typeof sig === 'function') {
77
+ callback = sig;
78
+ sig = null;
79
+ }
80
+
81
+ // Call the callback if specified:
82
+ if (callback)
83
+ callback(sig || graph);
84
+ }
85
+ };
86
+ xhr.send();
87
+ };
88
+ }).call(this);
@@ -0,0 +1,8 @@
1
+ sigma.plugins.animate
2
+ =====================
3
+
4
+ Plugin developed by [Alexis Jacomy](https://github.com/jacomyal).
5
+
6
+ ---
7
+
8
+ This plugin provides a method to animate a sigma instance by interpolating some node properties. Check the `sigma.plugins.animate` function doc or the `examples/animate.html` code sample to know more.
@@ -0,0 +1,165 @@
1
+ /**
2
+ * This plugin provides a method to animate a sigma instance by interpolating
3
+ * some node properties. Check the sigma.plugins.animate function doc or the
4
+ * examples/animate.html code sample to know more.
5
+ */
6
+ (function() {
7
+ 'use strict';
8
+
9
+ if (typeof sigma === 'undefined')
10
+ throw 'sigma is not declared';
11
+
12
+ sigma.utils.pkg('sigma.plugins');
13
+
14
+ var _id = 0,
15
+ _cache = {};
16
+
17
+ // TOOLING FUNCTIONS:
18
+ // ******************
19
+ function parseColor(val) {
20
+ if (_cache[val])
21
+ return _cache[val];
22
+
23
+ var result = [0, 0, 0];
24
+
25
+ if (val.match(/^#/)) {
26
+ val = (val || '').replace(/^#/, '');
27
+ result = (val.length === 3) ?
28
+ [
29
+ parseInt(val.charAt(0) + val.charAt(0), 16),
30
+ parseInt(val.charAt(1) + val.charAt(1), 16),
31
+ parseInt(val.charAt(2) + val.charAt(2), 16)
32
+ ] :
33
+ [
34
+ parseInt(val.charAt(0) + val.charAt(1), 16),
35
+ parseInt(val.charAt(2) + val.charAt(3), 16),
36
+ parseInt(val.charAt(4) + val.charAt(5), 16)
37
+ ];
38
+ } else if (val.match(/^ *rgba? *\(/)) {
39
+ val = val.match(
40
+ /^ *rgba? *\( *([0-9]*) *, *([0-9]*) *, *([0-9]*) *(,.*)?\) *$/
41
+ );
42
+ result = [
43
+ +val[1],
44
+ +val[2],
45
+ +val[3]
46
+ ];
47
+ }
48
+
49
+ _cache[val] = {
50
+ r: result[0],
51
+ g: result[1],
52
+ b: result[2]
53
+ };
54
+
55
+ return _cache[val];
56
+ }
57
+
58
+ function interpolateColors(c1, c2, p) {
59
+ c1 = parseColor(c1);
60
+ c2 = parseColor(c2);
61
+
62
+ var c = {
63
+ r: c1.r * (1 - p) + c2.r * p,
64
+ g: c1.g * (1 - p) + c2.g * p,
65
+ b: c1.b * (1 - p) + c2.b * p
66
+ };
67
+
68
+ return 'rgb(' + [c.r | 0, c.g | 0, c.b | 0].join(',') + ')';
69
+ }
70
+
71
+ /**
72
+ * This function will animate some specified node properties. It will
73
+ * basically call requestAnimationFrame, interpolate the values and call the
74
+ * refresh method during a specified duration.
75
+ *
76
+ * Recognized parameters:
77
+ * **********************
78
+ * Here is the exhaustive list of every accepted parameters in the settings
79
+ * object:
80
+ *
81
+ * {?(function|string)} easing Either the name of an easing in the
82
+ * sigma.utils.easings package or a
83
+ * function. If not specified, the
84
+ * quadraticInOut easing from this package
85
+ * will be used instead.
86
+ * {?number} duration The duration of the animation. If not
87
+ * specified, the "animationsTime" setting
88
+ * value of the sigma instance will be used
89
+ * instead.
90
+ * {?function} onComplete Eventually a function to call when the
91
+ * animation is ended.
92
+ *
93
+ * @param {sigma} s The related sigma instance.
94
+ * @param {object} animate An hash with the keys being the node properties
95
+ * to interpolate, and the values being the related
96
+ * target values.
97
+ * @param {?object} options Eventually an object with options.
98
+ */
99
+ sigma.plugins.animate = function(s, animate, options) {
100
+ var o = options || {},
101
+ id = ++_id,
102
+ duration = o.duration || s.settings('animationsTime'),
103
+ easing = typeof o.easing === 'string' ?
104
+ sigma.utils.easings[o.easing] :
105
+ typeof o.easing === 'function' ?
106
+ o.easing :
107
+ sigma.utils.easings.quadraticInOut,
108
+ start = sigma.utils.dateNow(),
109
+ // Store initial positions:
110
+ startPositions = s.graph.nodes().reduce(function(res, node) {
111
+ var k;
112
+ res[node.id] = {};
113
+ for (k in animate)
114
+ if (k in node)
115
+ res[node.id][k] = node[k];
116
+ return res;
117
+ }, {});
118
+
119
+ s.animations = s.animations || Object.create({});
120
+ sigma.plugins.kill(s);
121
+
122
+ function step() {
123
+ var p = (sigma.utils.dateNow() - start) / duration;
124
+
125
+ if (p >= 1) {
126
+ s.graph.nodes().forEach(function(node) {
127
+ for (var k in animate)
128
+ if (k in animate)
129
+ node[k] = node[animate[k]];
130
+ });
131
+
132
+ s.refresh();
133
+ if (typeof o.onComplete === 'function')
134
+ o.onComplete();
135
+ } else {
136
+ p = easing(p);
137
+ s.graph.nodes().forEach(function(node) {
138
+ for (var k in animate)
139
+ if (k in animate) {
140
+ if (k.match(/color$/))
141
+ node[k] = interpolateColors(
142
+ startPositions[node.id][k],
143
+ node[animate[k]],
144
+ p
145
+ );
146
+ else
147
+ node[k] =
148
+ node[animate[k]] * p +
149
+ startPositions[node.id][k] * (1 - p);
150
+ }
151
+ });
152
+
153
+ s.refresh();
154
+ s.animations[id] = requestAnimationFrame(step);
155
+ }
156
+ }
157
+
158
+ step();
159
+ };
160
+
161
+ sigma.plugins.kill = function(s) {
162
+ for (var k in (s.animations || {}))
163
+ cancelAnimationFrame(s.animations[k]);
164
+ };
165
+ }).call(window);
@@ -0,0 +1,8 @@
1
+ sigma.plugins.dragNodes
2
+ =====================
3
+
4
+ Plugin developed by [José M. Camacho](https://github.com/josemazo).
5
+
6
+ ---
7
+
8
+ This plugin provides a method to drag & drop nodes. At the moment, this plugin is not compatible with the WebGL renderer. Check the sigma.plugins.dragNodes function doc or the examples/drag-nodes.html code sample to know more.
@@ -0,0 +1,135 @@
1
+ /**
2
+ * This plugin provides a method to drag & drop nodes. Check the
3
+ * sigma.plugins.dragNodes function doc or the examples/basic.html &
4
+ * examples/api-candy.html code samples to know more.
5
+ */
6
+ (function() {
7
+ 'use strict';
8
+
9
+ if (typeof sigma === 'undefined')
10
+ throw 'sigma is not declared';
11
+
12
+ sigma.utils.pkg('sigma.plugins');
13
+
14
+ /**
15
+ * This function will add `mousedown`, `mouseup` & `mousemove` events to the
16
+ * nodes in the `overNode`event to perform drag & drop operations. It uses
17
+ * `linear interpolation` [http://en.wikipedia.org/wiki/Linear_interpolation]
18
+ * and `rotation matrix` [http://en.wikipedia.org/wiki/Rotation_matrix] to
19
+ * calculate the X and Y coordinates from the `cam` or `renderer` node
20
+ * attributes. These attributes represent the coordinates of the nodes in
21
+ * the real container, not in canvas.
22
+ *
23
+ * Recognized parameters:
24
+ * **********************
25
+ * @param {sigma} s The related sigma instance.
26
+ * @param {renderer} renderer The related renderer instance.
27
+ */
28
+ sigma.plugins.dragNodes = function(s, renderer) {
29
+ // A quick hardcoded rule to prevent people from using this plugin with the
30
+ // WebGL renderer (which is impossible at the moment):
31
+ if (
32
+ sigma.renderers.webgl &&
33
+ renderer instanceof sigma.renderers.webgl
34
+ )
35
+ throw new Error(
36
+ 'The sigma.plugins.dragNodes is not compatible with the WebGL renderer'
37
+ );
38
+
39
+ var _body = document.body,
40
+ _container = renderer.container,
41
+ _mouse = _container.lastChild,
42
+ _camera = renderer.camera,
43
+ _node = null,
44
+ _prefix = '',
45
+ _isOverNode = false,
46
+ _isMouseOverCanvas = false;
47
+
48
+ // It removes the initial substring ('read_') if it's a WegGL renderer.
49
+ if (renderer instanceof sigma.renderers.webgl) {
50
+ _prefix = renderer.options.prefix.substr(5);
51
+ } else {
52
+ _prefix = renderer.options.prefix;
53
+ }
54
+
55
+ var nodeMouseOver = function(event) {
56
+ if (!_isOverNode) {
57
+ _node = event.data.node;
58
+ _mouse.addEventListener('mousedown', nodeMouseDown);
59
+ _isOverNode = true;
60
+ }
61
+ };
62
+
63
+ var treatOutNode = function(event) {
64
+ if (_isOverNode) {
65
+ _mouse.removeEventListener('mousedown', nodeMouseDown);
66
+ _isOverNode = false;
67
+ }
68
+ };
69
+
70
+ var nodeMouseDown = function(event) {
71
+ var size = s.graph.nodes().length;
72
+ if (size > 1) {
73
+ _mouse.removeEventListener('mousedown', nodeMouseDown);
74
+ _body.addEventListener('mousemove', nodeMouseMove);
75
+ _body.addEventListener('mouseup', nodeMouseUp);
76
+
77
+ renderer.unbind('outNode', treatOutNode);
78
+
79
+ // Deactivate drag graph.
80
+ renderer.settings({mouseEnabled: false, enableHovering: false});
81
+ s.refresh();
82
+ }
83
+ };
84
+
85
+ var nodeMouseUp = function(event) {
86
+ _mouse.addEventListener('mousedown', nodeMouseDown);
87
+ _body.removeEventListener('mousemove', nodeMouseMove);
88
+ _body.removeEventListener('mouseup', nodeMouseUp);
89
+
90
+ treatOutNode();
91
+ renderer.bind('outNode', treatOutNode);
92
+
93
+ // Activate drag graph.
94
+ renderer.settings({mouseEnabled: true, enableHovering: true});
95
+ s.refresh();
96
+ };
97
+
98
+ var nodeMouseMove = function(event) {
99
+ var x = event.pageX - _container.offsetLeft,
100
+ y = event.pageY - _container.offsetTop,
101
+ cos = Math.cos(_camera.angle),
102
+ sin = Math.sin(_camera.angle),
103
+ nodes = s.graph.nodes(),
104
+ ref = [];
105
+
106
+ // Getting and derotating the reference coordinates.
107
+ for (var i = 0; i < 2; i++) {
108
+ var n = nodes[i];
109
+ var aux = {
110
+ x: n.x * cos + n.y * sin,
111
+ y: n.y * cos - n.x * sin,
112
+ renX: n[_prefix + 'x'],
113
+ renY: n[_prefix + 'y'],
114
+ };
115
+ ref.push(aux);
116
+ }
117
+
118
+ // Applying linear interpolation.
119
+ x = ((x - ref[0].renX) / (ref[1].renX - ref[0].renX)) *
120
+ (ref[1].x - ref[0].x) + ref[0].x;
121
+ y = ((y - ref[0].renY) / (ref[1].renY - ref[0].renY)) *
122
+ (ref[1].y - ref[0].y) + ref[0].y;
123
+
124
+ // Rotating the coordinates.
125
+ _node.x = x * cos - y * sin;
126
+ _node.y = y * cos + x * sin;
127
+
128
+ s.refresh();
129
+ };
130
+
131
+ renderer.bind('overNode', nodeMouseOver);
132
+ renderer.bind('outNode', treatOutNode);
133
+ };
134
+
135
+ }).call(window);