146 lines
4.0 KiB
Vue

<template>
<div id="visgraph"></div>
<teleport to="#visgraph-legend">
<div class="my-4 post-menu legend">
<h3>{{ $t('visgraph.Legend')}}</h3>
<div class="list-group">
<label class="list-group-item" v-for="layer in legendLayers">
<input
class="form-check-input me-1"
type="checkbox"
:value="layer.id"
v-model="checkedLayers"
@change="toggleLayer"
/>
{{ layer.label }}
</label>
</div>
</div>
<button class="btn btn-sm btn-outline-secondary" @click="refreshNetwork">{{ $t('action.refresh') }}</button>
</teleport>
</template>
<script>
import vis from 'vis-network/dist/vis-network'
import { mapState, mapGetters } from "vuex"
export default {
name: "App",
data() {
return {
container: '',
checkedLayers: [],
}
},
computed: {
...mapGetters(['nodes', 'edges']),
...mapState(['households', 'courses', 'excludedNodesIds',
// not used
'persons', 'links', 'relationships', 'personLoadedIds', 'householdLoadingIds', 'courseLoadedIds', 'relationshipLoadedIds',
]),
visgraph_data() {
console.log('::: visgraph_data :::', this.nodes.length, 'nodes,', this.edges.length, 'edges')
return {
nodes: this.nodes,
edges: this.edges
}
},
refreshNetwork() {
console.log('--- refresh network')
window.network.setData(this.visgraph_data)
},
legendLayers() {
console.log('--- refresh legend')
return [
...this.households,
...this.courses
]
},
rebuildCheckedLayers() {
console.log('--- rebuild checked Layers')
this.checkedLayers = []
let layersDisplayed = [
...this.nodes.filter(n => n.id.startsWith('household')),
...this.nodes.filter(n => n.id.startsWith('accompanying'))
]
layersDisplayed.forEach(layer => {
this.checkedLayers.push(layer.id)
})
},
checkedLayers() { // required to refresh data checkedLayers
return this.checkedLayers
}
},
mounted() {
console.log('=== mounted: init graph')
this.initGraph()
},
methods: {
initGraph() {
this.container = document.getElementById('visgraph')
// Instanciate vis objects in separate window variables, see vis-network.js
window.network = new vis.Network(this.container, this.visgraph_data, window.options )
},
forceUpdateComponent() {
console.log('forceUpdateComponent')
this.$forceUpdate()
this.refreshNetwork
},
toggleLayer(value) {
//console.log('toggleLayer')
this.forceUpdateComponent()
let id = value.target.value
if (this.checkedLayers.includes(id)) {
this.removeLayer(id)
} else {
this.addLayer(id)
}
},
addLayer(id) {
console.log('+ addLayer', id)
this.checkedLayers.push(id)
this.$store.commit('removeExcludedNode', id)
},
removeLayer(id) {
console.log('- removeLayer', id)
this.checkedLayers = this.checkedLayers.filter(i => i !== id)
this.$store.commit('addExcludedNode', id)
},
}
/*
TODO / TO CHECK / TO UNDERSTAND
///// A
new vis.Network(), param 2: why we don't need to instanciate node and edges with new vis.DataSet like in example ?
{
nodes: new vis.DataSet(this.nodes),
edges: new vis.DataSet(this.relationships)
}
///// B
refreshNetwork() computed: need to watch/listen event to force refreshing ?
*/
}
</script>
<style src="vis-network/dist/dist/vis-network.min.css"></style>
<style lang="scss" scoped>
div#visgraph {
margin: 2em auto;
height: 700px;
border: 0px solid lightgray;
}
div#visgraph-legend {
div.post-menu.legend {
}
}
</style>