barCharts.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. <template>
  2. <div class="chart" :id="id" :style="{ width, height }"></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. // 单位
  43. units: {
  44. type: Array,
  45. default: () => ["(万KWh)", ""],
  46. },
  47. // 显示 legend
  48. showLegend: {
  49. type: Boolean,
  50. default: true,
  51. },
  52. // X轴是否为时间
  53. xdate: {
  54. type: Boolean,
  55. default: true,
  56. },
  57. // 颜色#
  58. color: {
  59. type: Array,
  60. default: () => [
  61. "#005bd9",
  62. "#019f2e",
  63. "#db6200",
  64. "#a10f0f",
  65. "#850894",
  66. "#9fa0a2",
  67. ],
  68. },
  69. showAnimation: {
  70. type: Boolean,
  71. default: true,
  72. },
  73. colorIndex: {
  74. type: Boolean,
  75. default: false,
  76. },
  77. // 柱子最大宽度
  78. barMaxWidth: {
  79. type: Number || String,
  80. default: 0,
  81. },
  82. // 柱子间距
  83. barGap: {
  84. type: Number || String,
  85. default: 0,
  86. },
  87. dataInterval: {
  88. type: String,
  89. default: "D",
  90. },
  91. },
  92. data() {
  93. return {
  94. id: "",
  95. chart: null,
  96. firstAnimation: true,
  97. };
  98. },
  99. computed: {
  100. legend() {
  101. return this.list.map((t) => {
  102. return t.name;
  103. });
  104. },
  105. xdata() {
  106. let result = [];
  107. if (this.list && this.list.length > 0) {
  108. result = this.list[0].date.map((t) => {
  109. if (this.dataInterval === "M") {
  110. return dayjs(t).format("YYYY-MM");
  111. } else if (this.dataInterval === "Y") {
  112. return dayjs(t).format("YYYY");
  113. } else {
  114. return this.xdate ? dayjs(t).format("MM-DD") : t;
  115. }
  116. });
  117. }
  118. return result;
  119. },
  120. ydata() {
  121. let result = [];
  122. this.units.forEach((value, index) => {
  123. let data = null;
  124. if (index == 0) {
  125. data = {
  126. type: "value",
  127. name: value,
  128. axisLabel: {
  129. formatter: "{value} ",
  130. fontSize: 12,
  131. textStyle: {
  132. color: "#828484",
  133. },
  134. },
  135. //分格线
  136. splitLine: {
  137. lineStyle: {
  138. color: "rgba(96,103,105,0.3)",
  139. type: "dashed",
  140. },
  141. },
  142. };
  143. } else {
  144. data = {
  145. type: "value",
  146. name: value,
  147. axisLabel: {
  148. formatter: "{value}",
  149. fontSize: 12,
  150. textStyle: {
  151. color: "#828484",
  152. },
  153. },
  154. //分格线
  155. splitLine: {
  156. show: false,
  157. },
  158. };
  159. }
  160. result.push(data);
  161. });
  162. return result;
  163. },
  164. series() {
  165. let result = [];
  166. if (this.list && this.list.length > 0) {
  167. this.list.forEach((value, index) => {
  168. let seriesItem = {
  169. name: value.name,
  170. type: "bar",
  171. barWidth: "12",
  172. animation: this.firstAnimation && this.showAnimation,
  173. yAxisIndex: value.yAxisIndex,
  174. itemStyle: {
  175. borderColor: this.color[index],
  176. borderWidth: 1,
  177. // shadowBlur: 1,
  178. // shadowColor: "#16ADD4",
  179. },
  180. data: value.children,
  181. };
  182. result.push(seriesItem);
  183. });
  184. }
  185. return result;
  186. },
  187. colorList() {
  188. let result = [
  189. {
  190. type: "linear",
  191. x: 0,
  192. y: 0,
  193. x2: 0,
  194. y2: 1,
  195. colorStops: [
  196. { offset: 0, color: "#1c99ff" }, // 设置颜色渐变
  197. { offset: 1, color: "rgba(0,70,212,0)" },
  198. ],
  199. },
  200. {
  201. type: "linear",
  202. x: 0,
  203. y: 0,
  204. x2: 0,
  205. y2: 1,
  206. colorStops: [
  207. { offset: 0, color: "#DC143C" }, // 设置颜色渐变
  208. { offset: 1, color: "rgba(255,105,180,0)" },
  209. ],
  210. },
  211. {
  212. type: "linear",
  213. x: 0,
  214. y: 0,
  215. x2: 0,
  216. y2: 1,
  217. colorStops: [
  218. { offset: 0, color: "#ea8b00" },
  219. { offset: 1, color: "rgba(168,83,0,0)" },
  220. ],
  221. },
  222. {
  223. type: "linear",
  224. x: 0,
  225. y: 0,
  226. x2: 0,
  227. y2: 1,
  228. colorStops: [
  229. { offset: 0, color: "#696969" },
  230. { offset: 1, color: "rgba(211,211,211,0)" },
  231. ],
  232. },
  233. {
  234. type: "linear",
  235. x: 0,
  236. y: 0,
  237. x2: 0,
  238. y2: 1,
  239. colorStops: [
  240. { offset: 0, color: "#ff5378" },
  241. { offset: 1, color: "rgba(167,17,49,0)" },
  242. ],
  243. },
  244. {
  245. type: "linear",
  246. x: 0,
  247. y: 0,
  248. x2: 0,
  249. y2: 1,
  250. colorStops: [
  251. { offset: 0, color: "#05bb4c" },
  252. { offset: 1, color: "rgba(0,75,11,0)" },
  253. ],
  254. },
  255. ];
  256. let result1 = [
  257. {
  258. type: "linear",
  259. x: 0,
  260. y: 0,
  261. x2: 0,
  262. y2: 1,
  263. colorStops: [
  264. { offset: 0, color: "#DC143C" }, // 设置颜色渐变
  265. { offset: 1, color: "rgba(255,105,180,0)" },
  266. ],
  267. },
  268. {
  269. type: "linear",
  270. x: 0,
  271. y: 0,
  272. x2: 0,
  273. y2: 1,
  274. colorStops: [
  275. { offset: 0, color: "#ea8b00" },
  276. { offset: 1, color: "rgba(168,83,0,0)" },
  277. ],
  278. },
  279. {
  280. type: "linear",
  281. x: 0,
  282. y: 0,
  283. x2: 0,
  284. y2: 1,
  285. colorStops: [
  286. { offset: 0, color: "#696969" },
  287. { offset: 1, color: "rgba(211,211,211,0)" },
  288. ],
  289. },
  290. {
  291. type: "linear",
  292. x: 0,
  293. y: 0,
  294. x2: 0,
  295. y2: 1,
  296. colorStops: [
  297. { offset: 0, color: "#ff5378" },
  298. { offset: 1, color: "rgba(167,17,49,0)" },
  299. ],
  300. },
  301. {
  302. type: "linear",
  303. x: 0,
  304. y: 0,
  305. x2: 0,
  306. y2: 1,
  307. colorStops: [
  308. { offset: 0, color: "#05bb4c" },
  309. { offset: 1, color: "rgba(0,75,11,0)" },
  310. ],
  311. },
  312. ];
  313. return this.colorIndex ? result1 : result;
  314. },
  315. },
  316. methods: {
  317. resize() {
  318. this.initChart();
  319. },
  320. initChart() {
  321. let chart = echarts.init(this.$el);
  322. let option = {
  323. color: this.color,
  324. title: {
  325. text: this.pillarName,
  326. textStyle: {
  327. color: "#999999",
  328. fontSize: 18,
  329. },
  330. },
  331. zoom: 12,
  332. tooltip: {
  333. trigger: "axis",
  334. backgroundColor: "rgba(5, 187, 76,0.35)",
  335. borderWidth: 1,
  336. padding: [10, 10, 3, 10],
  337. borderColor: "#05bb4c",
  338. textStyle: {
  339. color: "#fff",
  340. fontSize: 12,
  341. },
  342. axisPointer: {
  343. type: "shadow",
  344. shadowStyle: {
  345. color: "rgba(105,105,105, .05)",
  346. width: "1",
  347. },
  348. },
  349. },
  350. legend: {
  351. show: this.showLegend,
  352. data: this.legend,
  353. padding: this.padding,
  354. right: 56,
  355. icon: "ract",
  356. itemWidth: 8,
  357. itemHeight: 8,
  358. inactiveColor: partten.getColor("gray"),
  359. textStyle: {
  360. fontSize: 12,
  361. color: partten.getColor("grayl"),
  362. },
  363. },
  364. grid: {
  365. top: 40,
  366. left: 10,
  367. right: 15,
  368. bottom: 10,
  369. containLabel: true,
  370. },
  371. xAxis: [
  372. {
  373. type: "category",
  374. data: this.xdata,
  375. nameLocation: "center",
  376. axisPointer: {
  377. type: "shadow",
  378. },
  379. axisLabel: {
  380. interval: this.interval,
  381. fontSize: 12,
  382. textStyle: {
  383. color: "rgb(116,124,128)",
  384. },
  385. },
  386. },
  387. ],
  388. yAxis: this.ydata,
  389. series: this.series,
  390. };
  391. chart.clear();
  392. chart.setOption(option);
  393. this.resize = function () {
  394. chart.resize();
  395. };
  396. window.addEventListener("resize", this.resize);
  397. },
  398. },
  399. created() {
  400. this.$nextTick(() => {
  401. this.id = "pie-chart-" + util.newGUID();
  402. });
  403. },
  404. mounted() {
  405. this.$nextTick(() => {
  406. // this.$el.style.width = this.width;
  407. // this.$el.style.height = this.height;
  408. this.initChart();
  409. this.firstAnimation = false;
  410. });
  411. },
  412. updated() {
  413. this.$nextTick(() => {
  414. this.initChart();
  415. });
  416. },
  417. unmounted() {
  418. window.removeEventListener("resize", this.resize);
  419. },
  420. watch: {
  421. "$store.state.themeName"() {
  422. this.initChart();
  423. },
  424. },
  425. };
  426. </script>
  427. <style lang="less">
  428. // .chart {
  429. // width: 100%;
  430. // height: 100%;
  431. // display: inline-block;
  432. // }
  433. </style>