sigma-rails 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|