BarAndLine.vue 4.0 KB

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