vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
11 KiB

  1. var fs = require('fs');
  2. var assert = require('assert');
  3. var vis = require('../dist/vis');
  4. var Network = vis.network;
  5. var jsdom_global = require('jsdom-global');
  6. var stdout = require('test-console').stdout;
  7. var Validator = require("./../lib/shared/Validator").default;
  8. //var {printStyle} = require('./../lib/shared/Validator');
  9. // Useful during debugging:
  10. // console.log(JSON.stringify(output, null, 2));
  11. /**
  12. * Load legacy-style (i.e. not module) javascript files into the given context.
  13. */
  14. function include(list, context) {
  15. if (!(list instanceof Array)) {
  16. list = [list];
  17. }
  18. for (var n in list) {
  19. var path = list[n];
  20. var arr = [fs.readFileSync(path) + ''];
  21. eval.apply(context, arr);
  22. }
  23. }
  24. /**
  25. * Defined network consists of two sub-networks:
  26. *
  27. * - 1-2-3-4
  28. * - 11-12-13-14
  29. *
  30. * For reference, this is the sample network of issue #1218
  31. */
  32. function createSampleNetwork() {
  33. var NumInitialNodes = 8;
  34. var NumInitialEdges = 6;
  35. var nodes = new vis.DataSet([
  36. {id: 1, label: '1'},
  37. {id: 2, label: '2'},
  38. {id: 3, label: '3'},
  39. {id: 4, label: '4'},
  40. {id: 11, label: '11'},
  41. {id: 12, label: '12'},
  42. {id: 13, label: '13'},
  43. {id: 14, label: '14'},
  44. ]);
  45. var edges = new vis.DataSet([
  46. {from: 1, to: 2},
  47. {from: 2, to: 3},
  48. {from: 3, to: 4},
  49. {from: 11, to: 12},
  50. {from: 12, to: 13},
  51. {from: 13, to: 14},
  52. ]);
  53. // create a network
  54. var container = document.getElementById('mynetwork');
  55. var data = {
  56. nodes: nodes,
  57. edges: edges
  58. };
  59. var options = {
  60. layout: {
  61. randomSeed: 8
  62. },
  63. edges: {
  64. smooth: {
  65. type: 'continuous' // avoid dynamic here, it adds extra hidden nodes
  66. }
  67. }
  68. };
  69. var network = new vis.Network(container, data, options);
  70. assertNumNodes(network, NumInitialNodes);
  71. assertNumEdges(network, NumInitialEdges);
  72. return [network, data, NumInitialNodes, NumInitialEdges];
  73. };
  74. /**
  75. * Create a cluster for the dynamic data change cases.
  76. *
  77. * Works on the network created by createSampleNetwork().
  78. *
  79. * This is actually a pathological case; there are two separate sub-networks and
  80. * a cluster is made of two nodes, each from one of the sub-networks.
  81. */
  82. function createCluster(network) {
  83. //console.log("clustering 1 and 11")
  84. var clusterOptionsByData = {
  85. joinCondition: function(node) {
  86. if (node.id == 1 || node.id == 11) return true;
  87. return false;
  88. },
  89. clusterNodeProperties: {id:"c1", label:'c1'}
  90. }
  91. network.cluster(clusterOptionsByData);
  92. }
  93. /**
  94. * Display node/edge state, useful during debugging
  95. */
  96. function log(network) {
  97. console.log(Object.keys(network.body.nodes));
  98. console.log(network.body.nodeIndices);
  99. console.log(Object.keys(network.body.edges));
  100. console.log(network.body.edgeIndices);
  101. };
  102. /**
  103. * Note that only the node and edges counts are asserted.
  104. * This might be done more thoroughly by explicitly checking the id's
  105. */
  106. function assertNumNodes(network, expectedPresent, expectedVisible) {
  107. if (expectedVisible === undefined) expectedVisible = expectedPresent;
  108. assert.equal(Object.keys(network.body.nodes).length, expectedPresent);
  109. assert.equal(network.body.nodeIndices.length, expectedVisible);
  110. };
  111. /**
  112. * Comment at assertNumNodes() also applies.
  113. */
  114. function assertNumEdges(network, expectedPresent, expectedVisible) {
  115. if (expectedVisible === undefined) expectedVisible = expectedPresent;
  116. assert.equal(Object.keys(network.body.edges).length, expectedPresent);
  117. assert.equal(network.body.edgeIndices.length, expectedVisible);
  118. };
  119. describe('Network', function () {
  120. before(function() {
  121. this.jsdom_global = jsdom_global(
  122. "<div id='mynetwork'></div>",
  123. { skipWindowCheck: true}
  124. );
  125. this.container = document.getElementById('mynetwork');
  126. });
  127. after(function() {
  128. this.jsdom_global();
  129. });
  130. /**
  131. * Check on fix for #1218
  132. */
  133. it('connects a new edge to a clustering node instead of the clustered node', function () {
  134. var [network, data, numNodes, numEdges] = createSampleNetwork();
  135. createCluster(network);
  136. numNodes += 1; // A clustering node is now hiding two nodes
  137. assertNumNodes(network, numNodes, numNodes - 2);
  138. numEdges += 2; // Two clustering edges now hide two edges
  139. assertNumEdges(network, numEdges, numEdges - 2);
  140. //console.log("Creating node 21")
  141. data.nodes.update([{id: 21, label: '21'}]);
  142. numNodes += 1; // New unconnected node added
  143. assertNumNodes(network, numNodes, numNodes - 2);
  144. assertNumEdges(network, numEdges, numEdges - 2); // edges unchanged
  145. //console.log("Creating edge 21 pointing to 1");
  146. // '1' is part of the cluster so should
  147. // connect to cluster instead
  148. data.edges.update([{from: 21, to: 1}]);
  149. assertNumNodes(network, numNodes, numNodes - 2); // nodes unchanged
  150. numEdges += 2; // A new clustering edge is hiding a new edge
  151. assertNumEdges(network, numEdges, numEdges - 3);
  152. });
  153. /**
  154. * Check on fix for #1315
  155. */
  156. it('can uncluster a clustered node when a node is removed that has an edge to that cluster', function () {
  157. // NOTE: this block is same as previous test
  158. var [network, data, numNodes, numEdges] = createSampleNetwork();
  159. createCluster(network);
  160. numNodes += 1; // A clustering node is now hiding two nodes
  161. assertNumNodes(network, numNodes, numNodes - 2);
  162. numEdges += 2; // Two clustering edges now hide two edges
  163. assertNumEdges(network, numEdges, numEdges - 2);
  164. // End block same as previous test
  165. //console.log("removing 12");
  166. data.nodes.remove(12);
  167. // NOTE:
  168. // At this particular point, there are still the two edges for node 12 in the edges DataSet.
  169. // If you want to do the delete correctly, these should also be deleted explictly from
  170. // the edges DataSet. In the Network instance, however, this.body.nodes and this.body.edges
  171. // should be correct, with the edges of 12 all cleared out.
  172. // 12 was connected to 11, which is clustered
  173. numNodes -= 1; // 12 removed, one less node
  174. assertNumNodes(network, numNodes, numNodes - 2);
  175. numEdges -= 3; // clustering edge c1-12 and 2 edges of 12 gone
  176. assertNumEdges(network, numEdges, numEdges - 1);
  177. //console.log("Unclustering c1");
  178. network.openCluster("c1");
  179. numNodes -= 1; // cluster node removed, one less node
  180. assertNumNodes(network, numNodes, numNodes); // all are visible again
  181. numEdges -= 1; // clustering edge gone, regular edge visible
  182. assertNumEdges(network, numEdges, numEdges); // all are visible again
  183. });
  184. /**
  185. * Check on fix for #1291
  186. */
  187. it('can remove a node inside a cluster and then open that cluster', function () {
  188. var [network, data, numNodes, numEdges] = createSampleNetwork();
  189. var clusterOptionsByData = {
  190. joinCondition: function(node) {
  191. if (node.id == 1 || node.id == 2 || node.id == 3) return true;
  192. return false;
  193. },
  194. clusterNodeProperties: {id:"c1", label:'c1'}
  195. }
  196. network.cluster(clusterOptionsByData);
  197. numNodes += 1; // new cluster node
  198. assertNumNodes(network, numNodes, numNodes - 3); // 3 clustered nodes
  199. numEdges += 1; // 1 cluster edge expected
  200. assertNumEdges(network, numEdges, numEdges - 3); // 3 edges hidden
  201. //console.log("removing node 2, which is inside the cluster");
  202. data.nodes.remove(2);
  203. numNodes -= 1; // clustered node removed
  204. assertNumNodes(network, numNodes, numNodes - 2); // view doesn't change
  205. numEdges -= 2; // edges removed hidden in cluster
  206. assertNumEdges(network, numEdges, numEdges - 1); // view doesn't change
  207. //console.log("Unclustering c1");
  208. network.openCluster("c1")
  209. numNodes -= 1; // cluster node gone
  210. assertNumNodes(network, numNodes, numNodes); // all visible
  211. numEdges -= 1; // cluster edge gone
  212. assertNumEdges(network, numEdges, numEdges); // all visible
  213. //log(network);
  214. });
  215. describe('on node.js', function () {
  216. it('should be running', function () {
  217. assert(this.container !== null, 'Container div not found');
  218. // The following should now just plain succeed
  219. var [network, data] = createSampleNetwork();
  220. assert.equal(Object.keys(network.body.nodes).length, 8);
  221. assert.equal(Object.keys(network.body.edges).length, 6);
  222. });
  223. describe('runs example ', function () {
  224. function loadExample(path, noPhysics) {
  225. include(path, this);
  226. var container = document.getElementById('mynetwork');
  227. // create a network
  228. var data = {
  229. nodes: new vis.DataSet(nodes),
  230. edges: new vis.DataSet(edges)
  231. };
  232. if (noPhysics) {
  233. // Avoid excessive processor time due to load.
  234. // We're just interested that the load itself is good
  235. options.physics = false;
  236. }
  237. var network = new vis.Network(container, data, options);
  238. return network;
  239. };
  240. it('basicUsage', function () {
  241. var network = loadExample('./test/network/basicUsage.js');
  242. //console.log(Object.keys(network.body.edges));
  243. // Count in following also contains the helper nodes for dynamic edges
  244. assert.equal(Object.keys(network.body.nodes).length, 10);
  245. assert.equal(Object.keys(network.body.edges).length, 5);
  246. });
  247. it('WorlCup2014', function () {
  248. // This is a huge example (which is why it's tested here!), so it takes a long time to load.
  249. this.timeout(10000);
  250. var network = loadExample('./examples/network/datasources/WorldCup2014.js', true);
  251. // Count in following also contains the helper nodes for dynamic edges
  252. assert.equal(Object.keys(network.body.nodes).length, 9964);
  253. assert.equal(Object.keys(network.body.edges).length, 9228);
  254. });
  255. // This actually failed to load, added for this reason
  256. it('disassemblerExample', function () {
  257. var network = loadExample('./examples/network/exampleApplications/disassemblerExample.js');
  258. // console.log(Object.keys(network.body.nodes));
  259. // console.log(Object.keys(network.body.edges));
  260. // Count in following also contains the helper nodes for dynamic edges
  261. assert.equal(Object.keys(network.body.nodes).length, 9);
  262. assert.equal(Object.keys(network.body.edges).length, 14 - 3); // NB 3 edges in data not displayed
  263. });
  264. }); // runs example
  265. }); // on node.js
  266. }); // Network