widgetPiechart.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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.setOptionsValue();
  98. this.setOptionsTooltip();
  99. this.setOptionsLegend();
  100. this.setOptionsColor();
  101. this.setOptionsData();
  102. this.setOptionsPiechartStyle();
  103. },
  104. // 饼图样式
  105. setOptionsPiechartStyle() {
  106. if (this.optionsSetup.piechartStyle == "shixin") {
  107. this.options.series[0]["radius"] = "50%";
  108. } else if (this.optionsSetup.piechartStyle == "kongxin") {
  109. this.options.series[0]["radius"] = ["40%", "70%"];
  110. } else {
  111. }
  112. },
  113. // 标题设置
  114. setOptionsTitle() {
  115. const optionsSetup = this.optionsSetup;
  116. const title = {};
  117. title.text = optionsSetup.titleText;
  118. title.show = optionsSetup.isNoTitle;
  119. title.left = optionsSetup.textAlign;
  120. title.textStyle = {
  121. color: optionsSetup.textColor,
  122. fontSize: optionsSetup.textFontSize,
  123. fontWeight: optionsSetup.textFontWeight,
  124. fontStyle: optionsSetup.textFontStyle,
  125. };
  126. title.subtext = optionsSetup.subText;
  127. title.subtextStyle = {
  128. color: optionsSetup.subTextColor,
  129. fontWeight: optionsSetup.subTextFontWeight,
  130. fontSize: optionsSetup.subTextFontSize,
  131. fontStyle: optionsSetup.subTextFontStyle,
  132. };
  133. this.options.title = title;
  134. },
  135. // 数值设定
  136. setOptionsValue() {
  137. const optionsSetup = this.optionsSetup;
  138. const series = this.options.series;
  139. const numberValue = optionsSetup.numberValue ? "{c}" : "";
  140. const percentage = optionsSetup.percentage ? "({d})%" : "";
  141. const label = {
  142. show: optionsSetup.isShow,
  143. formatter: `{a|{b}:${numberValue} ${percentage}}`,
  144. rich: {
  145. a: {
  146. padding: [-30, 15, -20, 15],
  147. color: optionsSetup.dataColor,
  148. fontSize: optionsSetup.fontSize,
  149. fontWeight: optionsSetup.fontWeight,
  150. },
  151. },
  152. fontSize: optionsSetup.fontSize,
  153. fontWeight: optionsSetup.optionsSetup,
  154. };
  155. for (const key in series) {
  156. if (series[key].type == "pie") {
  157. series[key].label = label;
  158. series[key].labelLine = { show: optionsSetup.isShow };
  159. }
  160. }
  161. },
  162. // 提示语设置 tooltip
  163. setOptionsTooltip() {
  164. const optionsSetup = this.optionsSetup;
  165. const tooltip = {
  166. trigger: "item",
  167. textStyle: {
  168. color: optionsSetup.tipsColor,
  169. fontSize: optionsSetup.tipsFontSize,
  170. },
  171. };
  172. this.options.tooltip = tooltip;
  173. },
  174. // 图例操作 legend
  175. setOptionsLegend() {
  176. const optionsSetup = this.optionsSetup;
  177. const legend = this.options.legend;
  178. legend.show = optionsSetup.isShowLegend;
  179. legend.left = optionsSetup.lateralPosition;
  180. legend.right = optionsSetup.lateralPosition;
  181. legend.top = optionsSetup.longitudinalPosition;
  182. legend.bottom =
  183. optionsSetup.longitudinalPosition;
  184. legend.orient = optionsSetup.layoutFront;
  185. legend.textStyle = {
  186. color: optionsSetup.legendColor,
  187. fontSize: optionsSetup.legendFontSize,
  188. };
  189. legend.itemWidth = optionsSetup.legendWidth;
  190. },
  191. // 图例颜色修改
  192. setOptionsColor() {
  193. const optionsSetup = this.optionsSetup;
  194. const customColor = optionsSetup.customColor;
  195. if (!customColor) return;
  196. const arrColor = [];
  197. for (let i = 0; i < customColor.length; i++) {
  198. arrColor.push(customColor[i].color);
  199. }
  200. this.options.color = arrColor;
  201. this.options = Object.assign({}, this.options);
  202. },
  203. setOptionsData(e, paramsConfig) {
  204. const optionsData = this.optionsData; // 数据类型 静态 or 动态
  205. // 联动接收者逻辑开始
  206. optionsData.dynamicData = optionsData.dynamicData || {}; // 兼容 dynamicData undefined
  207. const myDynamicData = optionsData.dynamicData;
  208. clearInterval(this.flagInter); // 不管咋,先干掉上一次的定时任务,避免多跑
  209. if (
  210. e &&
  211. optionsData.dataType !== "staticData" &&
  212. Object.keys(myDynamicData.contextData).length
  213. ) {
  214. const keyArr = Object.keys(myDynamicData.contextData);
  215. paramsConfig.forEach((conf) => {
  216. if (keyArr.includes(conf.targetKey)) {
  217. myDynamicData.contextData[conf.targetKey] = e[conf.originKey];
  218. }
  219. });
  220. }
  221. // 联动接收者逻辑结束
  222. optionsData.dataType == "staticData"
  223. ? this.staticDataFn(optionsData.staticData)
  224. : this.dynamicDataFn(optionsData.dynamicData, optionsData.refreshTime);
  225. },
  226. staticDataFn(val) {
  227. const staticData = typeof val == "string" ? JSON.parse(val) : val;
  228. for (const key in this.options.series) {
  229. if (this.options.series[key].type == "pie") {
  230. this.options.series[key].data = staticData;
  231. }
  232. }
  233. },
  234. dynamicDataFn(val, refreshTime) {
  235. if (!val) return;
  236. if (this.ispreview) {
  237. this.getEchartData(val);
  238. this.flagInter = setInterval(() => {
  239. this.getEchartData(val);
  240. }, refreshTime);
  241. } else {
  242. this.getEchartData(val);
  243. }
  244. },
  245. getEchartData(val) {
  246. const data = this.queryEchartsData(val);
  247. data.then((res) => {
  248. this.renderingFn(res);
  249. });
  250. },
  251. renderingFn(val) {
  252. for (const key in this.options.series) {
  253. if (this.options.series[key].type == "pie") {
  254. this.options.series[key].data = val;
  255. }
  256. }
  257. },
  258. },
  259. };
  260. </script>
  261. <style scoped lang="scss">
  262. .echarts {
  263. width: 100%;
  264. height: 100%;
  265. overflow: hidden;
  266. }
  267. </style>