Zooming in web seem quiet easy code like this:
const zoom = d3
.zoom<SVGSVGElement, unknown>()
.scaleExtent([1, 3])
.translateExtent([
[0, 0],
[width, height],
])
.extent([
[0, 0],
[width, height],
])
.on("zoom", ({ transform }: D3ZoomEvent<SVGSVGElement, unknown>) => {
x.range([0, width].map((d) => transform.applyX(d)));
xState.range([0, width].map((d) => transform.applyX(d)));
g.selectAll(".bar")
.attr("x", function (d) {
return x(
(d as { key: string; value: number }).key as string
) as number;
})
.attr("width", x.bandwidth());
g.selectAll(".category").attr("transform", function (d) {
return `translate(${xState(
(d as DataType).State as string
)},${containerHeight - margin.top})`;
});
});
svg.call(zoom);
However I have no idea how to implement this in react native? I made range in state, this is in react native:
const [xRange, setXRange] = useState([0, width]);
const x = d3.scaleBand().range(xRange).padding(0.25);
and the pinch handler:
<PinchGestureHandler
onGestureEvent={e => {
const zoomIdentity = d3.zoomIdentity.translate(
e.nativeEvent.focalX,
e.nativeEvent.focalY,
);
setXRange(xRange.map(d => zoomIdentity.applyX(d)));
}}>
<Svg style={styles.svg} width={width} height={width}>
{testData.map((d, index) => {
return (
<Rect
key={`rect:${index}`}
rx={5}
x={x(d.key)}
y={y(d.value)}
fill={color(d.value)}
width={xBandWidth}
height={height - y(d.value)}
/>
);
})}
{data.map((d, index) => {
return (
<SVGText
key={`label:${index}`}
fontSize={10}
transform={`translate(${xState(d.State) as number},${
height + 20
})`}
fill="green">
{d.State}
</SVGText>
);
})}
</Svg>
</PinchGestureHandler>
But it don't work, i want to have same zoom logic in web to react native?