import { onActivated, onDeactivated, onUnmounted, SetupContext, onMounted } from "vue"; import { debounce } from "@/utils/time" import { getTheme, ThemeEnum } from '@/common/config/theme'; import * as echarts from 'echarts' // 创建 iframe 对象 const createIframe = (parent: HTMLElement): HTMLIFrameElement => { const iframe = document.createElement('iframe'); // 设置 iframe 样式 iframe.style.cssText = 'position: absolute; z-index: -1000; left: 0; top: 0; width: 100%; height: 100%; border: 0; visibility: hidden; pointer-events: none;'; // 添加 iframe 节点 parent.appendChild(iframe); return iframe; } export function useEchart(el: HTMLElement) { const iframe = createIframe(el); const echartMap: echarts.ECharts[] = []; el.querySelectorAll('.echart__container').forEach((item) => { // 初始化图表 const echart = echarts.init(item as HTMLElement); echartMap.push(echart); }) // 显示加载动画 const showLoading = (loading: boolean) => { if (loading) { echartMap.forEach((echart) => { echart.clear(); // 清空图表 const theme = getTheme(); // 当前主题 switch (theme.value) { case ThemeEnum.default: case ThemeEnum.dark: echart.showLoading({ text: '加载中...', textColor: '#fff', color: 'rgba(255, 255, 255, 0.75)', maskColor: 'transparent', }); break; default: echart.showLoading({ text: '加载中...', maskColor: 'transparent', }); } }) } }; // 图表配置项 const setOptions = (options: echarts.EChartsOption[], notMerge = false) => { options.forEach((opt, i) => { echartMap[i].setOption(opt, notMerge); echartMap[i].hideLoading(); }); }; const onresize = () => { // 防抖函数待优化,同时调用多次timeoutId可能相同,导致后面的覆盖前面 debounce(() => { // 重置图表大小 echartMap.forEach((echart) => { echart.resize && echart.resize(); }) }, 50); }; // 键盘上下左右键控制图表 const onKeyup = (e: KeyboardEvent) => { // echartMap.forEach((chart) => { // const datazoom = chart.getOption().dataZoom as echarts.DataZoomComponentOption[]; // if (datazoom && datazoom.length) { // const start = datazoom[0].start!; // const end = datazoom[0].end!; // switch (e.key) { // case 'ArrowLeft': // if (start > 0) { // chart.setOption({ // dataZoom: [ // { // start: start - 1, // end: end - 1, // } // ] // }); // } // break; // case 'ArrowUp': // console.log('上'); // break; // case 'ArrowRight': // if (end < 100) { // chart.setOption({ // dataZoom: [ // { // start: start + 1, // end: end + 1, // } // ] // }); // } // break; // case 'ArrowDown': // console.log('下'); // break; // default: // console.log(e); // } // } // }); }; const addEventListener = () => { // 监听 iframe 变化重置图表尺寸 iframe.contentWindow?.addEventListener('resize', onresize); // 监听键盘事件 document.addEventListener('keyup', onKeyup); } const removeEventListener = () => { // 移除 iframe 监听事件 iframe.contentWindow?.removeEventListener('resize', onresize); // 移除键盘监听事件 document.removeEventListener('keyup', onKeyup); } addEventListener(); onUnmounted(() => { echartMap.forEach((echart) => { echart.dispose(); }) removeEventListener(); }) // 针对 keepalive 缓存组件 onActivated(() => { addEventListener(); }) // 针对 keepalive 缓存组件 onDeactivated(() => { removeEventListener(); }) return { setOptions, showLoading, } }