<!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>
|