sigma-rails 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/lib/sigma/rails.rb +8 -0
- data/lib/sigma/rails/version.rb +5 -0
- data/vendor/assets/javascripts/sigma.js +8723 -0
- data/vendor/assets/javascripts/sigma.layout.forceAtlas2/README.md +12 -0
- data/vendor/assets/javascripts/sigma.layout.forceAtlas2/sigma.layout.forceAtlas2.js +1051 -0
- data/vendor/assets/javascripts/sigma.parsers.gexf/README.md +29 -0
- data/vendor/assets/javascripts/sigma.parsers.gexf/gexf-parser.js +548 -0
- data/vendor/assets/javascripts/sigma.parsers.gexf/sigma.parsers.gexf.js +108 -0
- data/vendor/assets/javascripts/sigma.parsers.json/README.md +29 -0
- data/vendor/assets/javascripts/sigma.parsers.json/sigma.parsers.json.js +88 -0
- data/vendor/assets/javascripts/sigma.plugins.animate/README.md +8 -0
- data/vendor/assets/javascripts/sigma.plugins.animate/sigma.plugins.animate.js +165 -0
- data/vendor/assets/javascripts/sigma.plugins.dragNodes/README.md +8 -0
- data/vendor/assets/javascripts/sigma.plugins.dragNodes/sigma.plugins.dragNodes.js +135 -0
- data/vendor/assets/javascripts/sigma.plugins.neighborhoods/README.md +24 -0
- data/vendor/assets/javascripts/sigma.plugins.neighborhoods/sigma.plugins.neighborhoods.js +186 -0
- data/vendor/assets/javascripts/sigma.renderers.customShapes/README.md +55 -0
- data/vendor/assets/javascripts/sigma.renderers.customShapes/shape-library.js +145 -0
- data/vendor/assets/javascripts/sigma.renderers.customShapes/sigma.renderers.customShapes.js +112 -0
- 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);
|