You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

109 lines
2.2 KiB

import { CSSProperties } from 'react';
import * as echarts from 'echarts';
import { LineSeriesOption } from 'echarts';
import { useRef, useEffect } from 'react';
import { isEmpty, merge } from 'lodash';
import { CHARTS_COLORS, LOADING_COLOR } from './type';
import { useSize } from 'ahooks';
// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
type ECOption = echarts.ComposeOption<LineSeriesOption>;
export interface LineProps {
color?: Array<string>;
category: Array<string | number>;
series: Array<any>;
loading?: boolean;
smooth?: boolean;
loadingType?: any;
style?: CSSProperties;
options?: ECOption;
}
export function ChartsLine(props: LineProps) {
const {
color = CHARTS_COLORS,
category = [],
series,
loading,
style,
smooth,
options,
loadingType = { color: LOADING_COLOR },
} = props;
const contentEle = useRef<any>();
const chartRef = useRef<any>();
const defaultOptions: ECOption = merge(
{
color: color,
title: {
show: false,
},
legend: {
show: true,
itemWidth: 10,
itemHeight: 10,
left: 'right',
top: 0,
},
grid: {
top: 30,
left: 0,
right: 0,
bottom: 0,
containLabel: true,
},
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
data: category,
axisPointer: {
type: 'shadow',
},
},
yAxis: {
type: 'value',
},
},
options,
);
const responsive = useSize(contentEle.current);
useEffect(() => {
chartRef.current?.resize();
}, [JSON.stringify(responsive)]);
useEffect(() => {
if (!chartRef.current) {
chartRef.current = echarts.init(contentEle.current);
}
if (loading) {
chartRef.current.showLoading(Object.assign({ text: '' }, loadingType));
return;
} else {
chartRef.current.hideLoading();
}
window.onresize = function () {
chartRef.current?.resize();
};
if (!isEmpty(series)) {
chartRef.current.setOption({
...defaultOptions,
series: series.map((item) => ({
type: 'line',
data: item.data,
smooth: smooth || true,
symbol: 'none',
...item,
})),
});
}
}, [series, loading]);
return (
<div ref={contentEle} style={{ width: '100%', height: '100%', ...style }} />
);
}