Rumah  >  Soal Jawab  >  teks badan

React + d3 - Mengapa elemen <g> saya tidak bertindak balas kepada pendengar onClick

Saya agak baru dengan d3 dan saya tahu mungkin terdapat beberapa konflik antara React dan d3. Ini mungkin salah satu daripadanya.

Saya mempunyai svg yang melaksanakan tingkah laku berskala d3. Saya mahu menjadikan unsur-unsur di dalam svg boleh diseret. Percubaan pertama saya ialah meletakkan pendengar onClick untuk log sesuatu dalam konsol, tetapi ia tidak berjaya. Bolehkah anda jelaskan apa yang saya hilang di sini? Saya mengesyaki bahawa tingkah laku penskalaan d3 merampas acara klik. Terima kasih. Ini kodnya:

Grid dengan fungsi zum.

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

Komponen segi empat tepat. Saya mencuba elemen g dan elemen rect. tiada kerja.

const Rect = (props) => {
    return (
        <g onClick={(event) => { console.log({ event }); }}>
            <rect {...props} onClick={(event) => { console.log({ event }); }} />
        </g>

    )
}

export default Rect

P粉504080992P粉504080992236 hari yang lalu443

membalas semua(1)saya akan balas

  • P粉773659687

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

    Dalam kod anda, cangkuk useEffect akan dicetuskan selepas komponen Rect dipaparkan, yang bermaksud corak dan segi empat tepat latar belakang yang berkaitan dalam useEffect akan dipaparkan di atas komponen Rect. Mereka kemudian menghalang acara daripada merambat ke komponen segi empat tepat yang mendasari.

    Untuk menyelesaikan masalah ini, terdapat dua pilihan. Yang pertama ialah untuk menetapkan sifat "pointer-events" mod dan bahan berkaitan kepada "tiada", dan yang kedua ialah meletakkan bahan ini di bahagian bawah. Ini adalah demonstrasi secara langsung. Int Tangkapan skrin Pautan demo

    const D3Grid = () => {
      useEffect(() => {
        const background = svg.select(".background")
        background.append("pattern");
        background.append("rect");
      });
      return (
        
        {...rects}
      );
    }

    balas
    0
  • Batalbalas