| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- 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,
- }
- }
|