BarAndLine.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. import { columns } from '/@/views/monitor/datalog/datalog.data';
  14. type ChartColumn = {
  15. legend: string;
  16. seriesName: string;
  17. ymax: number;
  18. yname: string;
  19. linetype: string;
  20. yaxispos: string;
  21. color: string;
  22. sort: number;
  23. xRotate: number;
  24. dataIndex: string;
  25. };
  26. export default defineComponent({
  27. name: 'BarAndLine',
  28. props: {
  29. chartsColumns: {
  30. type: Array as PropType<ChartColumn[]>,
  31. default: () => [],
  32. },
  33. chartsColumnsType: {
  34. type: String,
  35. },
  36. chartsType: {
  37. type: String,
  38. default: '',
  39. },
  40. dataSource: {
  41. type: Array,
  42. default: () => [],
  43. },
  44. option: {
  45. type: Object,
  46. default: () => ({}),
  47. },
  48. xAxisPropType: {
  49. type: String,
  50. required: true,
  51. },
  52. width: {
  53. type: String as PropType<string>,
  54. default: '100%',
  55. },
  56. height: {
  57. type: String as PropType<string>,
  58. default: 'calc(100vh - 78px)',
  59. },
  60. },
  61. emits: ['refresh'],
  62. setup(props, { emit }) {
  63. const spinning = ref<boolean>(true);
  64. const chartRef = ref<HTMLDivElement | null>(null);
  65. const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
  66. const chartData = props.chartsColumnsType ? getTableHeaderColumns(props.chartsColumnsType) : [];
  67. let chartsColumns = (props.chartsColumns.length > 0 ? props.chartsColumns : chartData) as ChartColumn[];
  68. // let groupedByColumns = {};
  69. const option = reactive({
  70. name: '',
  71. color: ['#7B68EE', '#0000CD', '#6495ED', '#00BFFF', '#AFEEEE', '#008080', '#00FA9A', '#2E8B57', '#FAFAD2', '#DAA520'],
  72. tooltip: {},
  73. grid: {},
  74. toolbox: {
  75. feature: {
  76. saveAsImage: {
  77. iconStyle: {
  78. borderColor: '#ffffff',
  79. },
  80. show: true,
  81. },
  82. },
  83. },
  84. dataZoom: {},
  85. legend: {
  86. textStyle: {
  87. color: '#ffffff', // 字体颜色
  88. },
  89. top: '20',
  90. },
  91. timeline: null,
  92. xAxis: {},
  93. yAxis: null,
  94. series: null,
  95. });
  96. let optionUtil;
  97. watchEffect(() => {
  98. props.dataSource && props.xAxisPropType && option.series && initCharts();
  99. });
  100. watch([() => props.chartsType, () => props.chartsColumns], ([newChartsType, newChartsColumns]) => {
  101. spinning.value = true;
  102. chartsColumns = newChartsColumns;
  103. optionUtil.initChartOption(newChartsType, newChartsColumns);
  104. spinning.value = false;
  105. initCharts(true);
  106. emit('refresh');
  107. });
  108. // watch(yMax, (newVal) => {
  109. // // y轴最大值变化,需要重新更新
  110. // chartsColumns = chartsColumns.map((column: ChartColumn) => {
  111. // column['ymax'] = newVal;
  112. // });
  113. // optionUtil.initChartOption(props.chartsType, chartsColumns);
  114. // spinning.value = false;
  115. // initCharts(true);
  116. // emit('refresh');
  117. // });
  118. function initChartsOption() {
  119. // debugger;
  120. optionUtil = new EchartsUtil(merge(option, props.option));
  121. optionUtil.initChartOption(props.chartsType, chartsColumns);
  122. }
  123. initChartsOption();
  124. function initCharts(isRefresh = false) {
  125. debugger;
  126. if (props.dataSource.length < 1) return;
  127. //轴数据
  128. let isFresh = false;
  129. if (option.series && option.series.length === chartsColumns.length) {
  130. let xAxisData = props.dataSource.map((item) => item[props.xAxisPropType]);
  131. chartsColumns = [...chartsColumns].filter((propType: any, index) => {
  132. if (!propType) return;
  133. if (props.chartsType == 'listMonitor') {
  134. option.series[index].type = 'bar';
  135. }
  136. option.series[index].data = props.dataSource.map((item) => Number(item[propType.dataIndex]) || 0);
  137. console.log('nnn', option.series[index].data);
  138. // 这里动态计算echarts y轴最大值
  139. const max = Math.max(...option.series[index].data);
  140. const digitCount = max.toFixed(0).length;
  141. let yMax = 0;
  142. if (digitCount < 2) {
  143. yMax = 10;
  144. } else if (digitCount < 3) {
  145. const n = Number((Number(max.toFixed(0)) / 10).toFixed(0));
  146. yMax = (n + 1) * 10;
  147. } else if (digitCount < 4) {
  148. const n = Number((Number(max.toFixed(0)) / 100).toFixed(0));
  149. yMax = (n + 1) * 100;
  150. } else if (digitCount < 5) {
  151. const n = Number((Number(max.toFixed(0)) / 1000).toFixed(0));
  152. yMax = (n + 1) * 1000;
  153. } else if (digitCount < 6) {
  154. const n = Number((Number(max.toFixed(0)) / 10000).toFixed(0));
  155. yMax = (n + 1) * 10000;
  156. }
  157. if (yMax != 0 && yMax !== propType?.ymax) {
  158. propType.ymax = yMax;
  159. isFresh = true;
  160. }
  161. return true;
  162. });
  163. option.xAxis[0].data = xAxisData;
  164. if (isFresh) {
  165. spinning.value = true;
  166. optionUtil.initChartOption(props.chartsType, chartsColumns);
  167. spinning.value = false;
  168. initCharts(true);
  169. emit('refresh');
  170. nextTick(() => {
  171. setOptions(option, true);
  172. });
  173. } else {
  174. // console.log('echarts监测列表数据', option.xAxis[0].data);
  175. setOptions(option, isRefresh);
  176. }
  177. }
  178. }
  179. setTimeout(() => {
  180. spinning.value = false;
  181. initCharts(true);
  182. }, 1000);
  183. return { chartRef, spinning };
  184. },
  185. });
  186. </script>
  187. <style lang="less" scoped>
  188. .spinning {
  189. display: flex;
  190. width: 100%;
  191. height: 100%;
  192. justify-content: center;
  193. align-items: center;
  194. }
  195. </style>