pie-station-top5.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <template>
  2. <div class="chart" :id="id"></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. export default {
  9. name: "pie-chart",
  10. componentName: "pie-chart",
  11. props: {
  12. width: {
  13. type: String,
  14. default: "100%",
  15. },
  16. height: {
  17. type: String,
  18. default: "13.889vh",
  19. },
  20. // 传入数据
  21. list: {
  22. type: Array,
  23. default: () => [{ value: 0, name: "" }],
  24. },
  25. // 颜色
  26. color: {
  27. type: Array,
  28. default: () => [
  29. // "#005bd9",
  30. // "#019f2e",
  31. // "#db6200",
  32. // "#a10f0f",
  33. // "#850894",
  34. // "#9fa0a2",
  35. "#005bd9",
  36. "#019f2e",
  37. "#db6200",
  38. "#d24645",
  39. "#f00bd8",
  40. "#9fa0a2",
  41. ],
  42. },
  43. },
  44. data() {
  45. return {
  46. id: "",
  47. chart: null,
  48. newlist: null,
  49. };
  50. },
  51. watch: {
  52. list: {
  53. handler(newValue, oldValue) {
  54. this.newlist = newValue;
  55. this.$nextTick(() => {
  56. this.newlist = this.list;
  57. this.initChart();
  58. });
  59. },
  60. deep: true,
  61. },
  62. },
  63. computed: {},
  64. methods: {
  65. resize() {},
  66. initChart() {
  67. const chart = echarts.init(this.$el);
  68. let max =
  69. Math.max.apply(
  70. Math,
  71. this.list.map(function (o) {
  72. return o.value;
  73. })
  74. ) || 0;
  75. let index = this.list.findIndex((item) => item.value == max);
  76. let total =
  77. this.list.reduce((a, b) => {
  78. return a + b.value * 1;
  79. }, 0) || 0;
  80. let title = this.list.find((item) => item.value == max)?.name || "";
  81. let option = {
  82. color: this.color,
  83. legend: {
  84. top: 40,
  85. right: 0,
  86. orient: "vertical", //改变排列方式
  87. itemGap: 15, // 设置legend的间距
  88. itemWidth: 10, // 设置宽度
  89. itemHeight: 10, // 设置高度
  90. textStyle: {
  91. fontSize: 15,
  92. color: "#fff",
  93. },
  94. itemStyle: {
  95. borderColor: "transparent",
  96. },
  97. },
  98. title: {
  99. text: `{val|${
  100. max && total ? Number((max / total) * 100).toFixed(2) : 0
  101. }%}\n{name|${title || ""}}`,
  102. top: "43%",
  103. left: "34%",
  104. textAlign: "center",
  105. textStyle: {
  106. rich: {
  107. name: {
  108. fontSize: 15,
  109. fontWeight: "bold",
  110. color: this.color[index],
  111. },
  112. val: {
  113. fontSize: 14,
  114. fontWeight: "bold",
  115. color: this.color[index],
  116. },
  117. },
  118. },
  119. },
  120. series: [
  121. {
  122. radius: ["60%", "65%"],
  123. center: ["35%", "50%"],
  124. type: "pie",
  125. avoidLabelOverlap: false,
  126. hoverAnimation: false,
  127. label: {
  128. position: "center",
  129. normal: {
  130. fontSize: 14,
  131. fontWeight: "bold",
  132. show: true,
  133. padding: [-25, -40, 5, 1],
  134. formatter: (params) => {
  135. return `${params.name}${params.percent}%`;
  136. },
  137. },
  138. },
  139. labelLine: {
  140. lineStyle: {
  141. width: 1,
  142. },
  143. },
  144. itemStyle: {
  145. borderColor: "#000",
  146. },
  147. data: this.list,
  148. },
  149. {
  150. name: "",
  151. type: "pie",
  152. radius: ["30%", "60%"],
  153. center: ["35%", "50%"],
  154. avoidLabelOverlap: false,
  155. hoverAnimation: false,
  156. itemStyle: {
  157. opacity: 0.8,
  158. color: "#35383f",
  159. borderColor: "#000",
  160. },
  161. label: {
  162. show: false,
  163. },
  164. labelLine: {
  165. show: false,
  166. },
  167. data: this.list,
  168. },
  169. ],
  170. };
  171. chart.clear();
  172. chart.setOption(option);
  173. chart.on("mouseover", (event) => {
  174. let name = event.name;
  175. let value = event.percent;
  176. option.title.text = "{val|" + value + "%}\n{name|" + name + "}";
  177. option.animation = false;
  178. option.title.textStyle = {
  179. rich: {
  180. name: {
  181. fontSize: 15,
  182. fontWeight: "bold",
  183. color: this.color[event.dataIndex],
  184. },
  185. val: {
  186. fontSize: 14,
  187. fontWeight: "bold",
  188. color: this.color[event.dataIndex],
  189. },
  190. },
  191. };
  192. chart.setOption(option);
  193. });
  194. chart.on("mouseout", (event) => {
  195. option.animation = false;
  196. option.title = {
  197. text: `{val|${
  198. max && total ? Number((max / total) * 100).toFixed(2) : 0
  199. }%}\n{name|${title || ""}}`,
  200. top: "43%",
  201. left: "34%",
  202. textAlign: "center",
  203. textStyle: {
  204. rich: {
  205. name: {
  206. fontSize: 15,
  207. fontWeight: "bold",
  208. color: this.color[index],
  209. // padding: [10, 10],
  210. },
  211. val: {
  212. fontSize: 14,
  213. fontWeight: "bold",
  214. color: this.color[index],
  215. },
  216. },
  217. },
  218. };
  219. chart.setOption(option);
  220. });
  221. this.resize = function () {
  222. chart.resize();
  223. };
  224. window.addEventListener("resize", this.resize);
  225. },
  226. },
  227. created() {
  228. this.$nextTick(() => {
  229. this.id = "pie-chart-" + util.newGUID();
  230. });
  231. this.newlist = this.list;
  232. },
  233. mounted() {
  234. this.$nextTick(() => {
  235. this.$el.style.width = this.width;
  236. this.$el.style.height = this.height;
  237. this.initChart();
  238. });
  239. },
  240. updated() {
  241. this.$nextTick(() => {
  242. this.initChart();
  243. });
  244. },
  245. unmounted() {
  246. window.removeEventListener("resize", this.resize);
  247. },
  248. };
  249. </script>
  250. <style lang="less">
  251. .chart {
  252. width: 100%;
  253. height: 100%;
  254. display: inline-block;
  255. }
  256. </style>