useChartOptions.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. pollingInterval: (chartProps.dataSource?.refreshTime || 0) * 1000, // 刷新时间
  25. onError: (error) => {
  26. console.error(error);
  27. message.error(chartProps.dataSource.url + "请求失败");
  28. }
  29. });
  30. /* 初始请求 */
  31. if (chartProps.dataSource.sourceType === DataSourceType.API) {
  32. run();
  33. }
  34. watch(
  35. () => data.value,
  36. async (val) => {
  37. if (val && chartProps.dataSource.sourceType === DataSourceType.API) {
  38. let res = val;
  39. if(chartProps.dataSource.dataProcess) {
  40. res = await cllJsCode(chartProps.dataSource.dataProcess, JSON.stringify(val));
  41. }
  42. xAxis.value = res.xAxis || { data: res.xData };
  43. yAxis.value = res.yAxis || { data: res.yData };
  44. series.value = res.series;
  45. }
  46. },
  47. {
  48. deep: true,
  49. }
  50. );
  51. watch(
  52. () => [
  53. chartProps.dataSource.sourceType,
  54. chartProps.dataSource.method
  55. ],
  56. () => {
  57. if (chartProps.dataSource.sourceType === DataSourceType.API) {
  58. refresh();
  59. } else {
  60. cancel();
  61. const dataSource = chartProps.dataSource || {};
  62. const { xData, yData, series } = dataSource?.data || {};
  63. if(xData) {
  64. xAxis.value = { data: xData };
  65. }
  66. if(yData) {
  67. yAxis.value = { data: yData };
  68. }
  69. series.value = series;
  70. }
  71. },
  72. {
  73. deep: true,
  74. }
  75. );
  76. const options = computed((): EChartsOption => {
  77. const opt = omit(chartProps, [
  78. "width",
  79. "height",
  80. "dataSource",
  81. ]) as EChartsOption;
  82. // 通用标签
  83. const label = opt?.label || {};
  84. const result = defaultsDeep(
  85. {
  86. xAxis: xAxis.value,
  87. yAxis: yAxis.value,
  88. series: (series.value as any[])?.map((item: any) => {
  89. // 每个类型的图,可以单独设置series.类型
  90. const customSet = opt.series?.[item.type] || {};
  91. // TODO 动态计算上下左右距离
  92. return {
  93. ...label,
  94. ...item,
  95. ...customSet
  96. }
  97. }),
  98. },
  99. opt
  100. );
  101. console.log('option result:', result)
  102. return result;
  103. });
  104. return {
  105. options,
  106. loading,
  107. };
  108. };