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

1348 lines
74 KiB

  1. const e="48ba7a60-4d22-4b7e-ada8-e3a9f9d51816",n="custom-scrolltable-node",t="表格",a='<?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="1695274327794" class="icon" viewBox="0 0 1142 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12610" xmlns:xlink="http://www.w3.org/1999/xlink" width="223.046875" height="200"><path d="M1102.769231 39.384615v945.23077H39.384615V39.384615h1063.384616m0-39.384615H39.384615a39.384615 39.384615 0 0 0-39.384615 39.384615v945.23077a39.384615 39.384615 0 0 0 39.384615 39.384615h1063.384616a39.384615 39.384615 0 0 0 39.384615-39.384615V39.384615a39.384615 39.384615 0 0 0-39.384615-39.384615z" fill="#1296db" p-id="12611"></path><path d="M39.384615 393.846154h1063.384616v39.384615H39.384615zM39.384615 590.769231h1063.384616v39.384615H39.384615zM39.384615 787.692308h1063.384616v39.384615H39.384615zM39.384615 196.923077h1063.384616v39.384615H39.384615z" fill="#1296db" p-id="12612"></path><path d="M315.076923 196.923077v787.692308H275.692308V196.923077zM590.769231 196.923077v787.692308h-39.384616V196.923077zM866.461538 196.923077v787.692308h-39.384615V196.923077z" fill="#1296db" p-id="12613"></path><path d="M39.384615 39.384615h1063.384616v157.538462H39.384615z" fill="#1296db" p-id="12614"></path></svg>',o="svg",r="动态",l="数据展示",u=!1,c=!0,i="时序",d=`{"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 轴","name":"x","keyboard":true,"id":"u:29852d093d9d","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:1b561d652acc","md":6},{"body":[{"type":"input-number","label":"Y 轴","name":"y","keyboard":true,"id":"u:dc8c1daed8ed","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:9672575193ac","md":6}]},{"type":"grid","id":"u:a332a7bf83c1","className":"m-b","columns":[{"body":[{"type":"input-number","label":"旋转","name":"rotation","id":"u:f6a2dbb518f9","placeholder":"组件旋转角度","mode":"horizontal","size":"full","className":"","keyboard":true,"step":1,"suffix":"deg","value":0,"labelAlign":"left","inputClassName":"w-full"}],"id":"u:646cd98b7955","md":6},{"body":[{"type":"input-number","label":"透明","name":"opacity","id":"u:cf80f59d8d42","placeholder":"组件透明度","mode":"horizontal","size":"full","className":"m-b","keyboard":true,"step
  2. "nodes": [
  3. {
  4. "id": "d11b46e7-237d-4ca8-96fc-4c0f7a011316",
  5. "type": "custom-scrolltable-node",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "d11b46e7-237d-4ca8-96fc-4c0f7a011316",
  15. "width": 500,
  16. "height": 200,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "emptyTable": false,
  22. "headerHeight": 35,
  23. "tableBGC": "rgba(5, 32, 73, 1)",
  24. "headerBGC": "#00BAFF",
  25. "oddRowBGC": "",
  26. "evenRowBGC": "",
  27. "highlightBGC": "",
  28. "highlightFontColor": "rgba(245, 166, 35, 1)",
  29. "clickHighlight": true,
  30. "enableBorder": false,
  31. "onlyOuterBorder": false,
  32. "onlyHeaderBorder": false,
  33. "onlyHeaderHoriBorder": false,
  34. "onlyBodyBorder": false,
  35. "bodyBorderStyle": "solid",
  36. "onlyHoriBorder": false,
  37. "index": false,
  38. "enableCarousel": false,
  39. "waitTime": "2000ms",
  40. "hoverPause": false,
  41. "fontSize": 12,
  42. "headerFontSize": 14,
  43. "showDefaultValue": false,
  44. "showUnit": false,
  45. "nodeAlias": "表格",
  46. "rowNum": 5,
  47. "columnWidth": [
  48. {
  49. "col": "1",
  50. "colW": 150
  51. }
  52. ],
  53. "carousel": "single",
  54. "align": [
  55. {
  56. "col": "1",
  57. "align": "center"
  58. }
  59. ],
  60. "headerFontColor": "#ffffff",
  61. "fontColor": "#ffffff",
  62. "borderColor": "#4a4a4a",
  63. "colNum": 3,
  64. "oddRowGradBG": "",
  65. "evenRowGradBG": "",
  66. "highlightGradBG": "",
  67. "dynamic": {
  68. "normalData": {
  69. "dataPoint": "",
  70. "compareType": "",
  71. "conditionVariables": [],
  72. "defaultValue": "",
  73. "unit": "",
  74. "renderIntervalEnabled": true,
  75. "customDatasource": true,
  76. "enableTestDatas": true,
  77. "testDatas": "",
  78. "renderInterval": "30000ms",
  79. "dataFilterFn": "// datas 数据处理\\r\\n// datas.forEach().....\\r\\n\\r\\n// 返回格式为:\\r\\nconst defaultHeader = [{ val: '列1', style: { color: 'red' } }, { val: '列2', style: { color: 'red' } }, { val: '列3', style: { color: 'red' } }]\\r\\nconst defaultDatas = [\\r\\n [{ val: '行1列1', style: { color: 'red' } }, { val: '行1列2', style: { color: 'green' } }, { val: '行1列3', style: { color: 'blue', cursor: 'pointer' } }],\\r\\n [{ val: '行2列1', style: { color: 'red' } }, { val: '行2列2', style: { color: 'green' } }, { val: '行2列3', style: { color: 'blue', cursor: 'pointer' } }],\\r\\n]\\r\\n// 或\\r\\n// const defaultHeader = ['列1', '列2', '列3']\\r\\n// const defaultDatas = [\\r\\n// ['行1列1', '行1列2', '行1列3'],\\r\\n// ['行2列1', '行2列2', '行2列3'],\\r\\n// ]\\r\\nreturn {\\r\\n headerDatas: defaultHeader,\\r\\n tableDatas: defaultDatas\\r\\n}",
  80. "requestMethod": "get",
  81. "requestParams": "return {};"
  82. },
  83. "eventsData": {
  84. "eventCombo": [
  85. {
  86. "eventType": "change",
  87. "enable": false,
  88. "config": ""
  89. }
  90. ]
  91. },
  92. "uiData": {
  93. "dataPoint": "",
  94. "compareType": "",
  95. "conditionVariables": []
  96. },
  97. "animationData": {
  98. "animationCombo": [
  99. {
  100. "dataPoint": "",
  101. "min": "",
  102. "max": "",
  103. "animationName": "旋转"
  104. }
  105. ]
  106. },
  107. "hiddenData": {
  108. "hiddenCombo": [
  109. {
  110. "dataPoint": "",
  111. "min": "",
  112. "max": "",
  113. "showOrHiddenName": "隐藏"
  114. }
  115. ]
  116. }
  117. }
  118. }
  119. }
  120. ]
  121. }`,javascript:`// 工具函数
  122. /**
  123. * 精准判断对象类型
  124. * @param obj
  125. */
  126. function typeOf(obj) {
  127. const toString = Object.prototype.toString
  128. const map = {
  129. '[object Boolean]': 'boolean',
  130. '[object Number]': 'number',
  131. '[object String]': 'string',
  132. '[object Function]': 'function',
  133. '[object Array]': 'array',
  134. '[object Date]': 'date',
  135. '[object RegExp]': 'regExp',
  136. '[object Undefined]': 'undefined',
  137. '[object Null]': 'null',
  138. '[object Object]': 'object',
  139. }
  140. return map[toString.call(obj)]
  141. }
  142. /**
  143. * 深拷贝
  144. * @param data
  145. */
  146. function deepCopy(data) {
  147. const t = typeOf(data)
  148. let o
  149. if (t === 'array') {
  150. o = []
  151. } else if (t === 'object') {
  152. o = {}
  153. } else {
  154. return data
  155. }
  156. if (t === 'array') {
  157. for (let i = 0; i < data.length; i++) {
  158. o.push(deepCopy(data[i]))
  159. }
  160. } else if (t === 'object') {
  161. for (const i in data) {
  162. o[i] = deepCopy(data[i])
  163. }
  164. }
  165. return o
  166. }
  167. /**
  168. * 深覆盖
  169. * @param target
  170. * @param merged
  171. */
  172. function deepMerge(target, merged) {
  173. for (const key in merged) {
  174. if (target[key] && typeof target[key] === 'object') {
  175. deepMerge(target[key], merged[key])
  176. continue
  177. }
  178. if (typeof merged[key] === 'object') {
  179. target[key] = deepCopy(merged[key])
  180. continue
  181. }
  182. target[key] = merged[key]
  183. }
  184. return target
  185. }
  186. /**
  187. * 节流函数(限制函数的执行频率)返回函数连续调用时空闲时间必须大于或等于 waitfunc 才会执行
  188. * @param {function} func 回调函数
  189. * @param {number} wait 表示时间窗口的间隔
  190. * @param immediate 是否立即执行 true 则先调用false不先调用
  191. * @return {function} 返回客户调用函数
  192. */
  193. function throttle(func, wait, immediate) {
  194. let timeoutID
  195. let lastExec = 0
  196. function wrapper() {
  197. const self = this
  198. const elapsed = Number(new Date()) - lastExec
  199. const args = arguments
  200. function clearExistingTimeout() {
  201. if (timeoutID) {
  202. clearTimeout(timeoutID)
  203. }
  204. }
  205. function clear() {
  206. timeoutID = undefined
  207. }
  208. function exec() {
  209. lastExec = Number(new Date())
  210. func.apply(self, args)
  211. }
  212. if (immediate && !timeoutID) {
  213. exec()
  214. }
  215. clearExistingTimeout()
  216. if (immediate === undefined && elapsed > wait) {
  217. exec()
  218. } else {
  219. timeoutID = setTimeout(immediate ? clear : exec, immediate === undefined ? wait - elapsed : wait)
  220. }
  221. }
  222. return wrapper
  223. }
  224. /**
  225. * 防抖函数(限制函数的执行频率) 保证再一系列调用时间内只调用一次
  226. *
  227. * @param {function} func 回调函数
  228. * @param {number} wait 表示时间窗口的间隔
  229. * @return {function} 返回客户调用函数
  230. */
  231. function debounce(func, wait) {
  232. return throttle(func, wait, false)
  233. }
  234. const { createApp, createVNode, render, nextTick, onBeforeUnmount, onUnmounted, onMounted, reactive, ref, toRefs, watch } = Vue;
  235. const app = createApp({})
  236. function useAutoResize(props, afterResizeFun) {
  237. const domRef = ref(null) // dorm容器,默认设置为domRef
  238. const status = reactive({
  239. width: 0,
  240. height: 0,
  241. })
  242. let __resizeHandler = null
  243. function resize(resize = true) {
  244. nextTick().then(() => {
  245. const dom = domRef.value
  246. status.width = dom ? dom.clientWidth : 0
  247. status.height = dom ? dom.clientHeight : 0
  248. if (!dom) {
  249. console.warn('fei-datav: Failed to get dom node, component rendering may be abnormal!')
  250. } else if (!status.width || !status.height) {
  251. console.warn('fei-datav: Component width or height is 0px, rendering abnormality may occur!')
  252. }
  253. if (typeof afterResizeFun === 'function' && resize) afterResizeFun()
  254. })
  255. }
  256. watch([() => props.containerWidth, () => props.containerHeight], () => {
  257. __resizeHandler && __resizeHandler();
  258. })
  259. onMounted(() => {
  260. setTimeout(() => {
  261. resize();
  262. }, 500)
  263. __resizeHandler = debounce(resize, 100)
  264. })
  265. return {
  266. domRef,
  267. ...toRefs(status),
  268. resize,
  269. }
  270. }
  271. const ScrollTable = {
  272. template: \`
  273. <div class="bv-scroll-table" ref="domRef" :style="tableStyle">
  274. <div class="header" v-if="header.length && mergedConfig" :style="{'background-color': mergedConfig.headerBGC}">
  275. <div
  276. class="header-item"
  277. v-for="(headerItem, i) in header"
  278. :key="(headerItem.val || headerItem) + '-' + i"
  279. :style="getHeaderItemStyle(widths, mergedConfig, i, header, enableBorder, borderColor, headerFontSize, headerFontColor, onlyOuterBorder, onlyHeaderBorder, onlyHeaderHoriBorder, headerItem, aligns[i])"
  280. :align="aligns[i]"
  281. v-html="headerItem.val || headerItem"
  282. />
  283. </div>
  284. <div
  285. v-if="mergedConfig"
  286. class="rows"
  287. :style="getRowsHeight"
  288. >
  289. <div
  290. class="row-item"
  291. v-for="(row, ri) in rows"
  292. :key="row.toString() + '-' + row.scroll"
  293. :style="getRowItemStyle(heights, mergedConfig, row, ri, highlightGradBG, highlightBGC, rows, enableBorder, borderColor, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, onlyOuterBorder)"
  294. >
  295. <div
  296. class="cell"
  297. v-for="(cell, ci) in row.cells"
  298. :key="(cell.val || cell) + '-' + ri + '-' + ci"
  299. :style="getCellStyle(widths, ci, row.cells, enableBorder, borderColor, fontSize, fontColor, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, onlyOuterBorder, cell, row, highlightFontColor)"
  300. :align="aligns[ci]"
  301. v-html="getCellContent(cell)"
  302. @click="clickHandler('click', ri, ci, row, cell)"
  303. @mouseenter="handleHover(true, ri, ci, row, cell)"
  304. @mouseleave="handleHover(false)"
  305. @mousemove="(e) => handleMove(e, ri, ci, row, cell)"
  306. />
  307. </div>
  308. </div>
  309. </div>
  310. \`,
  311. name: 'BvScrollTable',
  312. props: {
  313. config: {
  314. type: Object,
  315. default: () => ({}),
  316. },
  317. containerWidth: {
  318. type: Number,
  319. default: 500,
  320. },
  321. containerHeight: {
  322. type: Number,
  323. default: 200,
  324. },
  325. fontColor: {
  326. type: String,
  327. default: ''
  328. },
  329. fontSize: {
  330. type: Number,
  331. default: 12
  332. },
  333. headerFontColor: {
  334. type: String,
  335. default: ''
  336. },
  337. headerFontSize: {
  338. type: Number,
  339. default: 12
  340. },
  341. enableBorder: {
  342. type: Boolean,
  343. default: true
  344. },
  345. borderColor: {
  346. type: String,
  347. default: ''
  348. },
  349. enableCarousel: {
  350. type: Boolean,
  351. default: false
  352. },
  353. onlyOuterBorder: {
  354. type: Boolean,
  355. default: false
  356. },
  357. onlyHeaderBorder: {
  358. type: Boolean,
  359. default: false
  360. },
  361. onlyBodyBorder: {
  362. type: Boolean,
  363. default: false
  364. },
  365. bodyBorderStyle: {
  366. type: String,
  367. default: 'solid'
  368. },
  369. onlyHoriBorder: {
  370. type: Boolean,
  371. default: false
  372. },
  373. onlyHeaderHoriBorder: {
  374. type: Boolean,
  375. default: false
  376. },
  377. tableBGC: {
  378. type: String,
  379. default: ''
  380. },
  381. clickHighlight: {
  382. type: Boolean,
  383. default: false
  384. },
  385. highlightBGC: {
  386. type: String,
  387. default: ''
  388. },
  389. highlightGradBG: {
  390. type: String,
  391. default: ''
  392. },
  393. highlightNumber: {
  394. type: Number,
  395. default: -1
  396. },
  397. highlightFontColor: {
  398. type: String,
  399. default: ''
  400. }
  401. },
  402. computed: {
  403. tableStyle() {
  404. const style = {};
  405. if (this.tableBGC) {
  406. style.background = this.tableBGC
  407. }
  408. if (this.enableBorder || this.onlyOuterBorder) {
  409. return {
  410. border: \`1px solid \${this.borderColor}\`,
  411. 'box-sizing': 'border-box',
  412. ...style
  413. }
  414. } else {
  415. return style
  416. }
  417. },
  418. getHeaderItemStyle: () => (widths, mergedConfig, i, header, enableBorder, borderColor, headerFontSize, headerFontColor, onlyOuterBorder, onlyHeaderBorder, onlyHeaderHoriBorder, headerItem, align) => {
  419. const isLast = i === header.length - 1;
  420. const borderObj = {}
  421. if (enableBorder) {
  422. !isLast && (borderObj['border-right'] = \`1px solid \${borderColor}\`);
  423. }
  424. if (!enableBorder && !onlyOuterBorder && onlyHeaderBorder && !onlyHeaderHoriBorder) {
  425. borderObj['border-top'] = \`1px solid \${borderColor}\`;
  426. borderObj['border-bottom'] = \`1px solid \${borderColor}\`;
  427. borderObj['border-right'] = \`1px solid \${borderColor}\`;
  428. i === 0 && (borderObj['border-left'] = \`1px solid \${borderColor}\`);
  429. }
  430. if (!enableBorder && !onlyOuterBorder && onlyHeaderBorder && onlyHeaderHoriBorder) {
  431. borderObj['border-top'] = \`1px solid \${borderColor}\`;
  432. borderObj['border-bottom'] = \`1px solid \${borderColor}\`;
  433. i === 0 && (borderObj['border-left'] = \`1px solid \${borderColor}\`);
  434. isLast && (borderObj['border-right'] = \`1px solid \${borderColor}\`);
  435. }
  436. if (!enableBorder && onlyOuterBorder && onlyHeaderBorder && !onlyHeaderHoriBorder) {
  437. borderObj['border-bottom'] = \`1px solid \${borderColor}\`;
  438. !isLast && (borderObj['border-right'] = \`1px solid \${borderColor}\`);
  439. }
  440. if (!enableBorder && onlyOuterBorder && onlyHeaderBorder && onlyHeaderHoriBorder) {
  441. borderObj['border-bottom'] = \`1px solid \${borderColor}\`;
  442. }
  443. let headItemStyle = {};
  444. if (headerItem.style) {
  445. headItemStyle = {
  446. ...headerItem.style
  447. }
  448. }
  449. return {
  450. 'height': mergedConfig.headerHeight + 'px',
  451. 'width': widths[i] + 'px',
  452. 'font-size': headerFontSize + 'px',
  453. 'color': headerFontColor,
  454. ...borderObj,
  455. ...headItemStyle,
  456. display: 'flex',
  457. 'justify-content': align === 'center' ? 'center' : align === 'left' ? 'flex-start' : align === 'right' ? 'flex-end' : 'left',
  458. 'align-items': 'center',
  459. 'text-align': align === 'center' ? 'center' : align === 'left' ? 'left' : align === 'right' ? 'right' : 'left',
  460. }
  461. },
  462. getCellStyle: () => (widths, ci, cells, enableBorder, borderColor, fontSize, fontColor, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, onlyOuterBorder, cell, row, highlightFontColor) => {
  463. const isLast = ci === cells.length - 1;
  464. const borderObj = {}
  465. if (enableBorder) {
  466. !isLast && (borderObj['border-right'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  467. }
  468. if (!enableBorder && !onlyOuterBorder && onlyBodyBorder && !onlyHoriBorder) {
  469. borderObj['border-right'] = \`1px \${bodyBorderStyle} \${borderColor}\`;
  470. ci === 0 && (borderObj['border-left'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  471. }
  472. if (!enableBorder && onlyOuterBorder && onlyBodyBorder && !onlyHoriBorder) {
  473. !isLast && (borderObj['border-right'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  474. }
  475. let cellStyle = {};
  476. if (cell.style) {
  477. cellStyle = {
  478. ...cell.style
  479. }
  480. }
  481. const isHighlight = row.isHighlight;
  482. let fontC = cellStyle.color || fontColor;
  483. if (isHighlight) {
  484. fontC = highlightFontColor;
  485. }
  486. return {
  487. width: widths[ci] + 'px',
  488. 'font-size': fontSize + 'px',
  489. ...borderObj,
  490. ...cellStyle,
  491. 'color': fontC,
  492. }
  493. },
  494. getRowsHeight() {
  495. const { height, header, mergedConfig, enableCarousel } = this;
  496. return {
  497. height: height - (header.length ? mergedConfig.headerHeight : 0) + 'px',
  498. overflow: enableCarousel ? 'hidden' : 'auto'
  499. }
  500. },
  501. getRowItemStyle: () => (heights, mergedConfig, row, ri, highlightGradBG, highlightBGC, rows, enableBorder, borderColor, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, onlyOuterBorder) => {
  502. const h = heights[ri];
  503. const isHighlight = row.isHighlight;
  504. let background = mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC'];
  505. if (background.includes('http') && !background.includes('url')) {
  506. background = \`url(\${background})\`;
  507. }
  508. if (isHighlight) {
  509. background = highlightGradBG || highlightBGC;
  510. if (background.includes('http') && !background.includes('url')) {
  511. background = \`url(\${background})\`;
  512. }
  513. }
  514. const borderObj = {}
  515. const isLastRow = ri === rows.length - 1;
  516. if (enableBorder) {
  517. ri === 0 && (borderObj['border-top'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  518. borderObj['border-bottom'] = \`1px \${bodyBorderStyle} \${borderColor}\`;
  519. }
  520. if (!enableBorder && !onlyOuterBorder && onlyBodyBorder && !onlyHoriBorder) {
  521. ri === 0 && (borderObj['border-top'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  522. borderObj['border-bottom'] = \`1px \${bodyBorderStyle} \${borderColor}\`;
  523. }
  524. if (!enableBorder && !onlyOuterBorder && onlyBodyBorder && onlyHoriBorder) {
  525. ri === 0 && (borderObj['border-top'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  526. borderObj['border-bottom'] = \`1px \${bodyBorderStyle} \${borderColor}\`;
  527. }
  528. if (!enableBorder && onlyOuterBorder && onlyBodyBorder && !onlyHoriBorder) {
  529. ri === 0 && (borderObj['border-top'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  530. !isLastRow && (borderObj['border-bottom'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  531. }
  532. if (!enableBorder && onlyOuterBorder && onlyBodyBorder && onlyHoriBorder) {
  533. ri === 0 && (borderObj['border-top'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  534. !isLastRow && (borderObj['border-bottom'] = \`1px \${bodyBorderStyle} \${borderColor}\`);
  535. }
  536. return {
  537. height: h + 'px',
  538. 'line-height': h + 'px',
  539. 'background': background,
  540. 'background-size': '100% 100%',
  541. ...borderObj
  542. }
  543. }
  544. },
  545. emits: ['mouseover', 'click'],
  546. setup(props, { emit }) {
  547. const { onUnmounted, watch, reactive, ref, toRefs } = Vue;
  548. const defaultConfig = ref({
  549. /**
  550. * @description Board header
  551. * @type {Array<String>}
  552. * @default header = []
  553. * @example header = ['column1', 'column2', 'column3']
  554. */
  555. header: [],
  556. /**
  557. * @description Board data
  558. * @type {Array<Array>}
  559. * @default data = []
  560. */
  561. data: [],
  562. /**
  563. * @description Row num
  564. * @type {Number}
  565. * @default rowNum = 5
  566. */
  567. rowNum: 5,
  568. /**
  569. * @description Header background color
  570. * @type {String}
  571. * @default headerBGC = '#00BAFF'
  572. */
  573. headerBGC: '#00BAFF',
  574. /**
  575. * @description Odd row background color
  576. * @type {String}
  577. * @default oddRowBGC = '#003B51'
  578. */
  579. oddRowBGC: '#003B51',
  580. /**
  581. * @description Even row background color
  582. * @type {String}
  583. * @default evenRowBGC = '#003B51'
  584. */
  585. evenRowBGC: '#0A2732',
  586. /**
  587. * @description Scroll wait time
  588. * @type {Number}
  589. * @default waitTime = 2000
  590. */
  591. waitTime: 2000,
  592. /**
  593. * @description Header height
  594. * @type {Number}
  595. * @default headerHeight = 35
  596. */
  597. headerHeight: 35,
  598. /**
  599. * @description Column width
  600. * @type {Array<Number>}
  601. * @default columnWidth = []
  602. */
  603. columnWidth: [],
  604. /**
  605. * @description Column align
  606. * @type {Array<String>}
  607. * @default align = []
  608. * @example align = ['left', 'center', 'right']
  609. */
  610. align: [],
  611. /**
  612. * @description Show index
  613. * @type {Boolean}
  614. * @default index = false
  615. */
  616. index: false,
  617. /**
  618. * @description index Header
  619. * @type {String}
  620. * @default indexHeader = '#'
  621. */
  622. indexHeader: '#',
  623. /**
  624. * @description Carousel type
  625. * @type {String}
  626. * @default carousel = 'single'
  627. * @example carousel = 'single' | 'page'
  628. */
  629. carousel: 'single',
  630. /**
  631. * @description Pause scroll when mouse hovered
  632. * @type {Boolean}
  633. * @default hoverPause = true
  634. * @example hoverPause = true | false
  635. */
  636. hoverPause: true,
  637. })
  638. function calcData() {
  639. stopAnimation()
  640. mergeConfig()
  641. calcHeaderData()
  642. calcRowsData()
  643. calcWidths()
  644. calcHeights()
  645. calcAligns()
  646. animation(true)
  647. }
  648. const { domRef, width, height, resize } = useAutoResize(props, calcData)
  649. const status = reactive({
  650. mergedConfig: null,
  651. header: [],
  652. rowsData: [],
  653. rows: [],
  654. widths: [],
  655. heights: [],
  656. avgHeight: 0,
  657. aligns: [],
  658. animationIndex: 0,
  659. animationHandler: '',
  660. updater: 0,
  661. needCalc: false,
  662. })
  663. function handleHover(enter, ri, ci, row, cell) {
  664. if (enter) emitEvent('mouseover', ri, ci, row, cell)
  665. if (!status.mergedConfig.hoverPause) return
  666. const tooltip = document.querySelector('.scroll-table-tooltip');
  667. if (enter) {
  668. stopAnimation()
  669. } else {
  670. animation(true);
  671. }
  672. }
  673. function onResize() {
  674. if (!status.mergedConfig) return
  675. stopAnimation()
  676. calcWidths()
  677. calcHeights(true)
  678. animation(true)
  679. }
  680. function mergeConfig() {
  681. status.mergedConfig = deepMerge(deepCopy(defaultConfig.value), props.config || {})
  682. }
  683. function calcHeaderData() {
  684. let { header, index, indexHeader } = status.mergedConfig
  685. if (!header.length) {
  686. status.header = []
  687. return
  688. }
  689. header = [...header]
  690. if (index) header.unshift(indexHeader)
  691. status.header = header
  692. }
  693. function calcRowsData() {
  694. let { data, index, headerBGC, rowNum, enableCarousel } = status.mergedConfig
  695. if (index) {
  696. data = data.map((row, i) => {
  697. row = [...row]
  698. const indexTag = \`<span class="index" style="background-color: \${headerBGC};">\${i + 1}</span>\`;
  699. row.unshift(indexTag)
  700. return row
  701. })
  702. }
  703. data = data.map((cells, i) => ({ cells, rowIndex: i }))
  704. const rowLength = data.length
  705. if (enableCarousel && rowLength > rowNum && rowLength < 2 * rowNum) {
  706. data = [...data, ...data]
  707. }
  708. data = data.map((d, i) => ({ ...d, scroll: i }))
  709. status.rowsData = data
  710. status.rows = data
  711. }
  712. function calcWidths() {
  713. const { mergedConfig, rowsData } = status
  714. const { columnWidth, header } = mergedConfig
  715. const usedWidth = columnWidth.reduce((all, w) => all + w, 0)
  716. let columnNum = 0
  717. if (rowsData[0]) {
  718. columnNum = rowsData[0].cells.length
  719. } else if (header.length) {
  720. columnNum = header.length
  721. }
  722. const avgWidth = (width.value - usedWidth) / (columnNum - columnWidth.length)
  723. const widths = new Array(columnNum).fill(avgWidth)
  724. status.widths = deepMerge(widths, columnWidth)
  725. }
  726. function calcHeights(onresize = false) {
  727. const { mergedConfig, header } = status
  728. const { headerHeight, rowNum, data } = mergedConfig
  729. let allHeight = height.value
  730. if (header.length) allHeight -= headerHeight
  731. const avgHeight = allHeight / rowNum
  732. status.avgHeight = avgHeight
  733. if (!onresize) status.heights = new Array(data.length).fill(avgHeight)
  734. }
  735. function calcAligns() {
  736. const { header, mergedConfig } = status
  737. const columnNum = header.length
  738. let aligns = new Array(columnNum).fill('left')
  739. const { align } = mergedConfig
  740. status.aligns = deepMerge(aligns, align)
  741. }
  742. async function animation(start = false) {
  743. if (!props.enableCarousel) return;
  744. const { needCalc, calcHeights, calcRowsData } = status
  745. if (needCalc) {
  746. calcRowsData()
  747. calcHeights()
  748. status.needCalc = false
  749. }
  750. let { avgHeight, animationIndex, mergedConfig, rowsData, updater } = status
  751. const { waitTime, carousel, rowNum } = mergedConfig
  752. const rowLength = rowsData.length
  753. if (rowNum >= rowLength) return
  754. if (start) {
  755. await new Promise(resolve => setTimeout(resolve, waitTime))
  756. if (updater !== status.updater) return
  757. }
  758. const animationNum = carousel === 'single' ? 1 : rowNum
  759. let rows = rowsData.slice(animationIndex)
  760. rows.push(...rowsData.slice(0, animationIndex))
  761. status.rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1)
  762. status.heights = new Array(rowLength).fill(avgHeight)
  763. await new Promise(resolve => setTimeout(resolve, 300))
  764. if (updater !== status.updater) return
  765. status.heights.splice(0, animationNum, ...new Array(animationNum).fill(0))
  766. animationIndex += animationNum
  767. const back = animationIndex - rowLength
  768. if (back >= 0) animationIndex = back
  769. status.animationIndex = animationIndex
  770. status.animationHandler = setTimeout(animation, waitTime - 300)
  771. }
  772. function stopAnimation() {
  773. const { animationHandler, updater } = status
  774. status.updater = (updater + 1) % 999999
  775. if (!animationHandler) return
  776. clearTimeout(animationHandler)
  777. }
  778. function emitEvent(type, ri, ci, row, cell) {
  779. emit(type, ri, ci, row, cell)
  780. }
  781. const clickHandler = (type, ri, ci, row, cell) => {
  782. if (props.clickHighlight) {
  783. status.rows.forEach((item, index) => {
  784. if (index === ri) {
  785. item['isHighlight'] = true
  786. } else {
  787. item['isHighlight'] = false
  788. }
  789. })
  790. }
  791. emit(type, ri, ci, row, cell)
  792. }
  793. function updateRows(rows, animationIndex) {
  794. const { mergedConfig, animationHandler } = {
  795. ...mergedConfig,
  796. data: [...rows],
  797. }
  798. status.needCalc = true
  799. if (typeof animationIndex === 'number') status.animationIndex = animationIndex
  800. if (!animationHandler) animation(true)
  801. }
  802. watch(() => props.config, () => {
  803. stopAnimation()
  804. status.animationIndex = 0
  805. calcData()
  806. }, { deep: true })
  807. watch(() => props.highlightNumber, (num) => {
  808. if (props.enableCarousel) {
  809. if (num > -1) {
  810. status.animationIndex = num;
  811. animation(false);
  812. if (status.rows.length <= props.config.rowNum) {
  813. status.rows.forEach((row, index) => {
  814. if (index === num) {
  815. row.isHighlight = true
  816. } else {
  817. row.isHighlight = false
  818. }
  819. })
  820. } else {
  821. status.rows.forEach((row, index) => {
  822. if (index === 0) {
  823. row.isHighlight = true
  824. } else {
  825. row.isHighlight = false
  826. }
  827. })
  828. }
  829. stopAnimation();
  830. setTimeout(() => {
  831. stopAnimation();
  832. animation(true);
  833. }, 3000)
  834. }
  835. } else {
  836. const rows = document.querySelectorAll('.bv-scroll-table .rows .row-item');
  837. if (rows[num]) {
  838. rows[num].scrollIntoView();
  839. status.rows.forEach((row, index) => {
  840. if (index === num) {
  841. row.isHighlight = true
  842. } else {
  843. row.isHighlight = false
  844. }
  845. })
  846. }
  847. }
  848. })
  849. const moveHandler = (e) => {
  850. const target = e.target;
  851. const insideTable = target.closest('.bv-scroll-table');
  852. if (!insideTable) {
  853. const tooltip = document.querySelector('.scroll-table-tooltip');
  854. if (tooltip) {
  855. tooltip.remove();
  856. }
  857. }
  858. }
  859. const handleMove = window._.debounce(function (e, ri, ci, row, cell) {
  860. const x = e.pageX;
  861. const y = e.pageY;
  862. const offsetWidth = e.target.offsetWidth;
  863. const scrollWidth = e.target.scrollWidth;
  864. if (offsetWidth < scrollWidth) {
  865. const tooltip = document.querySelector('.scroll-table-tooltip');
  866. if (!tooltip) {
  867. const span = document.createElement('span');
  868. span.className = 'scroll-table-tooltip';
  869. span.innerHTML = cell.val || cell;
  870. span.style.top = y + 10 + 'px';
  871. span.style.left = x + 15 + 'px';
  872. document.body.appendChild(span);
  873. } else {
  874. tooltip.innerHTML = cell.val || cell;
  875. tooltip.style.top = y + 10 + 'px';
  876. tooltip.style.left = x + 15 + 'px';
  877. }
  878. } else {
  879. const tooltip = document.querySelector('.scroll-table-tooltip');
  880. tooltip && tooltip.remove();
  881. }
  882. }, 200)
  883. onMounted(() => {
  884. document.body.addEventListener('mousemove', moveHandler)
  885. })
  886. onUnmounted(() => {
  887. stopAnimation();
  888. document.body.removeEventListener('mousemove', moveHandler)
  889. })
  890. const getCellContent = (cell) => {
  891. if (typeof cell === 'object') {
  892. return cell.val
  893. } else {
  894. return cell
  895. }
  896. }
  897. return {
  898. defaultConfig,
  899. ...toRefs(status),
  900. domRef,
  901. width,
  902. height,
  903. resize,
  904. updateRows,
  905. handleHover,
  906. onResize,
  907. emitEvent,
  908. clickHandler,
  909. handleMove,
  910. getCellContent,
  911. }
  912. }
  913. }
  914. const defaultHeader = ['列1', '列2', '列3']
  915. const defaultDatas = [
  916. ['行1列1', '行1列2', '行1列3'],
  917. ['行2列1', '行2列2', '行2列3'],
  918. ['行3列1', '行3列2', '行3列3'],
  919. ['行4列1', '行4列2', '行4列3'],
  920. ['行5列1', '行5列2', '行5列3'],
  921. ['行6列1', '行6列2', '行6列3'],
  922. ['行7列1', '行7列2', '行7列3'],
  923. ['行8列1', '行8列2', '行8列3'],
  924. ['行9列1', '行9列2', '行9列3'],
  925. ['行10列1', '行10列2', '行10列3']
  926. ]
  927. class CustomScrollTableNode extends HtmlResize.view {
  928. headerDatas = defaultHeader
  929. tableDatas = defaultDatas
  930. oldProperties = {}
  931. chartRendered = false
  932. historyDatas = []
  933. instance = null
  934. setHtml(rootEl) {
  935. if (!rootEl) return;
  936. const { graphModel, model } = this.props;
  937. const { properties, width, height, } = this.props.model;
  938. const {
  939. rowNum, headerBGC, oddRowBGC, evenRowBGC, waitTime, headerHeight, columnWidth,
  940. align, index, carousel, hoverPause, fontColor, headerFontColor, oddRowGradBG, evenRowGradBG,
  941. enableBorder, borderColor, enableCarousel, fontSize, headerFontSize, onlyHeaderHoriBorder,
  942. onlyOuterBorder, onlyHeaderBorder, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, tableBGC,
  943. clickHighlight, highlightBGC, highlightGradBG, highlightNumber, highlightFontColor } = properties;
  944. const alignData = align.map(i => i.align);
  945. const colWidths = columnWidth.map(i => i.colW);
  946. const clickHandler = (ri, ci, row, cell) => {
  947. graphModel.eventCenter.emit("node:change", {
  948. data: model,
  949. e: {
  950. ri, ci, row, cell
  951. },
  952. });
  953. }
  954. if (this.instance) {
  955. // 实时数据不能推送一次就创建一次图表,可以在原有实例基础之上更改数据。
  956. Object.assign(this.instance.component.props, {
  957. name: properties.nodeAlias,
  958. onClick: clickHandler,
  959. config: {
  960. header: this.headerDatas,
  961. data: this.tableDatas,
  962. rowNum,
  963. waitTime: parseInt(waitTime),
  964. headerBGC,
  965. oddRowBGC: oddRowBGC || oddRowGradBG,
  966. evenRowBGC: evenRowBGC || evenRowGradBG,
  967. headerHeight,
  968. columnWidth: colWidths,
  969. align: alignData,
  970. index, carousel,
  971. hoverPause,
  972. },
  973. containerWidth: width,
  974. containerHeight: height, clickHighlight, highlightBGC, highlightGradBG, highlightNumber, highlightFontColor,
  975. fontColor, headerFontColor, enableBorder, borderColor, enableCarousel, fontSize, headerFontSize,
  976. onlyOuterBorder, onlyHeaderBorder, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, onlyHeaderHoriBorder, tableBGC
  977. })
  978. return
  979. }
  980. const el = document.createElement('div');
  981. rootEl.innerHTML = '';
  982. el.style.height = '100%';
  983. const instance = createVNode(ScrollTable, {
  984. name: properties.nodeAlias,
  985. onClick: clickHandler,
  986. config: {
  987. header: this.headerDatas,
  988. data: this.tableDatas,
  989. rowNum,
  990. waitTime: parseInt(waitTime),
  991. headerBGC,
  992. oddRowBGC: oddRowBGC || oddRowGradBG,
  993. evenRowBGC: evenRowBGC || evenRowGradBG,
  994. headerHeight,
  995. columnWidth: colWidths,
  996. align: alignData,
  997. index, carousel,
  998. hoverPause,
  999. },
  1000. containerWidth: width,
  1001. containerHeight: height, clickHighlight, highlightBGC, highlightGradBG, highlightNumber, highlightFontColor,
  1002. fontColor, headerFontColor, enableBorder, borderColor, enableCarousel, fontSize, headerFontSize,
  1003. onlyOuterBorder, onlyHeaderBorder, onlyBodyBorder, bodyBorderStyle, onlyHoriBorder, onlyHeaderHoriBorder, tableBGC
  1004. })
  1005. instance.appContext = app._context
  1006. render(instance, el)
  1007. rootEl.appendChild(el);
  1008. this.instance = instance;
  1009. }
  1010. sameProps(properties) {
  1011. const isSame = window._.isEqual(this.oldProperties, properties);
  1012. if (isSame) return true;
  1013. this.oldProperties = properties;
  1014. return false
  1015. }
  1016. filterDatasByGroup(datas, attrs) {
  1017. let headers = [];
  1018. let tableDatas = [];
  1019. if (datas.length > 0) {
  1020. headers = ['物编码', '物属性', '时间', '值', '单位'];
  1021. const datasGrouped = window._.groupBy(datas, 'attrKey');
  1022. const unitMap = {};
  1023. for (const key in attrs) {
  1024. unitMap[key] = attrs[key].unit;
  1025. }
  1026. for (const key in datasGrouped) {
  1027. const serieData = datasGrouped[key];
  1028. serieData.forEach(i => {
  1029. const time = window.dayjs(Number(i.ts)).format('YYYY-MM-DD HH:mm:ss');
  1030. tableDatas.push([i.thingCode, i.attrKey, time, i.val, unitMap[i.attrKey] || ''])
  1031. })
  1032. }
  1033. this.headerDatas = headers;
  1034. this.tableDatas = tableDatas;
  1035. }
  1036. }
  1037. filterHistoryData(thingCodeArr, totalAttrs, dataPointArr, apiid, renderIntervalEnabled) {
  1038. if (dataPointArr && dataPointArr.length > 0) {
  1039. let datas = []
  1040. if (renderIntervalEnabled) {
  1041. datas = window.totalHistoryDatas[apiid];
  1042. } else {
  1043. datas = window.globalDashboardDatas[apiid].values;
  1044. }
  1045. if (datas && datas.length > 0) {
  1046. const gotValues = datas.filter((val) => thingCodeArr.includes(val.thingCode) && dataPointArr.includes(val.attrKey))
  1047. this.filterDatasByGroup(gotValues, totalAttrs)
  1048. this.chartRendered = true;
  1049. }
  1050. }
  1051. }
  1052. renderEmpty(properties) {
  1053. const { emptyTable, colNum, rowNum } = properties;
  1054. if (emptyTable != undefined && emptyTable) {
  1055. // 渲染空表格
  1056. this.headerDatas = new Array(colNum).fill('');
  1057. this.tableDatas = new Array(rowNum * 2).fill('').map(() => this.headerDatas.slice());
  1058. } else {
  1059. this.headerDatas = defaultHeader;
  1060. this.tableDatas = defaultDatas;
  1061. }
  1062. this.chartRendered = true;
  1063. }
  1064. // 生命周期 支持重写内容, 但格式需一致
  1065. shouldUpdate() {
  1066. const { properties } = this.props.model;
  1067. const { apiid } = properties;
  1068. const { normalData } = properties.dynamic || {};
  1069. const { dataPointArr, thingCodeArr, customApiDatas, enableTestDatas, testDatas } = normalData || {}
  1070. let totalAttrs = {}
  1071. if (normalData && normalData.dataPoint) {
  1072. if (window.isJSON(normalData.dataPoint)) {
  1073. const dataPointStrParsed = JSON.parse(normalData.dataPoint || '{}')
  1074. const { attrs } = dataPointStrParsed;
  1075. totalAttrs = attrs;
  1076. }
  1077. }
  1078. if (!dataPointArr || (dataPointArr && dataPointArr.length === 0)) {
  1079. this.renderEmpty(properties);
  1080. }
  1081. // 如果采用来自自定义数据源的数据
  1082. if (customApiDatas) {
  1083. this.headerDatas = customApiDatas.headerDatas || defaultHeader;
  1084. this.tableDatas = customApiDatas.tableDatas || defaultDatas;
  1085. this.chartRendered = true;
  1086. }
  1087. if (enableTestDatas && testDatas) {
  1088. const fn = new Function('', testDatas);
  1089. const ret = fn();
  1090. if (ret && ret.headerDatas && ret.tableDatas) {
  1091. this.headerDatas = ret.headerDatas;
  1092. this.tableDatas = ret.tableDatas;
  1093. this.chartRendered = true;
  1094. }
  1095. }
  1096. const propertiesBack = window._.cloneDeep(properties);
  1097. // 由于事件change 会给properties 增加一个 event 属性(见目录scadaDashboard/Diagram/useDynamicEventsHandler),会引发属性的改变,导致组件重渲染。
  1098. delete propertiesBack.event;
  1099. if (propertiesBack.dynamic.normalData) {
  1100. propertiesBack.dynamic.normalData.defaultValue = '';
  1101. const isSameProps = this.sameProps(propertiesBack);
  1102. if (isSameProps && this.chartRendered) {
  1103. return false
  1104. } else {
  1105. if (dataPointArr && apiid && !this.chartRendered) {
  1106. this.filterHistoryData(thingCodeArr, totalAttrs, dataPointArr, apiid, normalData.renderIntervalEnabled);
  1107. return true;
  1108. }
  1109. }
  1110. return true
  1111. }
  1112. }
  1113. updateHtml() {
  1114. this.setHtml(this.rootEl);
  1115. }
  1116. componentDidMount() {
  1117. const { properties } = this.props.model;
  1118. const { normalData } = properties.dynamic || {};
  1119. const { renderInterval, dataPointArr, thingCodeArr } = normalData || {};
  1120. let totalAttrs = {}
  1121. if (normalData && normalData.dataPoint) {
  1122. if (window.isJSON(normalData.dataPoint)) {
  1123. const dataPointStrParsed = JSON.parse(normalData.dataPoint || '{}')
  1124. const { attrs } = dataPointStrParsed;
  1125. totalAttrs = attrs;
  1126. }
  1127. }
  1128. if (this.shouldUpdate()) {
  1129. this.setHtml(this.rootEl);
  1130. }
  1131. let inters = parseInt(renderInterval || '300000')
  1132. if (normalData && !normalData.renderIntervalEnabled) {
  1133. inters = 1000
  1134. }
  1135. setInterval(() => {
  1136. if (window.totalHistoryDatas && window.totalHistoryDatas[properties.apiid]) {
  1137. this.filterHistoryData(thingCodeArr, totalAttrs, dataPointArr, properties.apiid, normalData.renderIntervalEnabled);
  1138. this.setHtml(this.rootEl);
  1139. }
  1140. }, inters)
  1141. // 防止拖动时候频繁渲染图表
  1142. this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
  1143. }
  1144. componentDidUpdate() {
  1145. if (this.shouldUpdate()) {
  1146. this.updateHtmlDebounced();
  1147. }
  1148. }
  1149. }
  1150. class CustomScrollTableModel extends HtmlResize.model {
  1151. initNodeData(data) {
  1152. // 自定义组件,需最开始重置一下text 。
  1153. data.text = {
  1154. value: "",
  1155. x: data.x,
  1156. y: data.y,
  1157. };
  1158. super.initNodeData(data);
  1159. const { properties } = this;
  1160. this.width = properties.width || 80;
  1161. this.height = properties.height || 35;
  1162. this.text.editable = false; // 不允许文本被编辑
  1163. }
  1164. setAttributes() {
  1165. // 自定义组件需重置 text
  1166. const { x, y, properties } = this;
  1167. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  1168. this.text = {
  1169. ...this.text,
  1170. x: x + textHorizontalMove,
  1171. y: y + textVerticalMove,
  1172. value: "",
  1173. }
  1174. }
  1175. }
  1176. lf.register({
  1177. type: 'custom-scrolltable-node',
  1178. view: CustomScrollTableNode,
  1179. model: CustomScrollTableModel,
  1180. })`,css:`.bv-scroll-table {\r
  1181. position: relative;\r
  1182. width: 100%;\r
  1183. height: 100%;\r
  1184. color: #fff;\r
  1185. }\r
  1186. \r
  1187. .bv-scroll-table .text {\r
  1188. padding: 0 10px;\r
  1189. box-sizing: border-box;\r
  1190. white-space: nowrap;\r
  1191. overflow: hidden;\r
  1192. text-overflow: ellipsis;\r
  1193. }\r
  1194. \r
  1195. .bv-scroll-table .header {\r
  1196. display: flex;\r
  1197. flex-direction: row;\r
  1198. font-size: 15px;\r
  1199. }\r
  1200. \r
  1201. .bv-scroll-table .header .header-item {\r
  1202. padding: 0 10px;\r
  1203. box-sizing: border-box;\r
  1204. transition: all 0.3s;\r
  1205. }\r
  1206. \r
  1207. .bv-scroll-table .rows {\r
  1208. overflow: hidden;\r
  1209. }\r
  1210. \r
  1211. .bv-scroll-table .rows::-webkit-scrollbar {\r
  1212. width: 8px;\r
  1213. }\r
  1214. \r
  1215. /* Track */\r
  1216. .bv-scroll-table .rows::-webkit-scrollbar-track {\r
  1217. box-shadow: inset 0 0 1px grey;\r
  1218. border-radius: 4px;\r
  1219. }\r
  1220. \r
  1221. /* Handle */\r
  1222. .bv-scroll-table .rows::-webkit-scrollbar-thumb {\r
  1223. background: #006FFF;\r
  1224. border-radius: 4px;\r
  1225. }\r
  1226. \r
  1227. /* Handle on hover */\r
  1228. .bv-scroll-table .rows::-webkit-scrollbar-thumb:hover {\r
  1229. background: #0090FF;\r
  1230. }\r
  1231. \r
  1232. .bv-scroll-table .rows .row-item {\r
  1233. display: flex;\r
  1234. font-size: 14px;\r
  1235. transition: all 0.3s;\r
  1236. }\r
  1237. \r
  1238. .bv-scroll-table .rows .cell {\r
  1239. padding: 0 10px;\r
  1240. box-sizing: border-box;\r
  1241. white-space: nowrap;\r
  1242. overflow: hidden;\r
  1243. text-overflow: ellipsis;\r
  1244. }\r
  1245. \r
  1246. .bv-scroll-table .rows .index {\r
  1247. border-radius: 3px;\r
  1248. padding: 0 3px;\r
  1249. }\r
  1250. \r
  1251. .scroll-table-tooltip {\r
  1252. position: absolute;\r
  1253. display: inline-block;\r
  1254. background-color: rgba(0, 0, 0, 0.65);\r
  1255. color: #ffffff;\r
  1256. font-size: 12px;\r
  1257. padding: 5px 5px;\r
  1258. max-width: 120px;\r
  1259. max-height: 120px;\r
  1260. overflow-y: auto;\r
  1261. z-index: 8888;\r
  1262. transition: all 0.2s;\r
  1263. }`,fakeData:""},m={id:e,name:n,aliasName:t,image:a,imageType:o,groupName:r,groupType:l,isRemote:!1,isDefault:!0,sectionType:i,config:d,files:s};export{t as aliasName,d as config,m as default,s as files,r as groupName,l as groupType,e as id,a as image,o as imageType,c as isDefault,u as isRemote,n as name,i as sectionType};