物管理前端
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.

379 lines
228 KiB

  1. const A="e24f1054-4026-4619-8e92-25546f819766",e="custom-simple-waterfill-node",E="简单球形水位",i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABGIAAANGCAYAAAC2qSgxAAAAAXNSR0IArs4c6QAAIABJREFUeF7svWuQLGd55/nPNzPr2tW3o25dOCBxJCShY6yrwQaB2R1mMNhzWbDYuRhjx06E1/Z+2NgNz34EfduwYzf2wxrWETNhYzyXtQw7FxuZGWaXi7h5kJAACUnAQYKDjtSt07fqrltmvrnxvJlv9VvZVdVV3X1K5/JvRUdVV2VWZf7e7Fb37zzP//HADxIgARIgARIgARIgARIgARIgARIgARIggZkQ8GbyLnwTEiABEiABEiABEiABEiABEiABEiABEiABUMTwIiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJUMTwGiABEiABEiABEiABEiABEiABEiABEiCBGRGgiJkRaL4NCZAACZAACZAACZAACZAACZAACZAACVDE8BogARIgARIgARIgARIgARIgARIgARIggRkRoIiZEWi+DQmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQxPAaIAESIAESIAESIAESIAESIAESIAESIIEZEaCImRFovg0JkAAJkAAJXN0E0mvkdwovvbrXkWdHAiRAAiRAAiRwqQlcI780XWqMfH0SIAESIAESuNoIHFOsXC264ti/KVHcXG3fGTwfEiABEiABEjgugWP/enHcA+D+JEACJEACJEACsyQwpWCZRKg8jIl+n/jYR492nk8/Mtnr21c/+xAmOeoDB/Oxhyc8vo9O8PoTEXHfj8JmQvrcjARIgARIgASueAJT/5pwxZ8xT4AESIAESIAErnoCh8iWaTTFGMlSFCtjhclDh0Nf/8J0wuXwVxzcYuXdEwiUR0a/alHwjBU3k8ga+1aH/jZGSTPtWnN7EiABEiABEricCRz6v/7L+eB5bCRAAiRAAiRAAkUCIyTMMPkyRLKMqloZkCyOVJlEnjQbkwuWdnX0tmcPWeynxzxfbU8gYfL9G83Dtx2QOo68GVWNM1TaDJM1I38zo4zh9zoJkAAJkAAJXC0EKGKulpXkeZAACZAACVxjBCYQLgXRMkyyTCNYhgmVojixsmS3NJl8aZ8vbHfLwWXsXpjsteye5RuHiJQXBl+3evpw2SJ7zPWy7YqSZ5jYGSZwphE2B2SNK2ooaK6x72+eLgmQAAmQwNVMgCLmal5dnhsJkAAJkMAVTGCCLJcxVS4j24byapZiJUtRsriCZZRcMRIlFycDsuT1GfbeK/sC5aab9peiuz5erPSC6cTLYYtcisdLl/LK/vMvvbT/aqXr88d/sv9YX/K8ABRlzjBpUxQ2RVnTFzV5Vc3I9qepqmdcIqykOez64PMkQAIkQAIkMGsCFDGzJs73IwESIAESIIEBAkfIcxlR6VKsbplEtgyTLP0qlVsAI1gcsWKFiitTrDiJ/EGBEjtfLwOItp3nl/YhxDvO44vZ43GzIGMWJrxstge3Cxq5TNnafzyYd8TM5v7j4QLSDWf3IBkUOGH+tSt2rMQRgeOKGyNs8iocV9i4smYiSTOk7Wls5Yw9/kN/w6OgmfCK4mYkQAIkQAIkcOIEDv3f9Im/I1+QBEiABEiABK5pAhO0FLl8HOniVrn0pcuQChdb3WKrWkS2uK1CtpLFShZbuSKSpShYXLkiYqUvVJaAvkBZzMXJApDsZgJlXmSK2pcpiXP
  2. "nodes": [
  3. {
  4. "id": "bc7326fa-edd9-4888-84b4-a4b0da8a5f21",
  5. "type": "custom-simple-waterfill-node",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "bc7326fa-edd9-4888-84b4-a4b0da8a5f21",
  15. "width": 200,
  16. "height": 200,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "outline": {
  22. "show": true,
  23. "borderDistance": 3,
  24. "itemStyle": {
  25. "borderColor": "rgba(54, 115, 233, 1)",
  26. "borderWidth": 8,
  27. "shadowColor": "rgba(63, 218, 255, 0.5)",
  28. "shadowBlur": 10
  29. }
  30. },
  31. "codeConfig": "return option;",
  32. "showDefaultValue": false,
  33. "showUnit": false,
  34. "valueColor": "rgba(245, 166, 35, 1)",
  35. "fontSize": 12,
  36. "nodeAlias": "简单球形水位",
  37. "Waves": [
  38. {
  39. "color": "rgba(13, 25, 148, 1)"
  40. },
  41. {
  42. "color": "rgba(27, 58, 222, 1)"
  43. },
  44. {
  45. "color": "rgba(37, 90, 233, 1)"
  46. }
  47. ],
  48. "waterFillShape": "circle",
  49. "backgroundStyle": {
  50. "color": "rgba(255, 0, 255, 0.01)"
  51. },
  52. "maxValue": 1000,
  53. "valueDecimal": 3,
  54. "dynamic": {
  55. "normalData": {
  56. "dataPoint": "",
  57. "compareType": "",
  58. "conditionVariables": [],
  59. "defaultValue": "",
  60. "unit": ""
  61. },
  62. "eventsData": {
  63. "eventCombo": [
  64. {
  65. "eventType": "click",
  66. "enable": false,
  67. "config": ""
  68. },
  69. {
  70. "eventType": "dblClick",
  71. "enable": false,
  72. "config": ""
  73. }
  74. ]
  75. },
  76. "uiData": {
  77. "dataPoint": "",
  78. "compareType": "",
  79. "conditionVariables": []
  80. },
  81. "animationData": {
  82. "animationCombo": [
  83. {
  84. "dataPoint": "",
  85. "min": "",
  86. "max": "",
  87. "animationName": "旋转"
  88. }
  89. ]
  90. },
  91. "hiddenData": {
  92. "hiddenCombo": [
  93. {
  94. "dataPoint": "",
  95. "min": "",
  96. "max": "",
  97. "showOrHiddenName": "隐藏"
  98. }
  99. ]
  100. }
  101. }
  102. }
  103. }
  104. ]
  105. }`,javascript:`const { createApp, createVNode, render } = Vue;
  106. const app = createApp({})
  107. const defaultVal = 623
  108. const SimpleWaterFill = {
  109. template: '<div :id="chartId" :style="getStyle"></div>',
  110. props: {
  111. chartId: {
  112. type: String,
  113. default: ''
  114. },
  115. currentData: {
  116. type: Number,
  117. default: 100
  118. },
  119. width: {
  120. type: Number,
  121. default: 350
  122. },
  123. height: {
  124. type: Number,
  125. default: 150
  126. },
  127. chartProps: {
  128. type: Object,
  129. default: () => { }
  130. },
  131. thingName: {
  132. type: String,
  133. default: ''
  134. },
  135. attr: {
  136. type: String,
  137. default: ''
  138. },
  139. unit: {
  140. type: String,
  141. default: ''
  142. },
  143. },
  144. computed: {
  145. getStyle() {
  146. return {
  147. width: \`\${this.width}px\`,
  148. height: \`\${this.height}px\`
  149. }
  150. }
  151. },
  152. setup(props) {
  153. const { onMounted, nextTick, toRefs, watch } = Vue;
  154. const { chartProps, currentData, thingName, attr, width, height } = toRefs(props);
  155. let myChart = null;
  156. const initChart = (data, pros) => {
  157. // 基于准备好的dom,初始化echarts实例
  158. const dom = document.getElementById(props.chartId);
  159. if (dom) {
  160. if (!myChart) {
  161. myChart = echarts.init(dom);
  162. }
  163. // 由于实时推送时候不会重复创建实例,但是需更新画布大小。
  164. myChart.resize({
  165. width: width.value,
  166. height: height.value,
  167. })
  168. if (data != null) {
  169. const { codeConfig, Waves, waterFillShape, backgroundStyle, outline, maxValue, valueDecimal } = pros;
  170. // 指定图表的配置项和数据
  171. const ratioVal = (+data / maxValue).toFixed(valueDecimal);
  172. const totalColor = Waves.map(i => i.color);
  173. const totalDatas = totalColor.map( () => +ratioVal)
  174. var option = {
  175. series: [
  176. {
  177. type: "liquidFill",
  178. data: totalDatas,
  179. shape: waterFillShape,
  180. direction: "right", //波浪方向或者静止
  181. radius: "80%",
  182. // 水球颜色
  183. color: totalColor,
  184. center: ["50%", "50%"], //水球位置
  185. // outline 外边
  186. outline,
  187. backgroundStyle,
  188. label: {
  189. show: true,
  190. normal: {
  191. textStyle: {
  192. fontSize: 20 //设置不起作用
  193. }
  194. },
  195. },
  196. tooltip: {
  197. show: true
  198. }
  199. }
  200. ]
  201. };
  202. // console.log('option', option);
  203. const func = new Function('option', 'datas', codeConfig);
  204. const opt = func(window._.cloneDeep(option), data);
  205. // console.log('opt', opt);
  206. // 使用刚指定的配置项和数据显示图表。
  207. myChart.setOption(opt);
  208. }
  209. }
  210. }
  211. watch([currentData, chartProps], ([val, pros]) => {
  212. nextTick(() => {
  213. initChart(val, pros)
  214. })
  215. }, {
  216. immediate: true,
  217. deep: true,
  218. })
  219. }
  220. }
  221. class CustomSimpleWaterFillNode extends HtmlResize.view {
  222. realValue = defaultVal
  223. oldProperties = {}
  224. chartRendered = false
  225. instance = null
  226. setHtml(rootEl) {
  227. if (!rootEl) return;
  228. const { properties, width, height } = this.props.model;
  229. const { normalData } = properties.dynamic || {}
  230. let thingName = 'pressure';
  231. let attr = 'score';
  232. if (normalData && normalData.dataPoint) {
  233. const dataPointStrParsed = JSON.parse(normalData.dataPoint || '{}')
  234. const { deviceCode, dataPoint } = dataPointStrParsed;
  235. thingName = deviceCode;
  236. attr = dataPoint.split(',')[0];
  237. }
  238. if (this.instance) {
  239. // 实时数据不能推送一次就创建一次图表,可以在原有实例基础之上更改数据。
  240. Object.assign(this.instance.component.props, {
  241. name: properties.nodeAlias,
  242. chartId: \`waterfill-\${properties.id}\`,
  243. currentData: this.realValue,
  244. width,
  245. height,
  246. chartProps: properties,
  247. thingName,
  248. attr,
  249. unit: normalData.unit || 'km/h'
  250. })
  251. return
  252. }
  253. const el = document.createElement('div');
  254. rootEl.innerHTML = '';
  255. const instance = createVNode(SimpleWaterFill, {
  256. name: properties.nodeAlias,
  257. chartId: \`gauge-\${properties.id}\`,
  258. currentData: this.realValue,
  259. width,
  260. height,
  261. chartProps: properties,
  262. thingName,
  263. attr,
  264. unit: normalData.unit || 'km/h'
  265. })
  266. instance.appContext = app._context
  267. render(instance, el)
  268. rootEl.appendChild(el);
  269. this.instance = instance;
  270. }
  271. sameProps(properties) {
  272. const isSame = window._.isEqual(this.oldProperties, properties);
  273. if (isSame) return true;
  274. this.oldProperties = properties;
  275. return false
  276. }
  277. // 生命周期 支持重写内容, 但格式需一致
  278. shouldUpdate() {
  279. const { properties } = this.props.model;
  280. const { normalData } = properties.dynamic || {};
  281. if (normalData && !normalData.dataPoint && !normalData.defaultValue) {
  282. this.realValue = defaultVal;
  283. return true
  284. }
  285. if (normalData) {
  286. const { defaultValue } = normalData || {};
  287. if (defaultValue) {
  288. const realValue = window.resolveScadaNewValue(defaultValue)
  289. if (this.realValue !== Number(realValue)) {
  290. this.realValue = Number(realValue);
  291. return true;
  292. }
  293. }
  294. }
  295. const propertiesBack = window._.cloneDeep(properties);
  296. if (propertiesBack.dynamic.normalData) {
  297. const isSameProps = this.sameProps(propertiesBack);
  298. if (isSameProps && this.chartRendered) {
  299. return false
  300. } else {
  301. if (!this.chartRendered) {
  302. this.chartRendered = true
  303. return true
  304. }
  305. if (!isSameProps) {
  306. return true;
  307. }
  308. }
  309. }
  310. }
  311. updateHtml() {
  312. this.setHtml(this.rootEl);
  313. }
  314. componentDidMount() {
  315. // 防止拖动时候频繁渲染图表
  316. this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
  317. if (this.shouldUpdate()) {
  318. this.setHtml(this.rootEl);
  319. }
  320. }
  321. componentDidUpdate() {
  322. if (this.shouldUpdate()) {
  323. this.updateHtmlDebounced();
  324. }
  325. }
  326. }
  327. class CustomSimpleWaterFillModel extends HtmlResize.model {
  328. initNodeData(data) {
  329. // 自定义组件,需最开始重���一下text 。
  330. data.text = {
  331. value: "",
  332. x: data.x,
  333. y: data.y,
  334. };
  335. super.initNodeData(data);
  336. const { properties } = this;
  337. this.width = properties.width || 80;
  338. this.height = properties.height || 35;
  339. this.text.editable = false; // 不允许文本被编辑
  340. }
  341. setAttributes() {
  342. // 自定义组件需重置 text
  343. const { x, y, properties } = this;
  344. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  345. this.text = {
  346. ...this.text,
  347. x: x + textHorizontalMove,
  348. y: y + textVerticalMove,
  349. value: "",
  350. }
  351. }
  352. }
  353. lf.register({
  354. type: 'custom-simple-waterfill-node',
  355. view: CustomSimpleWaterFillNode,
  356. model: CustomSimpleWaterFillModel,
  357. })`,css:"",fakeData:""},B={id:A,name:e,aliasName:E,image:i,imageType:I,groupName:C,groupType:a,isRemote:!1,isDefault:!0,sectionType:t,config:l,files:g};export{E as aliasName,l as config,B as default,g as files,C as groupName,a as groupType,A as id,i as image,I as imageType,n as isDefault,J as isRemote,e as name,t as sectionType};