BarAndLine.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <div v-if="spinning" class="spinning">
  3. <a-spin :spinning="true" />
  4. </div>
  5. <div v-if="!spinning" ref="chartRef" :style="{ height, width }"></div>
  6. </template>
  7. <script lang="ts">
  8. import { defineComponent, PropType, ref, Ref, reactive, watchEffect, watch, nextTick } from 'vue';
  9. import { useECharts } from '/@/hooks/web/useECharts';
  10. import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
  11. import EchartsUtil from '/@/utils/echartsUtil';
  12. export default defineComponent({
  13. name: 'BarAndLine',
  14. props: {
  15. chartsColumns: {
  16. type: Array,
  17. default: () => [],
  18. },
  19. chartsColumnsType: {
  20. type: String,
  21. },
  22. chartsType: {
  23. type: String,
  24. default: 'listMonitor',
  25. },
  26. dataSource: {
  27. type: Array,
  28. default: () => [],
  29. },
  30. option: {
  31. type: Object,
  32. default: () => ({}),
  33. },
  34. xAxisPropType: {
  35. type: String,
  36. required: true,
  37. },
  38. width: {
  39. type: String as PropType<string>,
  40. default: '100%',
  41. },
  42. height: {
  43. type: String as PropType<string>,
  44. default: 'calc(100vh - 78px)',
  45. },
  46. },
  47. emits: ['refresh'],
  48. setup(props, { emit }) {
  49. const spinning = ref<boolean>(true);
  50. const chartRef = ref<HTMLDivElement | null>(null);
  51. const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
  52. const chartData = props.chartsColumnsType ? getTableHeaderColumns(props.chartsColumnsType) : [];
  53. let chartsColumns = props.chartsColumns.length > 0 ? props.chartsColumns : chartData;
  54. const option = reactive({
  55. name: '',
  56. color: ['#7B68EE', '#0000CD', '#6495ED', '#00BFFF', '#AFEEEE', '#008080', '#00FA9A', '#2E8B57', '#FAFAD2', '#DAA520'],
  57. tooltip: {},
  58. grid: {},
  59. toolbox: {
  60. feature: {
  61. saveAsImage: {
  62. iconStyle: {
  63. borderColor: '#ffffff',
  64. },
  65. show: true,
  66. },
  67. },
  68. },
  69. dataZoom: {},
  70. legend: {},
  71. timeline: null,
  72. xAxis: null,
  73. yAxis: null,
  74. series: null,
  75. });
  76. let optionUtil;
  77. watchEffect(() => {
  78. props.dataSource && props.dataSource.length > 0 && option.series && initCharts();
  79. });
  80. watch([() => props.chartsType, () => props.chartsColumns], ([newChartsType, newChartsColumns]) => {
  81. spinning.value = true;
  82. chartsColumns = newChartsColumns;
  83. optionUtil.initChartOption(newChartsType, newChartsColumns);
  84. spinning.value = false;
  85. initCharts(true);
  86. emit('refresh');
  87. });
  88. function initChartsOption() {
  89. optionUtil = new EchartsUtil(Object.assign(option, props.option));
  90. optionUtil.initChartOption(props.chartsType, chartsColumns);
  91. }
  92. initChartsOption();
  93. function initCharts(isRefresh = false) {
  94. //轴数据
  95. if (option.series && option.series.length === chartsColumns.length) {
  96. let xAxisData = props.dataSource.map((item) => item[props.xAxisPropType]);
  97. [...chartsColumns].forEach((propType: any, index) => {
  98. option.series[index].data = props.dataSource.map((item) => item[propType.dataIndex] || 0);
  99. });
  100. option.xAxis[0].data = xAxisData;
  101. console.log('echarts监测列表数据', option.xAxis[0].data)
  102. setOptions(option, isRefresh);
  103. }
  104. }
  105. setTimeout(() => {
  106. spinning.value = false;
  107. }, 1000);
  108. return { chartRef, spinning };
  109. },
  110. });
  111. </script>
  112. <style lang="less" scoped>
  113. .spinning {
  114. display: flex;
  115. width: 100%;
  116. height: 100%;
  117. justify-content: center;
  118. align-items: center;
  119. }
  120. </style>