dash14 / v-network-graph

An interactive network graph visualization component for Vue 3
https://dash14.github.io/v-network-graph/
MIT License
480 stars 44 forks source link

Grid not showing when using event handler #121

Closed ikkysleepy closed 1 year ago

ikkysleepy commented 1 year ago

When I have a grid and I try to add an event handler the grid disspaers

<template>
    <div>
        <v-network-graph
            :nodes="data.nodes"
            :edges="data.edges"
            :layouts="data.layouts"
            :configs="configs"
        />
        <div ref="viewMenu" class="context-menu">Menu for the background</div>
        <div ref="nodeMenu" class="context-menu">
            Menu for the nodes
            <div>{{ menuTargetNode }}</div>
        </div>
        <div ref="edgeMenu" class="context-menu">
            Menu for the edges
            <div>{{ menuTargetEdges.join(", ") }}</div>
        </div>
    </div>
</template>

<script setup>
    import { ref } from "vue"
    import * as vNG from "v-network-graph"
    import { defineConfigs } from 'v-network-graph';
    const graph = ref();

    const configs = defineConfigs({
        view: {
            grid: {
                visible: true,
                    interval: 10,
                    thickIncrements: 5,
                    line: {
                    color: "#e0e0e0",
                        width: 1,
                        dasharray: 1,
                },
                thick: {
                    color: "#cccccc",
                        width: 1,
                        dasharray: 0,
                },
            },
            layoutHandler: new vNG.GridLayout({ grid: 10 }),
        }
    });

    const data = ref({
        nodes: {
            node1: { name: "N1" },
            node2: { name: "N2" },
            node3: { name: "N3" },
        },
        edges:  {
            edge1: { source: "node1", target: "node2" },
            edge2: { source: "node2", target: "node3" },
            edge3: { source: "node3", target: "node1" },
        },
        layouts: {
            nodes: {
                node1: { x: 50, y: 0 },
                node2: { x: 0, y: 75 },
                node3: { x: 100, y: 75 },
            },
        }
    });

    const showContextMenu = (element, event) => {
        element.style.left = event.pageX + "px"
        element.style.top = event.pageY + "px"
        element.style.visibility = "visible"
        const handler = (event) => {
            if (!event.target || !element.contains(event.target)) {
                element.style.visibility = "hidden"
                document.removeEventListener("pointerdown", handler, { capture: true })
            }
        }
        document.addEventListener("pointerdown", handler, { passive: true, capture: true })
    }

    const viewMenu = ref(null)
    const showViewContextMenu = (params) => {
        const { event } = params
        event.stopPropagation()
        event.preventDefault()
        if (viewMenu.value) {
            showContextMenu(viewMenu.value, event)
        }
    }

    const nodeMenu = ref(null)
    const menuTargetNode = ref("")
    const showNodeContextMenu = (params) => {
        const { node, event } = params
        event.stopPropagation()
        event.preventDefault()
        if (nodeMenu.value && data.value.nodes[node]) {
            menuTargetNode.value = data.value.nodes[node].name ?? ""
            showContextMenu(nodeMenu.value, event)
        }
    }

    const edgeMenu = ref(null)
    const menuTargetEdges = ref([])
    const showEdgeContextMenu = (params) => {
        const { event } = params
        event.stopPropagation()
        event.preventDefault()
        if (edgeMenu.value) {
            menuTargetEdges.value = params.summarized ? params.edges : [params.edge]
            showContextMenu(edgeMenu.value, event)
        }
    }

    const eventHandlers = {
        "view:contextmenu": showViewContextMenu,
        "node:contextmenu": showNodeContextMenu,
        "edge:contextmenu": showEdgeContextMenu,
    }
</script>

<style scoped>
    .context-menu {
        width: 180px;
        background-color: #efefef;
        padding: 10px;
        position: fixed;
        visibility: hidden;
        font-size: 12px;
        border: 1px solid #aaa;
        box-shadow: 2px 2px 2px #aaa;
        > div {
            border: 1px dashed #aaa;
            padding: 4px;
            margin-top: 8px;
        }
    }
</style>

So when I add

 :eventHandlers="eventHandlers"

The grid disappears on refresh of the page and sometimes when using watcher.

The event handler's work in both cases.

dash14 commented 1 year ago

Hi @ikkysleepy,

Thank you for your report! I have tried the code you provided, but unfortunately, I was unable to reproduce the issue in my own environment.

Please allow me to ask you a few questions:

It is difficult to identify the cause at this stage, as it is unlikely that the grid view and event handler are in conflict. There is a possibility that the problem is not occurring only in the library code, such as being caused by the browser or framework. If this is the case, it may be difficult to resolve.

The environment in which I tried this is as follows:

Thank you very much for your cooperation.

ikkysleepy commented 1 year ago

The issue was on my end.

I have the latest of everything on my M2 Mac using Chrome. I am using Vuejs framework and other plugins. I guess I meant just running run npm run dev, which auto refresh the page. Anyways I think the problem was mine I was doing this:

 line: {
                    color: isDarkMode ? '#1b2e4b' : '#e0e0e0',
                    width: 5,
                    dasharray: 1
                },
                thick: {
                    color: isDarkMode ? '#1b2e4b' : '#cccccc',
                    width: 5,
                    dasharray: 0
                }

which was causing some problems so instead of the code above I am now doing a watch on isDarkMode and updating the configuration. This method above was causing some colors to flip as well for some odd reason. Anyways, the issue appears to be on my side. Thank's for looking into the issue.