tw5-vis-network 10.5.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.
- package/LICENSE +10 -0
- package/README.md +37 -0
- package/package.json +37 -0
- package/plugins/vis-network/DefaultColourMappings.multids +7 -0
- package/plugins/vis-network/Stylesheet.tid +39 -0
- package/plugins/vis-network/adapter.js +179 -0
- package/plugins/vis-network/felixhayashi_vis_vis.js +36 -0
- package/plugins/vis-network/lib/icon.svg +2 -0
- package/plugins/vis-network/lib/tiddlywiki.files +27 -0
- package/plugins/vis-network/lib/vis-network.min.js +48 -0
- package/plugins/vis-network/license.tid +29 -0
- package/plugins/vis-network/messages/graph-center-node.js +19 -0
- package/plugins/vis-network/messages/graph-export-png.js +28 -0
- package/plugins/vis-network/messages/graph-move-view.js +52 -0
- package/plugins/vis-network/messages/tiddlywiki.files +17 -0
- package/plugins/vis-network/plugin.info +13 -0
- package/plugins/vis-network/properties/background.js +51 -0
- package/plugins/vis-network/properties/canvas.js +79 -0
- package/plugins/vis-network/properties/color.js +104 -0
- package/plugins/vis-network/properties/defaults.js +42 -0
- package/plugins/vis-network/properties/edges.js +87 -0
- package/plugins/vis-network/properties/events.js +127 -0
- package/plugins/vis-network/properties/id.js +24 -0
- package/plugins/vis-network/properties/image.js +35 -0
- package/plugins/vis-network/properties/interaction.js +48 -0
- package/plugins/vis-network/properties/layout.js +55 -0
- package/plugins/vis-network/properties/manipulation.js +181 -0
- package/plugins/vis-network/properties/nodes.js +42 -0
- package/plugins/vis-network/properties/physics.js +110 -0
- package/plugins/vis-network/properties/position.js +60 -0
- package/plugins/vis-network/properties/tiddlywiki.files +17 -0
- package/plugins/vis-network/readme.tid +8 -0
- package/plugins/vis-network/vis.js +59 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Manages images in nodes.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
exports.name = "image";
|
|
10
|
+
|
|
11
|
+
exports.properties = {
|
|
12
|
+
nodes: {
|
|
13
|
+
shape: {type: "enum", values: ["box", "circle", /*"circularImage",*/ "diamond", "database", "dot", "ellipse", "hexagon", /*"icon",*/ /*"image",*/ "square", "star", "text", "triangle", "triangleDown"]},
|
|
14
|
+
image: {type: "image"},
|
|
15
|
+
circular: {type: "boolean", parent: "image", default: false},
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
exports.process = function(objects, changes) {
|
|
20
|
+
if (changes.nodes) {
|
|
21
|
+
for (var id in changes.nodes) {
|
|
22
|
+
var node = changes.nodes[id];
|
|
23
|
+
if (node) {
|
|
24
|
+
if (node.image) {
|
|
25
|
+
node.shape = node.circular? "circularImage": "image";
|
|
26
|
+
node.circular = undefined;
|
|
27
|
+
} else {
|
|
28
|
+
if (node.shape === "image" || node.shape === "circularImage") {
|
|
29
|
+
node.shape = undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Manages all the structure for graph interaction.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
exports.name = "interaction";
|
|
10
|
+
|
|
11
|
+
exports.properties = {
|
|
12
|
+
graph: {
|
|
13
|
+
navigation: {type: "boolean"},
|
|
14
|
+
zoom: {type: "boolean", default: true},
|
|
15
|
+
zoomSpeed: {type: "number", min: 0, max: 10, increment: 0.1, default: 1},
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
exports.process = function(objects, changes) {
|
|
20
|
+
var graph = changes.graph;
|
|
21
|
+
if (graph) {
|
|
22
|
+
if (graph.zoom !== undefined) {
|
|
23
|
+
graph.interaction = graph.interaction || {};
|
|
24
|
+
graph.interaction.zoomView = graph.zoom;
|
|
25
|
+
graph.zoom = undefined;
|
|
26
|
+
} else if (objects.graph && objects.graph.interaction && objects.graph.interaction.zoomView == false) {
|
|
27
|
+
// It was set, and now we're unsetting it back to true
|
|
28
|
+
graph.interaction = {zoomView: true};
|
|
29
|
+
}
|
|
30
|
+
if (graph.navigation !== undefined) {
|
|
31
|
+
graph.interaction = graph.interaction || {};
|
|
32
|
+
graph.interaction.navigationButtons = graph.navigation;
|
|
33
|
+
graph.navigation = undefined;
|
|
34
|
+
} else if (objects.graph && objects.graph.interaction && objects.graph.interaction.navigationButtons == true) {
|
|
35
|
+
// It was set, and now we're unsetting it back to true
|
|
36
|
+
graph.interaction = graph.interaction || {};
|
|
37
|
+
graph.interaction.navigationButtons = false;
|
|
38
|
+
}
|
|
39
|
+
if (graph.zoomSpeed !== undefined) {
|
|
40
|
+
graph.interaction = graph.interaction || {};
|
|
41
|
+
graph.interaction.zoomSpeed = graph.zoomSpeed;
|
|
42
|
+
graph.zoomSpeed = undefined;
|
|
43
|
+
} else if (objects.graph && objects.graph.interaction && objects.graph.interaction.zoomSpeed !== undefined) {
|
|
44
|
+
graph.interaction = graph.interaction || {};
|
|
45
|
+
graph.interaction.zoomSpeed = 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Manages all the hierarchy for graph manipulation.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var map = {
|
|
10
|
+
hierarchyDirection: "direction",
|
|
11
|
+
hierarchyNodeSpacing: "nodeSpacing",
|
|
12
|
+
hierarchyParentCentralization: "parentCentralization",
|
|
13
|
+
hierarchyShakeTowards: "shakeTowards",
|
|
14
|
+
hierarchySortMethod: "sortMethod",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.name = "layout";
|
|
18
|
+
|
|
19
|
+
exports.properties = {
|
|
20
|
+
graph: {
|
|
21
|
+
hierarchy: {type: "boolean", default: false},
|
|
22
|
+
hierarchyDirection: {type: "enum", parent: "hierarchy", default: "UD", values: ["UD", "DU", "LR", "RL"]},
|
|
23
|
+
hierarchyNodeSpacing: {type: "number", parent: "hierarchy", default: 100, min: 0, max:200},
|
|
24
|
+
//hierarchyShakeTowards: {type: "enum", default: "leaves", values: ["leaves", "roots"]},
|
|
25
|
+
//hierarchyParentCentralization: {type: "boolean", default: true},
|
|
26
|
+
//hierarchySortMethod: {type: "enum", default: "hubsize", values: ["hubsize", "directed"]},
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
exports.process = function(objects, changes) {
|
|
31
|
+
var graph = changes.graph;
|
|
32
|
+
if (graph) {
|
|
33
|
+
if (graph.hierarchy !== undefined) {
|
|
34
|
+
graph.layout = {hierarchical: graph.hierarchy};
|
|
35
|
+
graph.hierarchy = undefined;
|
|
36
|
+
} else if (objects.graph && objects.graph.layout && objects.graph.layout.hierarchical) {
|
|
37
|
+
// It was already there. It must be removed.
|
|
38
|
+
graph.layout = {hierarchical: false};
|
|
39
|
+
}
|
|
40
|
+
var layout = graph.layout;
|
|
41
|
+
for (var property in graph) {
|
|
42
|
+
if (map[property]) {
|
|
43
|
+
if (layout && layout.hierarchical !== false) {
|
|
44
|
+
if (typeof layout.hierarchical !== "object") {
|
|
45
|
+
layout.hierarchical = {};
|
|
46
|
+
}
|
|
47
|
+
layout.hierarchical[map[property]] = graph[property];
|
|
48
|
+
}
|
|
49
|
+
// One way or another, we must always remove all
|
|
50
|
+
// single-depth hierarchy settings
|
|
51
|
+
graph[property] = undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Manages all the structure for graph manipulation.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
exports.name = "manipulation";
|
|
10
|
+
|
|
11
|
+
exports.properties = {
|
|
12
|
+
graph: {
|
|
13
|
+
hideControls: {type: "boolean", default: false, description: "Hide node and edge manipulation controls by default"},
|
|
14
|
+
addNode: {type: "actions", variables: ["x", "y"]},
|
|
15
|
+
addEdge: {type: "actions", variables: ["fromTiddler", "toTiddler"]},
|
|
16
|
+
},
|
|
17
|
+
nodes: {
|
|
18
|
+
delete: {type: "actions", variables: []},
|
|
19
|
+
edit: {type: "actions", variables: []},
|
|
20
|
+
},
|
|
21
|
+
edges: {
|
|
22
|
+
delete: {type: "actions"},
|
|
23
|
+
//edit: {type: "actions", variables: []},
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.process = function(objects, changes) {
|
|
28
|
+
var self = this,
|
|
29
|
+
old = objects.graph && objects.graph.manipulation,
|
|
30
|
+
wasUnset = !old;
|
|
31
|
+
if (wasUnset) {
|
|
32
|
+
old = defaults();
|
|
33
|
+
}
|
|
34
|
+
var settings = $tw.utils.extend({}, old);
|
|
35
|
+
if (!this.manipulation) {
|
|
36
|
+
// We keep track of how many of these we have so we can know when to
|
|
37
|
+
// keep these behaviors.
|
|
38
|
+
this.manipulation = {
|
|
39
|
+
deleteEdge: 0,
|
|
40
|
+
deleteNode: 0,
|
|
41
|
+
editEdge: 0,
|
|
42
|
+
editNode: 0,
|
|
43
|
+
fold: false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (changes.graph) {
|
|
47
|
+
if (changes.graph.addNode) {
|
|
48
|
+
settings.addNode = function(nodeData, callback) {
|
|
49
|
+
self.onevent({
|
|
50
|
+
type: "addNode",
|
|
51
|
+
objectType: "graph"
|
|
52
|
+
},{
|
|
53
|
+
x: round(nodeData.x),
|
|
54
|
+
y: round(nodeData.y)});
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
settings.addNode = false;
|
|
58
|
+
}
|
|
59
|
+
if (changes.graph.addEdge) {
|
|
60
|
+
settings.addEdge = function(edgeData, callback) {
|
|
61
|
+
self.onevent({
|
|
62
|
+
type: "addEdge",
|
|
63
|
+
objectType: "graph"
|
|
64
|
+
},{
|
|
65
|
+
fromTiddler: edgeData.from,
|
|
66
|
+
toTiddler: edgeData.to});
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
settings.addEdge = false;
|
|
70
|
+
}
|
|
71
|
+
// We set it undefined, whatever it is, because it'll need to be purged
|
|
72
|
+
// before being passed to vis. It doesn't like unknown properties.
|
|
73
|
+
changes.graph.addNode = undefined;
|
|
74
|
+
changes.graph.addEdge = undefined;
|
|
75
|
+
}
|
|
76
|
+
// Get an accurate count of object-specific manipulations
|
|
77
|
+
if (changes.edges) {
|
|
78
|
+
for (var id in changes.edges) {
|
|
79
|
+
this.manipulation.deleteEdge += difference(objects.edges, changes.edges, id, "delete");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
var oldEditCount = this.manipulation.editNode;
|
|
83
|
+
if (changes.nodes) {
|
|
84
|
+
for (var id in changes.nodes) {
|
|
85
|
+
this.manipulation.deleteNode += difference(objects.nodes, changes.nodes, id, "delete");
|
|
86
|
+
this.manipulation.editNode += difference(objects.nodes, changes.nodes, id, "edit");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// If we have a positive number of object manipulations, add them now
|
|
90
|
+
if (this.manipulation.deleteNode > 0) {
|
|
91
|
+
settings.deleteNode = function(selected, callback) {
|
|
92
|
+
self.onevent({
|
|
93
|
+
type: "delete",
|
|
94
|
+
objectType: "nodes",
|
|
95
|
+
id: selected.nodes[0]}, {});
|
|
96
|
+
callback({nodes: [], edges: []});
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
settings.deleteNode = false;
|
|
100
|
+
}
|
|
101
|
+
if (this.manipulation.editNode > 0) {
|
|
102
|
+
settings.editNode = function(node, callback) {
|
|
103
|
+
self.onevent({
|
|
104
|
+
type: "edit",
|
|
105
|
+
objectType: "nodes",
|
|
106
|
+
id: node.id}, {});
|
|
107
|
+
callback(null);
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
// Look at this. vis-network treats editNode differently.
|
|
111
|
+
// They don't take a boolean to turn it off, but they forgot that
|
|
112
|
+
// that means it can't be turned off at all without logging an
|
|
113
|
+
// error. YAY. We minimize how often we explicitly set editNode
|
|
114
|
+
// to false, to minimize this error.
|
|
115
|
+
settings.editNode = (oldEditCount > 0)? false: undefined;
|
|
116
|
+
}
|
|
117
|
+
if (this.manipulation.deleteEdge > 0) {
|
|
118
|
+
settings.deleteEdge = function(selected, callback) {
|
|
119
|
+
self.onevent({
|
|
120
|
+
type: "delete",
|
|
121
|
+
objectType: "edges",
|
|
122
|
+
id: selected.edges[0]}, {});
|
|
123
|
+
callback({nodes: [], edges: []});
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
settings.deleteEdge = false;
|
|
127
|
+
}
|
|
128
|
+
// We check if we manually set our manipulation folding
|
|
129
|
+
var fold = false;
|
|
130
|
+
if (changes.graph) {
|
|
131
|
+
fold = !!changes.graph.hideControls;
|
|
132
|
+
changes.graph.hideControls = undefined;
|
|
133
|
+
} else {
|
|
134
|
+
fold = this.manipulation.fold;
|
|
135
|
+
}
|
|
136
|
+
// Now we install our manipulations if we have any.
|
|
137
|
+
if (changed(old, settings) || fold !== this.manipulation.fold) {
|
|
138
|
+
changes.graph = changes.graph || objects.graph || Object.create(null);
|
|
139
|
+
this.manipulation.fold = fold;
|
|
140
|
+
if (changed(settings, defaults())) {
|
|
141
|
+
settings.initiallyActive = !fold;
|
|
142
|
+
changes.graph.manipulation = settings;
|
|
143
|
+
} else {
|
|
144
|
+
changes.graph.manipulation = false;
|
|
145
|
+
}
|
|
146
|
+
} else if (changes.graph && !wasUnset) {
|
|
147
|
+
// If we're updating graph settings, but not manipulation,
|
|
148
|
+
// we must preserve the old manipulation settings.
|
|
149
|
+
changes.graph.manipulation = old;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
function defaults() {
|
|
154
|
+
return {
|
|
155
|
+
addEdge: false,
|
|
156
|
+
addNode: false,
|
|
157
|
+
editEdge: false,
|
|
158
|
+
editNode: undefined,
|
|
159
|
+
deleteEdge: false,
|
|
160
|
+
deleteNode: false
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
function changed(oldManipulate, newManipulate) {
|
|
165
|
+
for (var action in newManipulate) {
|
|
166
|
+
if (!newManipulate[action] !== !oldManipulate[action]) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
function difference(oldObjects, newObjects, id, action) {
|
|
174
|
+
var oldObject = (oldObjects && oldObjects[id]) || {};
|
|
175
|
+
var newObject = (newObjects && newObjects[id]) || {};
|
|
176
|
+
return (newObject[action] || 0) - (oldObject[action] || 0);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
function round(number) {
|
|
180
|
+
return Math.round(number * 10) / 10;
|
|
181
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Miscellaneous node properties that don't need special handling.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
exports.names = "nodes";
|
|
10
|
+
|
|
11
|
+
exports.properties = {
|
|
12
|
+
nodes: {
|
|
13
|
+
borderWidth: {type: "number", min: 0, default: 1, increment: 0.1},
|
|
14
|
+
label: {type: "string"},
|
|
15
|
+
fixed: {type: "boolean", default: false},
|
|
16
|
+
size: {type: "number", min: 0, default: 25},
|
|
17
|
+
minWidth: {type: "number", min: 1, max: 500,
|
|
18
|
+
description: "Minimum width of labels. Affects the size of nodes when labels are contained within"},
|
|
19
|
+
maxWidth: {type: "number", min: 1, max: 500,
|
|
20
|
+
description: "Maximum allowed width of labels. Affects the size of nodes when labels are contained within."}
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
exports.process = function(objects, changes) {
|
|
25
|
+
if (changes.nodes) {
|
|
26
|
+
var oldNodes = (objects && objects.nodes) || {};
|
|
27
|
+
for (var id in changes.nodes) {
|
|
28
|
+
var node = changes.nodes[id];
|
|
29
|
+
if (node) {
|
|
30
|
+
if (node.minWidth !== undefined
|
|
31
|
+
|| node.maxWidth !== undefined) {
|
|
32
|
+
node.widthConstraint = {
|
|
33
|
+
minimum: node.minWidth,
|
|
34
|
+
maximum: node.maxWidth
|
|
35
|
+
};
|
|
36
|
+
node.minWidth = undefined;
|
|
37
|
+
node.maxWidth = undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Manages all the physics for the graph object.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var map = {
|
|
10
|
+
maxVelocity: "maxVelocity",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
var physics = {
|
|
14
|
+
barnesHut: {
|
|
15
|
+
theta: 0.5,
|
|
16
|
+
gravitationalConstant: -2000,
|
|
17
|
+
centralGravity: 0.3,
|
|
18
|
+
springLength: 95,
|
|
19
|
+
springConstant: 0.04,
|
|
20
|
+
damping: 0.09,
|
|
21
|
+
avoidOverlap: 0
|
|
22
|
+
},
|
|
23
|
+
forceAtlas2Based: {
|
|
24
|
+
theta: 0.5,
|
|
25
|
+
gravitationalConstant: -50,
|
|
26
|
+
centralGravity: 0.01,
|
|
27
|
+
springConstant: 0.08,
|
|
28
|
+
springLength: 100,
|
|
29
|
+
damping: 0.4,
|
|
30
|
+
avoidOverlap: 0
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//var solver = "barnesHut";
|
|
35
|
+
var solver = "forceAtlas2Based";
|
|
36
|
+
|
|
37
|
+
exports.name = "physics";
|
|
38
|
+
|
|
39
|
+
exports.properties = {
|
|
40
|
+
graph: {
|
|
41
|
+
physics: {type: "boolean", default: true},
|
|
42
|
+
centralGravity: {type: "number", parent: "physics",
|
|
43
|
+
min: 0, max: 1, increment: 0.1, default: 0.3},
|
|
44
|
+
damping: {type: "number", parent: "physics",
|
|
45
|
+
min: 0, max: 1, increment: 0.01, default: 0.09},
|
|
46
|
+
gravitationalConstant: {type: "number", parent: "physics",
|
|
47
|
+
min: -2000, max: 0, increment: 10, default: -2000},
|
|
48
|
+
springConstant: {type: "number", parent: "physics",
|
|
49
|
+
min: 0, max: 0.2, increment: 0.01, default: 0.04},
|
|
50
|
+
springLength: {type: "number", parent: "physics",
|
|
51
|
+
min: 0, max: 200, increment: 10, default: 95},
|
|
52
|
+
maxVelocity: {type: "number", parent: "physics",
|
|
53
|
+
min: 1, default: 50, max: 100},
|
|
54
|
+
},
|
|
55
|
+
nodes: {
|
|
56
|
+
physics: {type: "boolean", default: true},
|
|
57
|
+
},
|
|
58
|
+
edges: {
|
|
59
|
+
physics: {type: "boolean", default: true},
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.process = function(objects, changes) {
|
|
64
|
+
var graph = changes.graph;
|
|
65
|
+
var enabled = true;
|
|
66
|
+
if (graph) {
|
|
67
|
+
if (graph.physics !== undefined) {
|
|
68
|
+
if (typeof graph.physics === "boolean") {
|
|
69
|
+
// The only reason this wouldn't happen is because our graph
|
|
70
|
+
// settings got recreated by "manipulation", and thus we have
|
|
71
|
+
// an actually fully formed physics object.
|
|
72
|
+
graph.physics = freshSettings({enabled: graph.physics});
|
|
73
|
+
}
|
|
74
|
+
enabled = graph.physics.enabled;
|
|
75
|
+
} else {
|
|
76
|
+
if (objects.graph && objects.graph.physics) {
|
|
77
|
+
// It was specified at some point. We must continued
|
|
78
|
+
// to specify it, even if only to set the default.
|
|
79
|
+
graph.physics = freshSettings({enabled: true});
|
|
80
|
+
}
|
|
81
|
+
enabled = true;
|
|
82
|
+
}
|
|
83
|
+
for (var property in map) {
|
|
84
|
+
if (graph[property] !== undefined) {
|
|
85
|
+
if (enabled) {
|
|
86
|
+
graph.physics = graph.physics || freshSettings();
|
|
87
|
+
graph.physics[map[property]] = graph[property];
|
|
88
|
+
}
|
|
89
|
+
graph[property] = undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
var solverSettings = physics[solver];
|
|
93
|
+
for (var property in solverSettings) {
|
|
94
|
+
if (graph[property] !== undefined) {
|
|
95
|
+
if (enabled) {
|
|
96
|
+
graph.physics = graph.physics || freshSettings();
|
|
97
|
+
graph.physics[solver][property] = graph[property];
|
|
98
|
+
}
|
|
99
|
+
graph[property] = undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
function freshSettings(initial) {
|
|
106
|
+
initial = initial || {};
|
|
107
|
+
initial[solver] = Object.assign({}, physics[solver]);
|
|
108
|
+
initial.solver = solver;
|
|
109
|
+
return initial;
|
|
110
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Manages all the positioning for nodes in graph manipulation.
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
exports.name = "position";
|
|
10
|
+
|
|
11
|
+
exports.properties = {
|
|
12
|
+
nodes: {
|
|
13
|
+
x: {type: "number"},
|
|
14
|
+
y: {type: "number"},
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.process = function(objects, changes) {
|
|
19
|
+
if (!this.position) {
|
|
20
|
+
// We use this to store all positions that were given to us by TW5
|
|
21
|
+
this.position = Object.create(null);
|
|
22
|
+
}
|
|
23
|
+
if (changes.nodes) {
|
|
24
|
+
for (var id in changes.nodes) {
|
|
25
|
+
var node = changes.nodes[id];
|
|
26
|
+
if (node) {
|
|
27
|
+
if (node.x !== undefined || node.y !== undefined) {
|
|
28
|
+
var posKey = node.x + "," + node.y;
|
|
29
|
+
if (this.position[id] === posKey) {
|
|
30
|
+
// This isn't a new position
|
|
31
|
+
this.position[id] = posKey;
|
|
32
|
+
var nodePosition = this.vis.getPosition(id);
|
|
33
|
+
node.x = nodePosition.x;
|
|
34
|
+
node.y = nodePosition.y;
|
|
35
|
+
} else {
|
|
36
|
+
this.position[id] = posKey;
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
// Node does not specify a location.
|
|
40
|
+
// If one had existed, we should preserve its existing loc
|
|
41
|
+
if (this.position[id] !== undefined) {
|
|
42
|
+
var nodePosition = this.vis.getPosition(id);
|
|
43
|
+
node.x = nodePosition.x;
|
|
44
|
+
node.y = nodePosition.y;
|
|
45
|
+
// We forget the old set location.
|
|
46
|
+
// It's "free-floating" now
|
|
47
|
+
// In the future, we will always record SOME position, even if it's
|
|
48
|
+
// just what Vis already thinks it to be.
|
|
49
|
+
// Otherwise we can suffer some nasty recursion exceptions of out Vis.
|
|
50
|
+
this.position[id] = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} else if (this.position[id] !== undefined) {
|
|
54
|
+
// The node is being removed. Forget its initial position.
|
|
55
|
+
// Or that we ever positioned it at all (null).
|
|
56
|
+
this.position[id] = undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"directories": [
|
|
3
|
+
{
|
|
4
|
+
"path": ".",
|
|
5
|
+
"filesRegExp": "^.*\\.js$",
|
|
6
|
+
"isTiddlerFile": true,
|
|
7
|
+
"fields": {
|
|
8
|
+
"title": {
|
|
9
|
+
"source": "filename",
|
|
10
|
+
"prefix": "$:/plugins/flibbles/vis-network/properties/"
|
|
11
|
+
},
|
|
12
|
+
"module-type": "vis-property",
|
|
13
|
+
"type": "application/javascript"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/vis-network/vis.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: library
|
|
5
|
+
|
|
6
|
+
*** TO AVOID STRANGE LIB ERRORS FROM BUBBLING UP *****************
|
|
7
|
+
\*/
|
|
8
|
+
|
|
9
|
+
"use strict";
|
|
10
|
+
|
|
11
|
+
if($tw.boot.tasks.trapErrors) {
|
|
12
|
+
|
|
13
|
+
var defaultHandler = window.onerror;
|
|
14
|
+
window.onerror = function(errorMsg, url, lineNumber) {
|
|
15
|
+
|
|
16
|
+
if(errorMsg.indexOf("NS_ERROR_NOT_AVAILABLE") !== -1
|
|
17
|
+
&& url == "$:/plugins/flibbles/vis-network/vis-network.min.js") {
|
|
18
|
+
|
|
19
|
+
var text = "Strange firefox related vis.js error (see #125)";
|
|
20
|
+
console.error(text, arguments);
|
|
21
|
+
|
|
22
|
+
} else if(errorMsg.indexOf("Permission denied to access property") !== -1) {
|
|
23
|
+
|
|
24
|
+
var text = "Strange firefox related vis.js error (see #163)";
|
|
25
|
+
console.error(text, arguments);
|
|
26
|
+
|
|
27
|
+
} else if(errorMsg.indexOf("ResizeObserver loop") !== -1) {
|
|
28
|
+
// Issue appears sporatically. Hard to replicate. Site here indicates
|
|
29
|
+
// these errors can be safely ignored.
|
|
30
|
+
// https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded/50387233#50387233
|
|
31
|
+
// variations of this harmless error:
|
|
32
|
+
// ResizeObserver loop limit exceeded
|
|
33
|
+
// ResizeObserver loop completed with undelivered notifications
|
|
34
|
+
console.error(errorMsg, arguments);
|
|
35
|
+
} else if(defaultHandler) {
|
|
36
|
+
|
|
37
|
+
defaultHandler.apply(this, arguments);
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ($tw.browser) {
|
|
46
|
+
|
|
47
|
+
module.exports = require("$:/plugins/flibbles/vis-network/vis-network.min.js");
|
|
48
|
+
|
|
49
|
+
if (CanvasRenderingContext2D.prototype.circle === undefined) {
|
|
50
|
+
|
|
51
|
+
// For some reason, vis-network thinks this method exists. It don't.
|
|
52
|
+
// We've got to add it ourselves if it's not there.
|
|
53
|
+
CanvasRenderingContext2D.prototype.circle = function(x, y, radius) {
|
|
54
|
+
return this.arc(x, y, radius, 0, 2 * Math.PI);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|