import { ChartContext, last } from "@react-financial-charts/core"; import { interpolateNumber } from "d3-interpolate"; import * as React from "react"; export interface ZoomButtonsProps { readonly fill: string; readonly fillOpacity: number; readonly heightFromBase: number; readonly onReset?: () => void; readonly r: number; readonly stroke: string; readonly strokeWidth: number; readonly textFill: string; readonly zoomMultiplier: number; } export class ZoomButtons extends React.Component { public static defaultProps = { fill: "#ffffff", fillOpacity: 0.75, heightFromBase: 32, r: 16, stroke: "#e0e3eb", strokeWidth: 1, textFill: "#000000", zoomMultiplier: 1.5, }; public static contextType = ChartContext; private interval?: number; public render() { const { chartConfig } = this.context; const { width, height } = chartConfig; const { heightFromBase, r, fill, fillOpacity, onReset, stroke, strokeWidth, textFill } = this.props; const centerX = Math.round(width / 2); const y = height - heightFromBase; const zoomOutX = centerX - 16 - r * 2; const zoomInX = centerX - 8; const resetX = centerX + 16 + r * 2; return ( ); } private readonly handleZoomIn = () => { if (this.interval) { return; } this.zoom(-1); }; private readonly handleZoomOut = () => { if (this.interval) { return; } this.zoom(1); }; private readonly zoom = (direction: number) => { const { xAxisZoom, xScale, plotData, xAccessor } = this.context; const cx = xScale(xAccessor(last(plotData))); const { zoomMultiplier } = this.props; const c = direction > 0 ? 1 * zoomMultiplier : 1 / zoomMultiplier; const [start, end] = xScale.domain(); const [newStart, newEnd] = xScale .range() .map((x: number) => cx + (x - cx) * c) .map(xScale.invert); const left = interpolateNumber(start, newStart); const right = interpolateNumber(end, newEnd); const foo = [0.25, 0.3, 0.5, 0.6, 0.75, 1].map((i) => { return [left(i), right(i)]; }); this.interval = window.setInterval(() => { xAxisZoom(foo.shift()); if (foo.length === 0) { clearInterval(this.interval); delete this.interval; } }, 10); }; }