物管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

436 lines
44 KiB

  1. const e="0677d751-8a3b-40d8-ba76-02fef3a5ee62",t="custom-gauge-chart",a="仪表图",n='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1695020298267" class="icon" viewBox="0 0 1286 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6072" xmlns:xlink="http://www.w3.org/1999/xlink" width="251.171875" height="200"><path d="M792.260975 437.207122a56.22205 56.22205 0 0 0-29.32832 8.153046l-2.09488-3.453721-141.319474 141.772421c-1.981643 0.113237-4.076523 0.056618-5.888311 0.169855-48.012385 0-87.135685 39.010063-87.192303 87.022448 0 48.069004 39.1233 87.192303 87.192303 87.192304s87.192303-39.1233 87.135685-86.343028a45.464558 45.464558 0 0 0 0.283092-6.228022l131.467876-131.128165a56.618379 56.618379 0 0 0 16.645803-40.255668 56.278669 56.278669 0 0 0-16.702422-40.199049 56.505142 56.505142 0 0 0-40.199049-16.702421z" fill="#4DA1FF" p-id="6073"></path><path d="M1164.979763 284.733827C970.21254-3.623576 577.337609-79.775296 288.866969 114.822072 0.566184 309.532677-75.642154 702.520845 119.068451 991.048104c9.625124 13.814884 25.081942 22.36426 41.784363 23.156916l0.905894 0.396329h2.491209a53.900697 53.900697 0 0 0 46.540307-80.171624l-1.981643-3.566958a519.303771 519.303771 0 0 1-88.834236-259.708504l57.920601-0.056618c28.139334-1.981643 50.843304-24.742232 52.881566-52.881566a57.184563 57.184563 0 0 0-53.617605-60.921376h-52.994802a520.492757 520.492757 0 0 1 93.420325-227.152936l30.913635 30.857017c21.231892 18.457592 53.334513 18.570828 74.679642 0.33971 23.892956-20.439235 26.723875-56.618379 5.718456-81.190755l-33.857791-34.197501a526.154595 526.154595 0 0 1 289.999337-128.863431l-0.056619 1.641933 0.056619 72.811236c1.981643 28.252571 24.79885 51.013159 53.051421 53.051421a55.54263 55.54263 0 0 0 41.444653-13.871503 57.184563 57.184563 0 0 0 19.589959-39.915957V119.125069l-0.056618-1.472078a524.682517 524.682517 0 0 1 287.904456 126.881787l-36.292381 36.292381c-18.51421 21.684839-18.400973 53.051421 0.283092 74.566405a56.844852 56.844852 0 0 0 81.134137 5.208891l32.442331-32.102621a517.831693 517.831693 0 0 1 95.401969 228.681632l-55.655867 0.056619a57.354418 57.354418 0 0 0-52.881566 52.881566 56.901471 56.901471 0 0 0 53.617605 60.921375h59.789008a519.303771 519.303771 0 0 1-86.116554 255.405507 53.730842 53.730842 0 0 0 54.919827 81.360611 53.504368 53.504368 0 0 0 34.93354-22.307642 629.143426 629.143426 0 0 0-3.566958-700.765675z" fill="#4DA1FF" p-id="6074"></path></svg>',i="svg",l="动态",o="图表组件",u=!1,c=!0,d="时序",s=`{"type":"page","id":"u:270584784ce1","name":"page1","asideResizor":false,"style":{"boxShadow":" 0px 0px 0px 0px transparent"},"pullRefresh":{"disabled":true},"body":[{"type":"tabs","name":"tab","tabs":[{"title":"样式","icon":"fa fa-th-large","body":[{"type":"form","title":"","name":"basicPropForm","body":[{"type":"input-text","label":"名称","name":"nodeAlias","id":"u:6b126f0520cb","size":"full","mode":"horizontal","inputControlClassName":"w-100","className":"m-b"},{"type":"input-text","label":"ID&nbsp;&nbsp;&nbsp;&nbsp;","name":"id","id":"u:6232710ac003","size":"full","mode":"horizontal","inputControlClassName":"w-100","className":"m-b"},{"type":"grid","id":"u:c605398a724c","className":"m-b","columns":[{"body":[{"type":"input-number","label":"宽度","name":"width","keyboard":true,"id":"u:dcc0c21d16f6","step":1,"suffix":"px","placeholder":"组件左边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:14cc19d6ffb0","md":6},{"body":[{"type":"input-number","label":"高度","name":"height","keyboard":true,"id":"u:cd6fdff9ca88","step":1,"suffix":"px","placeholder":"组件上边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:4931801ca9b8","md":6}]},{"type":"grid","id":"u:da449a94908a","className":"m-b","columns":[{"body":[{"type":"input-number","label":"X 轴",
  2. "nodes": [
  3. {
  4. "id": "f7ceb814-b019-489f-8678-7ec0e3a11dec",
  5. "type": "custom-gauge-chart",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "f7ceb814-b019-489f-8678-7ec0e3a11dec",
  15. "width": 500,
  16. "height": 500,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "grid": {
  22. "show": false,
  23. "left": "20",
  24. "top": "20",
  25. "right": "20",
  26. "bottom": "20"
  27. },
  28. "range": {
  29. "startAngle": 180,
  30. "endAngle": 0,
  31. "min": 0,
  32. "splitNumber": 6,
  33. "max": 240
  34. },
  35. "progress": {
  36. "show": true,
  37. "roundCap": true,
  38. "width": 18
  39. },
  40. "pointer": {
  41. "show": true,
  42. "width": 12,
  43. "length": "75%",
  44. "icon": "path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z"
  45. },
  46. "axisLine": {
  47. "show": true,
  48. "roundCap": true,
  49. "lineStyle": {
  50. "color": [
  51. {
  52. "ratio": "0.3",
  53. "color": "#67e0e3"
  54. },
  55. {
  56. "ratio": "0.7",
  57. "color": "#37a2da"
  58. },
  59. {
  60. "ratio": "1",
  61. "color": "#fd666d"
  62. }
  63. ],
  64. "width": 18
  65. }
  66. },
  67. "axisTick": {
  68. "show": true,
  69. "splitNumber": 2,
  70. "lineStyle": {
  71. "color": "#999"
  72. }
  73. },
  74. "splitLine": {
  75. "show": true,
  76. "length": 13,
  77. "lineStyle": {
  78. "width": 3,
  79. "color": "#999"
  80. }
  81. },
  82. "axisLabel": {
  83. "show": true,
  84. "distance": 30,
  85. "fontSize": 20,
  86. "color": "#999"
  87. },
  88. "title": {
  89. "show": true,
  90. "color": "#50e3c2",
  91. "fontSize": 16
  92. },
  93. "codeConfig": "return option;",
  94. "showDefaultValue": false,
  95. "showUnit": false,
  96. "nodeAlias": "仪表图",
  97. "fontSize": 0,
  98. "itemStyle": {
  99. "color": "#7ed321"
  100. },
  101. "value": {
  102. "color": "#50e3c2",
  103. "fontSize": 14
  104. },
  105. "unit": {
  106. "color": "#50e3c2",
  107. "fontSize": 12
  108. },
  109. "valueConfig": {
  110. "color": "#50e3c2",
  111. "fontSize": 14
  112. },
  113. "dynamic": {
  114. "normalData": {
  115. "dataPoint": "",
  116. "compareType": "",
  117. "conditionVariables": [],
  118. "defaultValue": "",
  119. "unit": "kWh"
  120. }
  121. }
  122. }
  123. }
  124. ]
  125. }`,javascript:`const { createApp, createVNode, render } = Vue;
  126. const app = createApp({})
  127. const defaultValue = 100
  128. const GaugeChart = {
  129. template: '<div :id="chartId" :style="getStyle"></div>',
  130. props: {
  131. chartId: {
  132. type: String,
  133. default: ''
  134. },
  135. currentData: {
  136. type: Number,
  137. default: 100
  138. },
  139. width: {
  140. type: Number,
  141. default: 350
  142. },
  143. height: {
  144. type: Number,
  145. default: 150
  146. },
  147. chartProps: {
  148. type: Object,
  149. default: () => { }
  150. },
  151. thingName: {
  152. type: String,
  153. default: ''
  154. },
  155. attr: {
  156. type: String,
  157. default: ''
  158. },
  159. unit: {
  160. type: String,
  161. default: ''
  162. },
  163. },
  164. computed: {
  165. getStyle() {
  166. return {
  167. width: \`\${this.width}px\`,
  168. height: \`\${this.height}px\`
  169. }
  170. }
  171. },
  172. setup(props) {
  173. const { onMounted, nextTick, toRefs, watch } = Vue;
  174. const { chartProps, currentData, thingName, attr, width, height } = toRefs(props);
  175. let myChart = null;
  176. const initChart = (data, pros) => {
  177. // 基于准备好的dom,初始化echarts实例
  178. const dom = document.getElementById(props.chartId);
  179. if (dom) {
  180. if(!myChart) {
  181. myChart = echarts.init(dom);
  182. }
  183. // 由于实时推送时候不会重复创建实例,但是需更新画布大小。
  184. myChart.resize({
  185. width: width.value,
  186. height: height.value,
  187. })
  188. if (data) {
  189. const { grid, codeConfig, range, progress, pointer, axisLine, axisTick, splitLine, axisLabel, itemStyle, title, valueConfig, unit } = pros;
  190. // 指定图表的配置项和数据
  191. // 轴线底色拼装
  192. // 发现图表一直渲染的情况。就要注意图表数据多层对象嵌套的引用问题。
  193. const newAxisLine = window._.cloneDeep(axisLine);
  194. const Colors = []
  195. const oldColor = newAxisLine.lineStyle.color
  196. if (oldColor && oldColor.length > 0) {
  197. oldColor.forEach((item) => {
  198. Colors.push([item.ratio, item.color])
  199. })
  200. newAxisLine.lineStyle.color = Colors;
  201. } else if(oldColor && oldColor.length === 0) {
  202. delete newAxisLine.lineStyle.color
  203. }
  204. var option = {
  205. grid,
  206. tooltip: {
  207. formatter: '{a} <br/>{b} : {c}%'
  208. },
  209. series: [
  210. {
  211. name: thingName.value,
  212. title,
  213. type: 'gauge',
  214. ...range,
  215. progress,
  216. pointer,
  217. axisLine: newAxisLine,
  218. axisTick,
  219. splitLine,
  220. axisLabel,
  221. itemStyle,
  222. detail: {
  223. backgroundColor: 'transparent',
  224. borderColor: '#999',
  225. borderWidth: 0,
  226. width: '100%',
  227. lineHeight: 16,
  228. height: 16,
  229. borderRadius: 8,
  230. offsetCenter: [0, '35%'],
  231. valueAnimation: false,
  232. formatter: function (value) {
  233. return '{value|' + value.toFixed(2) + '}{unit|' + props.unit + '}';
  234. },
  235. rich: {
  236. value: {
  237. fontSize: valueConfig.fontSize,
  238. fontWeight: 'bolder',
  239. color: valueConfig.color,
  240. },
  241. unit: {
  242. fontSize: unit.fontSize,
  243. color: unit.color,
  244. padding: [0, 0, 0, 10]
  245. }
  246. }
  247. },
  248. data: [
  249. {
  250. value: data,
  251. name: attr.value
  252. }
  253. ]
  254. }
  255. ]
  256. };
  257. const func = new Function('option', 'datas', codeConfig);
  258. const opt = func(window._.cloneDeep(option), data);
  259. // console.log('opt', opt);
  260. // 使用刚指定的配置项和数据显示图表。
  261. myChart.setOption(opt);
  262. }
  263. }
  264. }
  265. watch([currentData, chartProps, width, height], ([val, pros]) => {
  266. if (val) {
  267. nextTick(() => {
  268. initChart(val, pros)
  269. })
  270. }
  271. }, {
  272. immediate: true,
  273. deep: true,
  274. })
  275. }
  276. }
  277. class CustomGaugeChartNode extends HtmlResize.view {
  278. realValue = defaultValue
  279. oldProperties = {}
  280. chartRendered = false
  281. instance = null
  282. setHtml(rootEl) {
  283. if (!rootEl) return;
  284. const { properties, width, height } = this.props.model;
  285. const { normalData } = properties.dynamic || {}
  286. let thingName = 'pressure';
  287. let attr = 'score';
  288. if(normalData && normalData.dataPoint) {
  289. const dataPointStrParsed = JSON.parse(normalData.dataPoint || '{}')
  290. const { deviceCode, dataPoint } = dataPointStrParsed;
  291. thingName = deviceCode;
  292. attr = dataPoint.split(',')[0];
  293. }
  294. if(this.instance) {
  295. // 实时数据不能推送一次就创建一次图表,可以在原有实例基础之上更改数据。
  296. Object.assign(this.instance.component.props,{
  297. name: properties.nodeAlias,
  298. chartId: \`gauge-\${properties.id}\`,
  299. currentData: this.realValue,
  300. width,
  301. height,
  302. chartProps: properties,
  303. thingName,
  304. attr,
  305. unit: normalData.unit || 'km/h'
  306. })
  307. return
  308. }
  309. const el = document.createElement('div');
  310. rootEl.innerHTML = '';
  311. const instance = createVNode(GaugeChart, {
  312. name: properties.nodeAlias,
  313. chartId: \`gauge-\${properties.id}\`,
  314. currentData: this.realValue,
  315. width,
  316. height,
  317. chartProps: properties,
  318. thingName,
  319. attr,
  320. unit: normalData.unit || 'km/h'
  321. })
  322. instance.appContext = app._context
  323. render(instance, el)
  324. rootEl.appendChild(el);
  325. this.instance = instance;
  326. }
  327. sameProps(properties) {
  328. const isSame = window._.isEqual(this.oldProperties, properties);
  329. if (isSame) return true;
  330. this.oldProperties = properties;
  331. return false
  332. }
  333. // 生命周期 支持重写内容, 但格式需一致
  334. shouldUpdate() {
  335. const { properties } = this.props.model;
  336. const { normalData } = properties.dynamic || {};
  337. if (normalData && !normalData.dataPoint && !normalData.defaultValue) {
  338. this.realValue = defaultValue;
  339. return true
  340. }
  341. if (normalData) {
  342. const { defaultValue } = normalData || {}
  343. if (defaultValue) {
  344. const realValue = window.resolveScadaNewValue(defaultValue)
  345. if(this.realValue !== Number(realValue)) {
  346. this.realValue = Number(realValue);
  347. return true;
  348. }
  349. }
  350. }
  351. const propertiesBack = window._.cloneDeep(properties);
  352. if (propertiesBack.dynamic.normalData) {
  353. const isSameProps = this.sameProps(propertiesBack);
  354. if (isSameProps && this.chartRendered) {
  355. return false
  356. } else {
  357. if (!this.chartRendered) {
  358. this.chartRendered = true
  359. return true
  360. }
  361. if(!isSameProps) {
  362. return true;
  363. }
  364. }
  365. }
  366. }
  367. updateHtml() {
  368. this.setHtml(this.rootEl);
  369. }
  370. componentDidMount() {
  371. if (this.shouldUpdate()) {
  372. this.setHtml(this.rootEl);
  373. }
  374. // 防止拖动时候频繁渲染图表
  375. this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
  376. }
  377. componentDidUpdate() {
  378. if (this.shouldUpdate()) {
  379. this.updateHtmlDebounced();
  380. }
  381. }
  382. }
  383. class CustomGaugeChartModel extends HtmlResize.model {
  384. initNodeData(data) {
  385. // 自定义组件,需最开始重置一下text 。
  386. data.text = {
  387. value: "",
  388. x: data.x,
  389. y: data.y,
  390. };
  391. super.initNodeData(data);
  392. const { properties } = this;
  393. this.width = properties.width || 80;
  394. this.height = properties.height || 35;
  395. this.text.editable = false; // 不允许文本被编辑
  396. }
  397. setAttributes() {
  398. // 自定义组件需重置 text
  399. const { x, y, properties } = this;
  400. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  401. this.text = {
  402. ...this.text,
  403. x: x + textHorizontalMove,
  404. y: y + textVerticalMove,
  405. value: "",
  406. }
  407. }
  408. }
  409. lf.register({
  410. type: 'custom-gauge-chart',
  411. view: CustomGaugeChartNode,
  412. model: CustomGaugeChartModel,
  413. })`,css:"",fakeData:""},p={id:e,name:t,aliasName:a,image:n,imageType:i,groupName:l,groupType:o,isRemote:!1,isDefault:!0,sectionType:d,config:s,files:r};export{a as aliasName,s as config,p as default,r as files,l as groupName,o as groupType,e as id,n as image,i as imageType,c as isDefault,u as isRemote,t as name,d as sectionType};