vis-network
Version:
A dynamic, browser-based visualization library.
164 lines (149 loc) • 5.15 kB
HTML
<html>
<head>
<title>Vis Network | Data | Dynamic filtering</title>
<script type="text/javascript" src="../../../dist/vis-network.min.js"></script>
<link href="../../../dist/vis-network.min.css" rel="stylesheet" type="text/css"/>
<style type="text/css">
#mynetwork {
width: 600px;
height: 400px;
border: 1px solid lightgray;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
</style>
</head>
<body>
<h1>Dynamic filtering</h1>
<p>
With <a
href="https://visjs.github.io/vis-data/data/dataview.html"
target="_blank">
<code>vis.DataView</code></a>
on top of vis.DataSet you can filter displayed data without modifying the data source.
</p>
<label>
Filter nodes
<select id='nodeFilterSelect'>
<option value=''>All characters</option>
<option value='kid'>kids</option>
<option value='adult'>adults</option>
<option value='male'>male</option>
<option value='female'>female</option>
</select>
</label>
<br>
<br>
<label>
Filter edges
<div>
<label>
<input type='checkbox' name='edgesFilter' value='parent' checked></input>
Is <span style="color:green">parent</span> of
</label>
</div>
<div>
<label>
<input type='checkbox' name='edgesFilter' value='teacher' checked></input>
Is <span style="color:blue">teacher</span> of
</label>
</div>
<div>
<label>
<input type='checkbox' name='edgesFilter' value='friend' checked></input>
Is <span style="color:red">friend</span> of
</label>
</div>
</label>
<br></br>
<div id="mynetwork"></div>
<script type="text/javascript">
const nodeFilterSelector = document.getElementById('nodeFilterSelect')
const edgeFilters = document.getElementsByName('edgesFilter')
function startNetwork(data) {
const container = document.getElementById('mynetwork')
const options = {}
new vis.Network(container, data, options)
}
/**
* In this example we do not mutate nodes or edges source data.
*/
const nodes = new vis.DataSet([
{ id: 1, label: 'Eric Cartman', age: 'kid', gender: 'male' },
{ id: 2, label: 'Stan Marsh', age: 'kid', gender: 'male' },
{ id: 3, label: 'Wendy Testaburger', age: 'kid', gender: 'female' },
{ id: 4, label: 'Mr Mackey', age: 'adult', gender: 'male' },
{ id: 5, label: 'Sharon Marsh', age: 'adult', gender: 'female' }
])
const edges = new vis.DataSet([
{ from: 1, to: 2, relation: 'friend', arrows: 'to, from', color: { color: 'red'} },
{ from: 1, to: 3, relation: 'friend', arrows: 'to, from', color: { color: 'red'} },
{ from: 2, to: 3, relation: 'friend', arrows: 'to, from', color: { color: 'red'} },
{ from: 5, to: 2, relation: 'parent', arrows: 'to', color: { color: 'green'} },
{ from: 4, to: 1, relation: 'teacher', arrows: 'to', color: { color: 'blue'} },
{ from: 4, to: 2, relation: 'teacher', arrows: 'to', color: { color: 'blue'} },
{ from: 4, to: 3, relation: 'teacher', arrows: 'to', color: { color: 'blue'} },
])
/**
* filter values are updated in the outer scope.
* in order to apply filters to new values, DataView.refresh() should be called
*/
let nodeFilterValue = ''
const edgesFilterValues = {
friend: true,
teacher: true,
parent: true
}
/*
filter function should return true or false
based on whether item in DataView satisfies a given condition.
*/
const nodesFilter = (node) => {
if (nodeFilterValue === '') {
return true
}
switch(nodeFilterValue) {
case('kid'):
return node.age === 'kid'
case('adult'):
return node.age === 'adult'
case('male'):
return node.gender === 'male'
case('female'):
return node.gender === 'female'
default:
return true
}
}
const edgesFilter = (edge) => {
return edgesFilterValues[edge.relation]
}
const nodesView = new vis.DataView(nodes, { filter: nodesFilter })
const edgesView = new vis.DataView(edges, { filter: edgesFilter })
nodeFilterSelector.addEventListener('change', (e) => {
// set new value to filter variable
nodeFilterValue = e.target.value
/*
refresh DataView,
so that its filter function is re-calculated with the new variable
*/
nodesView.refresh()
})
edgeFilters.forEach(filter => filter.addEventListener('change', (e) => {
const { value, checked } = e.target
edgesFilterValues[value] = checked
edgesView.refresh()
}))
startNetwork({ nodes: nodesView, edges: edgesView })
</script>
</body>
</html>