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,24 @@
|
|
1
|
+
sigma.plugins.neighborhood
|
2
|
+
==========================
|
3
|
+
|
4
|
+
Plugin developed by [Alexis Jacomy](https://github.com/jacomyal).
|
5
|
+
|
6
|
+
---
|
7
|
+
|
8
|
+
This plugin provides a method to retrieve the neighborhood of a node. Basically, it loads a graph and stores it in a headless `sigma.classes.graph` instance, that you can query to retrieve neighborhoods.
|
9
|
+
|
10
|
+
It is useful for people who want to provide a neighborhoods navigation inside a big graph instead of just displaying it, and without having to deploy an API or the list of every neighborhoods. But please note that this plugin is here as an example of what you can do with the graph model, and do not hesitate to try customizing your navigation through graphs.
|
11
|
+
|
12
|
+
This plugin also adds to the graph model a method called "neighborhood". Check the code for more information.
|
13
|
+
|
14
|
+
Here is how to use it:
|
15
|
+
|
16
|
+
````javascript
|
17
|
+
var db = new sigma.plugins.neighborhoods();
|
18
|
+
db.load('path/to/my/graph.json', function() {
|
19
|
+
var nodeId = 'anyNodeID';
|
20
|
+
mySigmaInstance
|
21
|
+
.read(db.neighborhood(nodeId))
|
22
|
+
.refresh();
|
23
|
+
});
|
24
|
+
````
|
@@ -0,0 +1,186 @@
|
|
1
|
+
/**
|
2
|
+
* This plugin provides a method to retrieve the neighborhood of a node.
|
3
|
+
* Basically, it loads a graph and stores it in a headless sigma.classes.graph
|
4
|
+
* instance, that you can query to retrieve neighborhoods.
|
5
|
+
*
|
6
|
+
* It is useful for people who want to provide a neighborhoods navigation
|
7
|
+
* inside a big graph instead of just displaying it, and without having to
|
8
|
+
* deploy an API or the list of every neighborhoods.
|
9
|
+
*
|
10
|
+
* This plugin also adds to the graph model a method called "neighborhood".
|
11
|
+
* Check the code for more information.
|
12
|
+
*
|
13
|
+
* Here is how to use it:
|
14
|
+
*
|
15
|
+
* > var db = new sigma.plugins.neighborhoods();
|
16
|
+
* > db.load('path/to/my/graph.json', function() {
|
17
|
+
* > var nodeId = 'anyNodeID';
|
18
|
+
* > mySigmaInstance
|
19
|
+
* > .read(db.neighborhood(nodeId))
|
20
|
+
* > .refresh();
|
21
|
+
* > });
|
22
|
+
*/
|
23
|
+
(function() {
|
24
|
+
'use strict';
|
25
|
+
|
26
|
+
if (typeof sigma === 'undefined')
|
27
|
+
throw 'sigma is not declared';
|
28
|
+
|
29
|
+
/**
|
30
|
+
* This method takes the ID of node as argument and returns the graph of the
|
31
|
+
* specified node, with every other nodes that are connected to it and every
|
32
|
+
* edges that connect two of the previously cited nodes. It uses the built-in
|
33
|
+
* indexes from sigma's graph model to search in the graph.
|
34
|
+
*
|
35
|
+
* @param {string} centerId The ID of the center node.
|
36
|
+
* @return {object} The graph, as a simple descriptive object, in
|
37
|
+
* the format required by the "read" graph method.
|
38
|
+
*/
|
39
|
+
sigma.classes.graph.addMethod(
|
40
|
+
'neighborhood',
|
41
|
+
function(centerId) {
|
42
|
+
var k1,
|
43
|
+
k2,
|
44
|
+
k3,
|
45
|
+
node,
|
46
|
+
center,
|
47
|
+
// Those two local indexes are here just to avoid duplicates:
|
48
|
+
localNodesIndex = {},
|
49
|
+
localEdgesIndex = {},
|
50
|
+
// And here is the resulted graph, empty at the moment:
|
51
|
+
graph = {
|
52
|
+
nodes: [],
|
53
|
+
edges: []
|
54
|
+
};
|
55
|
+
|
56
|
+
// Check that the exists:
|
57
|
+
if (!this.nodes(centerId))
|
58
|
+
return graph;
|
59
|
+
|
60
|
+
// Add center. It has to be cloned to add it the "center" attribute
|
61
|
+
// without altering the current graph:
|
62
|
+
node = this.nodes(centerId);
|
63
|
+
center = {};
|
64
|
+
center.center = true;
|
65
|
+
for (k1 in node)
|
66
|
+
center[k1] = node[k1];
|
67
|
+
|
68
|
+
localNodesIndex[centerId] = true;
|
69
|
+
graph.nodes.push(center);
|
70
|
+
|
71
|
+
// Add neighbors and edges between the center and the neighbors:
|
72
|
+
for (k1 in this.allNeighborsIndex[centerId]) {
|
73
|
+
if (!localNodesIndex[k1]) {
|
74
|
+
localNodesIndex[k1] = true;
|
75
|
+
graph.nodes.push(this.nodesIndex[k1]);
|
76
|
+
}
|
77
|
+
|
78
|
+
for (k2 in this.allNeighborsIndex[centerId][k1])
|
79
|
+
if (!localEdgesIndex[k2]) {
|
80
|
+
localEdgesIndex[k2] = true;
|
81
|
+
graph.edges.push(this.edgesIndex[k2]);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
// Add edges connecting two neighbors:
|
86
|
+
for (k1 in localNodesIndex)
|
87
|
+
if (k1 !== centerId)
|
88
|
+
for (k2 in localNodesIndex)
|
89
|
+
if (
|
90
|
+
k2 !== centerId &&
|
91
|
+
k1 !== k2 &&
|
92
|
+
this.allNeighborsIndex[k1][k2]
|
93
|
+
)
|
94
|
+
for (k3 in this.allNeighborsIndex[k1][k2])
|
95
|
+
if (!localEdgesIndex[k3]) {
|
96
|
+
localEdgesIndex[k3] = true;
|
97
|
+
graph.edges.push(this.edgesIndex[k3]);
|
98
|
+
}
|
99
|
+
|
100
|
+
// Finally, let's return the final graph:
|
101
|
+
return graph;
|
102
|
+
}
|
103
|
+
);
|
104
|
+
|
105
|
+
sigma.utils.pkg('sigma.plugins');
|
106
|
+
|
107
|
+
/**
|
108
|
+
* sigma.plugins.neighborhoods constructor.
|
109
|
+
*/
|
110
|
+
sigma.plugins.neighborhoods = function() {
|
111
|
+
var ready = false,
|
112
|
+
readyCallbacks = [],
|
113
|
+
graph = new sigma.classes.graph();
|
114
|
+
|
115
|
+
/**
|
116
|
+
* This method just returns the neighborhood of a node.
|
117
|
+
*
|
118
|
+
* @param {string} centerNodeID The ID of the center node.
|
119
|
+
* @return {object} Returns the neighborhood.
|
120
|
+
*/
|
121
|
+
this.neighborhood = function(centerNodeID) {
|
122
|
+
return graph.neighborhood(centerNodeID);
|
123
|
+
};
|
124
|
+
|
125
|
+
/**
|
126
|
+
* This method loads the JSON graph at "path", stores it in the local graph
|
127
|
+
* instance, and executes the callback.
|
128
|
+
*
|
129
|
+
* @param {string} path The path of the JSON graph file.
|
130
|
+
* @param {?function} callback Eventually a callback to execute.
|
131
|
+
*/
|
132
|
+
this.load = function(path, callback) {
|
133
|
+
// Quick XHR polyfill:
|
134
|
+
var xhr = (function() {
|
135
|
+
if (window.XMLHttpRequest)
|
136
|
+
return new XMLHttpRequest();
|
137
|
+
|
138
|
+
var names,
|
139
|
+
i;
|
140
|
+
|
141
|
+
if (window.ActiveXObject) {
|
142
|
+
names = [
|
143
|
+
'Msxml2.XMLHTTP.6.0',
|
144
|
+
'Msxml2.XMLHTTP.3.0',
|
145
|
+
'Msxml2.XMLHTTP',
|
146
|
+
'Microsoft.XMLHTTP'
|
147
|
+
];
|
148
|
+
|
149
|
+
for (i in names)
|
150
|
+
try {
|
151
|
+
return new ActiveXObject(names[i]);
|
152
|
+
} catch (e) {}
|
153
|
+
}
|
154
|
+
|
155
|
+
return null;
|
156
|
+
})();
|
157
|
+
|
158
|
+
if (!xhr)
|
159
|
+
throw 'XMLHttpRequest not supported, cannot load the data.';
|
160
|
+
|
161
|
+
xhr.open('GET', path, true);
|
162
|
+
xhr.onreadystatechange = function() {
|
163
|
+
if (xhr.readyState === 4) {
|
164
|
+
graph.clear().read(JSON.parse(xhr.responseText));
|
165
|
+
|
166
|
+
if (callback)
|
167
|
+
callback();
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
171
|
+
// Start loading the file:
|
172
|
+
xhr.send();
|
173
|
+
|
174
|
+
return this;
|
175
|
+
};
|
176
|
+
|
177
|
+
/**
|
178
|
+
* This method cleans the graph instance "reads" a graph into it.
|
179
|
+
*
|
180
|
+
* @param {object} g The graph object to read.
|
181
|
+
*/
|
182
|
+
this.read = function(g) {
|
183
|
+
graph.clear().read(g);
|
184
|
+
};
|
185
|
+
};
|
186
|
+
}).call(window);
|
@@ -0,0 +1,55 @@
|
|
1
|
+
sigma.renderers.customShapes
|
2
|
+
==================
|
3
|
+
|
4
|
+
Plugin developed by [Ron Peleg](https://github.com/rpeleg1970).
|
5
|
+
|
6
|
+
---
|
7
|
+
## General
|
8
|
+
This plugin registers custom node shape renderers, and allows adding scaled images on top of them. See the following [example code](../../examples/plugin-customShapes.html) for full usage.
|
9
|
+
|
10
|
+
To use, include all .js files under this folder.
|
11
|
+
|
12
|
+
The plugin implements the `node.borderColor` property to allow control of the (surprise) border color.
|
13
|
+
|
14
|
+
## Shapes
|
15
|
+
The plugin implements the following shapes. To set a shape renderer, you simply set `node.type='shape-name'` e.g. `node.type='star'`. The default renderer implemented by sigma.js is named `def` - see also [generic custom node renderer example](../../examples/custom-node-renderer.html)
|
16
|
+
* `circle`: similar to the `def` renderer, but also allows images
|
17
|
+
* `square`
|
18
|
+
* `diamond`
|
19
|
+
* `equilateral`: equilateral polygon. you can control additional properties in this polygon by setting more values as follows:
|
20
|
+
````javascript
|
21
|
+
node.equilateral = {
|
22
|
+
rotate: /* rotate right, value in deg */,
|
23
|
+
numPoints: /* default 5, integer */
|
24
|
+
}
|
25
|
+
````
|
26
|
+
* `star`: you can control additional properties in this star by setting more as follows:
|
27
|
+
````javascript
|
28
|
+
node.star = {
|
29
|
+
numPoints: /* default 5, integer */,
|
30
|
+
innerRatio: /* ratio of inner radius in star, compared to node.size */
|
31
|
+
}
|
32
|
+
````
|
33
|
+
* `pacman`: an example of a more exotic renderer
|
34
|
+
|
35
|
+
The list of available renderer types can be obtained by calling `ShapeLibrary.enumerate()`
|
36
|
+
|
37
|
+
## Images
|
38
|
+
You can add an image to any node, simply by adding `node.image` property, with the following content:
|
39
|
+
````javascript
|
40
|
+
node.image = {
|
41
|
+
url: /* mandatory image URL */,
|
42
|
+
clip: /* Ratio of image clipping disk compared to node size (def 1.0) - see example to how we adapt this to differenmt shapes */,
|
43
|
+
scale: /* Ratio of how to scale the image, compared to node size, default 1.0 */,
|
44
|
+
w: /* numeric width - important for correct scaling if w/h ratio is not 1.0 */,
|
45
|
+
h: /* numeric height - important for correct scaling if w/h ratio is not 1.0 */
|
46
|
+
}
|
47
|
+
````
|
48
|
+
Because the plug-in calls the sigma instance `refresh()` method on image loading, you MUST init as follows or you will not see rendered images:
|
49
|
+
````javascript
|
50
|
+
s = new sigma({
|
51
|
+
...
|
52
|
+
});
|
53
|
+
CustomShapes.init(s);
|
54
|
+
s.refresh();
|
55
|
+
````
|
@@ -0,0 +1,145 @@
|
|
1
|
+
;(function(undefined) {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
var shapes = [];
|
5
|
+
var register = function(name,drawShape,drawBorder) {
|
6
|
+
shapes.push({
|
7
|
+
'name': name,
|
8
|
+
'drawShape': drawShape,
|
9
|
+
'drawBorder': drawBorder
|
10
|
+
});
|
11
|
+
}
|
12
|
+
|
13
|
+
var enumerateShapes = function() {
|
14
|
+
return shapes;
|
15
|
+
}
|
16
|
+
|
17
|
+
/**
|
18
|
+
* For the standard closed shapes - the shape fill and border are drawn the
|
19
|
+
* same, with some minor differences for fill and border. To facilitate this we
|
20
|
+
* create the generic draw functions, that take a shape drawing func and
|
21
|
+
* return a shape-renderer/border-renderer
|
22
|
+
* ----------
|
23
|
+
*/
|
24
|
+
var genericDrawShape = function(shapeFunc) {
|
25
|
+
return function(node,x,y,size,color,context) {
|
26
|
+
context.fillStyle = color;
|
27
|
+
context.beginPath();
|
28
|
+
shapeFunc(node,x,y,size,context);
|
29
|
+
context.closePath();
|
30
|
+
context.fill();
|
31
|
+
};
|
32
|
+
}
|
33
|
+
|
34
|
+
var genericDrawBorder = function(shapeFunc) {
|
35
|
+
return function(node,x,y,size,color,context) {
|
36
|
+
context.strokeStyle = color;
|
37
|
+
context.lineWidth = size / 5;
|
38
|
+
context.beginPath();
|
39
|
+
shapeFunc(node,x,y,size,context);
|
40
|
+
context.closePath();
|
41
|
+
context.stroke();
|
42
|
+
};
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* We now proced to use the generics to define our standard shape/border
|
47
|
+
* drawers: square, diamond, equilateral (polygon), and star
|
48
|
+
* ----------
|
49
|
+
*/
|
50
|
+
var drawSquare = function(node,x,y,size,context) {
|
51
|
+
var rotate = Math.PI*45/180; // 45 deg rotation of a diamond shape
|
52
|
+
context.moveTo(x+size*Math.sin(rotate), y-size*Math.cos(rotate)); // first point on outer radius, dwangle 'rotate'
|
53
|
+
for(var i=1; i<4; i++) {
|
54
|
+
context.lineTo(x+Math.sin(rotate+2*Math.PI*i/4)*size, y-Math.cos(rotate+2*Math.PI*i/4)*size);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
register("square",genericDrawShape(drawSquare),genericDrawBorder(drawSquare));
|
58
|
+
|
59
|
+
var drawCircle = function(node,x,y,size,context) {
|
60
|
+
context.arc(x,y,size,0,Math.PI*2,true);
|
61
|
+
}
|
62
|
+
register("circle",genericDrawShape(drawCircle),genericDrawBorder(drawCircle));
|
63
|
+
|
64
|
+
var drawDiamond = function(node,x,y,size,context) {
|
65
|
+
context.moveTo(x-size, y);
|
66
|
+
context.lineTo(x, y-size);
|
67
|
+
context.lineTo(x+size, y);
|
68
|
+
context.lineTo(x, y+size);
|
69
|
+
}
|
70
|
+
register("diamond",genericDrawShape(drawDiamond),genericDrawBorder(drawDiamond));
|
71
|
+
|
72
|
+
var drawEquilateral = function(node,x,y,size,context) {
|
73
|
+
var pcount = (node.equilateral && node.equilateral.numPoints) || 5;
|
74
|
+
var rotate = ((node.equilateral && node.equilateral.rotate) || 0)*Math.PI/180;
|
75
|
+
var radius = size;
|
76
|
+
context.moveTo(x+radius*Math.sin(rotate), y-radius*Math.cos(rotate)); // first point on outer radius, angle 'rotate'
|
77
|
+
for(var i=1; i<pcount; i++) {
|
78
|
+
context.lineTo(x+Math.sin(rotate+2*Math.PI*i/pcount)*radius, y-Math.cos(rotate+2*Math.PI*i/pcount)*radius);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
register("equilateral",genericDrawShape(drawEquilateral),genericDrawBorder(drawEquilateral));
|
82
|
+
|
83
|
+
|
84
|
+
var starShape = function(node,x,y,size,context) {
|
85
|
+
var pcount = (node.star && node.star.numPoints) || 5,
|
86
|
+
inRatio = (node.star && node.star.innerRatio) || 0.5,
|
87
|
+
outR = size,
|
88
|
+
inR = size*inRatio,
|
89
|
+
angleOffset = Math.PI/pcount;
|
90
|
+
context.moveTo(x, y-size); // first point on outer radius, top
|
91
|
+
for(var i=0; i<pcount; i++) {
|
92
|
+
context.lineTo(x+Math.sin(angleOffset+2*Math.PI*i/pcount)*inR,
|
93
|
+
y-Math.cos(angleOffset+2*Math.PI*i/pcount)*inR);
|
94
|
+
context.lineTo(x+Math.sin(2*Math.PI*(i+1)/pcount)*outR,
|
95
|
+
y-Math.cos(2*Math.PI*(i+1)/pcount)*outR);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
register("star",genericDrawShape(starShape),genericDrawBorder(starShape));
|
99
|
+
|
100
|
+
/**
|
101
|
+
* An example of a non standard shape (pacman). Here we WILL NOT use the
|
102
|
+
* genericDraw functions, but rather register a full custom node renderer for
|
103
|
+
* fill, and skip the border renderer which is irrelevant for this shape
|
104
|
+
* ----------
|
105
|
+
*/
|
106
|
+
var drawPacman = function(node,x,y,size,color,context) {
|
107
|
+
context.fillStyle = 'yellow';
|
108
|
+
context.beginPath();
|
109
|
+
context.arc(x,y,size,1.25*Math.PI,0,false);
|
110
|
+
context.arc(x,y,size,0,0.75*Math.PI,false);
|
111
|
+
context.lineTo(x,y);
|
112
|
+
context.closePath();
|
113
|
+
context.fill();
|
114
|
+
|
115
|
+
context.fillStyle = 'white';
|
116
|
+
context.strokeStyle = 'black';
|
117
|
+
context.beginPath();
|
118
|
+
context.arc(x+size/3,y-size/3,size/4,0,2*Math.PI,false);
|
119
|
+
context.closePath();
|
120
|
+
context.fill();
|
121
|
+
context.stroke();
|
122
|
+
|
123
|
+
context.fillStyle = 'black';
|
124
|
+
context.beginPath();
|
125
|
+
context.arc(x+4*size/9,y-size/3,size/8,0,2*Math.PI,false);
|
126
|
+
context.closePath();
|
127
|
+
context.fill();
|
128
|
+
}
|
129
|
+
register("pacman",drawPacman,null);
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Exporting
|
133
|
+
* ----------
|
134
|
+
*/
|
135
|
+
this.ShapeLibrary = {
|
136
|
+
|
137
|
+
// Functions
|
138
|
+
enumerate: enumerateShapes,
|
139
|
+
// add: addShape,
|
140
|
+
|
141
|
+
// Version
|
142
|
+
version: '0.1'
|
143
|
+
};
|
144
|
+
|
145
|
+
}).call(this);
|
@@ -0,0 +1,112 @@
|
|
1
|
+
;(function(undefined) {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
if (typeof sigma === 'undefined')
|
5
|
+
throw 'sigma is not declared';
|
6
|
+
|
7
|
+
if (typeof ShapeLibrary === 'undefined')
|
8
|
+
throw 'ShapeLibrary is not declared';
|
9
|
+
|
10
|
+
|
11
|
+
// Initialize package:
|
12
|
+
sigma.utils.pkg('sigma.canvas.nodes');
|
13
|
+
|
14
|
+
var sigInst = undefined;
|
15
|
+
var imgCache = {};
|
16
|
+
|
17
|
+
var initPlugin = function(inst) {
|
18
|
+
sigInst = inst;
|
19
|
+
}
|
20
|
+
|
21
|
+
var drawImage = function (node,x,y,size,context) {
|
22
|
+
if(sigInst && node.image && node.image.url) {
|
23
|
+
var url = node.image.url;
|
24
|
+
var ih = node.image.h || 1; // 1 is arbitrary, anyway only the ratio counts
|
25
|
+
var iw = node.image.w || 1;
|
26
|
+
var scale = node.image.scale || 1;
|
27
|
+
var clip = node.image.clip || 1;
|
28
|
+
|
29
|
+
// create new IMG or get from imgCache
|
30
|
+
var image = imgCache[url];
|
31
|
+
if(!image) {
|
32
|
+
image = document.createElement('IMG');
|
33
|
+
image.src = url;
|
34
|
+
image.onload = function(){
|
35
|
+
// TODO see how we redraw on load
|
36
|
+
// need to provide the siginst as a parameter to the library
|
37
|
+
console.log("redraw on image load");
|
38
|
+
sigInst.refresh();
|
39
|
+
};
|
40
|
+
imgCache[url] = image;
|
41
|
+
}
|
42
|
+
|
43
|
+
// calculate position and draw
|
44
|
+
var xratio = (iw<ih) ? (iw/ih) : 1;
|
45
|
+
var yratio = (ih<iw) ? (ih/iw) : 1;
|
46
|
+
var r = size*scale;
|
47
|
+
|
48
|
+
// Draw the clipping disc:
|
49
|
+
context.save(); // enter clipping mode
|
50
|
+
context.beginPath();
|
51
|
+
context.arc(x,y,size*clip,0,Math.PI*2,true);
|
52
|
+
context.closePath();
|
53
|
+
context.clip();
|
54
|
+
|
55
|
+
// Draw the actual image
|
56
|
+
context.drawImage(image,
|
57
|
+
x+Math.sin(-3.142/4)*r*xratio,
|
58
|
+
y-Math.cos(-3.142/4)*r*yratio,
|
59
|
+
r*xratio*2*Math.sin(-3.142/4)*(-1),
|
60
|
+
r*yratio*2*Math.cos(-3.142/4));
|
61
|
+
context.restore(); // exit clipping mode
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
var register = function(name,drawShape,drawBorder) {
|
67
|
+
sigma.canvas.nodes[name] = function(node, context, settings) {
|
68
|
+
var args = arguments,
|
69
|
+
prefix = settings('prefix') || '',
|
70
|
+
size = node[prefix + 'size'],
|
71
|
+
color = node.color || settings('defaultNodeColor'),
|
72
|
+
borderColor = node.borderColor || color,
|
73
|
+
x = node[prefix + 'x'],
|
74
|
+
y = node[prefix + 'y'];
|
75
|
+
|
76
|
+
context.save();
|
77
|
+
|
78
|
+
if(drawShape) {
|
79
|
+
drawShape(node,x,y,size,color,context);
|
80
|
+
}
|
81
|
+
|
82
|
+
if(drawBorder) {
|
83
|
+
drawBorder(node,x,y,size,borderColor,context);
|
84
|
+
}
|
85
|
+
|
86
|
+
drawImage(node,x,y,size,context);
|
87
|
+
|
88
|
+
context.restore();
|
89
|
+
};
|
90
|
+
}
|
91
|
+
|
92
|
+
ShapeLibrary.enumerate().forEach(function(shape) {
|
93
|
+
register(shape.name,shape.drawShape,shape.drawBorder);
|
94
|
+
});
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Exporting
|
98
|
+
* ----------
|
99
|
+
*/
|
100
|
+
this.CustomShapes = {
|
101
|
+
|
102
|
+
// Functions
|
103
|
+
init: initPlugin,
|
104
|
+
// add pre-cache images
|
105
|
+
|
106
|
+
// Version
|
107
|
+
version: '0.1'
|
108
|
+
};
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
}).call(this);
|