reactjs 使用鼠标调整React流渲染器中的组类型节点的大小

3okqufwl  于 2023-01-05  发布在  React
关注(0)|答案(3)|浏览(196)

我想添加子流(组类型节点)的按钮点击和调整大小后,用鼠标和添加节点在这个组内拖放。我已经搜索了很多,但我发现的是你已经设置了parentNode的孩子这样做。
我希望所有这一切与鼠标拖放。这是可能的免费版本的React-flow-renderer

    • 编辑**

沙箱-〉https://codesandbox.io/embed/headless-architecture-6xbzu9?fontsize=14&hidenavigation=1&theme=dark
下面我已经附加了onDragEnd函数。。它的工作,但当我把一个节点内组,节点的位置发生变化,它去组外。移动组后,它与组一起移动,这意味着它的父设置正确,但位置不正确。试图设置手动位置,但它仍然不工作。

const handleDragEnd = useCallback(
(event: React.MouseEvent<Element>, node: Node) => {
  let groupNode: Node | undefined = undefined;
  if (node.type === ConstantsFlowChartNodeTypes.GROUP) return;
  nodes.map((nds: Node) => {
    if (nds.type === ConstantsFlowChartNodeTypes.GROUP) {
      console.log(
        nds.type,
        nds,
        nds.type === ConstantsFlowChartNodeTypes.GROUP
      );
      if (
        nds.position.x <= node.position.x &&
        nds.position.x + parseInt(nds.style?.width?.toString() || "0") >=
          node.position.x &&
        nds.position.y <= node.position.y &&
        nds.position.y + parseInt(nds.style?.height?.toString() || "0") >=
          node.position.y
      ) {
        groupNode = nds;
      }
    }
  });
  console.log(groupNode);
  if (groupNode) {
    const position = {
      x: event.clientX,
      y: event.clientY,
    };
    setNodes((prevNodes) => {
      return prevNodes.map((nds) => {
        nds.parentNode =
          nds.id === node.id ? groupNode?.id : nds.parentNode;
        // nds.positionAbsolute = position;
        console.log(event);
        return { ...nds };
      });
    });
  }
},
[]);
sauutmhj

sauutmhj1#

要解决在拖放节点时位置改变的问题,请将reactflow示例作为参数发送给函数。然后,您可以使用它,如拖放示例所示,如下所示:

const position = reactFlowInstance.project({
    x: event.clientX - reactFlowBounds.left,
    y: event.clientY - reactFlowBounds.top,
  });

这有助于设置相对于React流示例的位置。或
使用布局库象dagre或elkjs为一个更好的树结构.你可以检查这例子在这下面的链接为那Layout algorithm
接下来是第二点:节点应该留在子流中,我建议您使用自定义节点,并使节点结构如下:

{
id: '4b1',
data: { label: 'Node B.A.1' },
position: { x: 20, y: 40 },
className: 'light',
parentNode: '4b',
extent: 'parent' // this property is important to make the node stay inside parent

}
如果您需要进一步的帮助,请随时分享代码沙盒链接,我可以告诉你那里以及。

gjmwrych

gjmwrych2#

有可能!
如果我理解你的问题,你需要能够拖/放你的节点组之间。
你可以在react-flow中使用"onDragEnd" prop,只要给它传递一个函数,然后每当你在画布中拖放某个东西时,它就会给你精确的拖放位置,经过一些计算,你就可以找到目标组并更新被拖动节点的"parentNode

function handleDragEnd (event, node) {
  // node contains the absolute the drop position
 }

<ReactFlow
 ...your props
 onDragEnd={handleDragEnd}
/>
9jyewag0

9jyewag03#

所以在反复思考这个问题之后,我意识到,我实际上得到的是mousePointer的位置,而不是实际的节点。

  • 如果用户将节点从组外拖动到组内(子流),将放置什么位置。
  • 如果用户将节点从组内部拖动到组外部(子流),位置将是什么。
    组外到组内
nodeWithUpdatedPosition.position = {
            x: draggedNode.positionAbsolute?.x! - targetGroupNode.position.x,
            y: draggedNode.positionAbsolute?.y! - targetGroupNode.position.y,
          };

您必须减去targetGroupNode的位置,因为如果您向任何节点添加父节点,其位置将相对于该组(targetGroupNode),这意味着如果您将{x:0, y:0}的位置指定为draggedNode,则它将放置在targetGroupNode内部的左上角。

组内到组外

nodeWithUpdatedPosition.position = draggedNode.positionAbsolute!

这解决了所有与节点定位相关的问题。即使用户拖动,放大或缩小画布,它也能工作。
Working codeSandbox

相关问题