widgetPiechart.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <template>
  2. <div :style="styleObj">
  3. <v-chart ref="myVChart" :option="options" autoresize/>
  4. </div>
  5. </template>
  6. <script>
  7. import {
  8. originWidgetLinkageLogic,
  9. targetWidgetLinkageLogic,
  10. } from "@/views/bigscreenDesigner/designer/linkageLogic";
  11. export default {
  12. name: "WidgetPiechart",
  13. components: {},
  14. props: {
  15. value: Object,
  16. ispreview: Boolean,
  17. },
  18. data() {
  19. return {
  20. options: {
  21. title: {
  22. text: "",
  23. left: "center",
  24. textStyle: {
  25. color: "#fff",
  26. },
  27. },
  28. legend: {
  29. orient: "vertical",
  30. left: "left",
  31. textStyle: {
  32. color: "#fff",
  33. },
  34. },
  35. series: [
  36. {
  37. type: "pie",
  38. radius: "50%",
  39. data: [],
  40. emphasis: {
  41. itemStyle: {
  42. shadowBlur: 10,
  43. shadowOffsetX: 0,
  44. shadowColor: "rgba(0, 0, 0, 0.5)",
  45. },
  46. },
  47. },
  48. ],
  49. },
  50. optionsStyle: {}, // 样式
  51. optionsData: {}, // 数据
  52. optionsCollapse: {}, // 图标属性
  53. optionsSetup: {},
  54. flagInter: null,
  55. };
  56. },
  57. computed: {
  58. styleObj() {
  59. return {
  60. position: this.ispreview ? "absolute" : "static",
  61. width: this.optionsStyle.width + "px",
  62. height: this.optionsStyle.height + "px",
  63. left: this.optionsStyle.left + "px",
  64. top: this.optionsStyle.top + "px",
  65. background: this.optionsSetup.background,
  66. };
  67. },
  68. allComponentLinkage() {
  69. return this.$store.state.designer.allComponentLinkage;
  70. },
  71. },
  72. watch: {
  73. value: {
  74. handler(val) {
  75. this.optionsStyle = val.position;
  76. this.optionsData = val.data;
  77. this.optionsCollapse = val.collapse;
  78. this.optionsSetup = val.setup;
  79. this.editorOptions();
  80. },
  81. deep: true,
  82. },
  83. },
  84. created() {
  85. this.optionsStyle = this.value.position;
  86. this.optionsData = this.value.data;
  87. this.optionsCollapse = this.value.collapse;
  88. this.optionsSetup = this.value.setup;
  89. this.editorOptions();
  90. targetWidgetLinkageLogic(this); // 联动-目标组件逻辑
  91. originWidgetLinkageLogic(this); // 联动-源组件逻辑
  92. },
  93. methods: {
  94. // 修改图标options属性
  95. editorOptions() {
  96. this.setOptionsTitle();
  97. this.setOptionsTooltip();
  98. this.setOptionsLegend();
  99. this.setOptionsColor();
  100. this.setOptionsData();
  101. },
  102. // 标题设置
  103. setOptionsTitle() {
  104. const optionsSetup = this.optionsSetup;
  105. const title = {
  106. text: optionsSetup.text,
  107. show: optionsSetup.isShowTitle,
  108. left: optionsSetup.titleLeft,
  109. top: optionsSetup.titleTop + "%",
  110. itemGap: optionsSetup.titleItemGap,
  111. textStyle: {
  112. color: optionsSetup.textColor,
  113. fontSize: optionsSetup.textFontSize,
  114. fontWeight: optionsSetup.textFontWeight,
  115. fontStyle: optionsSetup.textFontStyle,
  116. fontFamily: optionsSetup.textFontFamily,
  117. },
  118. subtext: optionsSetup.subtext,
  119. subtextStyle: {
  120. color: optionsSetup.subtextColor,
  121. fontWeight: optionsSetup.subtextFontWeight,
  122. fontSize: optionsSetup.subtextFontSize,
  123. fontStyle: optionsSetup.subtextFontStyle,
  124. fontFamily: optionsSetup.subtextFontFamily
  125. },
  126. };
  127. this.options.title = title;
  128. },
  129. // 提示语设置 tooltip
  130. setOptionsTooltip() {
  131. const optionsSetup = this.optionsSetup;
  132. const tooltip = {
  133. trigger: "item",
  134. show: optionsSetup.isShowTooltip,
  135. backgroundColor: optionsSetup.tooltipBackgroundColor,
  136. borderColor: optionsSetup.tooltipBorderColor,
  137. borderWidth: optionsSetup.tooltipBorderWidth,
  138. textStyle: {
  139. color: optionsSetup.tooltipColor,
  140. fontSize: optionsSetup.tooltipFontSize,
  141. fontWeight: optionsSetup.tooltipFontWeight,
  142. fontStyle: optionsSetup.tooltipFontStyle,
  143. fontFamily: optionsSetup.tooltipFontFamily,
  144. },
  145. };
  146. this.options.tooltip = tooltip;
  147. },
  148. // 图例操作 legend
  149. setOptionsLegend() {
  150. const optionsSetup = this.optionsSetup;
  151. const legend = {
  152. show: optionsSetup.isShowLegend,
  153. left: optionsSetup.lateralPosition,
  154. //right: optionsSetup.lateralPosition,
  155. top: optionsSetup.longitudinalPosition,
  156. //bottom: optionsSetup.longitudinalPosition,
  157. orient: optionsSetup.layoutFront,
  158. textStyle: {
  159. color: optionsSetup.legendColor,
  160. fontSize: optionsSetup.legendFontSize,
  161. fontWeight: optionsSetup.legendFontWeight,
  162. fontStyle: optionsSetup.legendFontStyle,
  163. fontFamily: optionsSetup.legendFontFamily,
  164. },
  165. itemHeight: optionsSetup.legendHeight,
  166. itemWidth: optionsSetup.legendWidth,
  167. };
  168. this.options.legend = legend;
  169. },
  170. // 图例颜色修改
  171. setOptionsColor() {
  172. const optionsSetup = this.optionsSetup;
  173. const customColor = optionsSetup.customColor;
  174. if (!customColor) return;
  175. const arrColor = [];
  176. for (let i = 0; i < customColor.length; i++) {
  177. arrColor.push(customColor[i].color);
  178. }
  179. this.options.color = arrColor;
  180. this.options = Object.assign({}, this.options);
  181. },
  182. setOptionsData(e, paramsConfig) {
  183. const optionsData = this.optionsData; // 数据类型 静态 or 动态
  184. // 联动接收者逻辑开始
  185. optionsData.dynamicData = optionsData.dynamicData || {}; // 兼容 dynamicData undefined
  186. const myDynamicData = optionsData.dynamicData;
  187. clearInterval(this.flagInter); // 不管咋,先干掉上一次的定时任务,避免多跑
  188. if (
  189. e &&
  190. optionsData.dataType !== "staticData" &&
  191. Object.keys(myDynamicData.contextData).length
  192. ) {
  193. const keyArr = Object.keys(myDynamicData.contextData);
  194. paramsConfig.forEach((conf) => {
  195. if (keyArr.includes(conf.targetKey)) {
  196. myDynamicData.contextData[conf.targetKey] = e[conf.originKey];
  197. }
  198. });
  199. }
  200. // 联动接收者逻辑结束
  201. optionsData.dataType == "staticData"
  202. ? this.staticDataFn(optionsData.staticData)
  203. : this.dynamicDataFn(optionsData.dynamicData, optionsData.refreshTime);
  204. },
  205. staticDataFn(val) {
  206. const staticData = typeof val == "string" ? JSON.parse(val) : val;
  207. const optionsSetup = this.optionsSetup;
  208. const numberValue = optionsSetup.numberValue ? "\n{c}" : "";
  209. const percentage = optionsSetup.percentage ? "\n({d}%)" : "";
  210. const series = {
  211. type: "pie",
  212. center: ["50%", "50%"],
  213. left: optionsSetup.left,
  214. top: optionsSetup.top,
  215. right: optionsSetup.right,
  216. bottom: optionsSetup.bottom,
  217. radius: [optionsSetup.innerNumber + "%", optionsSetup.outerNumber + "%"],
  218. clockwise: optionsSetup.clockwise,
  219. startAngle: optionsSetup.startAngle,
  220. minAngle: optionsSetup.minAngle,
  221. minShowLabelAngle: optionsSetup.minShowLabelAngle,
  222. percentPrecision: optionsSetup.percentPrecision,
  223. // echarts v5.0.0开始支持
  224. itemStyle: {
  225. borderRadius: [optionsSetup.borderRadius + "%", optionsSetup.borderRadius + "%"],
  226. },
  227. // 高亮的扇区
  228. emphasis: {
  229. label: {
  230. show: optionsSetup.isShowEmphasisLabel,
  231. color: optionsSetup.emphasisLabelFontColor == '' ? null : optionsSetup.EmphasisLabelFontColor,
  232. fontSize: optionsSetup.emphasisLabelFontSize,
  233. fontWeight: optionsSetup.emphasisLabelFontWeight,
  234. fontStyle: optionsSetup.emphasisLabelFontStyle,
  235. fontFamily: optionsSetup.emphasisLabelFontFamily,
  236. },
  237. // 视觉引导线
  238. labelLine: {
  239. show: false,
  240. },
  241. // 色块描边
  242. itemStyle: {
  243. borderColor: optionsSetup.borderColor == '' ? "inherit" : optionsSetup.borderColor,
  244. borderWidth: optionsSetup.borderWidth,
  245. borderType: optionsSetup.borderType,
  246. shadowBlur: optionsSetup.shadowBlur,
  247. shadowColor: optionsSetup.shadowColor,
  248. },
  249. },
  250. label: {
  251. show: optionsSetup.isShow,
  252. position: optionsSetup.position,
  253. rotate: optionsSetup.rotate,
  254. formatter: `{b}${numberValue}${percentage}`,
  255. padding: optionsSetup.padding,
  256. fontSize: optionsSetup.fontSize,
  257. color: optionsSetup.fontColor == '' ? "inherit" : optionsSetup.fontColor,
  258. fontWeight: optionsSetup.fontWeight,
  259. fontStyle: optionsSetup.fontStyle,
  260. fontFamily: optionsSetup.fontFamily,
  261. },
  262. labelLine: {
  263. show: optionsSetup.isShowLabelLine,
  264. length: optionsSetup.labelLineLength,
  265. length2: optionsSetup.labelLineLength2,
  266. smooth: optionsSetup.labelLineSmooth,
  267. lineStyle: {
  268. color: optionsSetup.lineStyleColor == '' ? null : optionsSetup.lineStyleColor,
  269. width: optionsSetup.lineStyleWidth,
  270. type: optionsSetup.lineStyleType,
  271. }
  272. },
  273. data: staticData,
  274. };
  275. this.options.series[0] = series
  276. },
  277. dynamicDataFn(val, refreshTime) {
  278. if (!val) return;
  279. if (this.ispreview) {
  280. this.getEchartData(val);
  281. this.flagInter = setInterval(() => {
  282. this.getEchartData(val);
  283. }, refreshTime);
  284. } else {
  285. this.getEchartData(val);
  286. }
  287. },
  288. getEchartData(val) {
  289. const data = this.queryEchartsData(val);
  290. data.then((res) => {
  291. this.renderingFn(res);
  292. });
  293. },
  294. renderingFn(val) {
  295. const optionsSetup = this.optionsSetup;
  296. const numberValue = optionsSetup.numberValue ? "\n{c}" : "";
  297. const percentage = optionsSetup.percentage ? "\n({d}%)" : "";
  298. const series = {
  299. type: "pie",
  300. center: ["50%", "50%"],
  301. left: optionsSetup.left,
  302. top: optionsSetup.top,
  303. right: optionsSetup.right,
  304. bottom: optionsSetup.bottom,
  305. radius: [optionsSetup.innerNumber + "%", optionsSetup.outerNumber + "%"],
  306. clockwise: optionsSetup.clockwise,
  307. startAngle: optionsSetup.startAngle,
  308. minAngle: optionsSetup.minAngle,
  309. minShowLabelAngle: optionsSetup.minShowLabelAngle,
  310. percentPrecision: optionsSetup.percentPrecision,
  311. // echarts v5.0.0开始支持
  312. itemStyle: {
  313. borderRadius: [optionsSetup.borderRadius + "%", optionsSetup.borderRadius + "%"],
  314. },
  315. // 高亮的扇区
  316. emphasis: {
  317. label: {
  318. show: optionsSetup.isShowEmphasisLabel,
  319. color: optionsSetup.emphasisLabelFontColor == '' ? null : optionsSetup.EmphasisLabelFontColor,
  320. fontSize: optionsSetup.emphasisLabelFontSize,
  321. fontWeight: optionsSetup.emphasisLabelFontWeight,
  322. fontStyle: optionsSetup.emphasisLabelFontStyle,
  323. fontFamily: optionsSetup.emphasisLabelFontFamily,
  324. },
  325. // 视觉引导线
  326. labelLine: {
  327. show: false,
  328. },
  329. // 色块描边
  330. itemStyle: {
  331. borderColor: optionsSetup.borderColor == '' ? "inherit" : optionsSetup.borderColor,
  332. borderWidth: optionsSetup.borderWidth,
  333. borderType: optionsSetup.borderType,
  334. shadowBlur: optionsSetup.shadowBlur,
  335. shadowColor: optionsSetup.shadowColor,
  336. },
  337. },
  338. label: {
  339. show: optionsSetup.isShow,
  340. position: optionsSetup.position,
  341. rotate: optionsSetup.rotate,
  342. formatter: `{b}${numberValue}${percentage}`,
  343. padding: optionsSetup.padding,
  344. fontSize: optionsSetup.fontSize,
  345. color: optionsSetup.fontColor == '' ? "inherit" : optionsSetup.fontColor,
  346. fontWeight: optionsSetup.fontWeight,
  347. fontStyle: optionsSetup.fontStyle,
  348. fontFamily: optionsSetup.fontFamily,
  349. },
  350. labelLine: {
  351. show: optionsSetup.isShowLabelLine,
  352. length: optionsSetup.labelLineLength,
  353. length2: optionsSetup.labelLineLength2,
  354. smooth: optionsSetup.labelLineSmooth,
  355. lineStyle: {
  356. color: optionsSetup.lineStyleColor == '' ? null : optionsSetup.lineStyleColor,
  357. width: optionsSetup.lineStyleWidth,
  358. type: optionsSetup.lineStyleType,
  359. }
  360. },
  361. data: val,
  362. };
  363. this.$set(this.options.series, 0, series);
  364. },
  365. },
  366. };
  367. </script>
  368. <style scoped lang="scss">
  369. .echarts {
  370. width: 100%;
  371. height: 100%;
  372. overflow: hidden;
  373. }
  374. </style>