visjs-network
Version:
A dynamic, browser-based network visualization library.
130 lines (120 loc) • 3.53 kB
JavaScript
/* global vis */
var clusterIndex = 0
var clusters = []
var lastClusterZoomLevel = 0
var clusterFactor = 0.9
// create an array with nodes
var nodes = [
{ id: 1, label: 'Node 1' },
{ id: 2, label: 'Node 2' },
{ id: 3, label: 'Node 3' },
{ id: 4, label: 'Node 4' },
{ id: 5, label: 'Node 5' },
{ id: 6, label: 'Node 6' },
{ id: 7, label: 'Node 7' },
{ id: 8, label: 'Node 8' },
{ id: 9, label: 'Node 9' },
{ id: 10, label: 'Node 10' }
]
// create an array with edges
var edges = [
{ from: 1, to: 2 },
{ from: 1, to: 3 },
{ from: 10, to: 4 },
{ from: 2, to: 5 },
{ from: 6, to: 2 },
{ from: 7, to: 5 },
{ from: 8, to: 6 },
{ from: 9, to: 7 },
{ from: 10, to: 9 }
]
// create a network
var container = document.getElementById('mynetwork')
var data = {
nodes: nodes,
edges: edges
}
var options = {
layout: { randomSeed: 8 },
physics: { adaptiveTimestep: false }
}
var network = new vis.Network(container, data, options)
// set the first initial zoom level
network.once('initRedraw', function() {
if (lastClusterZoomLevel === 0) {
lastClusterZoomLevel = network.getScale()
}
})
// we use the zoom event for our clustering
network.on('zoom', function(params) {
if (params.direction == '-') {
if (params.scale < lastClusterZoomLevel * clusterFactor) {
makeClusters(params.scale)
lastClusterZoomLevel = params.scale
}
} else {
openClusters(params.scale)
}
})
// if we click on a node, we want to open it up!
network.on('selectNode', function(params) {
if (params.nodes.length == 1) {
if (network.isCluster(params.nodes[0]) == true) {
network.openCluster(params.nodes[0])
}
}
})
// make the clusters
// eslint-disable-next-line require-jsdoc
function makeClusters(scale) {
var clusterOptionsByData = {
processProperties: function(clusterOptions, childNodes) {
clusterIndex = clusterIndex + 1
var childrenCount = 0
for (var i = 0; i < childNodes.length; i++) {
childrenCount += childNodes[i].childrenCount || 1
}
clusterOptions.childrenCount = childrenCount
clusterOptions.label = '# ' + childrenCount + ''
clusterOptions.font = { size: childrenCount * 5 + 30 }
clusterOptions.id = 'cluster:' + clusterIndex
clusters.push({ id: 'cluster:' + clusterIndex, scale: scale })
return clusterOptions
},
clusterNodeProperties: {
borderWidth: 3,
shape: 'database',
font: { size: 30 }
}
}
network.clusterOutliers(clusterOptionsByData)
if (document.getElementById('stabilizeCheckbox').checked === true) {
// since we use the scale as a unique identifier, we do NOT want to fit after the stabilization
network.setOptions({ physics: { stabilization: { fit: false } } })
network.stabilize()
}
}
// open them back up!
// eslint-disable-next-line require-jsdoc
function openClusters(scale) {
var newClusters = []
var declustered = false
for (var i = 0; i < clusters.length; i++) {
if (clusters[i].scale < scale) {
network.openCluster(clusters[i].id)
lastClusterZoomLevel = scale
declustered = true
} else {
newClusters.push(clusters[i])
}
}
clusters = newClusters
if (
declustered === true &&
document.getElementById('stabilizeCheckbox').checked === true
) {
// since we use the scale as a unique identifier, we do NOT want to fit after the stabilization
network.setOptions({ physics: { stabilization: { fit: false } } })
network.stabilize()
}
}