widgetScaleVertical.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <template>
  2. <div :style="styleObj">
  3. <v-chart ref="myVChart" :options="options" autoresize/>
  4. </div>
  5. </template>
  6. <script>
  7. import echarts from "echarts";
  8. import {targetWidgetLinkageLogic} from "@/views/bigscreenDesigner/designer/linkageLogic";
  9. let scale = [];
  10. let max;
  11. let min;
  12. // 竖刻度尺
  13. export default {
  14. name: "widgetScaleVertical",
  15. components: {},
  16. props: {
  17. value: Object,
  18. ispreview: Boolean,
  19. },
  20. data() {
  21. return {
  22. options: {
  23. yAxis: [
  24. {
  25. // 对底部高度有影响
  26. show: true,
  27. data: [],
  28. min: 0,
  29. max: max,
  30. axisLine: {
  31. show: false
  32. }
  33. },
  34. {
  35. show: false,
  36. min: 0,
  37. max: max,
  38. },
  39. {
  40. type: 'category',
  41. position: 'left',
  42. offset: -5,
  43. axisLabel: {
  44. fontSize: 10,
  45. color: 'white'
  46. },
  47. axisLine: {
  48. show: false
  49. },
  50. axisTick: {
  51. show: false
  52. },
  53. }
  54. ],
  55. xAxis: [
  56. // 宽度
  57. {
  58. show: false,
  59. min: -10,
  60. max: 10,
  61. data: []
  62. },
  63. {
  64. show: false,
  65. min: -10,
  66. max: 10,
  67. data: []
  68. },
  69. {
  70. show: false,
  71. min: -10,
  72. max: 10,
  73. data: []
  74. },
  75. { // 刻度位置
  76. show: false,
  77. min: -3,
  78. max: 10,
  79. splitLine: {
  80. lineStyle: {
  81. color: 'rgba(56, 128, 138,1)',
  82. }
  83. }
  84. }
  85. ],
  86. series: [
  87. {
  88. name: "值",
  89. type: "bar",
  90. barWidth: 35,
  91. xAxisIndex: 0,
  92. itemStyle: {
  93. normal: {
  94. color: "#0C2F6F",
  95. barBorderRadius: 50,
  96. }
  97. },
  98. z: 2,
  99. data: [
  100. {
  101. label: {
  102. normal: {
  103. show: true,
  104. position: "top",
  105. backgroundColor: {},
  106. width: 10,
  107. height: 50,
  108. rich: {
  109. back: {
  110. align: 'center',
  111. lineHeight: 50,
  112. fontSize: 16,
  113. fontFamily: 'digifacewide',
  114. },
  115. }
  116. }
  117. }
  118. }
  119. ],
  120. },
  121. {
  122. name: '白框',
  123. type: 'bar',
  124. xAxisIndex: 1,
  125. barGap: '-100%',
  126. data: [max - 1],
  127. barWidth: 35,
  128. itemStyle: {
  129. normal: {
  130. color: '#0C2F6F',
  131. barBorderRadius: 50,
  132. }
  133. },
  134. z: 1
  135. },
  136. {
  137. name: '外框',
  138. type: 'bar',
  139. xAxisIndex: 2,
  140. barGap: '-100%',
  141. data: [max],
  142. barWidth: 45,
  143. itemStyle: {
  144. normal: {
  145. color: 'rgba(56, 128, 138,1)',
  146. barBorderRadius: 50,
  147. }
  148. },
  149. z: 0
  150. },
  151. {
  152. name: '刻度',
  153. type: 'bar',
  154. yAxisIndex: 0,
  155. xAxisIndex: 3,
  156. label: {
  157. normal: {
  158. show: true,
  159. position: 'left',
  160. distance: 10,
  161. color: 'rgba(56, 128, 138,1)',
  162. fontSize: 16,
  163. fontWeight: 'normal',
  164. formatter: function (params) {
  165. if (params.dataIndex % 10 === 0) {
  166. return params.dataIndex;
  167. } else if (params.dataIndex == max) {
  168. return params.dataIndex;
  169. } else {
  170. return ""
  171. }
  172. }
  173. }
  174. },
  175. barGap: '-40%',
  176. data: scale,
  177. barWidth: 2,
  178. itemStyle: {
  179. normal: {
  180. color: 'rgba(56, 128, 138,1)',
  181. }
  182. },
  183. z: 0
  184. }
  185. ],
  186. },
  187. optionsStyle: {}, // 样式
  188. optionsData: {}, // 数据
  189. optionsCollapse: {}, // 图标属性
  190. optionsSetup: {},
  191. flagInter: null,
  192. };
  193. },
  194. computed: {
  195. styleObj() {
  196. return {
  197. position: this.ispreview ? "absolute" : "static",
  198. width: this.optionsStyle.width + "px",
  199. height: this.optionsStyle.height + "px",
  200. left: this.optionsStyle.left + "px",
  201. top: this.optionsStyle.top + "px",
  202. background: this.optionsSetup.background,
  203. };
  204. },
  205. allComponentLinkage() {
  206. return this.$store.state.designer.allComponentLinkage;
  207. },
  208. },
  209. watch: {
  210. value: {
  211. handler(val) {
  212. this.optionsStyle = val.position;
  213. this.optionsData = val.data;
  214. this.optionsCollapse = val.collapse;
  215. this.optionsSetup = val.setup;
  216. this.editorOptions();
  217. },
  218. deep: true,
  219. },
  220. },
  221. created() {
  222. this.optionsStyle = this.value.position;
  223. this.optionsData = this.value.data;
  224. this.optionsCollapse = this.value.collapse;
  225. this.optionsSetup = this.value.setup;
  226. this.editorOptions();
  227. targetWidgetLinkageLogic(this); // 联动-目标组件逻辑
  228. },
  229. methods: {
  230. // 修改图标options属性
  231. editorOptions() {
  232. this.setOptionsTitle();
  233. this.setOptionsMaxScale();
  234. this.setOptionsYAxis();
  235. this.setOptionsScale();
  236. this.setOptionsOutBar();
  237. this.setOptionsMargin();
  238. this.setOptionsData();
  239. this.setOptionsInBar();
  240. },
  241. // 标题设置
  242. setOptionsTitle() {
  243. const optionsSetup = this.optionsSetup;
  244. const title = {};
  245. title.text = optionsSetup.titleText;
  246. title.show = optionsSetup.isNoTitle;
  247. title.left = optionsSetup.textAlign;
  248. title.textStyle = {
  249. color: optionsSetup.textColor,
  250. fontSize: optionsSetup.textFontSize,
  251. fontWeight: optionsSetup.textFontWeight,
  252. fontStyle: optionsSetup.textFontStyle,
  253. };
  254. title.subtext = optionsSetup.subText;
  255. title.subtextStyle = {
  256. color: optionsSetup.subTextColor,
  257. fontWeight: optionsSetup.subTextFontWeight,
  258. fontSize: optionsSetup.subTextFontSize,
  259. fontStyle: optionsSetup.subTextFontStyle,
  260. };
  261. this.options.title = title;
  262. },
  263. // 最大刻度设置
  264. setOptionsMaxScale() {
  265. const optionsSetup = this.optionsSetup;
  266. max = optionsSetup.maxScale;
  267. scale = this.setScale(max);
  268. },
  269. setScale(max) {
  270. let scale = [];
  271. for (let i = 0; i <= max; i++) {
  272. if (i <= 0 || i >= max) {
  273. scale.push('-2')
  274. } else {
  275. if ((i - 10) % 20 === 0) {
  276. scale.push('-2');
  277. } else if ((i - 10) % 4 === 0) {
  278. scale.push('-1');
  279. } else {
  280. scale.push('');
  281. }
  282. }
  283. }
  284. return scale;
  285. },
  286. setOptionsYAxis() {
  287. this.options.yAxis[0].max = max;
  288. this.options.yAxis[1].max = max;
  289. },
  290. // 刻度设定
  291. setOptionsScale() {
  292. const optionsSetup = this.optionsSetup;
  293. const series = this.options.series[3];
  294. // 刻度
  295. // 显示
  296. if (optionsSetup.isShowScale) {
  297. series.data = scale;
  298. }else {
  299. series.data = 0;
  300. }
  301. series.barWidth = optionsSetup.scaleBarWidth;
  302. series.itemStyle = {
  303. normal: {
  304. color: optionsSetup.scaleColor,
  305. }
  306. };
  307. //刻度值
  308. series.label = {
  309. normal: {
  310. show: true,
  311. position: 'left',
  312. distance: 10,
  313. fontSize: optionsSetup.scaleFontSize,
  314. color: optionsSetup.scaleDataColor,
  315. fontWeight: optionsSetup.scaleFontWeight,
  316. formatter: function (params) {
  317. if (params.dataIndex % 10 === 0) {
  318. return params.dataIndex;
  319. } else if (params.dataIndex == max) {
  320. return params.dataIndex;
  321. } else {
  322. return ""
  323. }
  324. }
  325. }
  326. };
  327. },
  328. // 外框设置
  329. setOptionsOutBar() {
  330. const optionsSetup = this.optionsSetup;
  331. const series = this.options.series[2];
  332. series.barWidth = optionsSetup.outBarWidth;
  333. series.itemStyle = {
  334. normal: {
  335. color: optionsSetup.outBarColor,
  336. barBorderRadius: optionsSetup.outBarRadius,
  337. }
  338. };
  339. series.data = [max];
  340. },
  341. // 内框设置
  342. setOptionsInBar() {
  343. const optionsSetup = this.optionsSetup;
  344. const series = this.options.series[1];
  345. series.barWidth = optionsSetup.inBarWidth;
  346. series.itemStyle = {
  347. normal: {
  348. color: optionsSetup.inBarColor,
  349. barBorderRadius: optionsSetup.inBarRadius,
  350. }
  351. };
  352. series.data = [max - 1];
  353. },
  354. // 渐变色设置
  355. setOptionsColor(inputValue, inputMax) {
  356. const optionsSetup = this.optionsSetup;
  357. let gradient = [];
  358. if (inputValue > (inputMax * 0.7)) {
  359. gradient.push(
  360. {
  361. offset: 0,
  362. color: optionsSetup.bar0Color,
  363. },
  364. {
  365. offset: 0.3,
  366. color: optionsSetup.bar30Color,
  367. },
  368. {
  369. offset: 0.7,
  370. color: optionsSetup.bar70Color,
  371. },
  372. {
  373. offset: 1,
  374. color: optionsSetup.bar100Color,
  375. })
  376. } else if (inputValue > (inputMax * 0.3)) {
  377. gradient.push(
  378. {
  379. offset: 0,
  380. color: optionsSetup.bar0Color,
  381. },
  382. {
  383. offset: 0.5,
  384. color: optionsSetup.bar30Color,
  385. },
  386. {
  387. offset: 1,
  388. color: optionsSetup.bar70Color,
  389. })
  390. } else {
  391. gradient.push(
  392. {
  393. offset: 0,
  394. color: optionsSetup.bar0Color,
  395. },
  396. {
  397. offset: 1,
  398. color: optionsSetup.bar30Color,
  399. })
  400. }
  401. return gradient;
  402. },
  403. setShowValue(inputValue, inputMax) {
  404. let showValue = inputValue;
  405. if (inputValue > inputMax) {
  406. showValue = inputMax
  407. } else {
  408. if (inputValue < 0) {
  409. showValue = 0
  410. } else {
  411. showValue = inputValue
  412. }
  413. }
  414. return showValue;
  415. },
  416. // 提示语设置 tooltip
  417. setOptionsTooltip() {
  418. const optionsSetup = this.optionsSetup;
  419. const tooltip = {
  420. trigger: "item",
  421. show: true,
  422. textStyle: {
  423. color: optionsSetup.lineColor,
  424. fontSize: optionsSetup.tipFontSize,
  425. },
  426. };
  427. this.options.tooltip = tooltip;
  428. },
  429. // 边距设置
  430. setOptionsMargin() {
  431. const optionsSetup = this.optionsSetup;
  432. const grid = {
  433. left: optionsSetup.marginLeft,
  434. right: optionsSetup.marginRight,
  435. bottom: optionsSetup.marginBottom,
  436. top: optionsSetup.marginTop,
  437. containLabel: true,
  438. };
  439. this.options.grid = grid;
  440. },
  441. setOptionsData(e, paramsConfig) {
  442. const optionsData = this.optionsData; // 数据类型 静态 or 动态
  443. optionsData.dynamicData = optionsData.dynamicData || {}; // 兼容 dynamicData undefined
  444. const myDynamicData = optionsData.dynamicData;
  445. clearInterval(this.flagInter); // 不管咋,先干掉上一次的定时任务,避免多跑
  446. if (
  447. e &&
  448. optionsData.dataType !== "staticData" &&
  449. Object.keys(myDynamicData.contextData).length
  450. ) {
  451. const keyArr = Object.keys(myDynamicData.contextData);
  452. paramsConfig.forEach((conf) => {
  453. if (keyArr.includes(conf.targetKey)) {
  454. myDynamicData.contextData[conf.targetKey] = e[conf.originKey];
  455. }
  456. });
  457. }
  458. optionsData.dataType == "staticData"
  459. ? this.staticDataFn(optionsData.staticData)
  460. : this.dynamicDataFn(optionsData.dynamicData, optionsData.refreshTime);
  461. },
  462. // 静态数据
  463. staticDataFn(val) {
  464. const optionsSetup = this.optionsSetup;
  465. const num = val[0]["num"];
  466. // 渐变色
  467. const gradient = this.setOptionsColor(num, optionsSetup.maxScale);
  468. // 数值设定
  469. const series = this.options.series[0];
  470. const data = {
  471. value: this.setShowValue(num, optionsSetup.maxScale),
  472. label: {
  473. normal: {
  474. show: optionsSetup.isShow,
  475. position: "top",
  476. distance: optionsSetup.fontDistance,
  477. width: 10,
  478. height: 50,
  479. formatter: '{back| ' + num + ' }',
  480. rich: {
  481. back: {
  482. align: 'center',
  483. lineHeight: 50,
  484. fontSize: optionsSetup.fontSize,
  485. fontWeight: optionsSetup.fontWeight,
  486. color: gradient[gradient.length - 1].color,
  487. },
  488. }
  489. }
  490. }
  491. }
  492. series.barWidth = optionsSetup.inBarWidth;
  493. series.itemStyle = {
  494. normal: {
  495. color: new echarts.graphic.LinearGradient(0, 1, 0, 0, gradient),
  496. barBorderRadius: optionsSetup.inBarRadius,
  497. }
  498. };
  499. series.data[0] = data;
  500. },
  501. dynamicDataFn(val, refreshTime) {
  502. if (!val) return;
  503. if (this.ispreview) {
  504. this.getEchartData(val);
  505. this.flagInter = setInterval(() => {
  506. this.getEchartData(val);
  507. }, refreshTime);
  508. } else {
  509. this.getEchartData(val);
  510. }
  511. },
  512. getEchartData(val) {
  513. const data = this.queryEchartsData(val);
  514. data.then((res) => {
  515. this.renderingFn(res);
  516. });
  517. },
  518. renderingFn(val) {
  519. const optionsSetup = this.optionsSetup;
  520. const num = val[0].value;
  521. // 渐变色
  522. const gradient = this.setOptionsColor(num, optionsSetup.maxScale);
  523. // 数值设定
  524. const series = this.options.series[0];
  525. const data = {
  526. value: this.setShowValue(num, optionsSetup.maxScale),
  527. label: {
  528. normal: {
  529. show: optionsSetup.isShow,
  530. position: "top",
  531. distance: optionsSetup.fontDistance,
  532. width: 10,
  533. height: 50,
  534. formatter: '{back| ' + num + ' }',
  535. rich: {
  536. back: {
  537. align: 'center',
  538. lineHeight: 50,
  539. fontSize: optionsSetup.fontSize,
  540. fontWeight: optionsSetup.fontWeight,
  541. color: gradient[gradient.length - 1].color,
  542. },
  543. }
  544. }
  545. }
  546. }
  547. series.barWidth = optionsSetup.inBarWidth;
  548. series.itemStyle = {
  549. normal: {
  550. color: new echarts.graphic.LinearGradient(0, 1, 0, 0, gradient),
  551. barBorderRadius: optionsSetup.inBarRadius,
  552. }
  553. };
  554. series.data[0] = data;
  555. },
  556. },
  557. };
  558. </script>
  559. <style scoped lang="scss">
  560. .echarts {
  561. width: 100%;
  562. height: 100%;
  563. overflow: hidden;
  564. }
  565. </style>