Commit ba8dff1a authored by tom's avatar tom

basic brush

parent 14fda4e3
...@@ -9,12 +9,9 @@ import GridLine from 'ui/shared/graphs/GridLine'; ...@@ -9,12 +9,9 @@ import GridLine from 'ui/shared/graphs/GridLine';
import Line from 'ui/shared/graphs/Line'; import Line from 'ui/shared/graphs/Line';
import Overlay from 'ui/shared/graphs/Overlay'; import Overlay from 'ui/shared/graphs/Overlay';
import Tooltip from 'ui/shared/graphs/Tooltip'; import Tooltip from 'ui/shared/graphs/Tooltip';
import useBrushX from 'ui/shared/graphs/useBrushX';
import useTimeGraphController from 'ui/shared/graphs/useTimeGraphController'; import useTimeGraphController from 'ui/shared/graphs/useTimeGraphController';
const data = {
items: json.map((d) => ({ ...d, date: new Date(d.date) })),
};
interface Props { interface Props {
margin?: { margin?: {
top?: number; top?: number;
...@@ -57,10 +54,17 @@ const EthereumDailyTxsChart = ({ margin }: Props) => { ...@@ -57,10 +54,17 @@ const EthereumDailyTxsChart = ({ margin }: Props) => {
}, [ calculateRect ]); }, [ calculateRect ]);
const { width, height } = rect; const { width, height } = rect;
const innerWidth = Math.max(width - (margin?.left || 0) - (margin?.right || 0), 0); const innerWidth = Math.max(width - (margin?.left || 0) - (margin?.right || 0), 0);
const innerHeight = Math.max(height - (margin?.bottom || 0) - (margin?.top || 0), 0); const innerHeight = Math.max(height - (margin?.bottom || 0) - (margin?.top || 0), 0);
const brushLimits = React.useMemo(() => (
[ [ 0, innerHeight ], [ innerWidth, height ] ] as [[number, number], [number, number]]
), [ height, innerHeight, innerWidth ]);
const range = useBrushX({ anchor: ref.current, limits: brushLimits });
const data = {
items: json.slice(range[0], range[1]).map((d) => ({ ...d, date: new Date(d.date) })),
};
const { yTickFormat, xScale, yScale } = useTimeGraphController({ data, width: innerWidth, height: innerHeight }); const { yTickFormat, xScale, yScale } = useTimeGraphController({ data, width: innerWidth, height: innerHeight });
const lineColor = useToken('colors', 'blue.500'); const lineColor = useToken('colors', 'blue.500');
......
...@@ -6,11 +6,13 @@ interface Props { ...@@ -6,11 +6,13 @@ interface Props {
children: React.ReactNode; children: React.ReactNode;
} }
const Overlay = ({ width, height, children }: Props, ref: React.LegacyRef<SVGRectElement>) => ( const Overlay = ({ width, height, children }: Props, ref: React.LegacyRef<SVGRectElement>) => {
<g> return (
{ children } <g className="TooltipOverlay">
<rect ref={ ref } width={ width } height={ height } opacity={ 0 }/> { children }
</g> <rect ref={ ref } width={ width } height={ height } opacity={ 0 }/>
); </g>
);
};
export default React.forwardRef(Overlay); export default React.forwardRef(Overlay);
import { useToken, useColorModeValue } from '@chakra-ui/react';
import * as d3 from 'd3';
import React from 'react';
interface Props {
limits: [[number, number], [number, number]];
anchor: SVGSVGElement | null;
}
export default function useBrushX({ limits, anchor }: Props) {
const brushRef = React.useRef<d3.BrushBehavior<unknown>>();
const [ range, setRange ] = React.useState<[number, number]>([ 0, Infinity ]);
const brushSelectionBg = useToken('colors', useColorModeValue('blackAlpha.400', 'whiteAlpha.500'));
React.useEffect(() => {
if (!anchor || brushRef.current) {
return;
}
const svgEl = d3.select(anchor).select('g');
brushRef.current = d3.brushX()
.extent(limits);
brushRef.current.on('end', (event) => {
setRange(event.selection);
});
const gBrush = svgEl?.append('g')
.attr('class', 'brush')
.call(brushRef.current);
gBrush.select('.selection')
.attr('stroke', 'none')
.attr('fill', brushSelectionBg);
}, [ anchor, brushSelectionBg, limits ]);
return range;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment