poweruse.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. <template>
  2. <div class="app-container">
  3. <el-tabs v-model="activeName" @tab-click="tabClick">
  4. <el-tab-pane label="总览" name="summery">
  5. <div class="First">
  6. <div class="time-range-buttons">
  7. <el-button :class="{ 'is-active': selectedTimeRange === 'day' }"
  8. @click="changeTimeRange('day')">今日</el-button>
  9. <el-button :class="{ 'is-active': selectedTimeRange === 'month' }"
  10. @click="changeTimeRange('month')">本月</el-button>
  11. <el-button :class="{ 'is-active': selectedTimeRange === 'year' }"
  12. @click="changeTimeRange('year')">本年</el-button>
  13. </div>
  14. <div class="first-content">
  15. <div>
  16. <SubTitle title="能耗统计" />
  17. <!-- 图表容器 -->
  18. <div ref="sumBySubCategoryChart" style="height: 380px;" />
  19. </div>
  20. <div>
  21. <SubTitle title="能耗总览" />
  22. <el-table border stripe show-summary :data="tableData" style="width: 100%;margin-top: 20px;">
  23. <el-table-column prop="name" align="center" label="设施名称">
  24. </el-table-column>
  25. <el-table-column prop="value" align="center" label="能耗(kW·h)">
  26. </el-table-column>
  27. </el-table>
  28. </div>
  29. </div>
  30. </div>
  31. <div>
  32. <div class="ctl-container">
  33. <SubTitle title="平均功率-15分钟" />
  34. <el-date-picker v-model="powerDate" type="datetimerange" @change="getPowerChart"
  35. :picker-options="pickerOptions" value-format="yyyy-MM-dd hh:mm:ss" range-separator="至"
  36. start-placeholder="开始日期" end-placeholder="结束日期" align="right">
  37. </el-date-picker>
  38. </div>
  39. <!--柱状图-->
  40. <div class="container-block" style="margin-top: 20px;">
  41. <BaseChart width="100%" height="350px" :option="powerLineOptions" />
  42. </div>
  43. </div>
  44. </el-tab-pane>
  45. <el-tab-pane v-for="item in facsCategoryOptions" :key="item.code" :label="item.name" :name="item.code">
  46. <el-col :span="4" :xs="24">
  47. <div class="head-container">
  48. <el-input v-model="areaName" placeholder="请输入区域名称" clearable size="small" prefix-icon="el-icon-search"
  49. style="margin-bottom: 20px" />
  50. </div>
  51. <div class="head-container" style="height: 100vh; overflow: hidden; position: relative;">
  52. <el-tree :data="areaOptions" :props="defaultProps" :expand-on-click-node="false"
  53. :filter-node-method="filterNode" ref="tree" node-key="id" default-expand-all highlight-current
  54. @node-click="handleNodeClick" style="height: calc(100vh - 50px); overflow-y: auto;" />
  55. </div>
  56. </el-col>
  57. <el-col :span="20" :xs="24">
  58. <div class="container-block">
  59. <div class="ctl-container">
  60. <SubTitle :title="`设施汇总电耗【${selectedLabel}】`" />
  61. <div>
  62. <el-select v-model="objCode" placeholder="选择设施" clearable @visible-change="handleObjSelectClick"
  63. @change="getList">
  64. <el-option v-for="item in objOptions" :label="item.facsName" :value="item.facsCode"
  65. :key="item.facsCode" />
  66. </el-select>
  67. <el-date-picker v-model="dateRange" type="datetimerange" @change="getList"
  68. :picker-options="pickerOptions" value-format="yyyy-MM-dd hh:mm:ss" range-separator="至"
  69. start-placeholder="开始日期" end-placeholder="结束日期" :clearable="false" align="right">
  70. </el-date-picker>
  71. </div>
  72. </div>
  73. <!-- 表格 -->
  74. <el-table v-loading="loading" :data="sumByFacsList" style="width: 100%; margin-top: 10px">
  75. <el-table-column label="设施编码" align="center" prop="objCode">
  76. <template slot-scope="scope">
  77. <span>{{ scope.row.objCode }}</span>
  78. </template>
  79. </el-table-column>
  80. <el-table-column label="设施名称" align="center" prop="objName">
  81. <template slot-scope="scope">
  82. <span>{{ scope.row.objName }}</span>
  83. </template>
  84. </el-table-column>
  85. <el-table-column label="用电量(kW·h)" align="center" prop="elecQuantity">
  86. <template slot-scope="scope">
  87. <span>{{ scope.row.elecQuantity }}</span>
  88. </template>
  89. </el-table-column>
  90. </el-table>
  91. <SubTitle title="设施时段电耗" style="margin-top: 20px;" />
  92. <!--柱状图-->
  93. <div class="container-block" style="margin-top: 20px;">
  94. <BaseChart width="100%" height="300px" :option="barChartOptions" />
  95. </div>
  96. <div>
  97. <div class="ctl-container">
  98. <SubTitle title="平均功率-15分钟" />
  99. </div>
  100. <!--柱状图-->
  101. <div class="container-block" style="margin-top: 20px;">
  102. <BaseChart width="100%" height="350px" v-if="activeName !== 'summery'"
  103. :option="equipPowerLineOptions" />
  104. </div>
  105. </div>
  106. </div>
  107. </el-col>
  108. </el-tab-pane>
  109. </el-tabs>
  110. </div>
  111. </template>
  112. <script>
  113. import * as echarts from 'echarts/core';
  114. import {listHSum, sumByFacsH, sumBySubCategoryH, getPowerData, getPowerMaxLoad} from '@/api/mgr/elecUseH'
  115. import {getFacsCategorygetByCode} from '@/api/basecfg/emsfacs'
  116. import {areaTreeByFacsCategory} from '@/api/basecfg/area'
  117. import {listAllFacs} from '@/api/basecfg/emsfacs'
  118. import dayjs from 'dayjs'
  119. import {DateTool} from '@/utils/DateTool'
  120. import {dateFormat} from '@/utils';
  121. import BaseChart from '@/components/BaseChart/index.vue'
  122. import SubTitle from '@/components/SubTitle'
  123. import Block from '@/components/Block/block.vue'
  124. import Treeselect from '@riophae/vue-treeselect'
  125. import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  126. export default {
  127. name: 'PowerUse',
  128. components: {
  129. Treeselect,
  130. BaseChart,
  131. Block,
  132. SubTitle
  133. },
  134. data () {
  135. const today = dateFormat(new Date(), 'yyyy-MM-dd')
  136. return {
  137. activeName: 'summery',
  138. // 遮罩层
  139. loading: true,
  140. // 选中数组
  141. ids: [],
  142. // 非单个禁用
  143. single: true,
  144. // 非多个禁用
  145. multiple: true,
  146. // 显示搜索条件
  147. showSearch: true,
  148. // 总条数
  149. total: 0,
  150. // 用能计量-小时表格数据
  151. hList: [],
  152. //查能耗
  153. sumByFacsList: [],
  154. // 弹出层标题
  155. title: '',
  156. // 是否显示弹出层
  157. open: false,
  158. facsCategory: undefined,
  159. facsSubCategory: undefined,
  160. // 区域名称
  161. areaName: undefined,
  162. selectedLabel: '全部',
  163. defaultProps: {
  164. children: 'children',
  165. label: 'label'
  166. },
  167. areaOptions: [],
  168. facsCategoryOptions: [],
  169. sumBySubCategoryChartOption: {},
  170. // 存储图表配置的变量
  171. selectedTimeRange: 'day',
  172. chartInstance: null,
  173. // 用于存储 ECharts 实例
  174. totalElecQuantity: 0,
  175. objOptions: [],
  176. objCode: undefined,
  177. dateRange: [dayjs().format(DateTool.DateFormat.YYYY_MM_DD_00_00_00), dayjs().format(DateTool.DateFormat.YYYY_MM_DD_23_59_59)],
  178. pickerOptions: {
  179. shortcuts: [
  180. {
  181. text: '最近一周',
  182. onClick (picker) {
  183. const end = new Date()
  184. const start = new Date()
  185. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  186. picker.$emit('pick', [start, end])
  187. }
  188. }, {
  189. text: '最近一个月',
  190. onClick (picker) {
  191. const end = new Date()
  192. const start = new Date()
  193. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
  194. picker.$emit('pick', [start, end])
  195. }
  196. }, {
  197. text: '最近三个月',
  198. onClick (picker) {
  199. const end = new Date()
  200. const start = new Date()
  201. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
  202. picker.$emit('pick', [start, end])
  203. }
  204. }
  205. ]
  206. },
  207. // 查询参数
  208. queryParams: {
  209. pageNum: 1,
  210. pageSize: 10,
  211. areaCode: '-1',
  212. objType: 2,
  213. objCode: null,
  214. facsCategory: 'Z',
  215. facsSubCategory: null,
  216. date: null,
  217. time: null,
  218. timeIndex: null
  219. },
  220. queryObjParams: {
  221. refArea: null,
  222. facsCategory: null,
  223. subCategory: null
  224. },
  225. // 表单参数
  226. form: {},
  227. tableData: [],
  228. powerDate: [`${today} 00:00:00`, `${today} 23:59:59`],
  229. powerChartData: [],
  230. powerMaxLoad: '',
  231. equipPowerChartData: [],
  232. equipPowerMaxLoad: ''
  233. }
  234. },
  235. watch: {
  236. // 根据名称筛选区域树
  237. areaName (val) {
  238. this.$refs.tree.filter(val)
  239. }
  240. },
  241. created () {
  242. this.facsCategory = 'Z'
  243. this.facsSubCategory = ''
  244. this.getFacsCategory(this.facsCategory)
  245. this.getAreaTree(this.facsCategory, this.facsSubCategory)
  246. this.getList()
  247. this.getsumByFacsH()
  248. this.getSumBySubCategoryH();
  249. this.getPowerChart()
  250. },
  251. computed: {
  252. barChartOptions () {
  253. const xAxisData = this.hList.map(item => item.time);
  254. const seriesData = this.hList.map(item => item.elecQuantity);
  255. return {
  256. toolbox: {
  257. itemGap: 10,
  258. itemSize: 16,
  259. right: 10,
  260. top: 0,
  261. show: true,
  262. feature: {
  263. magicType: {
  264. show: true,
  265. type: ['bar', 'line']
  266. },
  267. saveAsImage: {
  268. show: true
  269. }
  270. }
  271. },
  272. tooltip: {
  273. trigger: 'axis',
  274. axisPointer: {
  275. type: 'shadow'
  276. },
  277. formatter: (params) => {
  278. var relVal = params[0].name
  279. for (var i = 0, l = params.length; i < l; i++) {
  280. relVal =
  281. relVal +
  282. '<br/>' +
  283. params[i].marker +
  284. params[i].seriesName +
  285. '&nbsp;&nbsp;&nbsp;' +
  286. params[i].value +
  287. 'kW·h'
  288. }
  289. return relVal
  290. }
  291. },
  292. legend: {
  293. data: ['用电量']
  294. },
  295. xAxis: {
  296. type: 'category',
  297. data: xAxisData
  298. },
  299. yAxis: {
  300. name: 'kW·h(千瓦时)',
  301. type: 'value',
  302. },
  303. series: [{
  304. name: '用电量',
  305. type: 'bar',
  306. data: seriesData,
  307. barWidth: 20,
  308. itemStyle: {
  309. normal: {
  310. color: '#6395FA'
  311. }
  312. }
  313. }]
  314. };
  315. },
  316. powerLineOptions () {
  317. const xAxisData = this.powerChartData.map(item => `${item.date.substr(5)} ${item.time.substr(0, 5)} `);
  318. const yData1 = this.powerChartData.map(item => parseFloat(item.s).toFixed(2));
  319. const yData2 = this.powerChartData.map(item => item.p);
  320. const yData3 = this.powerChartData.map(item => item.q);
  321. return {
  322. toolbox: {
  323. itemGap: 10,
  324. itemSize: 16,
  325. right: 10,
  326. top: 0,
  327. show: true,
  328. feature: {
  329. magicType: {
  330. show: true,
  331. type: ['bar', 'line']
  332. },
  333. saveAsImage: {
  334. show: true
  335. }
  336. }
  337. },
  338. tooltip: {
  339. trigger: 'axis',
  340. axisPointer: {
  341. type: 'shadow'
  342. },
  343. formatter: (params) => {
  344. var relVal = params[0].name
  345. for (var i = 0, l = params.length; i < l; i++) {
  346. relVal =
  347. relVal +
  348. '<br/>' +
  349. params[i].marker +
  350. params[i].seriesName +
  351. '&nbsp;&nbsp;&nbsp;' +
  352. params[i].value +
  353. 'kW'
  354. }
  355. return relVal
  356. }
  357. },
  358. xAxis: {
  359. type: 'category',
  360. data: xAxisData
  361. },
  362. yAxis: {
  363. name: 'kW(千瓦)',
  364. type: 'value',
  365. },
  366. legend: {},
  367. dataZoom: [
  368. {
  369. type: "slider",
  370. start: 0,
  371. end: 100,
  372. height: 10,
  373. bottom: '10%',
  374. showDetail: false,
  375. showDataShadow: false,
  376. borderColor: "transparent"
  377. },
  378. {
  379. type: "inside",
  380. start: 0,
  381. end: 100,
  382. },
  383. ],
  384. series: [{
  385. name: '视在功率',
  386. type: 'line',
  387. data: yData1,
  388. markLine: {
  389. symbol: 'none',
  390. silent: true,
  391. lineStyle: {normal: {type: 'dashed'}},
  392. label: {position: 'end'},
  393. data: [
  394. {
  395. yAxis: this.powerMaxLoad,
  396. lineStyle: {width: 1.656, color: '#ff6367'},
  397. label: {
  398. show: true,
  399. textStyle: {
  400. color: '#ff6367'
  401. }
  402. }
  403. },
  404. ]
  405. },
  406. markPoint: {
  407. silent: true,
  408. data: [
  409. {
  410. yAxis: this.powerMaxLoad,
  411. x: '100%',
  412. symbolSize: 0.1,
  413. symbolOffset: [0, 0],
  414. label: {
  415. textStyle: {color: '#ff6367'},
  416. fontSize: 12,
  417. position: 'left',
  418. formatter: '最高负荷'
  419. }
  420. },
  421. ]
  422. },
  423. },
  424. {
  425. name: '有功功率',
  426. type: 'line',
  427. data: yData2,
  428. },
  429. {
  430. name: '无功功率',
  431. type: 'line',
  432. data: yData3,
  433. },
  434. ]
  435. };
  436. },
  437. equipPowerLineOptions () {
  438. const xAxisData = this.equipPowerChartData.map(item => `${item.date.substr(5)} ${item.time.substr(0, 5)} `);
  439. const yData1 = this.equipPowerChartData.map(item => parseFloat(item.s).toFixed(2));
  440. const yData2 = this.equipPowerChartData.map(item => item.p);
  441. const yData3 = this.equipPowerChartData.map(item => item.q);
  442. return {
  443. toolbox: {
  444. itemGap: 10,
  445. itemSize: 16,
  446. right: 10,
  447. top: 0,
  448. show: true,
  449. feature: {
  450. magicType: {
  451. show: true,
  452. type: ['bar', 'line']
  453. },
  454. saveAsImage: {
  455. show: true
  456. }
  457. }
  458. },
  459. legend: {},
  460. tooltip: {
  461. trigger: 'axis',
  462. axisPointer: {
  463. type: 'shadow'
  464. },
  465. formatter: (params) => {
  466. var relVal = params[0].name
  467. for (var i = 0, l = params.length; i < l; i++) {
  468. relVal =
  469. relVal +
  470. '<br/>' +
  471. params[i].marker +
  472. params[i].seriesName +
  473. '&nbsp;&nbsp;&nbsp;' +
  474. params[i].value +
  475. 'kW'
  476. }
  477. return relVal
  478. }
  479. },
  480. xAxis: {
  481. type: 'category',
  482. data: xAxisData
  483. },
  484. yAxis: {
  485. name: 'kW(千瓦)',
  486. type: 'value',
  487. },
  488. dataZoom: [
  489. {
  490. type: "slider",
  491. start: 0,
  492. end: 100,
  493. height: 10,
  494. bottom: '10%',
  495. showDetail: false,
  496. showDataShadow: false,
  497. borderColor: "transparent"
  498. },
  499. {
  500. type: "inside",
  501. start: 0,
  502. end: 100,
  503. },
  504. ],
  505. series: [{
  506. name: '视在功率',
  507. type: 'line',
  508. data: yData1,
  509. markLine: {
  510. symbol: 'none',
  511. silent: true,
  512. lineStyle: {normal: {type: 'dashed'}},
  513. label: {position: 'end'},
  514. data: [
  515. {
  516. yAxis: this.equipPowerMaxLoad,
  517. lineStyle: {width: 1.656, color: '#ff6367'},
  518. label: {
  519. show: true,
  520. textStyle: {
  521. color: '#ff6367'
  522. }
  523. }
  524. },
  525. ]
  526. },
  527. markPoint: {
  528. silent: true,
  529. data: [
  530. {
  531. yAxis: this.equipPowerMaxLoad,
  532. x: '100%',
  533. symbolSize: 0.1,
  534. symbolOffset: [0, 0],
  535. label: {
  536. textStyle: {color: '#ff6367'},
  537. fontSize: 12,
  538. position: 'left',
  539. formatter: '最高负荷'
  540. }
  541. },
  542. ]
  543. },
  544. },
  545. {
  546. name: '有功功率',
  547. type: 'line',
  548. data: yData2,
  549. },
  550. {
  551. name: '无功功率',
  552. type: 'line',
  553. data: yData3,
  554. },
  555. ]
  556. };
  557. }
  558. },
  559. methods: {
  560. getPowerChart () {
  561. this.powerMaxLoad = ''
  562. this.powerChartData = []
  563. const [startTime, endTime] = this.powerDate
  564. const params = {
  565. startTime,
  566. endTime,
  567. areaCode: '-1',
  568. objType: '2',
  569. }
  570. getPowerData({
  571. ...params,
  572. pageNum: 1,
  573. pageSize: 999
  574. }).then(({code, rows}) => {
  575. if (code === 200) {
  576. this.powerChartData = rows
  577. }
  578. })
  579. getPowerMaxLoad(params).then(({code, data}) => {
  580. if (code === 200 && data) {
  581. this.powerMaxLoad = parseFloat(data.s).toFixed(2)
  582. }
  583. })
  584. },
  585. getEquipPowerChart () {
  586. this.equipPowerMaxLoad = ''
  587. this.equipPowerChartData = []
  588. const [startTime, endTime] = this.dateRange
  589. const params = {
  590. startTime,
  591. endTime,
  592. areaCode: '-1',
  593. objType: '2',
  594. facsCategory: 'Z',
  595. facsSubCategory: this.activeName,
  596. objCode: this.objCode
  597. }
  598. getPowerData({
  599. ...params,
  600. pageNum: 1,
  601. pageSize: 999
  602. }).then(({code, rows}) => {
  603. if (code === 200) {
  604. this.equipPowerChartData = rows
  605. }
  606. })
  607. getPowerMaxLoad(params).then(({code, data}) => {
  608. if (code === 200) {
  609. this.equipPowerMaxLoad = parseFloat(data).toFixed(2)
  610. }
  611. })
  612. },
  613. /** 查询用能计量-小时列表 */
  614. getList () {
  615. this.loading = true
  616. this.queryParams.objCode = this.objCode
  617. listHSum(this.queryParams).then(response => {
  618. this.hList = response.rows
  619. this.total = response.total
  620. this.loading = false
  621. })
  622. this.getsumByFacsH()
  623. this.getEquipPowerChart()
  624. },
  625. /**根据设施查询能耗统计 */
  626. getsumByFacsH () {
  627. const params = {
  628. startRecTime: dayjs(this.dateRange[0]).format('YYYY-MM-DD HH:mm:ss'),
  629. endRecTime: dayjs(this.dateRange[1]).format('YYYY-MM-DD HH:mm:ss'),
  630. areaCode: this.queryParams.areaCode,
  631. facsSubCategory: this.activeName,
  632. objCode: this.queryParams.objCode
  633. };
  634. sumByFacsH(params).then(response => {
  635. this.sumByFacsList = response.data
  636. })
  637. },
  638. /**时间范围切换按钮点击事件处理器*/
  639. changeTimeRange (rangeType) {
  640. this.selectedTimeRange = rangeType;
  641. let start = dayjs();
  642. let end = dayjs();
  643. if (rangeType === 'day') {
  644. // 日:当前日期的 00:00:00 到 23:59:59
  645. start = start.startOf('day');
  646. end = end.endOf('day');
  647. } else if (rangeType === 'month') {
  648. // 月:当前月份的第一天 00:00:00 到 最后一天 23:59:59
  649. start = start.date(1).hour(0).minute(0).second(0);
  650. end = end.endOf('month').hour(23).minute(59).second(59);
  651. } else if (rangeType === 'year') {
  652. // 年:当前年份的第一天 00:00:00 到 最后一天 23:59:59
  653. start = start.startOf('year');
  654. end = end.endOf('year').hour(23).minute(59).second(59);
  655. }
  656. this.dateRange = [start.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss')];
  657. this.getSumBySubCategoryH(); // 重新获取数据
  658. },
  659. /**总览饼图*/
  660. getSumBySubCategoryH () {
  661. const params = {
  662. startRecTime: dayjs(this.dateRange[0]).format('YYYY-MM-DD HH:mm:ss'),
  663. endRecTime: dayjs(this.dateRange[1]).format('YYYY-MM-DD HH:mm:ss'),
  664. areaCode: this.queryParams.areaCode,
  665. };
  666. sumBySubCategoryH(params).then(response => {
  667. this.processDataForChart(response.data); // 处理数据并生成图表配置
  668. console.log("pie图", response.data)
  669. this.tableData = response.data.map(item => ({
  670. name: item.objName,
  671. value: item.elecQuantity || 0
  672. }))
  673. })
  674. },
  675. processDataForChart (data) {
  676. this.totalElecQuantity = data.reduce((sum, item) => sum + (item.elecQuantity || 0), 0);
  677. // 处理数据,生成图表配置
  678. const seriesData = data.map(item => ({
  679. name: item.objName,
  680. value: item.elecQuantity,
  681. percent: ((item.elecQuantity || 0) / this.totalElecQuantity * 100).toFixed(2),
  682. subentry: item.subentry.map(subItem => ({
  683. name: subItem.objName,
  684. value: subItem.elecQuantity
  685. }))
  686. }));
  687. // 设置图表配置
  688. this.sumBySubCategoryChartOption = {
  689. tooltip: {
  690. trigger: 'item',
  691. formatter: function (params) {
  692. const {name, value, percent} = params;
  693. const subentries = params.data.subentry;
  694. let tooltipContent = `<div><h4>${name}</h4><p>${value}kW·h (${percent}%)</p><ul>`;
  695. subentries.forEach(subItem => {
  696. tooltipContent += `<li>${subItem.name}: ${subItem.value} kW·h</li>`;
  697. });
  698. tooltipContent += `</ul></div>`;
  699. return tooltipContent;
  700. }
  701. },
  702. legend: {
  703. orient: 'vertical',
  704. top: '5%',
  705. left: '5%'
  706. },
  707. series: [
  708. {
  709. name: '能耗',
  710. type: 'pie',
  711. radius: ['35%', '55%'],
  712. data: seriesData,
  713. emphasis: {
  714. itemStyle: {
  715. shadowBlur: 10,
  716. shadowOffsetX: 0,
  717. shadowColor: 'rgba(0, 0, 0, 0.5)',
  718. }
  719. },
  720. label: {
  721. show: true,
  722. position: 'outside',
  723. formatter: '{b}\n{d}%',
  724. },
  725. labelLine: {
  726. show: true,
  727. length: 30, // 标签线长度
  728. lineStyle: {
  729. width: 1,
  730. type: 'dashed', // 设置虚线样式
  731. }
  732. }
  733. }
  734. ]
  735. };
  736. // 渲染图表
  737. this.$nextTick(() => {
  738. const chart = echarts.init(this.$refs.sumBySubCategoryChart);
  739. chart.setOption(this.sumBySubCategoryChartOption);
  740. });
  741. },
  742. async getFacsCategory (code) {
  743. getFacsCategorygetByCode(code).then(response => {
  744. this.facsCategoryOptions = response.data.subtypeList
  745. })
  746. },
  747. async getAreaTree (category, subCategory) {
  748. await areaTreeByFacsCategory(category, subCategory, false).then(response => {
  749. this.areaOptions = [{
  750. id: '-1',
  751. label: '全部',
  752. children: []
  753. }].concat(response.data)
  754. })
  755. },
  756. async getFacsObj (areaCode, category, subCategory) {
  757. this.queryObjParams.refArea = areaCode
  758. this.queryObjParams.facsCategory = category
  759. this.queryObjParams.subCategory = subCategory
  760. listAllFacs(this.queryObjParams).then(response => {
  761. this.objOptions = response.data
  762. })
  763. },
  764. tabClick () {
  765. this.reset()
  766. if (this.activeName !== 'summery') {
  767. this.dateRange = [dayjs().format(DateTool.DateFormat.YYYY_MM_DD_00_00_00), dayjs().format(DateTool.DateFormat.YYYY_MM_DD_23_59_59)]
  768. this.queryParams.facsCategory = this.facsCategory
  769. this.queryParams.facsSubCategory = this.activeName
  770. this.queryParams.pageNum = 1
  771. this.selectedLabel = '全部'
  772. this.getList()
  773. } else {
  774. }
  775. },
  776. /** 搜索按钮操作 */
  777. handleQuery () {
  778. this.queryParams.pageNum = 1
  779. this.getList()
  780. },
  781. handleObjSelectClick () {
  782. this.getFacsObj(this.queryParams.areaCode, this.facsCategory, this.activeName)
  783. this.getsumByFacsH();
  784. },
  785. // 筛选节点
  786. filterNode (value, data) {
  787. if (!value) return true
  788. return data.label.indexOf(value) !== -1
  789. },
  790. // 节点单击事件
  791. handleNodeClick (data) {
  792. this.queryParams.areaCode = data.id
  793. this.selectedLabel = data.label
  794. this.objCode = null
  795. this.handleQuery()
  796. },
  797. reset () {
  798. this.objCode = null
  799. this.queryParams.areaCode = '-1'
  800. this.queryParams.facsCategory = 'Z'
  801. this.queryParams.facsSubCategory = null
  802. this.queryParams.objCode = null
  803. this.objOptions = []
  804. }
  805. }
  806. }
  807. </script>
  808. <style lang="scss" scoped>
  809. .time-range-buttons {
  810. .is-active {
  811. background-color: #409eff;
  812. color: white;
  813. }
  814. }
  815. .first-content {
  816. display: flex;
  817. margin-top: 20px;
  818. >div:first-child {
  819. flex: 3;
  820. }
  821. >div:last-child {
  822. flex: 2;
  823. }
  824. }
  825. .container-block {
  826. padding-left: 20px;
  827. }
  828. .ctl-container {
  829. display: flex;
  830. justify-content: space-between;
  831. }
  832. </style>
  833. }