我对 d3 相当陌生,我知道 React 和 d3 之间可能存在一些冲突。这可能是其中之一。
我有一个 svg,它实现了 d3 的可缩放行为。我想让 svg 内的元素可拖动。我的第一次尝试是放置一个 onClick 侦听器在控制台中记录某些内容,但它不起作用。你能解释一下我在这里缺少什么吗?我怀疑 d3 缩放行为劫持了点击事件。谢谢。 下面是代码:
具有缩放功能的网格。
import React, { useState, useEffect, useRef } from 'react'
import * as d3 from 'd3';
import Rect from './Rect';
import './d3-grid.css';
const zoomBehaviour = (width, height, gridSize, gridRef) => d3
.zoom()
.scaleExtent([0.5, 2])
.translateExtent([[0, 0], [width, height]])
.on('zoom', (event) => {
const svg = d3.select(gridRef.current)
svg.select('#grid-pattern')
.attr('x', event.transform.x)
.attr('y', event.transform.y)
.attr('width', gridSize * event.transform.k)
.attr('height', gridSize * event.transform.k)
.selectAll('line')
.attr('opacity', Math.min(event.transform.k, 1));
d3.selectAll('g').attr('transform', event.transform);
})
const D3Grid = ({ data, width, height }) => {
const [shapes, setShapes] = useState(data);
const svgGridRef = useRef();
const content = useRef();
const gridSize = 25;
const gridColor = '#a4a4a4';
useEffect(() => {
const svg = d3.select(svgGridRef.current);
var pattern = svg.append('pattern')
.attr('id', 'grid-pattern')
.attr('patternUnits', 'userSpaceOnUse')
.attr('x', 0)
.attr('y', 0)
.attr('width', gridSize)
.attr('height', gridSize);
pattern.append('line')
.attr('stroke', gridColor)
.attr('x1', 0)
.attr('y1', 0)
.attr('x2', gridSize * 16)
.attr('y2', 0);
pattern.append('line')
.attr('stroke', gridColor)
.attr('x1', 0)
.attr('y1', 0)
.attr('x2', 0)
.attr('y2', gridSize * 16);
svg.append('rect')
.attr('fill', 'url(#grid-pattern)')
.attr('width', '100%')
.attr('height', '100%');
return () => {
// Clean up any D3 elements or listeners
};
}, [])
useEffect(() => {
const svg = d3.select(svgGridRef.current);
svg.call(zoomBehaviour(width, height, gridSize, svgGridRef));
return () => {
svg.on('.zoom', null);
};
}, []);
return (
<svg
className='main-svg'
ref={svgGridRef}
viewBox={`0 0 ${width} ${height}`}
>
{
shapes.map((shape, index) => (
<Rect
key={index}
id={shape.id}
fill={shape.fill}
rx={shape.rx}
width={shape.width}
height={shape.height}
x={shape.posX}
y={shape.posY}
/>
))
}
</svg >
)
}
export default D3Grid
矩形组件。我尝试了 g 元素和 rect 元素。没有工作。
const Rect = (props) => {
return (
<g onClick={(event) => { console.log({ event }); }}>
<rect {...props} onClick={(event) => { console.log({ event }); }} />
</g>
)
}
export default Rect Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
在您的代码中,useEffect 钩子将在 Rect 组件渲染后被触发,这意味着 useEffect 中的图案和相关背景矩形将渲染在 Rect 组件的顶部。然后,它们阻止事件传播到下面的矩形组件。
要解决这个问题,有两种选择。第一个是将模式的“pointer-events”属性和相关的东西设置为“none”,第二个是将这些东西放在底部。这是现场演示。 Int 屏幕截图 演示链接
const D3Grid = () => { useEffect(() => { const background = svg.select(".background") background.append("pattern"); background.append("rect"); }); return (); }