consumptionPower.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <template>
  2. <div class="_consume">
  3. <HeadlineTag value="能耗-电/kWh(周)"></HeadlineTag>
  4. <div class="_consume_mains" v-if="resultData && Object.keys(resultData).length != 0">
  5. <div ref="chartRef" style="width: 100%; height: 100%;"></div>
  6. </div>
  7. <Empty :bottom="true" v-else></Empty>
  8. </div>
  9. </template>
  10. <script setup>
  11. import { ref, onMounted, onUnmounted, nextTick } from 'vue';
  12. import * as echarts from 'echarts';
  13. import HeadlineTag from '@/components/HeadlineTag';
  14. import Empty from '@/components/Empty'
  15. const props = defineProps({
  16. resultData: {
  17. type: Object,
  18. default: {}
  19. }
  20. })
  21. const chartRef = ref(null);
  22. let chart = null;
  23. const generateRandomData = (length, max) => {
  24. const randomData = [];
  25. for (let i = 0; i < length; i++) {
  26. randomData.push(Math.floor(Math.random() * max));
  27. }
  28. return randomData;
  29. };
  30. const handleResize = () => {
  31. if (chart) {
  32. chart.resize();
  33. }
  34. };
  35. onMounted(() => {
  36. initChart();
  37. });
  38. const initChart = (dates, EPE) => {
  39. if (chartRef.value) {
  40. chart = echarts.init(chartRef.value);
  41. // 修改为 24 小时
  42. // const hours = Array.from({ length: 24 }, (_, i) => `${i}时`);
  43. const hours = []
  44. const option = {
  45. xAxis: {
  46. type: 'category',
  47. // 使用 24 小时数据
  48. data: hours,
  49. axisLabel: {
  50. color: '#fff'
  51. },
  52. data: dates,
  53. },
  54. tooltip: {
  55. trigger: 'axis',
  56. axisPointer: {
  57. type: 'cross',
  58. crossStyle: {
  59. color: '#999'
  60. }
  61. },
  62. textStyle: {
  63. color: '#fafafa',
  64. },
  65. borderColor: 'transparent',
  66. backgroundColor: 'rgba(0, 0, 0, 0.5)',
  67. extraCssText: 'backdrop-filter: blur(6px);',
  68. formatter: function (params) {
  69. let result = params[0].axisValue + '<br/>';
  70. params.forEach(item => {
  71. result += item.marker + item.seriesName + ':' + item.data + ' kW.h<br/>';
  72. });
  73. return result;
  74. }
  75. },
  76. grid: {
  77. top: '10%',
  78. bottom: '10%',
  79. right: '0%',
  80. },
  81. yAxis: {
  82. type: 'value',
  83. axisLabel: {
  84. show: true,
  85. color: '#fff'
  86. },
  87. splitLine: {
  88. show: false,
  89. lineStyle: {
  90. color: '#44585e'
  91. }
  92. },
  93. axisTick: {
  94. show: false
  95. },
  96. },
  97. series: [
  98. {
  99. name: '24小时电能耗',
  100. // data: generateRandomData(7, 50),
  101. data: EPE,
  102. type: 'line',
  103. showSymbol: false,
  104. smooth: true,
  105. color: '#00F7FF',
  106. lineStyle: {
  107. width: 2,
  108. },
  109. areaStyle: {
  110. color: new echarts.graphic.LinearGradient(
  111. 0,
  112. 0,
  113. 0,
  114. 1,
  115. [{
  116. offset: 0,
  117. color: 'rgba(0, 247, 255, .6)',
  118. },
  119. {
  120. offset: 0.8,
  121. color: 'rgba(0, 247, 255, .2)',
  122. },
  123. ],
  124. false
  125. ),
  126. shadowColor: 'rgba(0, 0, 0, 0.1)',
  127. shadowBlur: 10,
  128. },
  129. symbol: 'circle',
  130. symbolSize: 6,
  131. }
  132. ]
  133. };
  134. chart.setOption(option);
  135. }
  136. }
  137. // 假设 props.resultData.electricityCount 就是你给的数据
  138. const getChartData = (electricityCount) => {
  139. const dates = [];
  140. const EPE = [];
  141. const EPE_forecast = [];
  142. Object.entries(electricityCount || {}).forEach(([date, value]) => {
  143. dates.push(date);
  144. EPE.push(value.EPE);
  145. EPE_forecast.push(value.EPE_forecast);
  146. });
  147. return { dates, EPE, EPE_forecast };
  148. };
  149. watch(() => props.resultData, (newVal) => {
  150. const { dates, EPE, EPE_forecast } = getChartData(newVal);
  151. if (newVal && chart == null) {
  152. nextTick(() => {
  153. initChart(dates, EPE);
  154. });
  155. }
  156. if (chart) {
  157. chart.setOption({
  158. xAxis: {
  159. data: dates,
  160. },
  161. series: [{
  162. type: 'line',
  163. data: EPE,
  164. }],
  165. })
  166. }
  167. }, { deep: true, immediate: true } // 开启深度监听
  168. )
  169. onUnmounted(() => {
  170. window.removeEventListener('resize', handleResize);
  171. if (chart) {
  172. chart.dispose();
  173. }
  174. });
  175. </script>
  176. <style lang="scss">
  177. ._divider {
  178. height: 1px;
  179. border: 1px dashed #168cdb;
  180. flex: 1;
  181. margin: 0 10px;
  182. }
  183. ._consume {
  184. display: flex;
  185. flex-direction: column;
  186. &_mains {
  187. margin: 10px 30px;
  188. flex: 1;
  189. display: flex;
  190. &_item {
  191. display: flex;
  192. justify-content: space-between;
  193. align-items: center;
  194. padding: 10px;
  195. &_name {
  196. width: 30px;
  197. height: 30px;
  198. background: url("@/assets/images/content_circle_num.png");
  199. background-size: 100% 100%;
  200. background-position: center;
  201. background-repeat: no-repeat;
  202. // animation: scanning 4s linear infinite;
  203. border: 1px solid red;
  204. }
  205. &_flag {
  206. display: flex;
  207. align-items: center;
  208. gap: 3px;
  209. &_item {
  210. width: 30px;
  211. height: 30px;
  212. border: 3px dashed #168cdb;
  213. box-sizing: border-box;
  214. background: #0e6ead;
  215. color: #fff;
  216. border-radius: 50%;
  217. display: flex;
  218. align-items: center;
  219. justify-content: center;
  220. font-size: 14px;
  221. }
  222. }
  223. }
  224. &_item:hover {
  225. cursor: pointer;
  226. background-image: linear-gradient(to right, #168cdb, transparent);
  227. }
  228. }
  229. }
  230. </style>