import type { EChartsOption } from "echarts"; import { computed, watch, ref } from "vue"; import { omit, defaultsDeep } from "lodash-es"; import { useRequest } from "vue-hooks-plus"; import { DataSourceType } from "../chartEnum"; import { message } from "ant-design-vue"; import { cllJsCode } from "../utils"; export const useChartOptions = (chartProps: Record) => { const dataSource = chartProps.dataSource || {}; const xAxis = ref(); const yAxis = ref(); const series = ref(dataSource?.data?.series); const server = computed(() => { return async () => await fetch(chartProps.dataSource.url, { method: chartProps.dataSource.method, }) .then((res) => res.json()); }); // 直接通过设置的接口请求数据 const { run, refresh, cancel, data, loading } = useRequest(server.value, { defaultParams: chartProps.dataSource.params, manual: true, cacheKey: chartProps.dataSource.url, cacheTime: (chartProps.dataSource?.refreshTime || 0) * 1000, pollingInterval: (chartProps.dataSource?.refreshTime || 0) * 1000, // 刷新时间 onError: (error) => { console.error(error); message.error(chartProps.dataSource.url + "请求失败"); } }); /* 初始请求 */ if (chartProps.dataSource.sourceType === DataSourceType.API) { run(); } watch( () => data.value, async (val) => { if (val && chartProps.dataSource.sourceType === DataSourceType.API) { let res = val; if(chartProps.dataSource.dataProcess) { // 请求后数据处理 res = await cllJsCode(chartProps.dataSource.dataProcess, JSON.stringify(val)); } xAxis.value = res.xAxis || res.xData ? { data: res.xData } : xAxis.value; yAxis.value = res.yAxis || res.yData ? { data: res.yData } : yAxis.value; series.value = res.series; } }, { deep: true, } ); // 数据源设置 watch( () => [ chartProps.dataSource.sourceType, chartProps.dataSource.method, chartProps.dataSource.data ], () => { // 请求接口 if (chartProps.dataSource.sourceType === DataSourceType.API) { refresh(); } // 静态数据 if(chartProps.dataSource.sourceType === DataSourceType.STATIC) { cancel(); const dataSource = chartProps.dataSource || {}; const { xData, yData, series: seriesData } = dataSource?.data || {}; if(xData) { xAxis.value = { data: xData }; } if(yData) { yAxis.value = { data: yData }; } series.value = seriesData; } // 视图或基础数据源 if([DataSourceType.BASIC_PATH, DataSourceType.VIEW_CODE].includes(chartProps.dataSource.sourceType)) { window?.mabp && window.mabp.$doLoadComponentData(obj).then(function (res) { itemList.value = res.data; }); } }, { deep: true, } ); // 获取grid const getGrid = (opt: EChartsOption) => { let bottom = 34, right = 20, left = 30, top = 20; // 有标题 if(!Array.isArray(opt.title) && opt.title?.show) { top += 20; } // 图例位置 if(!Array.isArray(opt.legend) && opt.legend?.show) { if(opt.legend.left === 'center' && opt.legend.top !== 'auto') { top += 20; } if(opt.legend.left === 'center' && opt.legend.bottom !== 'auto') { bottom += 20; } if(opt.legend.top === 'center' && opt.legend.left !== 'auto') { left += 70; } if(opt.legend.top === 'center' && opt.legend.right !== 'auto') { right += 50; } } if(!Array.isArray(opt.xAxis) && opt.xAxis?.name) { bottom += 20; } if(!Array.isArray(opt.yAxis) && opt.yAxis?.name) { left += 20; } return { bottom, left, right, top } } const options = computed((): EChartsOption => { const opt = omit(chartProps, [ "width", "height", "dataSource", ]) as EChartsOption; if(!Array.isArray(opt.title) && !opt.title?.show && !Array.isArray(opt.legend) && opt.legend) { opt.legend.top = 12; } // 通用标签 const label = opt?.label || {}; const result = defaultsDeep( { xAxis: xAxis.value, yAxis: yAxis.value, series: (series.value as any[])?.map((item: any) => { // 每个类型的图,可以单独设置series.类型 const customSet = (opt.series as EChartsOption)?.[item.type] || {}; return { ...label, ...item, ...customSet, } }), grid: getGrid(opt) }, opt ); console.log('option result:', result) return result; }); return { options, loading, }; };