useChartOptions.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import type { EChartsOption } from "echarts";
  2. import { computed, watch, ref } from "vue";
  3. import { omit, defaultsDeep } from "lodash-es";
  4. import { useRequest } from "vue-hooks-plus";
  5. import { DataSourceType } from "../chartEnum";
  6. import { message } from "ant-design-vue";
  7. import { cllJsCode } from "../utils";
  8. export const useChartOptions = (chartProps: Record<string, any>) => {
  9. const dataSource = chartProps.dataSource || {};
  10. const xAxis = ref<EChartsOption["xAxis"]>();
  11. const yAxis = ref<EChartsOption["yAxis"]>();
  12. const series = ref<EChartsOption["series"]>(dataSource?.data?.series);
  13. const server = computed(() => {
  14. return async () =>
  15. await fetch(chartProps.dataSource.url, {
  16. method: chartProps.dataSource.method,
  17. })
  18. .then((res) => res.json());
  19. });
  20. // 直接通过设置的接口请求数据
  21. const { run, refresh, cancel, data, loading } = useRequest(server.value, {
  22. defaultParams: chartProps.dataSource.params,
  23. manual: true,
  24. cacheKey: chartProps.dataSource.url,
  25. cacheTime: (chartProps.dataSource?.refreshTime || 0) * 1000,
  26. pollingInterval: (chartProps.dataSource?.refreshTime || 0) * 1000, // 刷新时间
  27. onError: (error) => {
  28. console.error(error);
  29. message.error(chartProps.dataSource.url + "请求失败");
  30. }
  31. });
  32. /* 初始请求 */
  33. if (chartProps.dataSource.sourceType === DataSourceType.API) {
  34. run();
  35. }
  36. watch(
  37. () => data.value,
  38. async (val) => {
  39. if (val && chartProps.dataSource.sourceType === DataSourceType.API) {
  40. let res = val;
  41. if(chartProps.dataSource.dataProcess) {
  42. // 请求后数据处理
  43. res = await cllJsCode(chartProps.dataSource.dataProcess, JSON.stringify(val));
  44. }
  45. xAxis.value = res.xAxis || res.xData ? { data: res.xData } : xAxis.value;
  46. yAxis.value = res.yAxis || res.yData ? { data: res.yData } : yAxis.value;
  47. series.value = res.series;
  48. }
  49. },
  50. {
  51. deep: true,
  52. }
  53. );
  54. // 数据源设置
  55. watch(
  56. () => [
  57. chartProps.dataSource.sourceType,
  58. chartProps.dataSource.method,
  59. chartProps.dataSource.data
  60. ],
  61. () => {
  62. // 请求接口
  63. if (chartProps.dataSource.sourceType === DataSourceType.API) {
  64. refresh();
  65. }
  66. // 静态数据
  67. if(chartProps.dataSource.sourceType === DataSourceType.STATIC) {
  68. cancel();
  69. const dataSource = chartProps.dataSource || {};
  70. const { xData, yData, series: seriesData } = dataSource?.data || {};
  71. if(xData) {
  72. xAxis.value = { data: xData };
  73. }
  74. if(yData) {
  75. yAxis.value = { data: yData };
  76. }
  77. series.value = seriesData;
  78. }
  79. // 根据视图或基础数据源获取数据
  80. if([DataSourceType.BASIC_PATH, DataSourceType.VIEW_CODE].includes(chartProps.dataSource.sourceType)) {
  81. const dataSource = chartProps.dataSource || {};
  82. const obj = {
  83. viewCode: dataSource.viewCode,
  84. basicPath: dataSource.basicPath,
  85. items: '',
  86. filter: '',
  87. key: '',
  88. isOne: '',
  89. };
  90. (window as Window & typeof globalThis & {mabp: any}).mabp &&
  91. (window as Window & typeof globalThis & {mabp: any}).mabp
  92. .$doLoadComponentData(obj).then(function (res: any) {
  93. series.value = res.data;
  94. });
  95. }
  96. },
  97. {
  98. deep: true,
  99. }
  100. );
  101. // 获取grid
  102. const getGrid = (opt: EChartsOption) => {
  103. let bottom = 34, right = 20, left = 30, top = 20;
  104. // 有标题
  105. if(!Array.isArray(opt.title) && opt.title?.show) {
  106. top += 20;
  107. }
  108. // 图例位置
  109. if(!Array.isArray(opt.legend) && opt.legend?.show) {
  110. if(opt.legend.left === 'center' && opt.legend.top !== 'auto') {
  111. top += 20;
  112. }
  113. if(opt.legend.left === 'center' && opt.legend.bottom !== 'auto') {
  114. bottom += 20;
  115. }
  116. if(opt.legend.top === 'center' && opt.legend.left !== 'auto') {
  117. left += 70;
  118. }
  119. if(opt.legend.top === 'center' && opt.legend.right !== 'auto') {
  120. right += 50;
  121. }
  122. }
  123. if(!Array.isArray(opt.xAxis) && opt.xAxis?.name) {
  124. bottom += 20;
  125. }
  126. if(!Array.isArray(opt.yAxis) && opt.yAxis?.name) {
  127. left += 20;
  128. }
  129. return {
  130. bottom,
  131. left,
  132. right,
  133. top
  134. }
  135. }
  136. const options = computed((): EChartsOption => {
  137. const opt = omit(chartProps, [
  138. "width",
  139. "height",
  140. "dataSource",
  141. ]) as EChartsOption;
  142. if(!Array.isArray(opt.title) && !opt.title?.show && !Array.isArray(opt.legend) && opt.legend) {
  143. opt.legend.top = 12;
  144. }
  145. // 通用标签
  146. const label = opt?.label || {};
  147. const result = defaultsDeep(
  148. {
  149. xAxis: xAxis.value,
  150. yAxis: yAxis.value,
  151. series: (series.value as any[])?.map((item: any) => {
  152. // 每个图单独的系列配置
  153. const seriesExtend = (opt.seriesExtend as EChartsOption) || {};
  154. return {
  155. ...label,
  156. ...item,
  157. ...seriesExtend,
  158. }
  159. }),
  160. grid: getGrid(opt)
  161. },
  162. opt
  163. );
  164. console.log('option result:', result)
  165. return result;
  166. });
  167. return {
  168. options,
  169. loading,
  170. };
  171. };