list-bar-chart2.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <template>
  2. <div>
  3. <div
  4. class="chart"
  5. v-for="index of list.length"
  6. :key="index"
  7. :id="id + index"
  8. ></div>
  9. </div>
  10. </template>
  11. <script>
  12. import util from "@/helper/util.js";
  13. import partten from "@/helper/partten.js";
  14. import * as echarts from "echarts";
  15. export default {
  16. name: "percent-pie",
  17. componentName: "percent-pie",
  18. props: {
  19. width: {
  20. type: String,
  21. default: "100%",
  22. },
  23. height: {
  24. type: String,
  25. default: "18.519vh",
  26. },
  27. // 传入数据
  28. list: {
  29. type: Array,
  30. default: () => [
  31. {
  32. name: "当日预测电量",
  33. value: 103.62,
  34. total: 200,
  35. },
  36. {
  37. name: "实际发电量",
  38. value: 98.62,
  39. total: 100,
  40. },
  41. {
  42. name: "当月预测电量",
  43. value: 113.27,
  44. total: 100,
  45. },
  46. {
  47. name: "实际发电量",
  48. value: 136.72,
  49. total: 100,
  50. },
  51. ],
  52. },
  53. total: {
  54. type: Number,
  55. default: 150,
  56. },
  57. colors: {
  58. type: Array,
  59. default: () => ["green", "purple"],
  60. },
  61. },
  62. data() {
  63. return {
  64. id: "",
  65. chart: null,
  66. firstAnimation: true,
  67. };
  68. },
  69. created() {
  70. console.log("this.list", this.list);
  71. },
  72. computed: {
  73. datas() {
  74. return this.list.map((t) => {
  75. return t.value;
  76. });
  77. },
  78. },
  79. methods: {
  80. resize() {},
  81. initChart(value, index) {
  82. var currColor = this.colors[index % 2];
  83. var $dom = document.getElementById(this.id + (index + 1));
  84. $dom.style.width = this.width;
  85. $dom.style.height = `calc(${this.height} / ${this.list.length} - 4px)`;
  86. let chart = echarts.init($dom);
  87. let option = {
  88. xAxis: {
  89. max: value.total,
  90. splitLine: {
  91. show: false,
  92. },
  93. axisLine: {
  94. show: false,
  95. },
  96. axisLabel: {
  97. show: false,
  98. },
  99. axisTick: {
  100. show: false,
  101. },
  102. },
  103. grid: {
  104. left: 16,
  105. top: 16, // 设置条形图的边s距
  106. right: 110,
  107. bottom: 0,
  108. containLabel: true,
  109. },
  110. yAxis: [
  111. {
  112. type: "category",
  113. inverse: true,
  114. data: [value],
  115. axisLine: {
  116. show: false,
  117. },
  118. axisTick: {
  119. show: false,
  120. },
  121. axisLabel: {
  122. show: false,
  123. },
  124. },
  125. ],
  126. series: [
  127. // 内
  128. {
  129. type: "bar",
  130. barWidth: 6,
  131. animation: this.firstAnimation,
  132. // legendHoverLink: false,
  133. // silent: true,
  134. itemStyle: {
  135. normal: {
  136. color: function (params) {
  137. return {
  138. type: "linear",
  139. x: 0,
  140. y: 0,
  141. x2: 1,
  142. y2: 0,
  143. colorStops: [
  144. {
  145. offset: 0,
  146. color: partten.getColor(currColor), // 0% 处的颜色
  147. },
  148. {
  149. offset: 1,
  150. color: partten.getColor(currColor), // 100% 处的颜色
  151. },
  152. ],
  153. };
  154. },
  155. shadowBlur: 10,
  156. shadowColor: "rgba(255, 255, 255, 0.30)",
  157. },
  158. },
  159. label: {
  160. normal: {
  161. show: true,
  162. position: [0, util.vh("-20")],
  163. formatter: function (param) {
  164. return param.data.name;
  165. },
  166. textStyle: {
  167. color:
  168. this.$store.state.themeName === "dark" ? "#7a8385" : "#000",
  169. fontSize: 12,
  170. },
  171. },
  172. },
  173. data: [value],
  174. z: 1,
  175. animationEasing: "elasticOut",
  176. },
  177. // 三角
  178. {
  179. type: "pictorialBar",
  180. symbolPosition: "end",
  181. animation: this.firstAnimation,
  182. data: [value],
  183. symbol: "triangle",
  184. symbolOffset: [0, -10],
  185. symbolSize: [5, 5],
  186. symbolRotate: 180,
  187. itemStyle: {
  188. normal: {
  189. borderWidth: 0,
  190. color: function (params) {
  191. return partten.getColor(currColor);
  192. },
  193. // shadowBlur: 2,
  194. // shadowColor: "rgba(255, 255, 255, 0.80)",
  195. },
  196. },
  197. },
  198. // 分隔
  199. {
  200. type: "pictorialBar",
  201. itemStyle: {
  202. normal: {
  203. color:
  204. this.$store.state.themeName === "dark" ? "#20314f" : "#000",
  205. },
  206. },
  207. animation: this.firstAnimation,
  208. symbolRepeat: "fixed",
  209. symbolMargin: 4,
  210. symbol: "rect",
  211. symbolClip: true,
  212. symbolSize: [1, 8],
  213. symbolPosition: "start",
  214. symbolOffset: [8, -1],
  215. symbolBoundingData: value.total,
  216. symbolRotate: -15,
  217. data: [value],
  218. z: 2,
  219. animationEasing: "elasticOut",
  220. },
  221. // 外边框
  222. {
  223. type: "pictorialBar",
  224. animation: this.firstAnimation,
  225. symbol: "rect",
  226. symbolBoundingData: value.total,
  227. itemStyle: {
  228. normal: {
  229. color: "none",
  230. },
  231. },
  232. label: {
  233. normal: {
  234. formatter: (params) => {
  235. return "{gm|}{f| " + params.data + "}";
  236. },
  237. rich: {
  238. f: {
  239. color:
  240. this.$store.state.themeName === "dark" ? "#fff" : "#000",
  241. fontSize: 14,
  242. lineHeight: 20,
  243. fontFamily: "Bicubik",
  244. },
  245. gm: {
  246. backgroundColor: partten.getColor(currColor),
  247. width: 4,
  248. height: 4,
  249. lineHeight: 20,
  250. verticalAlign: "middle",
  251. borderRadius: [50, 50, 50, 50],
  252. },
  253. },
  254. position: "right",
  255. distance: 8, // 向右偏移位置
  256. show: true,
  257. },
  258. },
  259. data: [value.value],
  260. },
  261. // 外框
  262. {
  263. type: "bar",
  264. animation: this.firstAnimation,
  265. name: "外框",
  266. barGap: "-120%", // 设置外框粗细
  267. data: [
  268. {
  269. value: value.total,
  270. itemStyle: {
  271. normal: {
  272. color: "transparent",
  273. borderColor: partten.getColor(currColor), // [, "#333"],
  274. borderWidth: 1, // 边框宽度
  275. // barBorderRadius: 0, //圆角半径
  276. opacity: 0.5,
  277. label: {
  278. // 标签显示位置
  279. show: false,
  280. position: "top", // insideTop 或者横向的 insideLeft
  281. },
  282. },
  283. },
  284. },
  285. ],
  286. barWidth: 9,
  287. },
  288. ],
  289. };
  290. chart.clear();
  291. chart.setOption(option);
  292. this.resize = function () {
  293. chart.resize();
  294. };
  295. window.removeEventListener("resize", this.resize);
  296. window.addEventListener("resize", this.resize);
  297. },
  298. },
  299. created() {
  300. this.id = "pie-chart-" + util.newGUID();
  301. },
  302. mounted() {
  303. this.$nextTick(() => {
  304. this.$el.style.width = this.width;
  305. this.$el.style.height = this.height;
  306. this.list.forEach((value, index) => {
  307. this.initChart(value, index);
  308. });
  309. this.firstAnimation = false;
  310. });
  311. },
  312. updated() {
  313. this.$nextTick(() => {
  314. this.list.forEach((value, index) => {
  315. this.initChart(value, index);
  316. });
  317. });
  318. },
  319. unmounted() {
  320. window.removeEventListener("resize", this.resize);
  321. },
  322. watch: {
  323. "$store.state.themeName"() {
  324. this.list.forEach((value, index) => {
  325. this.initChart(value, index);
  326. });
  327. },
  328. },
  329. };
  330. </script>
  331. <style lang="less">
  332. .chart {
  333. width: 100%;
  334. height: 100%;
  335. display: inline-block;
  336. cursor: default;
  337. }
  338. </style>