widgetLinechart.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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: "WidgetLinechart",
  13. components: {},
  14. props: {
  15. value: Object,
  16. ispreview: Boolean,
  17. widgetIndex: {
  18. type: Number,
  19. default: 0,
  20. }, // 当前组件,在工作区变量widgetInWorkbench中的索引
  21. },
  22. data() {
  23. return {
  24. options: {
  25. grid: {},
  26. color: [],
  27. title: {
  28. text: "",
  29. textStyle: {
  30. color: "#fff",
  31. },
  32. },
  33. tooltip: {
  34. trigger: "item",
  35. formatter: "{a} <br/>{b} : {c}%",
  36. },
  37. legend: {
  38. textStyle: {
  39. color: "#fff",
  40. },
  41. },
  42. xAxis: {
  43. type: "category",
  44. data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  45. axisLabel: {
  46. show: true,
  47. textStyle: {
  48. color: "#fff",
  49. },
  50. },
  51. },
  52. yAxis: {
  53. type: "value",
  54. axisLabel: {
  55. show: true,
  56. textStyle: {
  57. color: "#fff",
  58. },
  59. },
  60. },
  61. series: [
  62. {
  63. data: [],
  64. type: "line",
  65. },
  66. ],
  67. },
  68. optionsStyle: {}, // 样式
  69. optionsData: {}, // 数据
  70. optionsCollapse: {}, // 图标属性
  71. optionsSetup: {},
  72. };
  73. },
  74. computed: {
  75. styleObj() {
  76. return {
  77. position: this.ispreview ? "absolute" : "static",
  78. width: this.optionsStyle.width + "px",
  79. height: this.optionsStyle.height + "px",
  80. left: this.optionsStyle.left + "px",
  81. top: this.optionsStyle.top + "px",
  82. background: this.optionsSetup.background,
  83. };
  84. },
  85. allComponentLinkage() {
  86. return this.$store.state.designer.allComponentLinkage;
  87. },
  88. },
  89. watch: {
  90. value: {
  91. handler(val) {
  92. this.optionsStyle = val.position;
  93. this.optionsData = val.data;
  94. this.optionsCollapse = val.collapse;
  95. this.optionsSetup = val.setup;
  96. this.editorOptions();
  97. },
  98. deep: true,
  99. },
  100. },
  101. mounted() {
  102. this.optionsStyle = this.value.position;
  103. this.optionsData = this.value.data;
  104. this.optionsCollapse = this.value.collapse;
  105. this.optionsSetup = this.value.setup;
  106. this.editorOptions();
  107. targetWidgetLinkageLogic(this); // 联动-目标组件逻辑
  108. originWidgetLinkageLogic(this); // 联动-源组件逻辑
  109. },
  110. methods: {
  111. // 修改图标options属性
  112. editorOptions() {
  113. this.setOptionsTitle();
  114. this.setOptionsX();
  115. this.setOptionsY();
  116. this.setOptionsTop();
  117. this.setOptionsTooltip();
  118. this.setOptionsData();
  119. this.setOptionsMargin();
  120. this.setOptionsColor();
  121. },
  122. // 标题修改
  123. setOptionsTitle() {
  124. const optionsSetup = this.optionsSetup;
  125. const title = {};
  126. title.text = optionsSetup.titleText;
  127. title.show = optionsSetup.isNoTitle;
  128. title.left = optionsSetup.textAlign;
  129. title.textStyle = {
  130. color: optionsSetup.textColor,
  131. fontSize: optionsSetup.textFontSize,
  132. fontWeight: optionsSetup.textFontWeight,
  133. fontStyle: optionsSetup.textFontStyle,
  134. };
  135. title.subtext = optionsSetup.subText;
  136. title.subtextStyle = {
  137. color: optionsSetup.subTextColor,
  138. fontWeight: optionsSetup.subTextFontWeight,
  139. fontSize: optionsSetup.subTextFontSize,
  140. fontStyle: optionsSetup.subTextFontStyle,
  141. };
  142. this.options.title = title;
  143. },
  144. // X轴设置
  145. setOptionsX() {
  146. const optionsSetup = this.optionsSetup;
  147. const xAxis = {
  148. type: "category",
  149. // 坐标轴是否显示
  150. show: optionsSetup.hideX,
  151. // 坐标轴名称
  152. name: optionsSetup.nameX,
  153. nameTextStyle: {
  154. color: optionsSetup.nameColorX,
  155. fontSize: optionsSetup.nameFontSizeX,
  156. },
  157. // 轴反转
  158. inverse: optionsSetup.reversalX,
  159. axisLabel: {
  160. show: true,
  161. // 文字间隔
  162. interval: optionsSetup.textInterval,
  163. // 文字角度
  164. rotate: optionsSetup.textAngleX,
  165. textStyle: {
  166. // 坐标文字颜色
  167. color: optionsSetup.colorX,
  168. fontSize: optionsSetup.fontSizeX,
  169. },
  170. },
  171. axisLine: {
  172. show: true,
  173. lineStyle: {
  174. color: optionsSetup.lineColorX,
  175. width: optionsSetup.lineWidthX,
  176. },
  177. },
  178. splitLine: {
  179. show: optionsSetup.isShowSplitLineX,
  180. lineStyle: {
  181. color: optionsSetup.splitLineColorX,
  182. width: optionsSetup.splitLineWidthX,
  183. },
  184. },
  185. };
  186. this.options.xAxis = xAxis;
  187. },
  188. // Y轴设置
  189. setOptionsY() {
  190. const optionsSetup = this.optionsSetup;
  191. const yAxis = {
  192. type: "value",
  193. scale: optionsSetup.scale,
  194. // 均分
  195. splitNumber: optionsSetup.splitNumberY,
  196. // 坐标轴是否显示
  197. show: optionsSetup.isShowY,
  198. // 坐标轴名称
  199. name: optionsSetup.textNameY,
  200. nameTextStyle: {
  201. color: optionsSetup.nameColorY,
  202. fontSize: optionsSetup.nameFontSizeY,
  203. },
  204. // 轴反转
  205. inverse: optionsSetup.reversalY,
  206. axisLabel: {
  207. show: true,
  208. // 文字角度
  209. rotate: optionsSetup.textAngleY,
  210. textStyle: {
  211. // 坐标文字颜色
  212. color: optionsSetup.colorY,
  213. fontSize: optionsSetup.fontSizeY,
  214. },
  215. },
  216. axisLine: {
  217. show: true,
  218. lineStyle: {
  219. color: optionsSetup.lineColorY,
  220. width: optionsSetup.lineWidthY,
  221. },
  222. },
  223. splitLine: {
  224. show: optionsSetup.isShowSplitLineY,
  225. lineStyle: {
  226. color: optionsSetup.splitLineColorY,
  227. width: optionsSetup.splitLineWidthY,
  228. },
  229. },
  230. };
  231. this.options.yAxis = yAxis;
  232. },
  233. // 折线设置
  234. setOptionsTop() {
  235. const optionsSetup = this.optionsSetup;
  236. const series = this.options.series;
  237. for (const key in series) {
  238. if (series[key].type == "line") {
  239. series[key].symbol = optionsSetup.symbol;
  240. series[key].showSymbol = optionsSetup.markPoint;
  241. series[key].symbolSize = optionsSetup.pointSize;
  242. series[key].smooth = optionsSetup.smoothCurve;
  243. if (optionsSetup.area) {
  244. series[key].areaStyle = {
  245. opacity: optionsSetup.areaThickness / 100,
  246. };
  247. } else {
  248. series[key].areaStyle = {
  249. opacity: 0,
  250. };
  251. }
  252. series[key].lineStyle = {
  253. width: optionsSetup.lineWidth,
  254. };
  255. series[key].label = {
  256. show: optionsSetup.isShow,
  257. position: "top",
  258. distance: 10,
  259. fontSize: optionsSetup.fontSize,
  260. color: optionsSetup.subTextColor,
  261. fontWeight: optionsSetup.fontWeight,
  262. };
  263. }
  264. }
  265. this.options.series = series;
  266. },
  267. // tooltip 设置
  268. setOptionsTooltip() {
  269. const optionsSetup = this.optionsSetup;
  270. const tooltip = {
  271. trigger: "item",
  272. show: true,
  273. textStyle: {
  274. color: optionsSetup.tipsColor,
  275. fontSize: optionsSetup.tipsFontSize,
  276. },
  277. };
  278. this.options.tooltip = tooltip;
  279. },
  280. // 边距设置
  281. setOptionsMargin() {
  282. const optionsSetup = this.optionsSetup;
  283. const grid = {
  284. left: optionsSetup.marginLeft,
  285. right: optionsSetup.marginRight,
  286. bottom: optionsSetup.marginBottom,
  287. top: optionsSetup.marginTop,
  288. containLabel: true,
  289. };
  290. this.options.grid = grid;
  291. },
  292. // 图例颜色修改
  293. setOptionsColor() {
  294. const optionsSetup = this.optionsSetup;
  295. const customColor = optionsSetup.customColor;
  296. if (!customColor) return;
  297. const arrColor = [];
  298. for (let i = 0; i < customColor.length; i++) {
  299. arrColor.push(customColor[i].color);
  300. }
  301. this.options.color = arrColor;
  302. this.options = Object.assign({}, this.options);
  303. },
  304. // 处理数据
  305. setOptionsData(e, paramsConfig) {
  306. const optionsData = this.optionsData; // 数据类型 静态 or 动态
  307. optionsData.dynamicData = optionsData.dynamicData || {}; // 兼容 dynamicData undefined
  308. const myDynamicData = optionsData.dynamicData;
  309. clearInterval(this.flagInter); // 不管咋,先干掉上一次的定时任务,避免多跑
  310. if (
  311. e &&
  312. optionsData.dataType !== "staticData" &&
  313. Object.keys(myDynamicData.contextData).length
  314. ) {
  315. const keyArr = Object.keys(myDynamicData.contextData);
  316. paramsConfig.forEach((conf) => {
  317. if (keyArr.includes(conf.targetKey)) {
  318. myDynamicData.contextData[conf.targetKey] = e[conf.originKey];
  319. }
  320. });
  321. }
  322. optionsData.dataType == "staticData"
  323. ? this.staticDataFn(optionsData.staticData)
  324. : this.dynamicDataFn(optionsData.dynamicData, optionsData.refreshTime);
  325. },
  326. staticDataFn(val) {
  327. const series = this.options.series;
  328. let axis = [];
  329. let data = [];
  330. for (const i in val) {
  331. axis[i] = val[i].axis;
  332. data[i] = val[i].data;
  333. }
  334. // x轴
  335. this.options.xAxis.data = axis;
  336. // series
  337. for (const i in series) {
  338. if (series[i].type == "line") {
  339. series[i].data = data;
  340. }
  341. }
  342. },
  343. dynamicDataFn(val, refreshTime) {
  344. if (!val) return;
  345. if (this.ispreview) {
  346. this.getEchartData(val);
  347. this.flagInter = setInterval(() => {
  348. this.getEchartData(val);
  349. }, refreshTime);
  350. } else {
  351. this.getEchartData(val);
  352. }
  353. },
  354. getEchartData(val) {
  355. const data = this.queryEchartsData(val);
  356. data.then((res) => {
  357. this.renderingFn(res);
  358. });
  359. },
  360. renderingFn(val) {
  361. // x轴
  362. this.options.xAxis.data = val.xAxis;
  363. // series
  364. const series = this.options.series;
  365. for (const i in series) {
  366. if (series[i].type == "line") {
  367. series[i].data = val.series[i].data;
  368. }
  369. }
  370. },
  371. },
  372. };
  373. </script>
  374. <style scoped lang="scss">
  375. .echarts {
  376. width: 100%;
  377. height: 100%;
  378. overflow: hidden;
  379. }
  380. </style>