我正在尝试复制在 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 部分的方式上,或者是否所有重新渲染(因为我正在并行更改两个值)影响钩子的性能,也许我应该以不同的方式更新角度方法。感谢您的时间!