mirror of
https://github.com/apache/superset.git
synced 2026-04-21 17:14:57 +00:00
119 lines
3.3 KiB
TypeScript
119 lines
3.3 KiB
TypeScript
/**
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
import React, {
|
|
useRef,
|
|
useEffect,
|
|
useMemo,
|
|
forwardRef,
|
|
useImperativeHandle,
|
|
useLayoutEffect,
|
|
useCallback,
|
|
} from 'react';
|
|
import { styled } from '@superset-ui/core';
|
|
import { ECharts, init } from 'echarts';
|
|
import { EchartsHandler, EchartsProps, EchartsStylesProps } from '../types';
|
|
|
|
const Styles = styled.div<EchartsStylesProps>`
|
|
height: ${({ height }) => height};
|
|
width: ${({ width }) => width};
|
|
`;
|
|
|
|
function Echart(
|
|
{
|
|
width,
|
|
height,
|
|
echartOptions,
|
|
eventHandlers,
|
|
zrEventHandlers,
|
|
selectedValues = {},
|
|
}: EchartsProps,
|
|
ref: React.Ref<EchartsHandler>,
|
|
) {
|
|
const divRef = useRef<HTMLDivElement>(null);
|
|
const chartRef = useRef<ECharts>();
|
|
const currentSelection = useMemo(
|
|
() => Object.keys(selectedValues) || [],
|
|
[selectedValues],
|
|
);
|
|
const previousSelection = useRef<string[]>([]);
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
getEchartInstance: () => chartRef.current,
|
|
}));
|
|
|
|
useEffect(() => {
|
|
if (!divRef.current) return;
|
|
if (!chartRef.current) {
|
|
chartRef.current = init(divRef.current);
|
|
}
|
|
|
|
Object.entries(eventHandlers || {}).forEach(([name, handler]) => {
|
|
chartRef.current?.off(name);
|
|
chartRef.current?.on(name, handler);
|
|
});
|
|
|
|
Object.entries(zrEventHandlers || {}).forEach(([name, handler]) => {
|
|
chartRef.current?.getZr().off(name);
|
|
chartRef.current?.getZr().on(name, handler);
|
|
});
|
|
|
|
chartRef.current.setOption(echartOptions, true);
|
|
}, [echartOptions, eventHandlers, zrEventHandlers]);
|
|
|
|
// highlighting
|
|
useEffect(() => {
|
|
if (!chartRef.current) return;
|
|
chartRef.current.dispatchAction({
|
|
type: 'downplay',
|
|
dataIndex: previousSelection.current.filter(
|
|
value => !currentSelection.includes(value),
|
|
),
|
|
});
|
|
if (currentSelection.length) {
|
|
chartRef.current.dispatchAction({
|
|
type: 'highlight',
|
|
dataIndex: currentSelection,
|
|
});
|
|
}
|
|
previousSelection.current = currentSelection;
|
|
}, [currentSelection]);
|
|
|
|
const handleSizeChange = useCallback(
|
|
({ width, height }: { width: number; height: number }) => {
|
|
if (chartRef.current) {
|
|
chartRef.current.resize({ width, height });
|
|
}
|
|
},
|
|
[],
|
|
);
|
|
|
|
// did mount
|
|
useEffect(() => {
|
|
handleSizeChange({ width, height });
|
|
}, []);
|
|
|
|
useLayoutEffect(() => {
|
|
handleSizeChange({ width, height });
|
|
}, [width, height, handleSizeChange]);
|
|
|
|
return <Styles ref={divRef} height={height} width={width} />;
|
|
}
|
|
|
|
export default forwardRef(Echart);
|