barCharts.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. "#2999a0",
  62. "#67b9ff",
  63. "#ff6271",
  64. "#05b2fa",
  65. "#0ef167",
  66. "#05bb4c",
  67. "#4b55ae",
  68. "#EDB32F",
  69. "#DB5520",
  70. "#323E6F",
  71. ],
  72. },
  73. showAnimation: {
  74. type: Boolean,
  75. default: true,
  76. },
  77. colorIndex: {
  78. type: Boolean,
  79. default: false,
  80. },
  81. // 柱子最大宽度
  82. barMaxWidth: {
  83. type: Number || String,
  84. default: 0,
  85. },
  86. // 柱子间距
  87. barGap: {
  88. type: Number || String,
  89. default: 0,
  90. },
  91. dataInterval: {
  92. type: String,
  93. default: "D",
  94. },
  95. },
  96. data() {
  97. return {
  98. id: "",
  99. chart: null,
  100. firstAnimation: true,
  101. };
  102. },
  103. computed: {
  104. legend() {
  105. return this.list.map((t) => {
  106. return t.name;
  107. });
  108. },
  109. xdata() {
  110. let result = [];
  111. if (this.list && this.list.length > 0) {
  112. result = this.list[0].date.map((t) => {
  113. if (this.dataInterval === "M") {
  114. return dayjs(t).format("YYYY-MM");
  115. } else if (this.dataInterval === "Y") {
  116. return dayjs(t).format("YYYY");
  117. } else {
  118. return this.xdate ? dayjs(t).format("MM-DD") : t;
  119. }
  120. });
  121. }
  122. return result;
  123. },
  124. ydata() {
  125. let result = [];
  126. this.units.forEach((value, index) => {
  127. let data = null;
  128. if (index == 0) {
  129. data = {
  130. type: "value",
  131. name: value,
  132. nameTextStyle: {
  133. color: "#a6c1dd",
  134. },
  135. axisLabel: {
  136. formatter: "{value} ",
  137. fontSize: 12,
  138. textStyle: {
  139. color: "#a6c1dd",
  140. },
  141. },
  142. //分格线
  143. splitLine: {
  144. lineStyle: {
  145. color: "#a6c1dd",
  146. type: "dashed",
  147. },
  148. },
  149. };
  150. } else {
  151. data = {
  152. type: "value",
  153. name: value,
  154. nameTextStyle: {
  155. color: "#a6c1dd",
  156. },
  157. axisLabel: {
  158. formatter: "{value}",
  159. fontSize: 12,
  160. textStyle: {
  161. color: "#a6c1dd",
  162. },
  163. },
  164. //分格线
  165. splitLine: {
  166. show: false,
  167. },
  168. };
  169. }
  170. result.push(data);
  171. });
  172. return result;
  173. },
  174. series() {
  175. let result = [];
  176. if (this.list && this.list.length > 0) {
  177. this.list.forEach((value, index) => {
  178. let seriesItem = {
  179. name: value.name,
  180. type: "bar",
  181. barWidth: "12",
  182. animation: this.firstAnimation && this.showAnimation,
  183. yAxisIndex: value.yAxisIndex,
  184. itemStyle: {
  185. borderColor: this.color[index],
  186. borderWidth: 1,
  187. // shadowBlur: 1,
  188. // shadowColor: "#16ADD4",
  189. },
  190. data: value.children,
  191. };
  192. result.push(seriesItem);
  193. });
  194. }
  195. return result;
  196. },
  197. },
  198. methods: {
  199. resize() {
  200. this.initChart();
  201. },
  202. initChart() {
  203. let chart = echarts.init(this.$el);
  204. let option = {
  205. color: this.color,
  206. title: {
  207. text: this.pillarName,
  208. textStyle: {
  209. color: "#999999",
  210. fontSize: 18,
  211. },
  212. },
  213. zoom: 12,
  214. tooltip: {
  215. trigger: "axis",
  216. backgroundColor: "rgba(#2169c3, 0.35)",
  217. borderWidth: 1,
  218. padding: [10, 10, 3, 10],
  219. borderColor: "#2169c3",
  220. textStyle: {
  221. color: "#fff",
  222. fontSize: 12,
  223. },
  224. axisPointer: {
  225. type: "shadow",
  226. shadowStyle: {
  227. color: "rgba(105,105,105, .05)",
  228. width: "1",
  229. },
  230. },
  231. formatter: function (params) {
  232. let tooltipText = params[0].axisValueLabel + "<br/>";
  233. params.forEach(function (item) {
  234. // 为每个数据项添加单位,假设数值的单位是'元'
  235. tooltipText +=
  236. item.seriesName + ":" + item.value + " 万kWh<br/>";
  237. });
  238. return tooltipText;
  239. },
  240. },
  241. legend: {
  242. show: this.showLegend,
  243. data: this.legend,
  244. padding: this.padding,
  245. right: 56,
  246. icon: "ract",
  247. itemWidth: 8,
  248. itemHeight: 8,
  249. inactiveColor: partten.getColor("gray"),
  250. textStyle: {
  251. fontSize: 12,
  252. color: partten.getColor("grayl"),
  253. },
  254. },
  255. grid: {
  256. top: 40,
  257. left: 10,
  258. right: 15,
  259. bottom: 10,
  260. containLabel: true,
  261. },
  262. xAxis: [
  263. {
  264. type: "category",
  265. data: this.xdata,
  266. nameLocation: "center",
  267. axisPointer: {
  268. type: "shadow",
  269. },
  270. axisLabel: {
  271. interval: this.interval,
  272. fontSize: 12,
  273. textStyle: {
  274. color: "#a6c1dd",
  275. },
  276. },
  277. },
  278. ],
  279. yAxis: this.ydata,
  280. series: this.series,
  281. };
  282. chart.clear();
  283. chart.setOption(option);
  284. this.resize = function () {
  285. chart.resize();
  286. };
  287. window.addEventListener("resize", this.resize);
  288. },
  289. },
  290. created() {
  291. this.$nextTick(() => {
  292. this.id = "pie-chart-" + util.newGUID();
  293. });
  294. },
  295. mounted() {
  296. this.$nextTick(() => {
  297. // this.$el.style.width = this.width;
  298. // this.$el.style.height = this.height;
  299. this.initChart();
  300. this.firstAnimation = false;
  301. });
  302. },
  303. updated() {
  304. this.$nextTick(() => {
  305. this.initChart();
  306. });
  307. },
  308. unmounted() {
  309. window.removeEventListener("resize", this.resize);
  310. },
  311. watch: {
  312. "$store.state.themeName"() {
  313. this.initChart();
  314. },
  315. },
  316. };
  317. </script>
  318. <style lang="less">
  319. // .chart {
  320. // width: 100%;
  321. // height: 100%;
  322. // display: inline-block;
  323. // }
  324. </style>