vis-rails 0.0.4 → 0.0.5
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 +5 -13
- data/lib/vis/rails/version.rb +1 -1
- data/vendor/assets/component/emitter.js +162 -0
- data/vendor/assets/javascripts/vis.js +1 -0
- data/vendor/assets/vis/DataSet.js +8 -2
- data/vendor/assets/vis/DataView.js +8 -4
- data/vendor/assets/vis/graph/Edge.js +210 -78
- data/vendor/assets/vis/graph/Graph.js +474 -652
- data/vendor/assets/vis/graph/Node.js +119 -82
- data/vendor/assets/vis/graph/css/graph-manipulation.css +128 -0
- data/vendor/assets/vis/graph/css/graph-navigation.css +62 -0
- data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +1141 -0
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +296 -0
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +433 -0
- data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +201 -0
- data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +173 -0
- data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +552 -0
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +558 -0
- data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +373 -0
- data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +64 -0
- data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +513 -0
- data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +66 -0
- data/vendor/assets/vis/graph/img/acceptDeleteIcon.png +0 -0
- data/vendor/assets/vis/graph/img/addNodeIcon.png +0 -0
- data/vendor/assets/vis/graph/img/backIcon.png +0 -0
- data/vendor/assets/vis/graph/img/connectIcon.png +0 -0
- data/vendor/assets/vis/graph/img/cross.png +0 -0
- data/vendor/assets/vis/graph/img/cross2.png +0 -0
- data/vendor/assets/vis/graph/img/deleteIcon.png +0 -0
- data/vendor/assets/vis/graph/img/downArrow.png +0 -0
- data/vendor/assets/vis/graph/img/editIcon.png +0 -0
- data/vendor/assets/vis/graph/img/leftArrow.png +0 -0
- data/vendor/assets/vis/graph/img/rightArrow.png +0 -0
- data/vendor/assets/vis/graph/img/upArrow.png +0 -0
- data/vendor/assets/vis/module/exports.js +0 -2
- data/vendor/assets/vis/module/header.js +2 -2
- data/vendor/assets/vis/module/imports.js +1 -2
- data/vendor/assets/vis/timeline/Controller.js +56 -45
- data/vendor/assets/vis/timeline/Range.js +68 -62
- data/vendor/assets/vis/timeline/Stack.js +11 -13
- data/vendor/assets/vis/timeline/TimeStep.js +43 -38
- data/vendor/assets/vis/timeline/Timeline.js +215 -93
- data/vendor/assets/vis/timeline/component/Component.js +19 -3
- data/vendor/assets/vis/timeline/component/CurrentTime.js +1 -1
- data/vendor/assets/vis/timeline/component/CustomTime.js +39 -120
- data/vendor/assets/vis/timeline/component/GroupSet.js +35 -1
- data/vendor/assets/vis/timeline/component/ItemSet.js +272 -9
- data/vendor/assets/vis/timeline/component/RootPanel.js +59 -47
- data/vendor/assets/vis/timeline/component/TimeAxis.js +10 -0
- data/vendor/assets/vis/timeline/component/css/item.css +53 -22
- data/vendor/assets/vis/timeline/component/item/Item.js +40 -5
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +3 -1
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +3 -1
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +67 -3
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +37 -9
- data/vendor/assets/vis/timeline/img/delete.png +0 -0
- data/vendor/assets/vis/util.js +169 -30
- metadata +39 -12
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NmZjNDhhYzgxOTVlYmNmNTYzNDg4NWE1YzJkN2U4ZDAyYzY3NzgzYw==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a580d6253ed70eb32d505bf44beff11f114a4f81
|
4
|
+
data.tar.gz: 2b0795e57a056c2347a7084bf93ae8e93cdb5e39
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
Mjk5NGQ3YTUxMTMzNGU4MDQ3M2FkNjM1OWUyZWIzMDRmZmUwOWI1YjEwOTQ2
|
11
|
-
MzIzNTUxNzE0MDcxMDVkMzc3NmFiNzczZDgzYzU3NTBjZTEwODQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTRlNjE0YzNiZDgxOTVhOGY2OWY5NmM0YTAzZGUyZWRmNThkNjZlY2M1MGIz
|
14
|
-
Nzc1MDhiZTRlNDIyNGQ5MjhkNjE4YTE3ZDliNTM0NzllYmUwMjQyMmJjOTIw
|
15
|
-
NWY3ODg5MTc0Y2U0NWRhYzQyMGNmOGUxNzA0YjUwYzcwY2UzY2M=
|
6
|
+
metadata.gz: f74e570dad14bb4b1be2682f924e6153c7b5d47bc36b5449d43b9ebb99a6692d524ec873c7f1882c1912fdb8f5f6ce4aa47f9c901bd656f227d735c4a994e1a5
|
7
|
+
data.tar.gz: 4ac01a2a19d2b44dce0629621dca14eba2b4a77f3ba008cbae56449540c73151443efd9fe21c64f219205a1a6e888e2e801611cf1f6f2b9b0dd39868a29644a0
|
data/lib/vis/rails/version.rb
CHANGED
@@ -0,0 +1,162 @@
|
|
1
|
+
|
2
|
+
/**
|
3
|
+
* Expose `Emitter`.
|
4
|
+
*/
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Initialize a new `Emitter`.
|
8
|
+
*
|
9
|
+
* @api public
|
10
|
+
*/
|
11
|
+
|
12
|
+
function Emitter(obj) {
|
13
|
+
if (obj) return mixin(obj);
|
14
|
+
};
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Mixin the emitter properties.
|
18
|
+
*
|
19
|
+
* @param {Object} obj
|
20
|
+
* @return {Object}
|
21
|
+
* @api private
|
22
|
+
*/
|
23
|
+
|
24
|
+
function mixin(obj) {
|
25
|
+
for (var key in Emitter.prototype) {
|
26
|
+
obj[key] = Emitter.prototype[key];
|
27
|
+
}
|
28
|
+
return obj;
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Listen on the given `event` with `fn`.
|
33
|
+
*
|
34
|
+
* @param {String} event
|
35
|
+
* @param {Function} fn
|
36
|
+
* @return {Emitter}
|
37
|
+
* @api public
|
38
|
+
*/
|
39
|
+
|
40
|
+
Emitter.prototype.on =
|
41
|
+
Emitter.prototype.addEventListener = function(event, fn){
|
42
|
+
this._callbacks = this._callbacks || {};
|
43
|
+
(this._callbacks[event] = this._callbacks[event] || [])
|
44
|
+
.push(fn);
|
45
|
+
return this;
|
46
|
+
};
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Adds an `event` listener that will be invoked a single
|
50
|
+
* time then automatically removed.
|
51
|
+
*
|
52
|
+
* @param {String} event
|
53
|
+
* @param {Function} fn
|
54
|
+
* @return {Emitter}
|
55
|
+
* @api public
|
56
|
+
*/
|
57
|
+
|
58
|
+
Emitter.prototype.once = function(event, fn){
|
59
|
+
var self = this;
|
60
|
+
this._callbacks = this._callbacks || {};
|
61
|
+
|
62
|
+
function on() {
|
63
|
+
self.off(event, on);
|
64
|
+
fn.apply(this, arguments);
|
65
|
+
}
|
66
|
+
|
67
|
+
on.fn = fn;
|
68
|
+
this.on(event, on);
|
69
|
+
return this;
|
70
|
+
};
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Remove the given callback for `event` or all
|
74
|
+
* registered callbacks.
|
75
|
+
*
|
76
|
+
* @param {String} event
|
77
|
+
* @param {Function} fn
|
78
|
+
* @return {Emitter}
|
79
|
+
* @api public
|
80
|
+
*/
|
81
|
+
|
82
|
+
Emitter.prototype.off =
|
83
|
+
Emitter.prototype.removeListener =
|
84
|
+
Emitter.prototype.removeAllListeners =
|
85
|
+
Emitter.prototype.removeEventListener = function(event, fn){
|
86
|
+
this._callbacks = this._callbacks || {};
|
87
|
+
|
88
|
+
// all
|
89
|
+
if (0 == arguments.length) {
|
90
|
+
this._callbacks = {};
|
91
|
+
return this;
|
92
|
+
}
|
93
|
+
|
94
|
+
// specific event
|
95
|
+
var callbacks = this._callbacks[event];
|
96
|
+
if (!callbacks) return this;
|
97
|
+
|
98
|
+
// remove all handlers
|
99
|
+
if (1 == arguments.length) {
|
100
|
+
delete this._callbacks[event];
|
101
|
+
return this;
|
102
|
+
}
|
103
|
+
|
104
|
+
// remove specific handler
|
105
|
+
var cb;
|
106
|
+
for (var i = 0; i < callbacks.length; i++) {
|
107
|
+
cb = callbacks[i];
|
108
|
+
if (cb === fn || cb.fn === fn) {
|
109
|
+
callbacks.splice(i, 1);
|
110
|
+
break;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
return this;
|
114
|
+
};
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Emit `event` with the given args.
|
118
|
+
*
|
119
|
+
* @param {String} event
|
120
|
+
* @param {Mixed} ...
|
121
|
+
* @return {Emitter}
|
122
|
+
*/
|
123
|
+
|
124
|
+
Emitter.prototype.emit = function(event){
|
125
|
+
this._callbacks = this._callbacks || {};
|
126
|
+
var args = [].slice.call(arguments, 1)
|
127
|
+
, callbacks = this._callbacks[event];
|
128
|
+
|
129
|
+
if (callbacks) {
|
130
|
+
callbacks = callbacks.slice(0);
|
131
|
+
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
132
|
+
callbacks[i].apply(this, args);
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
return this;
|
137
|
+
};
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Return array of callbacks for `event`.
|
141
|
+
*
|
142
|
+
* @param {String} event
|
143
|
+
* @return {Array}
|
144
|
+
* @api public
|
145
|
+
*/
|
146
|
+
|
147
|
+
Emitter.prototype.listeners = function(event){
|
148
|
+
this._callbacks = this._callbacks || {};
|
149
|
+
return this._callbacks[event] || [];
|
150
|
+
};
|
151
|
+
|
152
|
+
/**
|
153
|
+
* Check if this emitter has `event` handlers.
|
154
|
+
*
|
155
|
+
* @param {String} event
|
156
|
+
* @return {Boolean}
|
157
|
+
* @api public
|
158
|
+
*/
|
159
|
+
|
160
|
+
Emitter.prototype.hasListeners = function(event){
|
161
|
+
return !! this.listeners(event).length;
|
162
|
+
};
|
@@ -73,7 +73,7 @@ function DataSet (options) {
|
|
73
73
|
* {Object | null} params
|
74
74
|
* {String | Number} senderId
|
75
75
|
*/
|
76
|
-
DataSet.prototype.
|
76
|
+
DataSet.prototype.on = function on (event, callback) {
|
77
77
|
var subscribers = this.subscribers[event];
|
78
78
|
if (!subscribers) {
|
79
79
|
subscribers = [];
|
@@ -85,12 +85,15 @@ DataSet.prototype.subscribe = function (event, callback) {
|
|
85
85
|
});
|
86
86
|
};
|
87
87
|
|
88
|
+
// TODO: make this function deprecated (replaced with `on` since version 0.5)
|
89
|
+
DataSet.prototype.subscribe = DataSet.prototype.on;
|
90
|
+
|
88
91
|
/**
|
89
92
|
* Unsubscribe from an event, remove an event listener
|
90
93
|
* @param {String} event
|
91
94
|
* @param {function} callback
|
92
95
|
*/
|
93
|
-
DataSet.prototype.
|
96
|
+
DataSet.prototype.off = function off(event, callback) {
|
94
97
|
var subscribers = this.subscribers[event];
|
95
98
|
if (subscribers) {
|
96
99
|
this.subscribers[event] = subscribers.filter(function (listener) {
|
@@ -99,6 +102,9 @@ DataSet.prototype.unsubscribe = function (event, callback) {
|
|
99
102
|
}
|
100
103
|
};
|
101
104
|
|
105
|
+
// TODO: make this function deprecated (replaced with `on` since version 0.5)
|
106
|
+
DataSet.prototype.unsubscribe = DataSet.prototype.off;
|
107
|
+
|
102
108
|
/**
|
103
109
|
* Trigger an event
|
104
110
|
* @param {String} event
|
@@ -69,8 +69,8 @@ DataView.prototype.setData = function (data) {
|
|
69
69
|
this._trigger('add', {items: ids});
|
70
70
|
|
71
71
|
// subscribe to new dataset
|
72
|
-
if (this.data.
|
73
|
-
this.data.
|
72
|
+
if (this.data.on) {
|
73
|
+
this.data.on('*', this.listener);
|
74
74
|
}
|
75
75
|
}
|
76
76
|
};
|
@@ -276,6 +276,10 @@ DataView.prototype._onEvent = function (event, params, senderId) {
|
|
276
276
|
};
|
277
277
|
|
278
278
|
// copy subscription functionality from DataSet
|
279
|
-
DataView.prototype.
|
280
|
-
DataView.prototype.
|
279
|
+
DataView.prototype.on = DataSet.prototype.on;
|
280
|
+
DataView.prototype.off = DataSet.prototype.off;
|
281
281
|
DataView.prototype._trigger = DataSet.prototype._trigger;
|
282
|
+
|
283
|
+
// TODO: make these functions deprecated (replaced with `on` and `off` since version 0.5)
|
284
|
+
DataView.prototype.subscribe = DataView.prototype.on;
|
285
|
+
DataView.prototype.unsubscribe = DataView.prototype.off;
|
@@ -31,10 +31,14 @@ function Edge (properties, graph, constants) {
|
|
31
31
|
this.title = undefined;
|
32
32
|
this.width = constants.edges.width;
|
33
33
|
this.value = undefined;
|
34
|
-
this.length = constants.
|
34
|
+
this.length = constants.physics.springLength;
|
35
|
+
this.customLength = false;
|
36
|
+
this.selected = false;
|
37
|
+
this.smooth = constants.smoothCurves;
|
35
38
|
|
36
39
|
this.from = null; // a node
|
37
40
|
this.to = null; // a node
|
41
|
+
this.via = null; // a temp node
|
38
42
|
|
39
43
|
// we use this to be able to reconnect the edge to a cluster if its node is put into a cluster
|
40
44
|
// by storing the original information we can revert to the original connection when the cluser is opened.
|
@@ -48,13 +52,11 @@ function Edge (properties, graph, constants) {
|
|
48
52
|
// 2012-08-08
|
49
53
|
this.dash = util.extend({}, constants.edges.dash); // contains properties length, gap, altLength
|
50
54
|
|
51
|
-
this.stiffness = undefined; // depends on the length of the edge
|
52
55
|
this.color = constants.edges.color;
|
53
56
|
this.widthFixed = false;
|
54
57
|
this.lengthFixed = false;
|
55
58
|
|
56
59
|
this.setProperties(properties, constants);
|
57
|
-
|
58
60
|
}
|
59
61
|
|
60
62
|
/**
|
@@ -73,6 +75,7 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
73
75
|
if (properties.id !== undefined) {this.id = properties.id;}
|
74
76
|
if (properties.style !== undefined) {this.style = properties.style;}
|
75
77
|
if (properties.label !== undefined) {this.label = properties.label;}
|
78
|
+
|
76
79
|
if (this.label) {
|
77
80
|
this.fontSize = constants.edges.fontSize;
|
78
81
|
this.fontFace = constants.edges.fontFace;
|
@@ -81,10 +84,12 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
81
84
|
if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
|
82
85
|
if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
|
83
86
|
}
|
84
|
-
|
85
|
-
if (properties.
|
86
|
-
if (properties.
|
87
|
-
if (properties.
|
87
|
+
|
88
|
+
if (properties.title !== undefined) {this.title = properties.title;}
|
89
|
+
if (properties.width !== undefined) {this.width = properties.width;}
|
90
|
+
if (properties.value !== undefined) {this.value = properties.value;}
|
91
|
+
if (properties.length !== undefined) {this.length = properties.length;
|
92
|
+
this.customLength = true;}
|
88
93
|
|
89
94
|
// Added to support dashed lines
|
90
95
|
// David Jordan
|
@@ -102,7 +107,6 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
102
107
|
|
103
108
|
this.widthFixed = this.widthFixed || (properties.width !== undefined);
|
104
109
|
this.lengthFixed = this.lengthFixed || (properties.length !== undefined);
|
105
|
-
this.stiffness = 1 / this.length;
|
106
110
|
|
107
111
|
// set draw method based on style
|
108
112
|
switch (this.style) {
|
@@ -210,8 +214,7 @@ Edge.prototype.isOverlappingWith = function(obj) {
|
|
210
214
|
var xObj = obj.left;
|
211
215
|
var yObj = obj.top;
|
212
216
|
|
213
|
-
|
214
|
-
var dist = Edge._dist(xFrom, yFrom, xTo, yTo, xObj, yObj);
|
217
|
+
var dist = this._getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
|
215
218
|
|
216
219
|
return (dist < distMax);
|
217
220
|
};
|
@@ -229,14 +232,21 @@ Edge.prototype._drawLine = function(ctx) {
|
|
229
232
|
ctx.strokeStyle = this.color;
|
230
233
|
ctx.lineWidth = this._getLineWidth();
|
231
234
|
|
232
|
-
var point;
|
233
235
|
if (this.from != this.to) {
|
234
236
|
// draw line
|
235
237
|
this._line(ctx);
|
236
238
|
|
237
239
|
// draw label
|
240
|
+
var point;
|
238
241
|
if (this.label) {
|
239
|
-
|
242
|
+
if (this.smooth == true) {
|
243
|
+
var midpointX = 0.5*(0.5*(this.from.x + this.via.x) + 0.5*(this.to.x + this.via.x));
|
244
|
+
var midpointY = 0.5*(0.5*(this.from.y + this.via.y) + 0.5*(this.to.y + this.via.y));
|
245
|
+
point = {x:midpointX, y:midpointY};
|
246
|
+
}
|
247
|
+
else {
|
248
|
+
point = this._pointOnLine(0.5);
|
249
|
+
}
|
240
250
|
this._label(ctx, this.label, point.x, point.y);
|
241
251
|
}
|
242
252
|
}
|
@@ -268,7 +278,7 @@ Edge.prototype._drawLine = function(ctx) {
|
|
268
278
|
* @private
|
269
279
|
*/
|
270
280
|
Edge.prototype._getLineWidth = function() {
|
271
|
-
if (this.
|
281
|
+
if (this.selected == true) {
|
272
282
|
return Math.min(this.width * 2, this.widthMax)*this.graphScaleInv;
|
273
283
|
}
|
274
284
|
else {
|
@@ -285,7 +295,12 @@ Edge.prototype._line = function (ctx) {
|
|
285
295
|
// draw a straight line
|
286
296
|
ctx.beginPath();
|
287
297
|
ctx.moveTo(this.from.x, this.from.y);
|
288
|
-
|
298
|
+
if (this.smooth == true) {
|
299
|
+
ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y);
|
300
|
+
}
|
301
|
+
else {
|
302
|
+
ctx.lineTo(this.to.x, this.to.y);
|
303
|
+
}
|
289
304
|
ctx.stroke();
|
290
305
|
};
|
291
306
|
|
@@ -347,29 +362,82 @@ Edge.prototype._drawDashLine = function(ctx) {
|
|
347
362
|
ctx.strokeStyle = this.color;
|
348
363
|
ctx.lineWidth = this._getLineWidth();
|
349
364
|
|
350
|
-
//
|
351
|
-
ctx.
|
352
|
-
|
353
|
-
if (this.dash.altLength !== undefined) //If an alt dash value has been set add to the array this value
|
354
|
-
{
|
355
|
-
ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
|
356
|
-
[this.dash.length,this.dash.gap,this.dash.altLength,this.dash.gap]);
|
357
|
-
}
|
358
|
-
else if (this.dash.length !== undefined && this.dash.gap !== undefined) //If a dash and gap value has been set add to the array this value
|
359
|
-
{
|
360
|
-
ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
|
361
|
-
[this.dash.length,this.dash.gap]);
|
362
|
-
}
|
363
|
-
else //If all else fails draw a line
|
364
|
-
{
|
365
|
+
// only firefox and chrome support this method, else we use the legacy one.
|
366
|
+
if (ctx.mozDash !== undefined || ctx.setLineDash !== undefined) {
|
367
|
+
ctx.beginPath();
|
365
368
|
ctx.moveTo(this.from.x, this.from.y);
|
366
|
-
|
369
|
+
|
370
|
+
// configure the dash pattern
|
371
|
+
var pattern = [0];
|
372
|
+
if (this.dash.length !== undefined && this.dash.gap !== undefined) {
|
373
|
+
pattern = [this.dash.length,this.dash.gap];
|
374
|
+
}
|
375
|
+
else {
|
376
|
+
pattern = [5,5];
|
377
|
+
}
|
378
|
+
|
379
|
+
// set dash settings for chrome or firefox
|
380
|
+
if (typeof ctx.setLineDash !== 'undefined') { //Chrome
|
381
|
+
ctx.setLineDash(pattern);
|
382
|
+
ctx.lineDashOffset = 0;
|
383
|
+
|
384
|
+
} else { //Firefox
|
385
|
+
ctx.mozDash = pattern;
|
386
|
+
ctx.mozDashOffset = 0;
|
387
|
+
}
|
388
|
+
|
389
|
+
// draw the line
|
390
|
+
if (this.smooth == true) {
|
391
|
+
ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y);
|
392
|
+
}
|
393
|
+
else {
|
394
|
+
ctx.lineTo(this.to.x, this.to.y);
|
395
|
+
}
|
396
|
+
ctx.stroke();
|
397
|
+
|
398
|
+
// restore the dash settings.
|
399
|
+
if (typeof ctx.setLineDash !== 'undefined') { //Chrome
|
400
|
+
ctx.setLineDash([0]);
|
401
|
+
ctx.lineDashOffset = 0;
|
402
|
+
|
403
|
+
} else { //Firefox
|
404
|
+
ctx.mozDash = [0];
|
405
|
+
ctx.mozDashOffset = 0;
|
406
|
+
}
|
407
|
+
}
|
408
|
+
else { // unsupporting smooth lines
|
409
|
+
// draw dashed line
|
410
|
+
ctx.beginPath();
|
411
|
+
ctx.lineCap = 'round';
|
412
|
+
if (this.dash.altLength !== undefined) //If an alt dash value has been set add to the array this value
|
413
|
+
{
|
414
|
+
ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
|
415
|
+
[this.dash.length,this.dash.gap,this.dash.altLength,this.dash.gap]);
|
416
|
+
}
|
417
|
+
else if (this.dash.length !== undefined && this.dash.gap !== undefined) //If a dash and gap value has been set add to the array this value
|
418
|
+
{
|
419
|
+
ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
|
420
|
+
[this.dash.length,this.dash.gap]);
|
421
|
+
}
|
422
|
+
else //If all else fails draw a line
|
423
|
+
{
|
424
|
+
ctx.moveTo(this.from.x, this.from.y);
|
425
|
+
ctx.lineTo(this.to.x, this.to.y);
|
426
|
+
}
|
427
|
+
ctx.stroke();
|
367
428
|
}
|
368
|
-
ctx.stroke();
|
369
429
|
|
370
430
|
// draw label
|
371
431
|
if (this.label) {
|
372
|
-
var point
|
432
|
+
var point;
|
433
|
+
if (this.smooth == true) {
|
434
|
+
var midpointX = 0.5*(0.5*(this.from.x + this.via.x) + 0.5*(this.to.x + this.via.x));
|
435
|
+
var midpointY = 0.5*(0.5*(this.from.y + this.via.y) + 0.5*(this.to.y + this.via.y));
|
436
|
+
point = {x:midpointX, y:midpointY};
|
437
|
+
}
|
438
|
+
else {
|
439
|
+
point = this._pointOnLine(0.5);
|
440
|
+
}
|
373
441
|
this._label(ctx, this.label, point.x, point.y);
|
374
442
|
}
|
375
443
|
};
|
@@ -422,35 +490,42 @@ Edge.prototype._drawArrowCenter = function(ctx) {
|
|
422
490
|
// draw line
|
423
491
|
this._line(ctx);
|
424
492
|
|
425
|
-
// draw an arrow halfway the line
|
426
493
|
var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
|
427
494
|
var length = 10 + 5 * this.width; // TODO: make customizable?
|
428
|
-
|
495
|
+
// draw an arrow halfway the line
|
496
|
+
if (this.smooth == true) {
|
497
|
+
var midpointX = 0.5*(0.5*(this.from.x + this.via.x) + 0.5*(this.to.x + this.via.x));
|
498
|
+
var midpointY = 0.5*(0.5*(this.from.y + this.via.y) + 0.5*(this.to.y + this.via.y));
|
499
|
+
point = {x:midpointX, y:midpointY};
|
500
|
+
}
|
501
|
+
else {
|
502
|
+
point = this._pointOnLine(0.5);
|
503
|
+
}
|
504
|
+
|
429
505
|
ctx.arrow(point.x, point.y, angle, length);
|
430
506
|
ctx.fill();
|
431
507
|
ctx.stroke();
|
432
508
|
|
433
509
|
// draw label
|
434
510
|
if (this.label) {
|
435
|
-
point = this._pointOnLine(0.5);
|
436
511
|
this._label(ctx, this.label, point.x, point.y);
|
437
512
|
}
|
438
513
|
}
|
439
514
|
else {
|
440
515
|
// draw circle
|
441
516
|
var x, y;
|
442
|
-
var radius = this.length
|
517
|
+
var radius = 0.25 * Math.max(100,this.length);
|
443
518
|
var node = this.from;
|
444
519
|
if (!node.width) {
|
445
520
|
node.resize(ctx);
|
446
521
|
}
|
447
522
|
if (node.width > node.height) {
|
448
|
-
x = node.x + node.width
|
523
|
+
x = node.x + node.width * 0.5;
|
449
524
|
y = node.y - radius;
|
450
525
|
}
|
451
526
|
else {
|
452
527
|
x = node.x + radius;
|
453
|
-
y = node.y - node.height
|
528
|
+
y = node.y - node.height * 0.5;
|
454
529
|
}
|
455
530
|
this._circle(ctx, x, y, radius);
|
456
531
|
|
@@ -485,39 +560,66 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
485
560
|
ctx.fillStyle = this.color;
|
486
561
|
ctx.lineWidth = this._getLineWidth();
|
487
562
|
|
488
|
-
// draw line
|
489
563
|
var angle, length;
|
564
|
+
//draw a line
|
490
565
|
if (this.from != this.to) {
|
491
|
-
// calculate length and angle of the line
|
492
566
|
angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
|
493
567
|
var dx = (this.to.x - this.from.x);
|
494
568
|
var dy = (this.to.y - this.from.y);
|
495
|
-
var
|
569
|
+
var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
|
570
|
+
|
571
|
+
var fromBorderDist = this.from.distanceToBorder(ctx, angle + Math.PI);
|
572
|
+
var fromBorderPoint = (edgeSegmentLength - fromBorderDist) / edgeSegmentLength;
|
573
|
+
var xFrom = (fromBorderPoint) * this.from.x + (1 - fromBorderPoint) * this.to.x;
|
574
|
+
var yFrom = (fromBorderPoint) * this.from.y + (1 - fromBorderPoint) * this.to.y;
|
496
575
|
|
497
|
-
var lFrom = this.from.distanceToBorder(ctx, angle + Math.PI);
|
498
|
-
var pFrom = (lEdge - lFrom) / lEdge;
|
499
|
-
var xFrom = (pFrom) * this.from.x + (1 - pFrom) * this.to.x;
|
500
|
-
var yFrom = (pFrom) * this.from.y + (1 - pFrom) * this.to.y;
|
501
576
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
577
|
+
if (this.smooth == true) {
|
578
|
+
angle = Math.atan2((this.to.y - this.via.y), (this.to.x - this.via.x));
|
579
|
+
dx = (this.to.x - this.via.x);
|
580
|
+
dy = (this.to.y - this.via.y);
|
581
|
+
edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
|
582
|
+
}
|
583
|
+
var toBorderDist = this.to.distanceToBorder(ctx, angle);
|
584
|
+
var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
|
585
|
+
|
586
|
+
var xTo,yTo;
|
587
|
+
if (this.smooth == true) {
|
588
|
+
xTo = (1 - toBorderPoint) * this.via.x + toBorderPoint * this.to.x;
|
589
|
+
yTo = (1 - toBorderPoint) * this.via.y + toBorderPoint * this.to.y;
|
590
|
+
}
|
591
|
+
else {
|
592
|
+
xTo = (1 - toBorderPoint) * this.from.x + toBorderPoint * this.to.x;
|
593
|
+
yTo = (1 - toBorderPoint) * this.from.y + toBorderPoint * this.to.y;
|
594
|
+
}
|
506
595
|
|
507
596
|
ctx.beginPath();
|
508
|
-
ctx.moveTo(xFrom,
|
509
|
-
|
597
|
+
ctx.moveTo(xFrom,yFrom);
|
598
|
+
if (this.smooth == true) {
|
599
|
+
ctx.quadraticCurveTo(this.via.x,this.via.y,xTo, yTo);
|
600
|
+
}
|
601
|
+
else {
|
602
|
+
ctx.lineTo(xTo, yTo);
|
603
|
+
}
|
510
604
|
ctx.stroke();
|
511
605
|
|
512
606
|
// draw arrow at the end of the line
|
513
|
-
length = 10 + 5 * this.width;
|
607
|
+
length = 10 + 5 * this.width;
|
514
608
|
ctx.arrow(xTo, yTo, angle, length);
|
515
609
|
ctx.fill();
|
516
610
|
ctx.stroke();
|
517
611
|
|
518
612
|
// draw label
|
519
613
|
if (this.label) {
|
520
|
-
var point
|
614
|
+
var point;
|
615
|
+
if (this.smooth == true) {
|
616
|
+
var midpointX = 0.5*(0.5*(this.from.x + this.via.x) + 0.5*(this.to.x + this.via.x));
|
617
|
+
var midpointY = 0.5*(0.5*(this.from.y + this.via.y) + 0.5*(this.to.y + this.via.y));
|
618
|
+
point = {x:midpointX, y:midpointY};
|
619
|
+
}
|
620
|
+
else {
|
621
|
+
point = this._pointOnLine(0.5);
|
622
|
+
}
|
521
623
|
this._label(ctx, this.label, point.x, point.y);
|
522
624
|
}
|
523
625
|
}
|
@@ -525,12 +627,12 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
525
627
|
// draw circle
|
526
628
|
var node = this.from;
|
527
629
|
var x, y, arrow;
|
528
|
-
var radius = this.length
|
630
|
+
var radius = 0.25 * Math.max(100,this.length);
|
529
631
|
if (!node.width) {
|
530
632
|
node.resize(ctx);
|
531
633
|
}
|
532
634
|
if (node.width > node.height) {
|
533
|
-
x = node.x + node.width
|
635
|
+
x = node.x + node.width * 0.5;
|
534
636
|
y = node.y - radius;
|
535
637
|
arrow = {
|
536
638
|
x: x,
|
@@ -540,7 +642,7 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
540
642
|
}
|
541
643
|
else {
|
542
644
|
x = node.x + radius;
|
543
|
-
y = node.y - node.height
|
645
|
+
y = node.y - node.height * 0.5;
|
544
646
|
arrow = {
|
545
647
|
x: node.x,
|
546
648
|
y: y,
|
@@ -548,7 +650,6 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
548
650
|
};
|
549
651
|
}
|
550
652
|
ctx.beginPath();
|
551
|
-
// TODO: do not draw a circle, but an arc
|
552
653
|
// TODO: similarly, for a line without arrows, draw to the border of the nodes instead of the center
|
553
654
|
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
|
554
655
|
ctx.stroke();
|
@@ -581,31 +682,46 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
581
682
|
* @param {number} y3
|
582
683
|
* @private
|
583
684
|
*/
|
584
|
-
Edge.
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
685
|
+
Edge.prototype._getDistanceToEdge = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point
|
686
|
+
if (this.smooth == true) {
|
687
|
+
var minDistance = 1e9;
|
688
|
+
var i,t,x,y,dx,dy;
|
689
|
+
for (i = 0; i < 10; i++) {
|
690
|
+
t = 0.1*i;
|
691
|
+
x = Math.pow(1-t,2)*x1 + (2*t*(1 - t))*this.via.x + Math.pow(t,2)*x2;
|
692
|
+
y = Math.pow(1-t,2)*y1 + (2*t*(1 - t))*this.via.y + Math.pow(t,2)*y2;
|
693
|
+
dx = Math.abs(x3-x);
|
694
|
+
dy = Math.abs(y3-y);
|
695
|
+
minDistance = Math.min(minDistance,Math.sqrt(dx*dx + dy*dy));
|
696
|
+
}
|
697
|
+
return minDistance
|
595
698
|
}
|
699
|
+
else {
|
700
|
+
var px = x2-x1,
|
701
|
+
py = y2-y1,
|
702
|
+
something = px*px + py*py,
|
703
|
+
u = ((x3 - x1) * px + (y3 - y1) * py) / something;
|
704
|
+
|
705
|
+
if (u > 1) {
|
706
|
+
u = 1;
|
707
|
+
}
|
708
|
+
else if (u < 0) {
|
709
|
+
u = 0;
|
710
|
+
}
|
596
711
|
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
712
|
+
var x = x1 + u * px,
|
713
|
+
y = y1 + u * py,
|
714
|
+
dx = x - x3,
|
715
|
+
dy = y - y3;
|
601
716
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
717
|
+
//# Note: If the actual distance does not matter,
|
718
|
+
//# if you only want to compare what this function
|
719
|
+
//# returns to other results of this function, you
|
720
|
+
//# can just return the squared distance instead
|
721
|
+
//# (i.e. remove the sqrt) to gain a little performance
|
607
722
|
|
608
|
-
|
723
|
+
return Math.sqrt(dx*dx + dy*dy);
|
724
|
+
}
|
609
725
|
};
|
610
726
|
|
611
727
|
|
@@ -617,4 +733,20 @@ Edge._dist = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point
|
|
617
733
|
*/
|
618
734
|
Edge.prototype.setScale = function(scale) {
|
619
735
|
this.graphScaleInv = 1.0/scale;
|
736
|
+
};
|
737
|
+
|
738
|
+
|
739
|
+
Edge.prototype.select = function() {
|
740
|
+
this.selected = true;
|
741
|
+
};
|
742
|
+
|
743
|
+
Edge.prototype.unselect = function() {
|
744
|
+
this.selected = false;
|
745
|
+
};
|
746
|
+
|
747
|
+
Edge.prototype.positionBezierNode = function() {
|
748
|
+
if (this.via !== null) {
|
749
|
+
this.via.x = 0.5 * (this.from.x + this.to.x);
|
750
|
+
this.via.y = 0.5 * (this.from.y + this.to.y);
|
751
|
+
}
|
620
752
|
};
|