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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | import React from 'react';
import YagrComponent, {YagrChartProps, YagrReactRef} from '@gravity-ui/yagr/react';
import isEmpty from 'lodash/isEmpty';
import {i18n} from '../../../i18n';
import {CHARTKIT_ERROR_CODE, ChartKitError} from '../../../libs';
import type {ChartKitWidgetRef} from '../../../types';
import {Yagr, YagrWidgetProps} from '../types';
import './polyfills';
import {useWidgetData} from './useWidgetData';
import {checkFocus, detectClickOutside, synchronizeTooltipTablesCellsWidth} from './utils';
import '@gravity-ui/yagr/dist/index.css';
// We need to save order in such state
// eslint-disable-next-line import/order
import './YagrWidget.scss';
const YagrWidget = React.forwardRef<ChartKitWidgetRef | undefined, YagrWidgetProps>(
function YagrWidget(props, forwardedRef) {
const {
id,
data: {data},
onLoad,
onRender,
onChartLoad,
tooltip,
} = props;
const yagrRef = React.useRef<YagrReactRef>(null);
const [yagr, setYagr] = React.useState<Yagr>();
if (!data || isEmpty(data)) {
throw new ChartKitError({
code: CHARTKIT_ERROR_CODE.NO_DATA,
message: i18n('error', 'label_no-data'),
});
}
const {config, debug} = useWidgetData(props, id);
const handleChartLoading: NonNullable<YagrChartProps['onChartLoad']> = React.useCallback(
(chart, {renderTime}) => {
onLoad?.({...data, widget: chart, widgetRendering: renderTime});
onRender?.({renderTime});
setYagr(chart);
},
[onLoad, onRender, data, setYagr],
);
const onWindowResize = React.useCallback(() => {
if (yagr) {
yagr.reflow();
}
}, []);
React.useImperativeHandle(
forwardedRef,
() => ({
reflow() {
onWindowResize();
},
}),
[onWindowResize],
);
React.useEffect(() => {
if (!yagr || yagr.config?.tooltip?.virtual) {
return;
}
const handlers: Record<string, null | ((event: MouseEvent) => void)> = {
mouseMove: null,
mouseDown: null,
};
yagr.plugins.tooltip?.on('render', (tooltip) => {
synchronizeTooltipTablesCellsWidth(tooltip);
});
yagr.plugins.tooltip?.on('pin', (tooltip, {actions}) => {
handlers.mouseMove = checkFocus({tooltip, yagr});
handlers.mouseDown = detectClickOutside({tooltip, actions, yagr});
document.addEventListener('mousemove', handlers.mouseMove);
document.addEventListener('mousedown', handlers.mouseDown);
});
yagr.plugins.tooltip?.on('unpin', () => {
if (handlers.mouseMove) {
document.removeEventListener('mousemove', handlers.mouseMove);
handlers.mouseMove = null;
}
if (handlers.mouseDown) {
document.removeEventListener('mousedown', handlers.mouseDown);
handlers.mouseDown = null;
}
});
}, [yagr]);
React.useLayoutEffect(() => {
onChartLoad?.({widget: yagr});
}, [yagr, onChartLoad]);
return (
<React.Fragment>
{tooltip &&
yagr &&
tooltip({
yagr,
})}
<YagrComponent
ref={yagrRef}
id={id}
config={config}
debug={debug}
onChartLoad={handleChartLoading}
/>
</React.Fragment>
);
},
);
export default YagrWidget;
|