Search code examples
vis.jsreact-vis-network

Weird rendering with vis-network on react


I'm using vis-network on react / next.js.

When I go to a page with a network on it, the network appears in the top left corner, although the canvas fills out the entire screen (except for the navbar):

enter image description here

I have to click the same navbar item again to get the network in the middle of the screen.

Then there is another issue: The nodes of the network often overlap, although there should be enough space. Any way to fix that?

Try it yourself

The code is on GitHub, so you can clone and run the project:

git clone https://github.com/bennetrr/kafka-der-process.git -b feature/final
cd kafka-der-process/src
yarn install
yarn dev

The pages with networks on it are Themen and Textsprache.


Solution

  • I fixed the problems myself.

    For the first issue: Setting the size of the network manually and then calling network.fit() fixes the problem. The component now looks like this:

    import React, { useEffect, useRef, useState } from "react";
    import { Network } from "vis-network";
    import VisNetworkProps from "../types/VisNetworkProps";
    
    function useContentDimensions() {
        const [contentWidth, setContentWidth] = useState(0);
        const [contentHeight, setContentHeight] = useState(0);
    
        const updateWidthAndHeight = () => {
            setContentWidth(window.innerWidth);
            setContentHeight(window.innerHeight - 50);
        };
    
        useEffect(() => {
            window.addEventListener("resize", updateWidthAndHeight);
            updateWidthAndHeight()
        });
    
        return {contentWidth, contentHeight};
    }
    
    export default function VisNetwork({nodes, edges, options, events}: VisNetworkProps) {
        const visJsRef = useRef<HTMLDivElement>(null);
        const [network, setNetwork] = useState<Network>();
        const {contentWidth, contentHeight} = useContentDimensions();
    
        useEffect(() => {
            const nw = visJsRef.current && new Network(visJsRef.current, {nodes, edges}, options || {});
            nw && setNetwork(nw);
    
            // Apply events
            nw && events && events.forEach(x => nw.on(x.event, x.callback));
        }, [visJsRef, nodes, edges, options, events]);
    
        network && network.setSize(`${contentWidth}px`, `${contentHeight}px`);
        network && network.fit();
    
        return (
            <div ref={visJsRef} style={{width: contentWidth, height: contentHeight}}/>
        );
    }
    
    

    For the second problem: I had the physics simulation disabled. Setting the avoidOverlap option to 1 on a solver, that doesn't move around with this setting, I get this code:

    const options: Options = {
        // ...
        physics: {
            solver: "hierarchicalRepulsion",
            hierarchicalRepulsion: { avoidOverlap: 1 }
        },
        // ...
    };