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

410 lines
162 KiB

  1. const A="f6bd2c27-bcc0-456a-8447-545b10d97a5d",e="custom-polar-waterfill-node",C="极坐标水位图",E="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABGIAAANGCAYAAAC2qSgxAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3QmcndP9+PHvee7MXWeySSRCJCRINAhqi4r8iiK1azVtUdRS/tZq1dIqWpRfS1pNKbUVrX0tFVt+SkVrTyQRQiQksgozc/e5z/m/nrvM3DtzZ7vPc/fP/F5+SWbu8z3f8z7PL3799pzvUcIXAggggAACCCCAAAIIIIAAAggggEBJBFRJRmEQBBBAAAEEEEAAAQQQQAABBBBAAAGhEMNLgAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBBBAAAEEEEAAAQQQoBDDO4AAAggggAACCCCAAAIIIIAAAgiUSIBCTImgGQYBBBBAAAEEEEAAAQQQQAABBBCgEMM7gAACCCCAAAIIIIAAAggggAACCJRIgEJMiaAZBgEEEEAAAQQQQAABBBBAAAEEEKAQwzuAAAIIIIAAAggggAACCCCAAAIIlEiAQkyJoBkGAQQQQAABBDoFbp+7zOtyDx8Ui5mDEqYepJSrWUyjWRJmk243mhJaN4m4/NJuBkyt/Dqh/dpUPq3FJ+3iTbSLb1DAaNtypHy61Zb609GbygadkKhhGBGt26Pa5YrouI66XDqitY42NDREwlpHGxOJSCKRiDY3N0dEJKqUamddEEAAAQQQQACBUgpQiCmlNmMhgAACCCBQYwKXzdUNm3g2TDAbGsfFYnpsPJHYIpEwNmtPGCOi7ebweFyGxNplUDQmgUhcvOGIuENR7YrHRJRWokwRw/pViygz9auR/jXzPSP5sy6f7/Lnb3xN5MgDC8INi8gGEbVBKb1Ba/25KLVBTNmglNpgmvpzpczk7w3D2BCPxz9vamqy/mwWNBoPIYAAAggggEDdC1CIqftXAAAEEEAAAQTyC1z7zrpd4qaxS6RdvhKJqwnBeGLLtphsGopLUyiqPaG4NASjWnUWVDqLKb0XWLIKMMmCSuq5/hRccgs26eJMulAzahMll56nS7ScamNH4UaMz5TICkn+o1aIJFZorVcEAoFVJUqGYRBAAAEEEECgigQoxFTRYpEqAggggAACTgn879LVm0birt1DptoxEtcTQ+3mVqG4bNYS05t8ETOb1od1g7aKJF13ouTsXMkthCR3tmR93irQGDl/zlNwyd4Bk9kR0yVOqkCT2TWT3kHTww6ZbceJnHNqqYoxfa5Ge6ZAo1WmUCMrtFIrGpVa4Xa7Vyilgn1G4QMIIIAAAgggUFMCFGJqajmZDAIIIIAAArkCv1i6Zu9QuzqoJd6+5+ftatv1scSIDTHtbY2ZqZ0sDhdCMvEkGTdVqLEKKZI5gtTrEaNeCi45R5YyO2ryf/7bh4pMm1oxxZi+XknrWNQKJfp9rWWBiJpvGHq+z+db3teD/BwBBBBAAAEEqlOAQkx1rhtZI4AAAgggkCNw2bK1o9qk/fC2dpn2ebvsuDravuUnMbM51G6q7r1XnDkalHv8qPceLqmdMgPdETOAI0uZAk+6AHTVL7Q0NVXvS6K1tCgl85Wo+VonFiilrOLMfKVUW/XOiswRQAABBBBAwBKgEMN7gAACCCCAQJUJXPjJ2oO+1IkDNibM3dbH2rdZFdfDV8XbGzoKLt2O9mSODPWjsJGzQ6ZzR0vXI0q973DJGidvE97eCkF9HEHq59Gos0/VMmHrqtkVM5A3cJm1a0aUnm9qvUAbxvxBXu+SgQTgswgggAACCCBQXgEKMeX1Z3QEEEAAAQR6Ffj5ss+mbxQ5Zk3C/NqKeGLrj+LxQEx06n9UL7cJZR0NyuxG6drDpfuf+9GLpZ+FkEzhJrdHTKZnTNY4Az4a1UdT33S8bx+uZZ/qOZ5k6/8KlFJRrc0FSoz/KKXn
  2. "nodes": [
  3. {
  4. "id": "36843e65-444a-41ea-8223-5fbc4faae00c",
  5. "type": "custom-polar-waterfill-node",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "36843e65-444a-41ea-8223-5fbc4faae00c",
  15. "width": 200,
  16. "height": 200,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "outline": {
  22. "show": false
  23. },
  24. "codeConfig": "return option;",
  25. "nodeAlias": "极坐标水位图",
  26. "showDefaultValue": false,
  27. "showUnit": false,
  28. "valueColor": "rgba(245, 166, 35, 1)",
  29. "fontSize": 12,
  30. "Waves": [
  31. {
  32. "color": "rgba(46, 85, 244, 1)"
  33. },
  34. {
  35. "color": "rgba(36, 98, 242, 1)"
  36. },
  37. {
  38. "color": "rgba(19, 87, 239, 1)"
  39. }
  40. ],
  41. "maxValue": 1000,
  42. "waterFillShape": "circle",
  43. "backgroundStyle": {
  44. "color": "rgba(255, 255, 225, 0)",
  45. "borderWidth": 1
  46. },
  47. "outCircleColor": "rgba(225, 225, 225, 0.5)",
  48. "circleColors": [
  49. {
  50. "offset": 0,
  51. "color": "#A098FC"
  52. },
  53. {
  54. "offset": 0.3,
  55. "color": "#4386FA"
  56. },
  57. {
  58. "offset": 0.6,
  59. "color": "#4FADFD"
  60. },
  61. {
  62. "offset": 0.8,
  63. "color": "#0CD3DB"
  64. },
  65. {
  66. "offset": 1,
  67. "color": "#646CF9"
  68. }
  69. ],
  70. "dynamic": {
  71. "normalData": {
  72. "dataPoint": "",
  73. "compareType": "",
  74. "conditionVariables": [],
  75. "defaultValue": "",
  76. "unit": ""
  77. }
  78. }
  79. }
  80. }
  81. ]
  82. }`,javascript:`const { createApp, createVNode, render } = Vue;
  83. const app = createApp({})
  84. const defaultVal = 623;
  85. const PolarWaterFill = {
  86. template: '<div :id="chartId" :style="getStyle"></div>',
  87. props: {
  88. chartId: {
  89. type: String,
  90. default: ''
  91. },
  92. currentData: {
  93. type: Number,
  94. default: 100
  95. },
  96. width: {
  97. type: Number,
  98. default: 350
  99. },
  100. height: {
  101. type: Number,
  102. default: 150
  103. },
  104. chartProps: {
  105. type: Object,
  106. default: () => { }
  107. },
  108. thingName: {
  109. type: String,
  110. default: ''
  111. },
  112. attr: {
  113. type: String,
  114. default: ''
  115. },
  116. unit: {
  117. type: String,
  118. default: ''
  119. },
  120. },
  121. computed: {
  122. getStyle() {
  123. return {
  124. width: \`\${this.width}px\`,
  125. height: \`\${this.height}px\`
  126. }
  127. }
  128. },
  129. setup(props) {
  130. const { onMounted, nextTick, toRefs, watch } = Vue;
  131. const { chartProps, currentData, thingName, attr, width, height } = toRefs(props);
  132. let myChart = null;
  133. const initChart = (data, pros) => {
  134. // 基于准备好的dom,初始化echarts实例
  135. const dom = document.getElementById(props.chartId);
  136. if (dom) {
  137. if (!myChart) {
  138. myChart = echarts.init(dom);
  139. }
  140. // 由于实时推送时候不会重复创建实例,但是需更新画布大小。
  141. myChart.resize({
  142. width: width.value,
  143. height: height.value,
  144. })
  145. if (data != null) {
  146. const { codeConfig, Waves, waterFillShape, backgroundStyle, outline, maxValue, circleColors, outCircleColor } = pros;
  147. // 指定图表的配置项和数据
  148. const ratioVal = (+data / maxValue).toFixed(2);
  149. const totalColor = Waves.map(i => i.color);
  150. const totalDatas = totalColor.map(() => +ratioVal);
  151. var option = {
  152. angleAxis: {
  153. max: 1000,
  154. clockwise: false,
  155. axisLine: {
  156. show: false,
  157. },
  158. axisTick: {
  159. show: false,
  160. },
  161. axisLabel: {
  162. show: false,
  163. },
  164. splitLine: {
  165. show: false,
  166. },
  167. },
  168. radiusAxis: {
  169. type: 'category',
  170. show: true,
  171. axisLabel: {
  172. show: false,
  173. },
  174. axisLine: {
  175. show: false,
  176. },
  177. axisTick: {
  178. show: false,
  179. },
  180. },
  181. polar: {
  182. center: ['50%', '50%'], //中心点位置
  183. radius: ['80%', '85%'], //图形大小
  184. },
  185. series: [
  186. {
  187. type: 'bar',
  188. z: 10,
  189. name: '外环',
  190. data: [620],
  191. showBackground: true,
  192. backgroundStyle: {
  193. color: outCircleColor,
  194. },
  195. coordinateSystem: 'polar',
  196. roundCap: true,
  197. barWidth: 25,
  198. itemStyle: {
  199. normal: {
  200. color: {
  201. // 完成的圆环的颜色
  202. colorStops: circleColors,
  203. },
  204. },
  205. },
  206. },
  207. {
  208. type: "liquidFill",
  209. data: totalDatas,
  210. shape: waterFillShape,
  211. direction: "right", //波浪方向或者静止
  212. radius: "80%",
  213. // 水球颜色
  214. color: totalColor,
  215. center: ["50%", "50%"], //水球位置
  216. // outline 外边
  217. outline,
  218. backgroundStyle,
  219. label: {
  220. show: true,
  221. normal: {
  222. textStyle: {
  223. fontSize: 20 //设置不起作用
  224. }
  225. },
  226. },
  227. tooltip: {
  228. show: true
  229. }
  230. },
  231. ]
  232. };
  233. // console.log('option', option);
  234. const func = new Function('option', 'datas', codeConfig);
  235. const opt = func(window._.cloneDeep(option), data);
  236. // console.log('opt', opt);
  237. // 使用刚指定的配置项和数据显示图表。
  238. myChart.setOption(opt);
  239. }
  240. }
  241. }
  242. watch([currentData, chartProps], ([val, pros]) => {
  243. nextTick(() => {
  244. initChart(val, pros)
  245. })
  246. }, {
  247. immediate: true,
  248. deep: true,
  249. })
  250. }
  251. }
  252. class CustomPolarWaterFillNode extends HtmlResize.view {
  253. realValue = defaultVal
  254. oldProperties = {}
  255. chartRendered = false
  256. instance = null
  257. setHtml(rootEl) {
  258. if (!rootEl) return;
  259. const { properties, width, height } = this.props.model;
  260. const { normalData } = properties.dynamic || {}
  261. let thingName = 'pressure';
  262. let attr = 'score';
  263. if (normalData && normalData.dataPoint) {
  264. const dataPointStrParsed = JSON.parse(normalData.dataPoint || '{}')
  265. const { deviceCode, dataPoint } = dataPointStrParsed;
  266. thingName = deviceCode;
  267. attr = dataPoint.split(',')[0];
  268. }
  269. if (this.instance) {
  270. // 实时数据不能推送一次就创建一次图表,可以在原有实例基础之上更改数据。
  271. Object.assign(this.instance.component.props, {
  272. name: properties.nodeAlias,
  273. chartId: \`polarwaterfill-\${properties.id}\`,
  274. currentData: this.realValue,
  275. width,
  276. height,
  277. chartProps: properties,
  278. thingName,
  279. attr,
  280. unit: normalData.unit || 'km/h'
  281. })
  282. return
  283. }
  284. const el = document.createElement('div');
  285. rootEl.innerHTML = '';
  286. const instance = createVNode(PolarWaterFill, {
  287. name: properties.nodeAlias,
  288. chartId: \`gauge-\${properties.id}\`,
  289. currentData: this.realValue,
  290. width,
  291. height,
  292. chartProps: properties,
  293. thingName,
  294. attr,
  295. unit: normalData.unit || 'km/h'
  296. })
  297. instance.appContext = app._context
  298. render(instance, el)
  299. rootEl.appendChild(el);
  300. this.instance = instance;
  301. }
  302. sameProps(properties) {
  303. const isSame = window._.isEqual(this.oldProperties, properties);
  304. if (isSame) return true;
  305. this.oldProperties = properties;
  306. return false
  307. }
  308. // 生命周期 支持重写内容, 但格式需一致
  309. shouldUpdate() {
  310. const { properties } = this.props.model;
  311. const { normalData } = properties.dynamic || {};
  312. if (normalData && !normalData.dataPoint && !normalData.defaultValue) {
  313. this.realValue = defaultVal;
  314. return true
  315. }
  316. if (normalData) {
  317. const { defaultValue } = normalData || {};
  318. if (defaultValue) {
  319. const realValue = window.resolveScadaNewValue(defaultValue)
  320. if (this.realValue !== Number(realValue)) {
  321. this.realValue = Number(realValue);
  322. return true;
  323. }
  324. }
  325. }
  326. const propertiesBack = window._.cloneDeep(properties);
  327. if (propertiesBack.dynamic.normalData) {
  328. const isSameProps = this.sameProps(propertiesBack);
  329. if (isSameProps && this.chartRendered) {
  330. return false
  331. } else {
  332. if (!this.chartRendered) {
  333. this.chartRendered = true
  334. return true
  335. }
  336. if (!isSameProps) {
  337. return true;
  338. }
  339. }
  340. }
  341. }
  342. updateHtml() {
  343. this.setHtml(this.rootEl);
  344. }
  345. componentDidMount() {
  346. // 防止拖动时候频繁渲染图表
  347. this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
  348. if (this.shouldUpdate()) {
  349. this.setHtml(this.rootEl);
  350. }
  351. }
  352. componentDidUpdate() {
  353. if (this.shouldUpdate()) {
  354. this.updateHtmlDebounced();
  355. }
  356. }
  357. }
  358. class CustomPolarWaterFillModel extends HtmlResize.model {
  359. initNodeData(data) {
  360. // 自定义组件,需最开始重���一下text 。
  361. data.text = {
  362. value: "",
  363. x: data.x,
  364. y: data.y,
  365. };
  366. super.initNodeData(data);
  367. const { properties } = this;
  368. this.width = properties.width || 80;
  369. this.height = properties.height || 35;
  370. this.text.editable = false; // 不允许文本被编辑
  371. }
  372. setAttributes() {
  373. // 自定义组件需重置 text
  374. const { x, y, properties } = this;
  375. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  376. this.text = {
  377. ...this.text,
  378. x: x + textHorizontalMove,
  379. y: y + textVerticalMove,
  380. value: "",
  381. }
  382. }
  383. }
  384. lf.register({
  385. type: 'custom-polar-waterfill-node',
  386. view: CustomPolarWaterFillNode,
  387. model: CustomPolarWaterFillModel,
  388. })`,css:"",fakeData:""},l={id:A,name:e,aliasName:C,image:E,imageType:t,groupName:I,groupType:a,isRemote:!1,isDefault:!0,sectionType:g,config:B,files:Q};export{C as aliasName,B as config,l as default,Q as files,I as groupName,a as groupType,A as id,E as image,t as imageType,i as isDefault,n as isRemote,e as name,g as sectionType};