All files / src/plugins/gravity-charts/renderer/withSplitPane withSplitPane.tsx

0% Statements 0/25
0% Branches 0/4
0% Functions 0/9
0% Lines 0/25

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;
}