| <!DOCTYPE html> | |
| <!-- saved from url=(0044)http://kenedict.com/networks/worldcup14/vis/ , thanks Andre!--> | |
| <html><head><meta http-equiv="content-type" content="text/html; charset=UTF8"> | |
|   <title>Network |  Static smooth curves - World Cup Network</title> | |
| 
 | |
|   <script type="text/javascript" src="../../dist/vis.js"></script> | |
|   <link type="text/css" rel="stylesheet" href="../../dist/vis.css"> | |
| 
 | |
|   <script src="./data/WorldCup2014.js"></script> | |
| 
 | |
|   <style type="text/css"> | |
|     #mynetwork { | |
|       width: 800px; | |
|       height: 800px; | |
|       border: 1px solid lightgray; | |
|     } | |
|   </style> | |
|   <script src="../googleAnalytics.js"></script> | |
| </head> | |
| 
 | |
| <body> | |
| 
 | |
| <h2>Dynamic Data - Neighbourhood Highlight</h2> | |
| <div style="width:800px; font-size:14px;"> | |
|   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. | |
|   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 | |
|   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..). | |
|   <br /><br /> | |
| </div> | |
| 
 | |
| <div id="mynetwork"></div> | |
| 
 | |
| <script type="text/javascript"> | |
|   var network; | |
| 
 | |
|   var nodes = new vis.DataSet(); | |
|   var edges = new vis.DataSet(); | |
| 
 | |
|   function redrawAll() { | |
|     nodes.clear(); | |
|     edges.clear(); | |
| 
 | |
|     network = null; | |
| 
 | |
|     var container = document.getElementById('mynetwork'); | |
|     var options = { | |
|       nodes: { | |
|         shape: 'dot', | |
|         scaling: { | |
|           min: 10, | |
|           max: 30, | |
|           label: { | |
|             min: 8, | |
|             max: 20, | |
|             drawThreshold: 12, | |
|             maxVisible: 20 | |
|           } | |
|         }, | |
|         font: { | |
|           size: 12, | |
|           face: 'Tahoma' | |
|         } | |
|       }, | |
|       edges: { | |
|         width: 0.15, | |
|         color: {inherit: 'from'}, | |
|         smooth: { | |
|           dynamic: false, | |
|           type: 'continuous' | |
|         } | |
|       }, | |
|       physics: false, | |
|       interaction: { | |
|         tooltipDelay: 200 | |
|       }, | |
|       rendering: { | |
|         hideEdgesOnDrag: true | |
|       } | |
|     }; | |
| 
 | |
|     // Note: data is coming from ./data/WorldCup2014.js | |
|     network = new vis.Network(container, data, options); | |
|     network.on("click",onClick); | |
|   } | |
| 
 | |
| 
 | |
|   function onClick(selectedItems) { | |
|     var nodeId; | |
|     var degrees = 2; | |
|     // we get all data from the dataset once to avoid updating multiple times. | |
|     var allNodes = nodes.get({returnType:"Object"}); | |
|     if (selectedItems.nodes.length == 0) { | |
|       // restore on unselect | |
|       for (nodeId in allNodes) { | |
|         if (allNodes.hasOwnProperty(nodeId)) { | |
|           allNodes[nodeId].color = undefined; | |
|           if (allNodes[nodeId].oldLabel !== undefined) { | |
|             allNodes[nodeId].label = allNodes[nodeId].oldLabel; | |
|             allNodes[nodeId].oldLabel = undefined; | |
|           } | |
|           allNodes[nodeId]['levelOfSeperation'] = undefined; | |
|           allNodes[nodeId]['inConnectionList'] = undefined; | |
|         } | |
|       } | |
|     } | |
|     else { | |
|       // we clear the level of separation in all nodes. | |
|       clearLevelOfSeperation(allNodes); | |
| 
 | |
|       // we will now start to collect all the connected nodes we want to highlight. | |
|       var connectedNodes = selectedItems.nodes; | |
| 
 | |
|       // we can store them into levels of separation and we could then later use this to define a color per level | |
|       // any data can be added to a node, this is just stored in the nodeObject. | |
|       storeLevelOfSeperation(connectedNodes,0, allNodes); | |
|       for (var i = 1; i < degrees + 1; i++) { | |
|         appendConnectedNodes(connectedNodes); | |
|         storeLevelOfSeperation(connectedNodes, i, allNodes); | |
|       } | |
|       for (nodeId in allNodes) { | |
|         if (allNodes.hasOwnProperty(nodeId)) { | |
|           if (allNodes[nodeId]['inConnectionList'] == true) { | |
|             if (allNodes[nodeId]['levelOfSeperation'] !== undefined) { | |
|               if (allNodes[nodeId]['levelOfSeperation'] >= 2) { | |
|                 allNodes[nodeId].color = 'rgba(150,150,150,0.75)'; | |
|               } | |
|               else { | |
|                 allNodes[nodeId].color = undefined; | |
|               } | |
|             } | |
|             else { | |
|               allNodes[nodeId].color = undefined; | |
|             } | |
|             if (allNodes[nodeId].oldLabel !== undefined) { | |
|               allNodes[nodeId].label = allNodes[nodeId].oldLabel; | |
|               allNodes[nodeId].oldLabel = undefined; | |
|             } | |
|           } | |
|           else { | |
|             allNodes[nodeId].color = 'rgba(200,200,200,0.5)'; | |
|             if (allNodes[nodeId].oldLabel === undefined) { | |
|               allNodes[nodeId].oldLabel = allNodes[nodeId].label; | |
|               allNodes[nodeId].label = ''; | |
|             } | |
|           } | |
|         } | |
|       } | |
|     } | |
|     var updateArray = []; | |
|     for (nodeId in allNodes) { | |
|       if (allNodes.hasOwnProperty(nodeId)) { | |
|         updateArray.push(allNodes[nodeId]); | |
|       } | |
|     } | |
|     nodes.update(updateArray); | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * update the allNodes object with the level of separation. | |
|    * Arrays are passed by reference, we do not need to return them because we are working in the same object. | |
|    */ | |
|   function storeLevelOfSeperation(connectedNodes, level, allNodes) { | |
|     for (var i = 0; i < connectedNodes.length; i++) { | |
|       var nodeId = connectedNodes[i]; | |
|       if (allNodes[nodeId]['levelOfSeperation'] === undefined) { | |
|         allNodes[nodeId]['levelOfSeperation'] = level; | |
|       } | |
|       allNodes[nodeId]['inConnectionList'] = true; | |
|     } | |
|   } | |
| 
 | |
|   function clearLevelOfSeperation(allNodes) { | |
|     for (var nodeId in allNodes) { | |
|       if (allNodes.hasOwnProperty(nodeId)) { | |
|         allNodes[nodeId]['levelOfSeperation'] = undefined; | |
|         allNodes[nodeId]['inConnectionList'] = undefined; | |
|       } | |
|     } | |
|   } | |
| 
 | |
|   /** | |
|    * Add the connected nodes to the list of nodes we already have | |
|    * | |
|    * | |
|    */ | |
|   function appendConnectedNodes(sourceNodes) { | |
|     var tempSourceNodes = []; | |
|     // first we make a copy of the nodes so we do not extend the array we loop over. | |
|     for (var i = 0; i < sourceNodes.length; i++) { | |
|       tempSourceNodes.push(sourceNodes[i]) | |
|     } | |
| 
 | |
|     for (var i = 0; i < tempSourceNodes.length; i++) { | |
|       var nodeId = tempSourceNodes[i]; | |
|       if (sourceNodes.indexOf(nodeId) == -1) { | |
|         sourceNodes.push(nodeId); | |
|       } | |
|       var connectedNodes = network.getConnectedNodes(nodeId); | |
|       addUnique(connectedNodes,sourceNodes); | |
|     } | |
|     tempSourceNodes = null; | |
|   } | |
| 
 | |
|   /** | |
|    * Join two arrays without duplicates | |
|    * @param fromArray | |
|    * @param toArray | |
|    */ | |
|   function addUnique(fromArray, toArray) { | |
|     for (var i = 0; i < fromArray.length; i++) { | |
|       if (toArray.indexOf(fromArray[i]) == -1) { | |
|         toArray.push(fromArray[i]); | |
|       } | |
|     } | |
|   } | |
| 
 | |
|   redrawAll() | |
| 
 | |
| </script> | |
| 
 | |
| </body></html>
 |