antv/g6 and react. How to update graph?

1.9k views Asked by At

I have a graph and need to update it after clicking on the button. But it creates a new canvas every time.

What am I doing wrong?

https://codesandbox.io/s/gallant-galileo-ye91n

const Graph = () => {
    let graph = null;
    const [data, setData] = useState({ nodes: [{ id: 'node1', label: '1' }, { id: 'node2', label: '2' },], edges: [], });
    const ref = React.useRef(null);


    useEffect(() => {
        graph = new G6.Graph({
            container: ref.current,
            width: 300,
            height: 300,
            modes: {
                default: ['drag-canvas', 'zoom-canvas', 'drag-node']
            },
        });

        graph.data(data);
        graph.render();

        return () => {
            graph.changeData(data);
        };
    }, [data]);


    const handleClick = () => {
        setData({
            nodes: [
                { id: 'node1', label: '1' },
                { id: 'node2', label: '2' },
            ],
            edges: [
                { source: 'node1', target: 'node2' },
            ],
        });
    }
    return <>
        <button onClick={handleClick}>changeData</button>
        <div ref={ref}></div>
    </>;
}
1

There are 1 answers

0
Siyavash Hamdi On

Please note that whenever data is changed, a new G6.Graph will be called. So a new canvas will be created.

Try the following code:

import { useEffect, useRef, useState } from "react";
import G6 from "@antv/g6";

let graph = null;

const Graph = () => {
  const [data, setData] = useState({
    nodes: [
      { id: "node1", label: "1" },
      { id: "node2", label: "2" },
    ],
    edges: [],
  });
  
  const ref = useRef(null);

  useEffect(() => {
    if (!graph) {
      graph = new G6.Graph({
        container: ref.current,
        width: 300,
        height: 300,
        modes: {
          default: ["drag-canvas", "zoom-canvas", "drag-node"],
        },
      });
    }

    graph.data(data);
    graph.render();

    return () => {
      graph.changeData(data);
    };
  }, [data]);

  const handleClick = () => {
    setData({
      nodes: [
        { id: "node1", label: "1" },
        { id: "node2", label: "2" },
      ],
      edges: [{ source: "node1", target: "node2" }],
    });
  };
  return (
    <>
      <button onClick={handleClick}>changeData</button>
      <div ref={ref}></div>
    </>
  );
};

export default Graph;