forked from ddrilling/asb_cloud_front
Добавлен зум для графика на странице Операции
This commit is contained in:
parent
b7317a02d5
commit
a924cd0ff1
@ -124,6 +124,7 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
|
|||||||
const [xAxisRef, setXAxisRef] = useState<SVGGElement | null>(null)
|
const [xAxisRef, setXAxisRef] = useState<SVGGElement | null>(null)
|
||||||
const [yAxisRef, setYAxisRef] = useState<SVGGElement | null>(null)
|
const [yAxisRef, setYAxisRef] = useState<SVGGElement | null>(null)
|
||||||
const [chartAreaRef, setChartAreaRef] = useState<SVGGElement | null>(null)
|
const [chartAreaRef, setChartAreaRef] = useState<SVGGElement | null>(null)
|
||||||
|
const [currentZoomState, setCurrentZoomState] = useState<d3.ZoomTransform | null>(null)
|
||||||
|
|
||||||
const xAxisArea = useCallback(() => d3.select(xAxisRef), [xAxisRef])
|
const xAxisArea = useCallback(() => d3.select(xAxisRef), [xAxisRef])
|
||||||
const yAxisArea = useCallback(() => d3.select(yAxisRef), [yAxisRef])
|
const yAxisArea = useCallback(() => d3.select(yAxisRef), [yAxisRef])
|
||||||
@ -159,8 +160,13 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
|
|||||||
xAxis.domain([domain?.x?.min ?? minX, domain?.x?.max ?? maxX])
|
xAxis.domain([domain?.x?.min ?? minX, domain?.x?.max ?? maxX])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentZoomState) {
|
||||||
|
const newXScale = currentZoomState.rescaleX(xAxis)
|
||||||
|
xAxis.domain(newXScale.domain())
|
||||||
|
}
|
||||||
|
|
||||||
return xAxis
|
return xAxis
|
||||||
}, [xAxisConfig, data, domain, width, offset])
|
}, [xAxisConfig, data, domain, width, offset, currentZoomState])
|
||||||
|
|
||||||
const yAxis = useMemo(() => {
|
const yAxis = useMemo(() => {
|
||||||
if (!data) return
|
if (!data) return
|
||||||
@ -200,8 +206,13 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
|
|||||||
|
|
||||||
yAxis.range([height - offset.top - offset.bottom, 0])
|
yAxis.range([height - offset.top - offset.bottom, 0])
|
||||||
|
|
||||||
|
if (currentZoomState) {
|
||||||
|
const newYScale = currentZoomState.rescaleY(yAxis)
|
||||||
|
yAxis.domain(newYScale.domain())
|
||||||
|
}
|
||||||
|
|
||||||
return yAxis
|
return yAxis
|
||||||
}, [charts, data, domain, height, offset])
|
}, [charts, data, domain, height, offset, currentZoomState])
|
||||||
|
|
||||||
const nTicks = {
|
const nTicks = {
|
||||||
color: 'lightgray',
|
color: 'lightgray',
|
||||||
@ -348,6 +359,19 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
|
|||||||
redrawCharts()
|
redrawCharts()
|
||||||
}, [redrawCharts])
|
}, [redrawCharts])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!svgRef) return
|
||||||
|
const zoom = d3.zoom<SVGSVGElement, unknown>()
|
||||||
|
.scaleExtent([1, 5])
|
||||||
|
.translateExtent([[0, 0], [width, height]])
|
||||||
|
.on('zoom', () => {
|
||||||
|
const zoomState = d3.zoomTransform(svgRef)
|
||||||
|
setCurrentZoomState(zoomState)
|
||||||
|
})
|
||||||
|
|
||||||
|
d3.select(svgRef).call(zoom)
|
||||||
|
}, [svgRef, width, height, offset])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal
|
<LoaderPortal
|
||||||
show={loading}
|
show={loading}
|
||||||
@ -366,7 +390,17 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
|
|||||||
<svg ref={setSvgRef} width={'100%'} height={'100%'}>
|
<svg ref={setSvgRef} width={'100%'} height={'100%'}>
|
||||||
<g ref={setXAxisRef} className={'axis x'} transform={`translate(${offset.left}, ${height - offset.bottom})`} />
|
<g ref={setXAxisRef} className={'axis x'} transform={`translate(${offset.left}, ${height - offset.bottom})`} />
|
||||||
<g ref={setYAxisRef} className={'axis y'} transform={`translate(${offset.left}, ${offset.top})`} />
|
<g ref={setYAxisRef} className={'axis y'} transform={`translate(${offset.left}, ${offset.top})`} />
|
||||||
<g ref={setChartAreaRef} className={'chart-area'} transform={`translate(${offset.left}, ${offset.top})`}>
|
<defs>
|
||||||
|
<clipPath id={'clipPath'}>
|
||||||
|
<rect
|
||||||
|
x={0}
|
||||||
|
y={0}
|
||||||
|
width={Math.max(width - offset.left - offset.right, 0)}
|
||||||
|
height={Math.max(height - offset.top - offset.bottom, 0)}
|
||||||
|
/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<g clipPath={'url(#clipPath)'} ref={setChartAreaRef} className={'chart-area'} transform={`translate(${offset.left}, ${offset.top})`}>
|
||||||
<rect
|
<rect
|
||||||
width={Math.max(width - offset.left - offset.right, 0)}
|
width={Math.max(width - offset.left - offset.right, 0)}
|
||||||
height={Math.max(height - offset.top - offset.bottom, 0)}
|
height={Math.max(height - offset.top - offset.bottom, 0)}
|
||||||
|
Loading…
Reference in New Issue
Block a user