widgetPiechart.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <div :style="styleObj">
  3. <v-chart ref="myVChart" :options="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.setOptionsPie();
  98. this.setOptionsValue();
  99. this.setOptionsTooltip();
  100. this.setOptionsLegend();
  101. this.setOptionsColor();
  102. this.setOptionsData();
  103. },
  104. // 标题设置
  105. setOptionsTitle() {
  106. const optionsSetup = this.optionsSetup;
  107. const title = {
  108. text: optionsSetup.text,
  109. show: optionsSetup.isShowTitle,
  110. left: optionsSetup.titleLeft,
  111. top: optionsSetup.titleTop + "%",
  112. itemGap: optionsSetup.titleItemGap,
  113. textStyle: {
  114. color: optionsSetup.textColor,
  115. fontSize: optionsSetup.textFontSize,
  116. fontWeight: optionsSetup.textFontWeight,
  117. fontStyle: optionsSetup.textFontStyle,
  118. fontFamily: optionsSetup.textFontFamily,
  119. },
  120. subtext: optionsSetup.subtext,
  121. subtextStyle: {
  122. color: optionsSetup.subtextColor,
  123. fontWeight: optionsSetup.subtextFontWeight,
  124. fontSize: optionsSetup.subtextFontSize,
  125. fontStyle: optionsSetup.subtextFontStyle,
  126. fontFamily: optionsSetup.subtextFontFamily
  127. },
  128. };
  129. this.options.title = title;
  130. },
  131. // 饼图设置
  132. setOptionsPie() {
  133. const optionsSetup = this.optionsSetup;
  134. const series = {
  135. type: "pie",
  136. center: ["50%", "50%"],
  137. left: optionsSetup.left,
  138. top: optionsSetup.top,
  139. right: optionsSetup.right,
  140. bottom: optionsSetup.bottom,
  141. radius: [optionsSetup.innerNumber + "%", optionsSetup.outerNumber + "%"],
  142. clockwise: optionsSetup.clockwise,
  143. startAngle: optionsSetup.startAngle,
  144. minAngle: optionsSetup.minAngle,
  145. minShowLabelAngle: optionsSetup.minShowLabelAngle,
  146. percentPrecision: optionsSetup.percentPrecision,
  147. // echarts v5.0.0开始支持
  148. /* itemStyle: {
  149. borderRadius: [optionsSetup.borderRadius + "%", optionsSetup.borderRadius + "%"],
  150. },
  151. */
  152. // 高亮的扇区
  153. emphasis: {
  154. label: {
  155. show: optionsSetup.isShowEmphasisLabel,
  156. color: optionsSetup.emphasisLabelFontColor == '' ? null : optionsSetup.EmphasisLabelFontColor,
  157. fontSize: optionsSetup.emphasisLabelFontSize,
  158. fontWeight: optionsSetup.emphasisLabelFontWeight,
  159. fontStyle: optionsSetup.emphasisLabelFontStyle,
  160. fontFamily: optionsSetup.emphasisLabelFontFamily,
  161. },
  162. // 视觉引导线
  163. labelLine: {
  164. show: false,
  165. },
  166. // 色块描边
  167. itemStyle: {
  168. borderColor: optionsSetup.borderColor == '' ? null : optionsSetup.borderColor,
  169. borderWidth: optionsSetup.borderWidth,
  170. borderType: optionsSetup.borderType,
  171. shadowBlur: optionsSetup.shadowBlur,
  172. shadowColor: optionsSetup.shadowColor,
  173. },
  174. },
  175. };
  176. this.options.series[0] = series;
  177. },
  178. // 数值设定
  179. setOptionsValue() {
  180. const optionsSetup = this.optionsSetup;
  181. const numberValue = optionsSetup.numberValue ? "\n{c}" : "";
  182. const percentage = optionsSetup.percentage ? "\n({d}%)" : "";
  183. const label = {
  184. show: optionsSetup.isShow,
  185. position: optionsSetup.position,
  186. rotate: optionsSetup.rotate,
  187. formatter: `{b}${numberValue}${percentage}`,
  188. padding: optionsSetup.padding,
  189. fontSize: optionsSetup.fontSize,
  190. color: optionsSetup.fontColor == '' ? null : optionsSetup.fontColor,
  191. fontWeight: optionsSetup.fontWeight,
  192. fontStyle: optionsSetup.fontStyle,
  193. fontFamily: optionsSetup.fontFamily,
  194. };
  195. // 引导线
  196. const labelLine = {
  197. show: optionsSetup.isShowLabelLine,
  198. length: optionsSetup.labelLineLength,
  199. length2: optionsSetup.labelLineLength2,
  200. smooth: optionsSetup.labelLineSmooth,
  201. lineStyle: {
  202. color: optionsSetup.lineStyleColor == '' ? null : optionsSetup.lineStyleColor,
  203. width: optionsSetup.lineStyleWidth,
  204. type: optionsSetup.lineStyleType,
  205. }
  206. }
  207. this.options.series[0].label = label;
  208. this.options.series[0].labelLine = labelLine;
  209. },
  210. // 提示语设置 tooltip
  211. setOptionsTooltip() {
  212. const optionsSetup = this.optionsSetup;
  213. const tooltip = {
  214. trigger: "item",
  215. show: optionsSetup.isShowTooltip,
  216. textStyle: {
  217. color: optionsSetup.tooltipColor,
  218. fontSize: optionsSetup.tooltipFontSize,
  219. fontWeight: optionsSetup.tooltipFontWeight,
  220. fontStyle: optionsSetup.tooltipFontStyle,
  221. fontFamily: optionsSetup.tooltipFontFamily,
  222. },
  223. };
  224. this.options.tooltip = tooltip;
  225. },
  226. // 图例操作 legend
  227. setOptionsLegend() {
  228. const optionsSetup = this.optionsSetup;
  229. const legend = {
  230. show: optionsSetup.isShowLegend,
  231. left: optionsSetup.lateralPosition,
  232. //right: optionsSetup.lateralPosition,
  233. top: optionsSetup.longitudinalPosition,
  234. //bottom: optionsSetup.longitudinalPosition,
  235. orient: optionsSetup.layoutFront,
  236. textStyle: {
  237. color: optionsSetup.legendColor,
  238. fontSize: optionsSetup.legendFontSize,
  239. fontWeight: optionsSetup.legendFontWeight,
  240. fontStyle: optionsSetup.legendFontStyle,
  241. fontFamily: optionsSetup.legendFontFamily,
  242. },
  243. itemHeight: optionsSetup.legendHeight,
  244. itemWidth: optionsSetup.legendWidth,
  245. };
  246. this.options.legend = legend;
  247. },
  248. // 图例颜色修改
  249. setOptionsColor() {
  250. const optionsSetup = this.optionsSetup;
  251. const customColor = optionsSetup.customColor;
  252. if (!customColor) return;
  253. const arrColor = [];
  254. for (let i = 0; i < customColor.length; i++) {
  255. arrColor.push(customColor[i].color);
  256. }
  257. this.options.color = arrColor;
  258. this.options = Object.assign({}, this.options);
  259. },
  260. setOptionsData(e, paramsConfig) {
  261. const optionsData = this.optionsData; // 数据类型 静态 or 动态
  262. // 联动接收者逻辑开始
  263. optionsData.dynamicData = optionsData.dynamicData || {}; // 兼容 dynamicData undefined
  264. const myDynamicData = optionsData.dynamicData;
  265. clearInterval(this.flagInter); // 不管咋,先干掉上一次的定时任务,避免多跑
  266. if (
  267. e &&
  268. optionsData.dataType !== "staticData" &&
  269. Object.keys(myDynamicData.contextData).length
  270. ) {
  271. const keyArr = Object.keys(myDynamicData.contextData);
  272. paramsConfig.forEach((conf) => {
  273. if (keyArr.includes(conf.targetKey)) {
  274. myDynamicData.contextData[conf.targetKey] = e[conf.originKey];
  275. }
  276. });
  277. }
  278. // 联动接收者逻辑结束
  279. optionsData.dataType == "staticData"
  280. ? this.staticDataFn(optionsData.staticData)
  281. : this.dynamicDataFn(optionsData.dynamicData, optionsData.refreshTime);
  282. },
  283. staticDataFn(val) {
  284. const staticData = typeof val == "string" ? JSON.parse(val) : val;
  285. for (const key in this.options.series) {
  286. if (this.options.series[key].type == "pie") {
  287. this.options.series[key].data = staticData;
  288. }
  289. }
  290. },
  291. dynamicDataFn(val, refreshTime) {
  292. if (!val) return;
  293. if (this.ispreview) {
  294. this.getEchartData(val);
  295. this.flagInter = setInterval(() => {
  296. this.getEchartData(val);
  297. }, refreshTime);
  298. } else {
  299. this.getEchartData(val);
  300. }
  301. },
  302. getEchartData(val) {
  303. const data = this.queryEchartsData(val);
  304. data.then((res) => {
  305. this.renderingFn(res);
  306. });
  307. },
  308. renderingFn(val) {
  309. for (const key in this.options.series) {
  310. if (this.options.series[key].type == "pie") {
  311. this.options.series[key].data = val;
  312. }
  313. }
  314. },
  315. },
  316. };
  317. </script>
  318. <style scoped lang="scss">
  319. .echarts {
  320. width: 100%;
  321. height: 100%;
  322. overflow: hidden;
  323. }
  324. </style>