>  Q&A  >  본문

React + d3 - 내 <g> 요소가 onClick 리스너에 응답하지 않는 이유는 무엇입니까?

저는 d3를 처음 접했고 React와 d3 사이에 충돌이 있을 수 있다는 것을 알고 있습니다. 이것은 그 중 하나일 수 있습니다.

d3의 확장 가능한 동작을 구현하는 SVG가 있습니다. svg 내부의 요소를 드래그 가능하게 만들고 싶습니다. 내 첫 번째 시도는 콘솔에 무언가를 기록하기 위해 onClick 리스너를 넣는 것이었지만 작동하지 않았습니다. 내가 여기서 무엇을 놓치고 있는지 설명해 주실 수 있나요? d3 스케일링 동작이 클릭 이벤트를 가로채는 것 같습니다. 감사해요. 코드는 다음과 같습니다.

줌 기능이 있는 그리드.

으아아아

직사각형 구성요소. 나는 g 요소와 ret 요소를 시도했습니다. 백수.

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

P粉504080992P粉504080992287일 전474

모든 응답(1)나는 대답할 것이다

  • P粉773659687

    P粉7736596872024-01-30 00:06:32

    코드에서 useEffect 후크는 Rect 구성 요소가 렌더링된 후에 트리거됩니다. 즉, useEffect의 패턴 및 관련 배경 사각형이 Rect 구성 요소 위에 렌더링됩니다. 그런 다음 이벤트가 기본 직사각형 구성 요소로 전파되는 것을 방지합니다.

    이 문제를 해결하려면 두 가지 옵션이 있습니다. 첫 번째는 모드의 "pointer-events" 속성과 관련 항목을 "none"으로 설정하는 것이고, 두 번째는 이러한 항목을 맨 아래에 배치하는 것입니다. 이것은 라이브 데모입니다. 정수 스크린샷 데모 링크

    으아아아

    회신하다
    0
  • 취소회신하다