如何防止在React Flow中将节点添加到视图区域之外?

huangapple go评论80阅读模式
英文:

How can I prevent nodes from being added outside the view area in React Flow?

问题

我使用React Flow构建了一个演示应用程序。当我构建一个巨大的图形或者缩放然后添加一个节点时,我希望该节点位于可见区域的中心,但实际上它被添加到了视图区域之外。我该如何修复这个问题?

当我添加一个新节点时,我希望它位于视图窗口内(最好位于中心位置)。

英文:

I built a demo application using react flow. When I build a huge graph or when I zoom in and then add a node, I want the node to the visible and in the centre of the page, instead, it is added outside the view area. How can I fix this?

When I add a new node, I want it inside the view port (preferably in the centre)

答案1

得分: 1

使用React Flow的useStoreApi()钩子可以获取有关视口的基本信息,以便计算当前中心点的位置。一旦获得这些信息,就可以通过一些简单的数学计算来确定新节点的x和y位置。

例如:

...

const { addNodes } = useReactFlow();
const store = useStoreApi();

const onClick = useCallback(() => {
  // 获取有关视口的基本信息
  const {
    height,
    width,
    transform: [transformX, transformY, zoomLevel]
  } = store.getState();
  const zoomMultiplier = 1 / zoomLevel;

  // 计算当前视口的中心点
  const centerX = -transformX * zoomMultiplier + (width * zoomMultiplier) / 2;
  const centerY =
    -transformY * zoomMultiplier + (height * zoomMultiplier) / 2;

  // 为新节点的高度/宽度添加偏移量
  //(假设您不必另外计算此偏移量)
  const nodeWidthOffset = NODE_WIDTH / 2;
  const nodeHeightOffset = NODE_HEIGHT / 2;

  // 使用所需的x和y添加节点的标准方式
  // 从React Flow示例中复制和粘贴
  const id = `${++nodeId}`;
  const newNode = {
    id,
    position: {
      x: centerX - nodeWidthOffset + currentOverlapOffset,
      y: centerY - nodeHeightOffset + currentOverlapOffset
    },
    data: {
      label: `Node ${id}`
    }
  };
  addNodes(newNode);

  // 为了示例,额外添加的内容(以防多个新节点不会直接堆叠在一起)
  currentOverlapOffset += OVERLAP_OFFSET; // 可能希望更好地处理这个偏移量
}, [addNodes, store]);

...

工作示例: https://codesandbox.io/s/broken-snowflake-qhc7x9?file=/App.js

英文:

With so little information/code, I'm going to have to make quite a few assumptions with my answer.

You can use the React Flow useStoreApi() hook to get the basic information that you need (height, width, transformX, transformY, and zoomLevel) about the viewport in order to calculate the current center. Once you have that, it's just a little math to figure out the x and y placement of the new node(s).

For example:

...

  const { addNodes } = useReactFlow();
  const store = useStoreApi();

  const onClick = useCallback(() => {
    // Get the basic info about the viewport
    const {
      height,
      width,
      transform: [transformX, transformY, zoomLevel]
    } = store.getState();
    const zoomMultiplier = 1 / zoomLevel;

    // Figure out the center of the current viewport
    const centerX = -transformX * zoomMultiplier + (width * zoomMultiplier) / 2;
    const centerY =
      -transformY * zoomMultiplier + (height * zoomMultiplier) / 2;

    // Add offsets for the height/width of the new node 
    // (Assuming that you don't have to calculate this as well
    const nodeWidthOffset = NODE_WIDTH / 2;
    const nodeHeightOffset = NODE_HEIGHT / 2;

    // Standard addition of node with desired x and y
    // copy and pasted from the React Flow examples
    const id = `${++nodeId}`;
    const newNode = {
      id,
      position: {
        x: centerX - nodeWidthOffset + currentOverlapOffset,
        y: centerY - nodeHeightOffset + currentOverlapOffset
      },
      data: {
        label: `Node ${id}`
      }
    };
    addNodes(newNode);

    // Bonus, purely for example's sake (so multiple new nodes don't appear directly on top of each other)
    currentOverlapOffset += OVERLAP_OFFSET; // May want to handle this a bit better
  }, [addNodes, store]);

...

Working Example: https://codesandbox.io/s/broken-snowflake-qhc7x9?file=/App.js

huangapple
  • 本文由 发表于 2023年5月28日 05:18:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349086.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定