Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import React from 'react';
import {Chart, getDefaultTooltipHeaderFormat} from '@gravity-ui/charts';
import type {ChartData, ChartProps, ChartRef} from '@gravity-ui/charts';
import {getComponentName} from '@gravity-ui/uikit';
import isEmpty from 'lodash/isEmpty';
import {SplitTooltip} from '../../../../components/SplitTooltip';
import {TooltipContent} from './TooltipContent';
import type {TooltipContentRef} from './TooltipContent';
import {useViewportSplitTooltipLayout} from './useViewportSplitTooltipLayout';
type WithSplitPaneProps = {};
type PointerMoveHandler = NonNullable<
NonNullable<NonNullable<ChartData['chart']>['events']>['pointermove']
>;
const SplitPaneContent = (props: ChartProps & {ChartComponent: typeof Chart}) => {
const {data, ChartComponent, ...restProps} = props;
const chartRef = React.useRef<ChartRef>(null);
const tooltipRef = React.useRef<TooltipContentRef>(null);
const [tooltipVisible, setTooltipVisible] = React.useState(false);
const layout = useViewportSplitTooltipLayout();
const headerFormat = React.useMemo(() => {
return (
data.tooltip?.headerFormat ??
getDefaultTooltipHeaderFormat({
seriesData: data.series.data,
yAxes: data.yAxis,
xAxis: data.xAxis,
})
);
}, [data.tooltip?.headerFormat, data.series.data, data.yAxis, data.xAxis]);
const resultData = React.useMemo(() => {
const userPointerMoveHandler = data.chart?.events?.pointermove;
const pointerMoveHandler: PointerMoveHandler = (pointerMoveData, event) => {
if (!isEmpty(pointerMoveData?.hovered)) {
setTooltipVisible(true);
tooltipRef.current?.redraw(pointerMoveData);
}
userPointerMoveHandler?.(pointerMoveData, event);
};
return {
defaultState: {
hoveredPosition: {x: 0, y: 0},
},
...data,
chart: {
...data.chart,
events: {
...data.chart?.events,
pointermove: pointerMoveHandler,
},
},
tooltip: {
...data.tooltip,
enabled: false,
},
} satisfies ChartData;
}, [data]);
return (
<SplitTooltip
layout={layout}
resizerVisible={tooltipVisible}
onMainPaneSizeChange={() => chartRef.current?.reflow()}
renderMainPane={() => (
<ChartComponent {...restProps} ref={chartRef} data={resultData} />
)}
renderTooltip={() => (
<TooltipContent
ref={tooltipRef}
renderer={resultData.tooltip.renderer}
headerFormat={headerFormat}
valueFormat={resultData.tooltip.valueFormat}
rowRenderer={resultData.tooltip.rowRenderer}
totals={resultData.tooltip.totals}
rows={resultData.tooltip.rows}
/>
)}
/>
);
};
export function withSplitPane(ChartComponent: typeof Chart) {
const componentName = getComponentName(ChartComponent);
const component = React.forwardRef<ChartRef, ChartProps & WithSplitPaneProps>(
function WithSplitPaneComponent(props, _ref) {
return <SplitPaneContent ChartComponent={ChartComponent} {...props} />;
},
);
component.displayName = `withSplitPane(${componentName})`;
return component;
}
|