我對 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
在您的程式碼中,useEffect 鉤子將在 Rect 元件渲染後觸發,這表示 useEffect 中的圖案和相關背景矩形將渲染在 Rect 元件的頂部。然後,它們阻止事件傳播到下面的矩形元件。
要解決這個問題,有兩個選擇。第一個是將模式的“pointer-events”屬性和相關的東西設為“none”,第二個是將這些東西放在底部。這是現場演示。 Int 螢幕截圖 示範連結