forecastBarComponent.vue 9.1 KB

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