在 Cosmograph React 组件中实现节点的拖放功能

问题描述 投票:0回答:1

Stack Overflow 社区,

我正在开发一个 React 项目,其中使用 Cosmograph 库来渲染带有节点和边的图形。我正在寻求实现一项功能,允许用户拖放节点以更改其在图表中的位置(移动节点)。然而,在查看了 Cosmograph 文档和可用资源后,我还没有在 Cosmograph 中找到内置方法或 API 来直接更新节点的 x 和 y 位置。

这是我当前如何设置 Cosmograph 组件的示例:

import React, { useRef, useState } from 'react';
import { Cosmograph, CosmographProvider } from '@cosmograph/react';

// Node and Link types definitions
// GraphData state setup
// Example of current Cosmograph component setup

<CosmographProvider>
    <Cosmograph
        ref={containerRef}
        nodes={graphData.nodes}
        links={graphData.edges}
        // Other configurations
    />
</CosmographProvider>

我考虑过跟踪 Cosmograph 组件外部的鼠标事件来手动更新节点位置并重新渲染图形,但这种方法看起来很复杂,可能不是最有效的方法。

这里有人使用 Cosmograph 并为节点实现了类似的拖放功能吗?如果是这样,您能否分享一下您的方法或关于如何实现这一目标的任何见解?此外,如果有任何推荐的做法来处理 React 中与图形节点的此类交互,我将非常感谢您的指导。

感谢您的时间和帮助!

javascript reactjs drag-and-drop
1个回答
0
投票

虽然 Cosmograph 库本身可能不提供通过拖放直接更新节点位置的内置方法,但您仍然可以通过结合使用外部库进行拖放交互和功能来实现此功能宇宙计。

这是使用 React 和

react-dnd
库实现拖放功能的通用方法:

  1. 安装

    react-dnd
    react-dnd-html5-backend

    npm install react-dnd react-dnd-html5-backend
    
  2. 创建

    DraggableNode
    组件:

    import React from 'react';
    import { useDrag } from 'react-dnd';
    
    const DraggableNode = ({ node, onDrag }) => {
      const [{ isDragging }, drag] = useDrag({
        item: { type: 'NODE', id: node.id, originalX: node.x, originalY: node.y },
        collect: (monitor) => ({
          isDragging: !!monitor.isDragging(),
        }),
      });
    
      return (
        <div
          ref={drag}
          style={{
            opacity: isDragging ? 0.5 : 1,
            cursor: 'move',
            position: 'absolute',
            left: node.x,
            top: node.y,
          }}
        >
          {node.label}
        </div>
      );
    };
    
    export default DraggableNode;
    
  3. 更新您的主要组件:

    import React, { useRef } from 'react';
    import { useDrop } from 'react-dnd';
    import { Cosmograph, CosmographProvider } from '@cosmograph/react';
    import DraggableNode from './DraggableNode';
    
    const YourGraphComponent = () => {
      const containerRef = useRef(null);
    
      const [, drop] = useDrop({
        accept: 'NODE',
        drop: (item, monitor) => {
          const delta = monitor.getDifferenceFromInitialOffset();
          const left = Math.round(item.originalX + delta.x);
          const top = Math.round(item.originalY + delta.y);
    
          // Update node position in your graphData
          // You'll need to implement a function to update the node positions
          // and re-render the Cosmograph component
          updateNodePosition(item.id, left, top);
        },
      });
    
      return (
        <CosmographProvider>
          <div ref={(node) => drop(containerRef)}>
            {graphData.nodes.map((node) => (
              <DraggableNode key={node.id} node={node} />
            ))}
          </div>
          <Cosmograph ref={containerRef} nodes={graphData.nodes} links={graphData.edges} />
        </CosmographProvider>
      );
    };
    
    export default YourGraphComponent;
    

此方法使用

react-dnd
进行拖放交互,当节点被删除时,它会更新处于
graphData
状态的节点位置。您需要根据您的具体状态管理和重新渲染逻辑来实现
updateNodePosition
函数。

请记住调整代码以适应您的应用程序结构和状态管理实践。

© www.soinside.com 2019 - 2024. All rights reserved.