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

462 lines
120 KiB

  1. const A="4349220d-c128-4918-951e-c8e3c89b6513",E="custom-guage-outline-one",I="仪表板1",g="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABGIAAANGCAYAAAC2qSgxAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3QmcXGWV8P9zblVn7cAQhUFGBfM6vK8gmyQyobt6SQchiAOyBAgBV9wdRf+OCC64gOAMyzgK4jI4QlgCQXEhLOl0p5cgS9jRGZw3EBf0FYliOmtX3fP/1HKrb1Xfqrq9Vdet+vXn46ftzr33Oc/3uVRXnfs851HhCwEEEEAAAQQQQAABBBBAAAEEEECgKgJalVZoBAEEEEAAAQQQQAABBBBAAAEEEEBASMRwEyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAggggAACCCCAAAIIIIAAAlUSIBFTJWiaQQABBBBAAAEEEEAAAQQQQAABBEjEcA8ggAACCCCAAAIIIIAAAggggAACVRIgEVMlaJpBAAEEEEAAAQQQQAABBBBAAAEESMRwDyCAAAIIIIAAAggggAACCCCAAAJVEiARUyVomkEAAQQQQAABBBBAAAEEEEAAAQRIxHAPIIAAAgg
  2. "nodes": [
  3. {
  4. "id": "9454c2bf-21d4-47f7-a0f8-bd8b79a8d366",
  5. "type": "custom-guage-outline-one",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "9454c2bf-21d4-47f7-a0f8-bd8b79a8d366",
  15. "width": 420,
  16. "height": 420,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "codeConfig": "return option",
  22. "nodeAlias": "仪表板1",
  23. "showDefaultValue": false,
  24. "showUnit": false,
  25. "valueColor": "rgba(245, 166, 35, 1)",
  26. "fontSize": 12,
  27. "range": {
  28. "startAngle": 225,
  29. "endAngle": -45,
  30. "min": 0,
  31. "max": 100
  32. },
  33. "guage": {
  34. "radius": 85,
  35. "axisTick": {
  36. "length": 5,
  37. "lineStyle": {
  38. "color": "rgba(60,189,252,1)"
  39. }
  40. },
  41. "splitLine": {
  42. "length": 10,
  43. "lineStyle": {
  44. "color": "rgba(60,189,252,1)"
  45. }
  46. },
  47. "axisLabel": {
  48. "distance": 10,
  49. "color": "#E6F5EE",
  50. "fontSize": 16
  51. },
  52. "pointer": {
  53. "width": 10,
  54. "length": 70
  55. },
  56. "detail": {
  57. "color": "#3CBDFC",
  58. "fontSize": 26
  59. }
  60. },
  61. "outline": {
  62. "itemStyle": {
  63. "normal": {
  64. "color": "#54F200"
  65. }
  66. },
  67. "radius": 95,
  68. "axisLine": {
  69. "lineStyle": {
  70. "width": 16,
  71. "color": [
  72. {}
  73. ],
  74. "bgColor": "#314655"
  75. }
  76. }
  77. },
  78. "dynamic": {
  79. "normalData": {
  80. "dataPoint": "",
  81. "compareType": "",
  82. "conditionVariables": [],
  83. "defaultValue": "",
  84. "unit": ""
  85. }
  86. }
  87. }
  88. }
  89. ]
  90. }`,javascript:`const { createApp, createVNode, render } = Vue;
  91. const app = createApp({})
  92. const defaultVal = 45
  93. const GuageOutlineOne = {
  94. template: '<div :id="chartId" :style="getStyle"></div>',
  95. props: {
  96. chartId: {
  97. type: String,
  98. default: ''
  99. },
  100. currentData: {
  101. type: Number,
  102. default: 100
  103. },
  104. width: {
  105. type: Number,
  106. default: 350
  107. },
  108. height: {
  109. type: Number,
  110. default: 150
  111. },
  112. chartProps: {
  113. type: Object,
  114. default: () => { }
  115. },
  116. thingName: {
  117. type: String,
  118. default: ''
  119. },
  120. attr: {
  121. type: String,
  122. default: ''
  123. },
  124. unit: {
  125. type: String,
  126. default: ''
  127. },
  128. },
  129. computed: {
  130. getStyle() {
  131. return {
  132. width: \`\${this.width}px\`,
  133. height: \`\${this.height}px\`
  134. }
  135. }
  136. },
  137. setup(props) {
  138. const { onMounted, nextTick, toRefs, watch } = Vue;
  139. const { chartProps, currentData, thingName, attr, width, height } = toRefs(props);
  140. let myChart = null;
  141. const initChart = (data, pros) => {
  142. // 基于准备好的dom,初始化echarts实例
  143. const dom = document.getElementById(props.chartId);
  144. if (dom) {
  145. if (!myChart) {
  146. myChart = echarts.init(dom);
  147. }
  148. // 由于实时推送时候不会重复创建实例,但是需更新画布大小。
  149. myChart.resize({
  150. width: width.value,
  151. height: height.value,
  152. })
  153. if (data != null) {
  154. const { codeConfig, range, guage, outline } = pros;
  155. const { startAngle, endAngle, min, max } = range;
  156. const outlineCloned = window._.cloneDeep(outline);
  157. const guageCloned = window._.cloneDeep(guage);
  158. outlineCloned.radius = outlineCloned.radius + '%';
  159. guageCloned.radius = guageCloned.radius + '%';
  160. // 指定图表的配置项和数据
  161. var color = new echarts.graphic.LinearGradient(
  162. 0, 0, 1, 0, [{
  163. offset: 0,
  164. color: "#41D7F3",
  165. },
  166. {
  167. offset: 1,
  168. color: "#3D9FFF",
  169. }
  170. ]
  171. );
  172. var option = {
  173. backgroundColor: '',
  174. tooltip: {
  175. formatter: "{a} <br/>{c} {b}"
  176. },
  177. series: [
  178. {
  179. name: '',
  180. type: 'gauge',
  181. startAngle,
  182. endAngle,
  183. min,
  184. max,
  185. radius: guageCloned.radius,
  186. title: {
  187. show: false
  188. },
  189. detail: {
  190. show: true,
  191. fontFamily: 'DIN',
  192. fontWeight: '500',
  193. color: guageCloned.detail.color,
  194. offsetCenter: [0, '70%'],
  195. formatter: function (value) {
  196. return value
  197. },
  198. fontSize: guageCloned.detail.fontSize
  199. },
  200. axisLine: {
  201. show: false
  202. },
  203. axisTick: guageCloned.axisTick,
  204. splitLine: guageCloned.splitLine,
  205. axisLabel: {
  206. //数字离圆的距离
  207. distance: guageCloned.axisLabel.distance,
  208. borderRadius: 1,
  209. color: guageCloned.axisLabel.color,
  210. fontWeight: 600,
  211. padding: 1,
  212. fontFamily: 'Alibaba PuHuiTi',
  213. fontSize: guageCloned.axisLabel.fontSize
  214. },
  215. pointer: {
  216. ...guageCloned.pointer,
  217. length: guageCloned.pointer.length + '%'
  218. },
  219. itemStyle: {
  220. color: color,
  221. shadowColor: 'rgba(0,138,255,0.45)',
  222. shadowBlur: 10,
  223. shadowOffsetX: 2,
  224. shadowOffsetY: 2
  225. },
  226. data: [{
  227. value: data,
  228. name: '两区面积'
  229. }]
  230. },
  231. {
  232. name: "已到人数",
  233. type: 'gauge',
  234. radius: outlineCloned.radius,
  235. startAngle,
  236. endAngle,
  237. min,
  238. max,
  239. title: {
  240. show: false
  241. },
  242. detail: {
  243. show: false
  244. },
  245. axisLine: {
  246. show: true,
  247. lineStyle: {
  248. width: outlineCloned.axisLine.lineStyle.width,
  249. color: [
  250. [
  251. data / 100, color
  252. ],
  253. [
  254. 1, outlineCloned.axisLine.lineStyle.bgColor
  255. ]
  256. ],
  257. }
  258. },
  259. axisTick: {
  260. show: false,
  261. },
  262. splitLine: {
  263. show: false,
  264. },
  265. axisLabel: {
  266. show: false
  267. },
  268. pointer: {
  269. show: false,
  270. },
  271. itemStyle: {
  272. normal: {
  273. color: '#54F200',
  274. }
  275. },
  276. data: [{
  277. value: data,
  278. name: '年售电量情况'
  279. }]
  280. }
  281. ]
  282. }
  283. // console.log('option', option);
  284. const func = new Function('option', 'datas', codeConfig);
  285. const opt = func(window._.cloneDeep(option), data);
  286. // console.log('opt', opt);
  287. // 使用刚指定的配置项和数据显示图表。
  288. myChart.setOption(opt);
  289. }
  290. }
  291. }
  292. watch([currentData, chartProps], ([val, pros]) => {
  293. nextTick(() => {
  294. initChart(val, pros)
  295. })
  296. }, {
  297. immediate: true,
  298. deep: true,
  299. })
  300. }
  301. }
  302. class CustomGuageOutlineOneNode extends HtmlResize.view {
  303. realValue = defaultVal
  304. oldProperties = {}
  305. chartRendered = false
  306. instance = null
  307. setHtml(rootEl) {
  308. if (!rootEl) return;
  309. const { properties, width, height } = this.props.model;
  310. const { normalData } = properties.dynamic || {}
  311. let thingName = 'pressure';
  312. let attr = 'score';
  313. if (normalData && normalData.dataPoint) {
  314. const dataPointStrParsed = JSON.parse(normalData.dataPoint || '{}')
  315. const { deviceCode, dataPoint } = dataPointStrParsed;
  316. thingName = deviceCode;
  317. attr = dataPoint.split(',')[0];
  318. }
  319. if (this.instance) {
  320. // 实时数据不能推送一次就创建一次图表,可以在原有实例基础之上更改数据。
  321. Object.assign(this.instance.component.props, {
  322. name: properties.nodeAlias,
  323. chartId: \`waterfill-\${properties.id}\`,
  324. currentData: this.realValue,
  325. width,
  326. height,
  327. chartProps: properties,
  328. thingName,
  329. attr,
  330. unit: normalData.unit || 'km/h'
  331. })
  332. return
  333. }
  334. const el = document.createElement('div');
  335. rootEl.innerHTML = '';
  336. const instance = createVNode(GuageOutlineOne, {
  337. name: properties.nodeAlias,
  338. chartId: \`gauge-\${properties.id}\`,
  339. currentData: this.realValue,
  340. width,
  341. height,
  342. chartProps: properties,
  343. thingName,
  344. attr,
  345. unit: normalData.unit || 'km/h'
  346. })
  347. instance.appContext = app._context
  348. render(instance, el)
  349. rootEl.appendChild(el);
  350. this.instance = instance;
  351. }
  352. sameProps(properties) {
  353. const isSame = window._.isEqual(this.oldProperties, properties);
  354. if (isSame) return true;
  355. this.oldProperties = properties;
  356. return false
  357. }
  358. // 生命周期 支持重写内容, 但格式需一致
  359. shouldUpdate() {
  360. const { properties } = this.props.model;
  361. const { normalData } = properties.dynamic || {};
  362. if (normalData && !normalData.dataPoint && !normalData.defaultValue) {
  363. this.realValue = defaultVal;
  364. return true
  365. }
  366. if (normalData) {
  367. const { defaultValue } = normalData || {};
  368. if (defaultValue) {
  369. const realValue = window.resolveScadaNewValue(defaultValue)
  370. if (this.realValue !== Number(realValue)) {
  371. this.realValue = Number(realValue);
  372. return true;
  373. }
  374. }
  375. }
  376. const propertiesBack = window._.cloneDeep(properties);
  377. if (propertiesBack.dynamic.normalData) {
  378. const isSameProps = this.sameProps(propertiesBack);
  379. if (isSameProps && this.chartRendered) {
  380. return false
  381. } else {
  382. if (!this.chartRendered) {
  383. this.chartRendered = true
  384. return true
  385. }
  386. if (!isSameProps) {
  387. return true;
  388. }
  389. }
  390. }
  391. }
  392. updateHtml() {
  393. this.setHtml(this.rootEl);
  394. }
  395. componentDidMount() {
  396. // 防止拖动时候频繁渲染图表
  397. this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
  398. if (this.shouldUpdate()) {
  399. this.setHtml(this.rootEl);
  400. }
  401. }
  402. componentDidUpdate() {
  403. if (this.shouldUpdate()) {
  404. this.updateHtmlDebounced();
  405. }
  406. }
  407. }
  408. class CustomGuageOutlineOneModel extends HtmlResize.model {
  409. initNodeData(data) {
  410. // 自定义组件,需最开始重���一下text 。
  411. data.text = {
  412. value: "",
  413. x: data.x,
  414. y: data.y,
  415. };
  416. super.initNodeData(data);
  417. const { properties } = this;
  418. this.width = properties.width || 80;
  419. this.height = properties.height || 35;
  420. this.text.editable = false; // 不允许文本被编辑
  421. }
  422. setAttributes() {
  423. // 自定义组件需重置 text
  424. const { x, y, properties } = this;
  425. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  426. this.text = {
  427. ...this.text,
  428. x: x + textHorizontalMove,
  429. y: y + textVerticalMove,
  430. value: "",
  431. }
  432. }
  433. }
  434. lf.register({
  435. type: 'custom-guage-outline-one',
  436. view: CustomGuageOutlineOneNode,
  437. model: CustomGuageOutlineOneModel,
  438. })`,css:"",fakeData:""},l={id:A,name:E,aliasName:I,image:g,imageType:e,groupName:C,groupType:B,isRemote:!1,isDefault:!0,sectionType:Q,config:n,files:t};export{I as aliasName,n as config,l as default,t as files,C as groupName,B as groupType,A as id,g as image,e as imageType,a as isDefault,i as isRemote,E as name,Q as sectionType};