I am trying to replicate the gauge seen here in React with Hooks. It's the first time I am working with D3.js and even though I managed to replicate the gauge itself, the behavior is a bit strange (transition of the needles does not work) and I am not fully understanding the dynamics between useEffect and D3. Basically I want to add two needles that will each receive different values and use a transition when their value changes.
//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 and angle2 are updated via useState hook, but the transition does not work and makes the needles look bugged. Without the transition it works OK, but the movement of the needles looks very rough. I am not sure if the problem is in the way I am integrating the d3 part or if all the re-renders (because I am changing two values in paralel) affect the performance of the hook and maybe I should update the angles in a different way. Thank you for your time!