Closed happylilem closed 2 years ago
Hi @happylilem, I tried but could not reproduce it on my end. Is it possible for you to provide the minimum code?
I noticed in the process of checking, is the following code which included in the example using d3-force, also included in your code? This code reconstructs the nodes and edges, so if it is included, this process may be the cause. If not, sorry.
watchEffect(() => {
buildNetwork(nodeCount.value, nodes, edges)
})
I don't have that code snippet included in my code, but here's a minimum code that can reproduce the problem--
App.vue
<script setup lang="ts">
import { reactive, ref, computed } from "vue"
import * as vNG from "v-network-graph"
import { Nodes, Edges } from "v-network-graph"
import {
ForceLayout,
} from "v-network-graph/lib/force-layout"
import data from "./test-data.json"
const nodes: Nodes = reactive({ ...data.nodes })
const edges: Edges = reactive({ ...data.edges })
const selectedNodes = ref<string[]>([])
const selectedEdges = ref<string[]>([])
const configs = reactive(
vNG.defineConfigs({
view: {
minZoomLevel: 0.1,
maxZoomLevel: 16,
layoutHandler: new ForceLayout({
positionFixedByDrag: false,
positionFixedByClickWithAltKey: true,
}),
},
node: {
selectable: 2,
},
edge: {
selectable: true,
normal: {
width: 3,
},
},
})
)
const d3ForceEnabled = computed({
get: () => configs.view.layoutHandler instanceof ForceLayout,
set: (value: boolean) => {
if (value) {
configs.view.layoutHandler = new ForceLayout()
} else {
configs.view.layoutHandler = new vNG.SimpleLayout()
}
},
})
function removeNode() {
for (const nodeId of selectedNodes.value) {
delete nodes[nodeId]
}
}
function removeEdge() {
for (const edgeId of selectedEdges.value) {
delete edges[edgeId]
}
}
</script>
<template>
<div class="demo-control-panel">
<div>
<label>Node:</label>
<el-button :disabled="selectedNodes.length == 0" @click="removeNode"
>remove</el-button
>
</div>
<div>
<label>Edge:</label>
<el-button :disabled="selectedEdges.length == 0" @click="removeEdge"
>remove</el-button
>
</div>
</div>
<div>
<input type="checkbox" id="force" v-model="d3ForceEnabled">
<label for="force">D3-Force enabled</label>
</div>
<v-network-graph
v-model:selected-nodes="selectedNodes"
v-model:selected-edges="selectedEdges"
:nodes="nodes"
:edges="edges"
:layouts="data.layouts"
:configs="configs"
/>
</template>
test-data.json file:
{
"nodes": {
"1": {"name": "node 1", "size": 32, "color": "gray", "label": true },
"2": {"name": "node 2", "size": 24, "color": "pink", "label": true },
"3": {"name":"node 3", "size": 16, "color": "pink", "label": true },
"4": {"name":"node 4", "size": 16, "color": "pink", "label": true }
},
"edges": {
"1": { "source": "1", "target": "2", "width": 3},
"2": { "source": "1", "target": "3", "width": 3 },
"3": { "source": "1", "target": "4", "width": 3 },
"4": { "source": "2", "target": "3", "width": 1 }
}
}
Besides, after I disabled d3-force and deleted a node with its associated edges and then switched back to d3-force positioning, I'm not able to operate the graph anymore since it throws this error: Uncaught (in promise) Error: node not found: 4
(where 4 is the number of node that has been removed).
Hi @happylilem, Thank you for providing a reproducible snippet! I now understand the situation that is an error.
I've fixed and released.
With the new release(v0.6.3), when passing a list of edges
to d3-force, edges
containing non-existent nodes
are excluded.
However, note that v-network-graph does not modify the contents of nodes
and edges
, so edges
contains nodes
that do not exist actually.
Best Regards
I close this issue for now. If you have any questions, please open a new issue or re-open this.
Hi, I'm using d3-force layout for my network and found that when a node has any edge connected to it, the remove node function wouldn't work. I did a few trials and can confirm that this issue only occurs when d3-force is enabled. As long as d3-force is disabled, the node and the associated edges can be removed. So I guess this is a bug in the library?