barCharts.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. <template>
  2. <div class="chart" :id="id" style="margin-top: 10px"></div>
  3. </template>
  4. <script>
  5. import util from "@/helper/util.js";
  6. import partten from "@/helper/partten.js";
  7. import * as echarts from "echarts";
  8. import dayjs from "dayjs";
  9. export default {
  10. name: "multiple-bar-chart",
  11. componentName: "multiple-bar-chart",
  12. props: {
  13. width: {
  14. type: String,
  15. default: "100%",
  16. },
  17. height: {
  18. type: String,
  19. default: "13.889vh",
  20. },
  21. pillarName: {
  22. type: String,
  23. default: "",
  24. },
  25. top: {
  26. type: Number,
  27. default: 30,
  28. },
  29. interval: {
  30. type: Number,
  31. default: 0,
  32. },
  33. padding: {
  34. type:Array,
  35. default: [10,10]
  36. },
  37. // 传入数据
  38. list: {
  39. type: Array,
  40. default: () => [
  41. {
  42. title: "日发电量",
  43. yAxisIndex: 0,
  44. value: [
  45. {
  46. text: "1日",
  47. value: 1,
  48. },
  49. {
  50. text: "2日",
  51. value: 2,
  52. },
  53. {
  54. text: "3日",
  55. value: 5,
  56. },
  57. {
  58. text: "4日",
  59. value: 25,
  60. },
  61. {
  62. text: "5日",
  63. value: 4,
  64. },
  65. {
  66. text: "6日",
  67. value: 9,
  68. },
  69. ],
  70. },
  71. {
  72. title: "上网电量",
  73. yAxisIndex: 0,
  74. value: [
  75. {
  76. text: "1日",
  77. value: 1,
  78. },
  79. {
  80. text: "2日",
  81. value: 6,
  82. },
  83. {
  84. text: "3日",
  85. value: 2,
  86. },
  87. {
  88. text: "4日",
  89. value: 3,
  90. },
  91. {
  92. text: "5日",
  93. value: 3,
  94. },
  95. {
  96. text: "6日",
  97. value: 6,
  98. },
  99. {
  100. text: "7日",
  101. value: 3,
  102. },
  103. ],
  104. },
  105. {
  106. title: "购网电量",
  107. yAxisIndex: 0,
  108. value: [
  109. {
  110. text: "1日",
  111. value: 3,
  112. },
  113. {
  114. text: "2日",
  115. value: 11,
  116. },
  117. {
  118. text: "3日",
  119. value: 1,
  120. },
  121. {
  122. text: "4日",
  123. value: 7,
  124. },
  125. {
  126. text: "5日",
  127. value: 9,
  128. },
  129. {
  130. text: "6日",
  131. value: 3,
  132. },
  133. {
  134. text: "7日",
  135. value: 3,
  136. },
  137. ],
  138. },
  139. {
  140. title: "风速",
  141. yAxisIndex: 1,
  142. value: [
  143. {
  144. text: "1日",
  145. value: 8,
  146. },
  147. {
  148. text: "2日",
  149. value: 15,
  150. },
  151. {
  152. text: "3日",
  153. value: 3,
  154. },
  155. {
  156. text: "4日",
  157. value: 8,
  158. },
  159. {
  160. text: "5日",
  161. value: 12,
  162. },
  163. {
  164. text: "6日",
  165. value: 3,
  166. },
  167. {
  168. text: "7日",
  169. value: 3,
  170. },
  171. ],
  172. },
  173. {
  174. title: "风速1",
  175. yAxisIndex: 1,
  176. value: [
  177. {
  178. text: "1日",
  179. value: 8,
  180. },
  181. {
  182. text: "2日",
  183. value: 15,
  184. },
  185. {
  186. text: "3日",
  187. value: 3,
  188. },
  189. {
  190. text: "4日",
  191. value: 8,
  192. },
  193. {
  194. text: "5日",
  195. value: 12,
  196. },
  197. {
  198. text: "6日",
  199. value: 3,
  200. },
  201. {
  202. text: "7日",
  203. value: 3,
  204. },
  205. ],
  206. },
  207. {
  208. title: "风速2",
  209. yAxisIndex: 1,
  210. value: [
  211. {
  212. text: "1日",
  213. value: 8,
  214. },
  215. {
  216. text: "2日",
  217. value: 15,
  218. },
  219. {
  220. text: "3日",
  221. value: 3,
  222. },
  223. {
  224. text: "4日",
  225. value: 8,
  226. },
  227. {
  228. text: "5日",
  229. value: 12,
  230. },
  231. {
  232. text: "6日",
  233. value: 3,
  234. },
  235. {
  236. text: "7日",
  237. value: 3,
  238. },
  239. ],
  240. },
  241. ],
  242. },
  243. // 单位
  244. units: {
  245. type: Array,
  246. default: () => ["(万KWh)"],
  247. },
  248. // 显示 legend
  249. showLegend: {
  250. type: Boolean,
  251. default: true,
  252. },
  253. // X轴是否为时间
  254. xdate: {
  255. type: Boolean,
  256. default: true,
  257. },
  258. // 颜色#
  259. color: {
  260. type: Array,
  261. default: () => [
  262. "#005bd9",
  263. "#019f2e",
  264. "#db6200",
  265. "#a10f0f",
  266. "#850894",
  267. "#9fa0a2",
  268. ],
  269. },
  270. showAnimation: {
  271. type: Boolean,
  272. default: true,
  273. },
  274. colorIndex: {
  275. type: Boolean,
  276. default: false,
  277. },
  278. // 柱子最大宽度
  279. barMaxWidth: {
  280. type: Number || String,
  281. default: 0,
  282. },
  283. // 柱子间距
  284. barGap: {
  285. type: Number || String,
  286. default: 0,
  287. },
  288. dataInterval: {
  289. type: String,
  290. default: 'D',
  291. },
  292. },
  293. data() {
  294. return {
  295. id: "",
  296. chart: null,
  297. firstAnimation: true,
  298. };
  299. },
  300. computed: {
  301. legend() {
  302. return this.list.map((t) => {
  303. return t.name;
  304. });
  305. },
  306. xdata() {
  307. let result = [];
  308. if (this.list && this.list.length > 0) {
  309. result = this.list[0].date.map((t) => {
  310. if(this.dataInterval === 'M'){
  311. return dayjs(t).format("YYYY-MM");
  312. }else if(this.dataInterval === 'Y'){
  313. return dayjs(t).format("YYYY");
  314. }else{
  315. return this.xdate?dayjs(t).format("MM-DD"):t;
  316. }
  317. });
  318. }
  319. return result;
  320. },
  321. ydata() {
  322. let result = [];
  323. this.units.forEach((value, index) => {
  324. let data = null;
  325. if (index == 0) {
  326. data = {
  327. type: "value",
  328. name: value,
  329. axisLabel: {
  330. formatter: "{value} ",
  331. fontSize: 12,
  332. textStyle: {
  333. color: "#b3b3b3",
  334. },
  335. },
  336. nameTextStyle: {
  337. color: "#b3b3b3",
  338. fontSize: 12,
  339. },
  340. //分格线
  341. splitLine: {
  342. lineStyle: {
  343. color: "rgba(96,103,105,0.3)",
  344. type: "dashed",
  345. },
  346. },
  347. };
  348. } else {
  349. data = {
  350. type: "value",
  351. name: value,
  352. axisLabel: {
  353. formatter: "{value}",
  354. fontSize: 12,
  355. textStyle: {
  356. color: "#b3b3b3",
  357. },
  358. },
  359. axisLine:{
  360. lineStyle:{
  361. color:'#b3b3b3'
  362. }
  363. },
  364. //分格线
  365. splitLine: {
  366. show: false,
  367. },
  368. };
  369. }
  370. result.push(data);
  371. });
  372. return result;
  373. },
  374. series() {
  375. let result = [];
  376. if (this.list && this.list.length > 0) {
  377. this.list.forEach((value, index) => {
  378. let seriesItem = {
  379. name: value.name,
  380. type: "bar",
  381. barWidth: "12",
  382. animation: this.firstAnimation && this.showAnimation,
  383. yAxisIndex: value.yAxisIndex,
  384. itemStyle: {
  385. borderColor: this.color[index],
  386. borderWidth: 1,
  387. // shadowBlur: 1,
  388. // shadowColor: "#16ADD4",
  389. },
  390. data: value.children,
  391. };
  392. result.push(seriesItem);
  393. });
  394. }
  395. return result;
  396. },
  397. colorList() {
  398. let result = [
  399. {
  400. type: 'linear',
  401. x: 0,
  402. y: 0,
  403. x2: 0,
  404. y2: 1,
  405. colorStops: [
  406. { offset: 0, color: '#1c99ff' }, // 设置颜色渐变
  407. { offset: 1, color: 'rgba(0,70,212,0)' }
  408. ]
  409. },
  410. {
  411. type: 'linear',
  412. x: 0,
  413. y: 0,
  414. x2: 0,
  415. y2: 1,
  416. colorStops: [
  417. { offset: 0, color: '#DC143C' }, // 设置颜色渐变
  418. { offset: 1, color: 'rgba(255,105,180,0)' }
  419. ]
  420. },
  421. {
  422. type: 'linear',
  423. x: 0,
  424. y: 0,
  425. x2: 0,
  426. y2: 1,
  427. colorStops: [
  428. { offset: 0, color: '#ea8b00' },
  429. { offset: 1, color: 'rgba(168,83,0,0)' }
  430. ]
  431. },
  432. {
  433. type: 'linear',
  434. x: 0,
  435. y: 0,
  436. x2: 0,
  437. y2: 1,
  438. colorStops: [
  439. { offset: 0, color: '#696969' },
  440. { offset: 1, color: 'rgba(211,211,211,0)' }
  441. ]
  442. },
  443. {
  444. type: 'linear',
  445. x: 0,
  446. y: 0,
  447. x2: 0,
  448. y2: 1,
  449. colorStops: [
  450. { offset: 0, color: '#ff5378' },
  451. { offset: 1, color: 'rgba(167,17,49,0)' }
  452. ]
  453. },
  454. {
  455. type: 'linear',
  456. x: 0,
  457. y: 0,
  458. x2: 0,
  459. y2: 1,
  460. colorStops: [
  461. { offset: 0, color: '#05bb4c' },
  462. { offset: 1, color: 'rgba(0,75,11,0)' }
  463. ]
  464. },
  465. ]
  466. let result1 = [
  467. {
  468. type: 'linear',
  469. x: 0,
  470. y: 0,
  471. x2: 0,
  472. y2: 1,
  473. colorStops: [
  474. { offset: 0, color: '#DC143C' }, // 设置颜色渐变
  475. { offset: 1, color: 'rgba(255,105,180,0)' }
  476. ]
  477. },
  478. {
  479. type: 'linear',
  480. x: 0,
  481. y: 0,
  482. x2: 0,
  483. y2: 1,
  484. colorStops: [
  485. { offset: 0, color: '#ea8b00' },
  486. { offset: 1, color: 'rgba(168,83,0,0)' }
  487. ]
  488. },
  489. {
  490. type: 'linear',
  491. x: 0,
  492. y: 0,
  493. x2: 0,
  494. y2: 1,
  495. colorStops: [
  496. { offset: 0, color: '#696969' },
  497. { offset: 1, color: 'rgba(211,211,211,0)' }
  498. ]
  499. },
  500. {
  501. type: 'linear',
  502. x: 0,
  503. y: 0,
  504. x2: 0,
  505. y2: 1,
  506. colorStops: [
  507. { offset: 0, color: '#ff5378' },
  508. { offset: 1, color: 'rgba(167,17,49,0)' }
  509. ]
  510. },
  511. {
  512. type: 'linear',
  513. x: 0,
  514. y: 0,
  515. x2: 0,
  516. y2: 1,
  517. colorStops: [
  518. { offset: 0, color: '#05bb4c' },
  519. { offset: 1, color: 'rgba(0,75,11,0)' }
  520. ]
  521. },
  522. ]
  523. return this.colorIndex? result1 : result
  524. }
  525. },
  526. methods: {
  527. resize() {
  528. this.initChart();
  529. },
  530. initChart() {
  531. let chart = echarts.init(this.$el);
  532. let option = {
  533. color: this.color,
  534. title: {
  535. text: this.pillarName,
  536. textStyle: {
  537. color: "#999999",
  538. fontSize: 18,
  539. },
  540. },
  541. zoom: 12,
  542. tooltip: {
  543. trigger: "axis",
  544. backgroundColor: "rgba(0,70,199,0.35)",
  545. borderWidth: 1,
  546. padding: [10, 10, 3, 10],
  547. borderColor: '#074EAD',
  548. textStyle: {
  549. color: "#fff",
  550. fontSize: 12,
  551. },
  552. axisPointer: {
  553. type: 'shadow',
  554. shadowStyle: {
  555. color: 'rgba(105,105,105, .05)',
  556. width: '1'
  557. }
  558. }
  559. },
  560. legend: {
  561. show: this.showLegend,
  562. data: this.legend,
  563. padding: this.padding,
  564. right: 0,
  565. top:15,
  566. icon: "ract",
  567. itemWidth: 8,
  568. itemHeight: 8,
  569. inactiveColor: partten.getColor("gray"),
  570. textStyle: {
  571. fontSize: 12,
  572. color: partten.getColor("grayl"),
  573. },
  574. },
  575. grid: {
  576. top: this.top,
  577. left: 8,
  578. right: 8,
  579. bottom: 90,
  580. containLabel: true,
  581. },
  582. xAxis: [
  583. {
  584. type: "category",
  585. data: this.xdata,
  586. nameLocation: "center",
  587. axisPointer: {
  588. type: "shadow",
  589. },
  590. axisLabel: {
  591. interval: this.interval,
  592. fontSize: 12,
  593. textStyle: {
  594. color: "#b3b3b3",
  595. },
  596. },
  597. },
  598. ],
  599. yAxis: this.ydata,
  600. series: this.series,
  601. };
  602. chart.clear();
  603. chart.setOption(option);
  604. this.resize = function () {
  605. chart.resize();
  606. };
  607. window.addEventListener("resize", this.resize);
  608. },
  609. },
  610. created() {
  611. this.$nextTick(() => {
  612. this.id = "pie-chart-" + util.newGUID();
  613. });
  614. },
  615. mounted() {
  616. this.$nextTick(() => {
  617. this.$el.style.width = this.width;
  618. this.$el.style.height = this.height;
  619. this.initChart();
  620. this.firstAnimation = false;
  621. });
  622. },
  623. updated() {
  624. this.$nextTick(() => {
  625. this.initChart();
  626. });
  627. },
  628. unmounted() {
  629. window.removeEventListener("resize", this.resize);
  630. },
  631. watch: {
  632. "$store.state.themeName"() {
  633. this.initChart();
  634. },
  635. },
  636. };
  637. </script>
  638. <style lang="less">
  639. .chart {
  640. width: 100%;
  641. height: 100%;
  642. display: inline-block;
  643. }
  644. </style>