antvis/G6

5.0版本动态添加元素边,拖拽和缩放画布之后边错位,如果在新增边也是错位的 #6031

silentRiding posted onGitHub

Describe the bug / 问题描述

5.0版本使用react创建的元素,给元素添加新增删除按钮,动态添加元素和边之后,拖拽和缩放画布之后边出现错位,如果再新增元素,边也是错位的

No response

Steps to Reproduce the Bug or Issue / 重现步骤

`` 这是index页面 import { Graph, ExtensionCategory, register, CanvasEvent } from '@antv/g6'; import { useEffect, useRef, useState } from 'react'; import { ReactNode, GNode } from '@antv/g6-extension-react'; import InitNode from './initNode'; import AddNode from './addNode';

register(ExtensionCategory.NODE, 'react', ReactNode); export default () => { const [startPoint, setStartPoint] = useState({ x: 0, y: 0 }); const containerRef = useRef<HTMLDivElement>(null); const documentClientHeight = document.documentElement.clientHeight - 20; const documentClientWidth = document.documentElement.clientWidth - 20; useEffect(() => { const graph = new Graph({ container: containerRef.current!, width: 5000, height: 5000, // background: '#ECECEC', // autoFit: { // type: 'view', // options: { // direction: 'both', // when: 'always' // } // }, data: { nodes: [ { id: 'node-1', type: 'react', style: { x: documentClientWidth / 2 - 200, y: 100 }, data: { isInit: true }, } ], edges: [ // { // id: 'edge-1', source: 'node-1', target: 'node-2' // }, // { // id: 'edge-2', source: 'node-1', target: 'node-3' // }, // { // id: 'edge-3', source: 'node-1', target: 'node-4' // } ], }, node: { // type: 'react', style: { size: [426, 100], component: (data: any) => { // 判断加载初始节点/新增节点 if (Object.prototype.toString.call(data.data.isInit) === '[object Boolean]' && data.data.isInit) { return <InitNode data={data} graph={graph} /> } else { return <AddNode data={data} graph={graph} /> } }, ports: [{ placement: 'top' }, { placement: 'bottom' }], }, }, edge: { type: 'cubic-vertical', // style: { // endArrow: true, // }, }, // 通过插件实现背景色 plugins: [ { type: 'background', width: 5000 + 'px', height: 5000 + 'px', background: '#ECECEC', } ], behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element'], }); console.log(graph, 'graph') graph.on(CanvasEvent.DRAG_START, (evt) => { const { x, y } = evt.offset; // graph.translateTo([x, y]) setStartPoint({ x, y }); console.log(evt, 'offset') // 更新画布中所有节点的位置 // graph.getNodes().forEach(node => { // const model = node.getModel(); // graph.update(node, { // x: model.x + dx, // y: model.y + dy, // }); // }); }); graph.on(CanvasEvent.DRAG_END, ({ offset }) => { const { x, y } = offset; const dx = x - startPoint.x; const dy = y - startPoint.y; console.log(graph.getNodeData()); // 更新画布中所有节点的位置 graph.getNodeData().forEach(({ id }) => { // graph.translateElementBy( id, [dx, dy]) }) const newEdgeData: any = [] graph.getEdgeData().forEach(({ id, source, target }) => { newEdgeData.push({ id, source, target }) }) graph.updateNodeData([...graph.getNodeData()]) graph.updateEdgeData([...newEdgeData]) // graph.updateData([...graph.getData()]) // graph.translateBy([dx, dy]) graph.updateTransform({ key: 'matrix', translateX: 200, translateY: -10, scaleX: 1.5, scaleY: 1, rotation: 45, // 45度顺时针旋转 }) // graph.render(); }); graph.render(); }, []);

return <div ref={containerRef} />;

};

这是组件页面 addNode组件 import { PlusOutlined, CloseOutlined } from '@ant-design/icons'; import { Button } from 'antd'; import { useState } from 'react';

interface EdgeData { id: string; source: string; target: string; }

export default function AddNode(props: any): JSX.Element { const [isShow, setIsShow] = useState(false); // 点击新增按钮 const handlerAddNode = () => { const { x, y } = props.data.style const newPosition = calculateLocation(props.data.id) const nodeData = { id: node_${new Date().getTime()}, type: 'react', style: { x: newPosition.newX ? newPosition.newX : x - 200, y: newPosition.newY ? newPosition.newY : y + 206 }, data: { isInit: false }, } const edgeData = { id: edge_${new Date().getTime()}, source: props.data.id, target: nodeData.id } props.graph.addNodeData([nodeData]) props.graph.addEdgeData([edgeData]) props.graph.render() } // 点击删除按钮 const handlerDelNode = (id: string) => { handlerEdgeNode(id) props.graph.removeNodeData([id]); } // 删除相关点的所有节点 const handlerEdgeNode = (id: string) => { const edgeData = props.graph.getEdgeData().filter((item: EdgeData) => item.source === id) if (edgeData.length) { edgeData.forEach((item: EdgeData) => { handlerDelNode(item.target) }) } props.graph.render() } // 计算新增节点的位置 const calculateLocation = (id: string) => { const edgeData = props.graph.getEdgeData().filter((item: EdgeData) => item.source === id) if (edgeData.length) { const nodeData = props.graph.getNodeData(edgeData[edgeData.length - 1].target) return { newX: nodeData.style.x + 430, newY: nodeData.style.y } } else { return {} } } return ( <div id="add_node" onMouseEnter={() => setIsShow(true)} onMouseLeave={() => setIsShow(false)}> {isShow ? <div className="add_node_plus"> <Button onClick={handlerAddNode} type="primary" shape="circle" icon={<PlusOutlined />} /> </div> : null} {isShow ? <div className="add_node_del"> <Button onClick={() => handlerDelNode(props.data.id)} shape="circle" icon={<CloseOutlined style={{ color: '#f5222d' }} />} /> </div> : null} </div> ); } initNode组件 import { PlusOutlined, CloseOutlined } from '@ant-design/icons'; import { Button } from 'antd'; import './index.less'; import { useEffect, useState } from 'react';

interface EdgeData { id: string; source: string; target: string; } // 创建一个新的日期对象,表示当前时间 const currentDate = new Date();

// 获取年、月、日 const year = currentDate.getFullYear(); const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1,然后补齐两位数 const day = String(currentDate.getDate()).padStart(2, '0'); // 补齐两位数的日期

// 获取时、分、秒 const hours = String(currentDate.getHours()).padStart(2, '0'); const minutes = String(currentDate.getMinutes()).padStart(2, '0'); const seconds = String(currentDate.getSeconds()).padStart(2, '0');

// 构造最终的时间字符串 const currentDateTime = ${year}-${month}-${day} ${hours}:${minutes}:${seconds};

const DocsPage = (props: any) => { const [isShow, setIsShow] = useState(false); // 点击新增按钮 const handlerAddNode = () => { const { x, y } = props.data.style const newPosition = calculateLocation(props.data.id) const nodeData = { id: node_${new Date().getTime()}, type: 'react', style: { x: newPosition.newX ? newPosition.newX : x - 200, y: newPosition.newY ? newPosition.newY : y + 206 }, data: { isInit: false }, } const edgeData = { id: edge_${new Date().getTime()}, source: props.data.id, target: nodeData.id } props.graph.addNodeData([nodeData]) props.graph.addEdgeData([edgeData]) props.graph.render() } // 计算新增节点的位置 const calculateLocation = (id: string) => { const edgeData = props.graph.getEdgeData().filter((item: EdgeData) => item.source === id) if (edgeData.length) { const nodeData = props.graph.getNodeData(edgeData[edgeData.length - 1].target) return { newX: nodeData.style.x + 430, newY: nodeData.style.y } } else { return {} } } return ( <div> <div id="init_node" onMouseEnter={() => setIsShow(true)} onMouseLeave={() => setIsShow(false)}> <p className="init-node-p">任务开始时间:  {currentDateTime}</p> {isShow ? <div className="add_node_plus"> <Button onClick={handlerAddNode} type="primary" shape="circle" icon={<PlusOutlined />} /> </div> : null} {/* {isShow ? <div className="add_node_del"> <Button onClick={handlerDelNode} shape="circle" icon={<CloseOutlined style={{ color: '#f5222d' }} />} /> </div> : null} */} </div> </div> ); };

export default DocsPage;

G6 Version / G6 版本

🆕 5.x

Operating System / 操作系统

Windows

Browser / 浏览器

Chrome

Additional context / 补充说明

No response


duplicate with: https://github.com/antvis/G6/issues/5781

系渲染引擎层问题,待统一修复

posted by Aarebecca 10 months ago

Fund this Issue

$0.00
Funded

Pull requests