vue_visgraph: add checkbox legend to enable/disable layers

This commit is contained in:
Mathieu Jaumotte 2021-10-26 21:29:17 +02:00
parent ccf6c7ad91
commit 2a86fd12d7
3 changed files with 97 additions and 34 deletions

View File

@ -1,30 +1,28 @@
<template> <template>
<!--
-->
<div id="visgraph"></div> <div id="visgraph"></div>
<teleport to="#visgraph-legend"> <teleport to="#visgraph-legend">
<div class="my-4 post-menu legend"> <div class="my-4 post-menu legend">
<h3>Afficher</h3> <h3>Légende</h3>
<div class="list-group"> <div class="list-group">
<label class="list-group-item"> <label class="list-group-item" v-for="layer in legendLayers">
<input class="form-check-input me-1" type="checkbox" value=""> <input
Ménage n°65 class="form-check-input me-1"
</label> type="checkbox"
<label class="list-group-item"> :value="layer.id"
<input class="form-check-input me-1" type="checkbox" value=""> v-model="checkedLayers"
Parcours n°1615 @change="toggleLayer"
</label> /> <!--
<label class="list-group-item"> -->
<input class="form-check-input me-1" type="checkbox" value=""> {{ layer.label }}
Parcours n°1613
</label>
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
Parcours n°1614
</label> </label>
</div> </div>
</div> </div>
<pre>
Checked layers: {{ checkedLayers }}
Unchecked layers: {{ excludedNodesIds }}
</pre>
<button class="btn btn-sm btn-outline-secondary" @click="refreshNetwork">Rafraîchir</button> <button class="btn btn-sm btn-outline-secondary" @click="refreshNetwork">Rafraîchir</button>
</teleport> </teleport>
</template> </template>
@ -37,12 +35,19 @@ export default {
name: "App", name: "App",
data() { data() {
return { return {
container: '' container: '',
checkedLayers: [],
} }
}, },
computed: { computed: {
//not used ...mapState(['persons', 'households', 'courses', 'relationships', 'householdLoadingIds', 'courseLoadedIds']),
...mapGetters(['nodes', 'edges']), ...mapGetters(['nodes', 'edges']),
...mapState(['households', 'courses',
'excludedNodesIds'
//'persons',
//'relationships',
//'householdLoadingIds',
//'courseLoadedIds',
]),
visgraph_data() { visgraph_data() {
console.log('::: visgraph_data :::', this.nodes.length, 'nodes,', this.edges.length, 'edges') console.log('::: visgraph_data :::', this.nodes.length, 'nodes,', this.edges.length, 'edges')
@ -51,10 +56,36 @@ export default {
edges: this.edges edges: this.edges
} }
}, },
refreshNetwork() { // B refreshNetwork() { // B
console.log('--- refresh network') console.log('--- refresh network')
window.network.setData(this.visgraph_data) window.network.setData(this.visgraph_data)
},
legendLayers() {
console.log('--- refresh legendLayers')
return [
...this.households,
...this.courses
]
},
rebuildCheckedLayers() {
console.log('-*- rebuild checked Layers Arrays from graph nodes')
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() { mounted() {
console.log('=== mounted: init graph') console.log('=== mounted: init graph')
@ -63,7 +94,6 @@ export default {
methods: { methods: {
initGraph() { initGraph() {
this.container = document.getElementById('visgraph') this.container = document.getElementById('visgraph')
// Instanciate vis objects in window variables, see vis-network.js // Instanciate vis objects in window variables, see vis-network.js
window.network = new vis.Network(this.container, this.visgraph_data, window.options ) // A window.network = new vis.Network(this.container, this.visgraph_data, window.options ) // A
}, },
@ -71,7 +101,29 @@ export default {
console.log('forceUpdateComponent - method 3') console.log('forceUpdateComponent - method 3')
this.$forceUpdate() this.$forceUpdate()
this.refreshNetwork this.refreshNetwork
} },
toggleLayer(value) {
let id = value.target.value
console.log('--> toggleLayer', this.checkedLayers)
if (this.checkedLayers.includes(id)) {
this.removeLayer(id)
} else {
this.addLayer(id)
}
console.log('<-- toggleLayer after', this.checkedLayers)
},
addLayer(id) {
console.log('+ add Layer', id)
this.checkedLayers.push(id)
this.$store.commit('removeExcludedNode', id)
},
removeLayer(id) {
console.log('- remove Layer', id)
this.checkedLayers = this.checkedLayers.filter(i => i !== id)
this.$store.commit('addExcludedNode', id)
},
} }
/* /*
TODO / TO CHECK / TO UNDERSTAND TODO / TO CHECK / TO UNDERSTAND
@ -98,14 +150,6 @@ div#visgraph {
} }
div#visgraph-legend { div#visgraph-legend {
div.post-menu.legend { div.post-menu.legend {
ul.legend-list {
padding-left: 0;
list-style-type: square;
li::marker {
color: red;
background-color: cyan;
}
}
} }
} }
</style> </style>

View File

@ -12,7 +12,8 @@ const store = createStore({
courses: [], courses: [],
relationships: [], relationships: [],
householdLoadingIds: [], householdLoadingIds: [],
courseLoadedIds: [] courseLoadedIds: [],
excludedNodesIds: []
}, },
getters: { getters: {
nodes(state) { nodes(state) {
@ -26,6 +27,10 @@ const store = createStore({
state.courses.forEach(c => { state.courses.forEach(c => {
nodes.push(c) nodes.push(c)
}) })
// except excluded nodes (unchecked layers)
state.excludedNodesIds.forEach(excluded => {
nodes = nodes.filter(n => n.id !== excluded)
})
return nodes return nodes
}, },
edges(state) { edges(state) {
@ -56,7 +61,7 @@ const store = createStore({
state.courses.push(adapt2vis(course)) state.courses.push(adapt2vis(course))
}, },
addRelationship(state, relationship) { addRelationship(state, relationship) {
console.log('+ addRelationship', relationship) console.log('+ addRelationship from', relationship.from, 'to', relationship.to)
state.relationships.push(relationship) state.relationships.push(relationship)
}, },
markHouseholdLoading(state, id) { markHouseholdLoading(state, id) {
@ -72,6 +77,12 @@ const store = createStore({
unmarkCourseLoaded(state, id) { unmarkCourseLoaded(state, id) {
state.courseLoadedIds = state.courseLoadedIds.filter(i => i !== id) state.courseLoadedIds = state.courseLoadedIds.filter(i => i !== id)
}, },
addExcludedNode(state, id) {
state.excludedNodesIds.push(id)
},
removeExcludedNode(state, id) {
state.excludedNodesIds = state.excludedNodesIds.filter(e => e !== id)
}
}, },
actions: { actions: {
/** /**
@ -185,7 +196,7 @@ const store = createStore({
arrows: 'to', arrows: 'to',
color: 'orange', color: 'orange',
font: { color: 'orange' }, font: { color: 'orange' },
label: 'usager', label: 'concerné',
//group: 'link_person_course', //group: 'link_person_course',
}) })
}) })

View File

@ -10,6 +10,14 @@ import { visMessages } from './i18n'
window.options = { window.options = {
locale: 'fr', locale: 'fr',
locales: visMessages, locales: visMessages,
/*
configure: {
enabled: true,
filter: 'nodes,edges',
container: undefined,
showButton: true
},
*/
manipulation: { manipulation: {
enabled: true, enabled: true,
initiallyActive: true, initiallyActive: true,
@ -63,7 +71,7 @@ window.options = {
physics: true, physics: true,
font: { font: {
color: '#b0b0b0', color: '#b0b0b0',
size: 9, size: 9,
face: 'arial', face: 'arial',
background: 'none', background: 'none',
strokeWidth: 2, // px strokeWidth: 2, // px