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.

222 lines
6.6 KiB

  1. <!DOCTYPE html>
  2. <!-- saved from url=(0044)http://kenedict.com/networks/worldcup14/vis/ , thanks Andre!-->
  3. <html><head><meta http-equiv="content-type" content="text/html; charset=UTF8">
  4. <title>Network | Static smooth curves - World Cup Network</title>
  5. <script type="text/javascript" src="../../dist/vis.js"></script>
  6. <link type="text/css" rel="stylesheet" href="../../dist/vis.css">
  7. <script src="./data/WorldCup2014.js"></script>
  8. <style type="text/css">
  9. #mynetwork {
  10. width: 800px;
  11. height: 800px;
  12. border: 1px solid lightgray;
  13. }
  14. </style>
  15. <script src="../googleAnalytics.js"></script>
  16. </head>
  17. <body>
  18. <h2>Dynamic Data - Neighbourhood Highlight</h2>
  19. <div style="width:800px; font-size:14px;">
  20. This example shows the power of the DataSet. Once a node is clicked, all nodes are greyed out except for the first and second order connected nodes.
  21. In this example we show how you can determine the order of connection per node as well as applying individual styling to the nodes based on whether or not
  22. they are connected to the selected node. The code doing the highlighting only takes about 20ms, the rest of the time is the redrawing of the network (9200 edges..).
  23. <br /><br />
  24. </div>
  25. <div id="mynetwork"></div>
  26. <script type="text/javascript">
  27. var network;
  28. var nodes = new vis.DataSet();
  29. var edges = new vis.DataSet();
  30. function redrawAll() {
  31. nodes.clear();
  32. edges.clear();
  33. network = null;
  34. var container = document.getElementById('mynetwork');
  35. var options = {
  36. nodes: {
  37. shape: 'dot',
  38. scaling: {
  39. min: 10,
  40. max: 30,
  41. label: {
  42. min: 8,
  43. max: 20,
  44. drawThreshold: 12,
  45. maxVisible: 20
  46. }
  47. },
  48. font: {
  49. size: 12,
  50. face: 'Tahoma'
  51. }
  52. },
  53. edges: {
  54. width: 0.15,
  55. color: {inherit: 'from'},
  56. smooth: {
  57. dynamic: false,
  58. type: 'continuous'
  59. }
  60. },
  61. physics: false,
  62. interaction: {
  63. tooltipDelay: 200
  64. },
  65. rendering: {
  66. hideEdgesOnDrag: true
  67. }
  68. };
  69. // Note: data is coming from ./data/WorldCup2014.js
  70. network = new vis.Network(container, data, options);
  71. network.on("click",onClick);
  72. }
  73. function onClick(selectedItems) {
  74. var nodeId;
  75. var degrees = 2;
  76. // we get all data from the dataset once to avoid updating multiple times.
  77. var allNodes = nodes.get({returnType:"Object"});
  78. if (selectedItems.nodes.length == 0) {
  79. // restore on unselect
  80. for (nodeId in allNodes) {
  81. if (allNodes.hasOwnProperty(nodeId)) {
  82. allNodes[nodeId].color = undefined;
  83. if (allNodes[nodeId].oldLabel !== undefined) {
  84. allNodes[nodeId].label = allNodes[nodeId].oldLabel;
  85. allNodes[nodeId].oldLabel = undefined;
  86. }
  87. allNodes[nodeId]['levelOfSeperation'] = undefined;
  88. allNodes[nodeId]['inConnectionList'] = undefined;
  89. }
  90. }
  91. }
  92. else {
  93. // we clear the level of separation in all nodes.
  94. clearLevelOfSeperation(allNodes);
  95. // we will now start to collect all the connected nodes we want to highlight.
  96. var connectedNodes = selectedItems.nodes;
  97. // we can store them into levels of separation and we could then later use this to define a color per level
  98. // any data can be added to a node, this is just stored in the nodeObject.
  99. storeLevelOfSeperation(connectedNodes,0, allNodes);
  100. for (var i = 1; i < degrees + 1; i++) {
  101. appendConnectedNodes(connectedNodes);
  102. storeLevelOfSeperation(connectedNodes, i, allNodes);
  103. }
  104. for (nodeId in allNodes) {
  105. if (allNodes.hasOwnProperty(nodeId)) {
  106. if (allNodes[nodeId]['inConnectionList'] == true) {
  107. if (allNodes[nodeId]['levelOfSeperation'] !== undefined) {
  108. if (allNodes[nodeId]['levelOfSeperation'] >= 2) {
  109. allNodes[nodeId].color = 'rgba(150,150,150,0.75)';
  110. }
  111. else {
  112. allNodes[nodeId].color = undefined;
  113. }
  114. }
  115. else {
  116. allNodes[nodeId].color = undefined;
  117. }
  118. if (allNodes[nodeId].oldLabel !== undefined) {
  119. allNodes[nodeId].label = allNodes[nodeId].oldLabel;
  120. allNodes[nodeId].oldLabel = undefined;
  121. }
  122. }
  123. else {
  124. allNodes[nodeId].color = 'rgba(200,200,200,0.5)';
  125. if (allNodes[nodeId].oldLabel === undefined) {
  126. allNodes[nodeId].oldLabel = allNodes[nodeId].label;
  127. allNodes[nodeId].label = '';
  128. }
  129. }
  130. }
  131. }
  132. }
  133. var updateArray = [];
  134. for (nodeId in allNodes) {
  135. if (allNodes.hasOwnProperty(nodeId)) {
  136. updateArray.push(allNodes[nodeId]);
  137. }
  138. }
  139. nodes.update(updateArray);
  140. }
  141. /**
  142. * update the allNodes object with the level of separation.
  143. * Arrays are passed by reference, we do not need to return them because we are working in the same object.
  144. */
  145. function storeLevelOfSeperation(connectedNodes, level, allNodes) {
  146. for (var i = 0; i < connectedNodes.length; i++) {
  147. var nodeId = connectedNodes[i];
  148. if (allNodes[nodeId]['levelOfSeperation'] === undefined) {
  149. allNodes[nodeId]['levelOfSeperation'] = level;
  150. }
  151. allNodes[nodeId]['inConnectionList'] = true;
  152. }
  153. }
  154. function clearLevelOfSeperation(allNodes) {
  155. for (var nodeId in allNodes) {
  156. if (allNodes.hasOwnProperty(nodeId)) {
  157. allNodes[nodeId]['levelOfSeperation'] = undefined;
  158. allNodes[nodeId]['inConnectionList'] = undefined;
  159. }
  160. }
  161. }
  162. /**
  163. * Add the connected nodes to the list of nodes we already have
  164. *
  165. *
  166. */
  167. function appendConnectedNodes(sourceNodes) {
  168. var tempSourceNodes = [];
  169. // first we make a copy of the nodes so we do not extend the array we loop over.
  170. for (var i = 0; i < sourceNodes.length; i++) {
  171. tempSourceNodes.push(sourceNodes[i])
  172. }
  173. for (var i = 0; i < tempSourceNodes.length; i++) {
  174. var nodeId = tempSourceNodes[i];
  175. if (sourceNodes.indexOf(nodeId) == -1) {
  176. sourceNodes.push(nodeId);
  177. }
  178. var connectedNodes = network.getConnectedNodes(nodeId);
  179. addUnique(connectedNodes,sourceNodes);
  180. }
  181. tempSourceNodes = null;
  182. }
  183. /**
  184. * Join two arrays without duplicates
  185. * @param fromArray
  186. * @param toArray
  187. */
  188. function addUnique(fromArray, toArray) {
  189. for (var i = 0; i < fromArray.length; i++) {
  190. if (toArray.indexOf(fromArray[i]) == -1) {
  191. toArray.push(fromArray[i]);
  192. }
  193. }
  194. }
  195. redrawAll()
  196. </script>
  197. </body></html>