簡體   English   中英

在 React Hooks 和 D3 中使用轉換

[英]Using transitions in React Hooks and D3

我正在嘗試復制在 React with Hooks 中看到的量規。 這是我第一次使用 D3.js,盡管我設法復制了儀表本身,但行為有點奇怪(指針的轉換不起作用),我並不完全理解 useEffect 和 D3 之間的動態。 基本上我想添加兩個針,它們每個都會接收不同的值,並在它們的值發生變化時使用轉換。

//declaring angle value
const [angle1, setAngle1] = useState(0)

//useEffect hook
 useEffect(() => {
    const outerR = Math.min(window.innerWidth, window.innerHeight) / 2

    const svg = select(svgRef.current)
    svg.selectAll('*').remove()

    const EXTRA_ANGLE = 15

    const angleScale = scaleLinear()
      .domain([0, 100])
      .range([-90 - EXTRA_ANGLE, 90 + EXTRA_ANGLE])

    const arcAxis = axisRadialInner(
      angleScale.copy().range(angleScale.range().map(deg2rad)),
      outerR - 5
    )

    svg
      .attr('width', outerR * 2)
      .attr('height', outerR * 1.5)
      .attr(
        'viewBox',
        `${-outerR} ${-outerR * 0.8} ${outerR * 2} ${outerR * 1}`
      )
      .append('g')
      .classed('axis', true)
      .call(arcAxis)

    const needle1 = svg
      .append('g')
      .attr('transform', `scale(${outerR * 0.85})`)
      .append('path')
      .classed('needle1', true)
      .attr(
        'd',
        ['M0 -1', 'L0.03 0', 'A 0.03 0.03 0 0 1 -0.03 0', 'Z'].join(' ')
      )
      .transition()
      .attr('transform', `rotate(${angleScale(angle1)})`)

    const needle2 = svg
      .append('g')
      .attr('transform', `scale(${outerR * 0.85})`)
      .append('path')
      .classed(needle2, true)
      .attr(
        'd',
        ['M0 -1', 'L0.03 0', 'A 0.03 0.03 0 0 1 -0.03 0', 'Z'].join(' ')
      )
      .transition()
      .attr('transform', `rotate(${angleScale(angle2)})`)

    // Add val label
    const label = svg
      .append('text')
      .classed('label', true)
      .attr('x', 0)
      .attr('y', outerR * 0.2)
      .attr('text-anchor', 'middle')
      .text(angle1)

    function deg2rad (deg) {
      return (deg * Math.PI) / 180
    }

  }, [angle1, angle2])

//updating an angle
function updateAngle1(){
   setInterval(() => {
      setAngle1(angle1 => angle1 + 1)
    }, 200); 

Angle1 和 angle2 是通過 useState 鈎子更新的,但是過渡不起作用並且使針看起來有問題。 如果沒有過渡,它可以正常工作,但是針的運動看起來很粗糙。 我不確定問題是否出在我整合 d3 部分的方式上,或者是否所有重新渲染(因為我正在並行更改兩個值)影響鈎子的性能,也許我應該以不同的方式更新角度方法。 感謝您的時間!

我不是react專家,但在我看來你想創建兩個useEffect塊。 第一個,只觸發一次以進行初始d3設置。 第二,更新你的角度並移動指針。

 const {useState, useEffect} = React; const App = () => { //declaring angle value let [angle1, setAngle1] = useState(0); function deg2rad (deg) { return (deg * Math.PI) / 180; } const EXTRA_ANGLE = 15; const angleScale = d3.scaleLinear().domain([0, 100]).range([-90 - EXTRA_ANGLE, 90 + EXTRA_ANGLE]); useEffect(() => { const svg = d3.select('svg'); const outerR = Math.min(window.innerWidth, window.innerHeight) / 2; const arcAxis = d3.axisRadialInner( angleScale.copy().range(angleScale.range().map(deg2rad)), outerR - 5 ); svg.attr('width', outerR * 2).attr('height', outerR * 1.5).attr( 'viewBox', `${-outerR} ${-outerR * 0.8} ${outerR * 2} ${outerR * 1}` ).append('g').classed('axis', true).call(arcAxis); const needle1 = svg.append('g').attr('transform', `scale(${outerR * 0.85})`).append('path').classed('needle1', true).attr( 'd', ['M0 -1', 'L0.03 0', 'A 0.03 0.03 0 0 1 -0.03 0', 'Z'].join(' ') ); // Add val label const label = svg.append('text').classed('label', true).attr('x', 0).attr('y', outerR * 0.2).attr('text-anchor', 'middle'); // kick off updates setInterval(() => { angle1 += 1; if (angle1 > 100) angle1 = 100; setAngle1(angle1); }, 500); },[]) useEffect(() => { d3.select('.needle1').transition().attr('transform', `rotate(${angleScale(angle1)})`); d3.select('.label').text(angle1); }, [angle1]) return <svg></svg>; } // Render it ReactDOM.render( <App />, document.getElementById("react") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/d3-radial-axis@1.6.4/dist/d3-radial-axis.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="react"></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM