Commit 44f575d9f489994999ff399b0cea3123c43d4fb8

Authored by xp.Huang
2 parents f5e8fcc4 df08498c

Merge branch 'ww' into 'main'

feat: implement dashboard chart component

See merge request huang/thingskit-drawio!40
... ... @@ -22,26 +22,26 @@
22 22 <meta name="mobile-web-app-capable" content="yes">
23 23 <meta name="theme-color" content="#d89000">
24 24
25   - <link rel="stylesheet" href="./js/plugin/layui/css/layui.css?v=1659336383769">
  25 + <link rel="stylesheet" href="./js/plugin/layui/css/layui.css?v=1659688272638">
26 26
27 27 <!-- load configure file -->
28   - <script src="./js/config/config.js?v=1659336383769"></script>
  28 + <script src="./js/config/config.js?v=1659688272638"></script>
29 29
30 30 <!-- crypto-js -->
31   - <script src="./js/plugin/crypto-js/crypto-js.js?v=1659336383769"></script>
  31 + <script src="./js/plugin/crypto-js/crypto-js.js?v=1659688272638"></script>
32 32
33 33 <!-- storage persistent -->
34   - <script src="./js/const/persistentStorage.js?v=1659336383769"></script>
  34 + <script src="./js/const/persistentStorage.js?v=1659688272638"></script>
35 35 <!-- Global const -->
36   - <script src="./js/const/const.js?v=1659336383769"></script>
  36 + <script src="./js/const/const.js?v=1659688272638"></script>
37 37
38 38 <!-- Axios -->
39   - <script src="./js/plugin/axios/axios.min.js?v=1659336383769"></script>
40   - <script src="./js/plugin/axios/DefHttp.js?v=1659336383769"></script>
41   - <script src="./js/api/index.js?v=1659336383769"></script>
  39 + <script src="./js/plugin/axios/axios.min.js?v=1659688272638"></script>
  40 + <script src="./js/plugin/axios/DefHttp.js?v=1659688272638"></script>
  41 + <script src="./js/api/index.js?v=1659688272638"></script>
42 42
43 43 <!-- load script -->
44   - <script src="./js/config/loadScript.js?v=1659336383769"></script>
  44 + <script src="./js/config/loadScript.js?v=1659688272638"></script>
45 45
46 46 <!-- act editor -->
47 47 <!-- <script src="https://oss.yuntengcloud.com/iotdocs/thingskit-scada/ace.js"></script> -->
... ... @@ -54,7 +54,7 @@
54 54 <!-- <script src="https://vjs.zencdn.net/7.10.2/video.min.js"></script> -->
55 55 <!-- <script src="https://oss.yuntengcloud.com/iotdocs/thingskit-scada/video.min.js"></script> -->
56 56
57   - <script src="./js/plugin/layui/layui.js?v=1659336383769"></script>
  57 + <script src="./js/plugin/layui/layui.js?v=1659688272638"></script>
58 58 <!-- <link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/layui/2.6.8/css/layui.min.css"
59 59 integrity="sha512-iQBJbsNHXUcgEIgWThd2dr8tOdKPvICwqjPEZYY81z3eMya44A5MiAqfWSCh+Ee1YzNYkdrI982Qhwgr8LEYOQ=="
60 60 crossorigin="anonymous" referrerpolicy="no-referrer" />
... ... @@ -63,7 +63,7 @@
63 63 crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
64 64
65 65 <!-- 引入修改样式 -->
66   - <link rel="stylesheet" href="./styles/formatChange.css?v=1659336383769">
  66 + <link rel="stylesheet" href="./styles/formatChange.css?v=1659688272638">
67 67
68 68 <script type="text/javascript">
69 69 /**
... ... @@ -590,7 +590,11 @@
590 590 </div>
591 591 <script>
592 592 var timeInterval = setInterval(() => {
593   - if (!echarts) return
  593 + try {
  594 + if (!echarts) return
  595 + } catch (error) {
  596 +
  597 + }
594 598 clearInterval(timeInterval)
595 599 timeInterval = null
596 600 var chartDom
... ... @@ -622,7 +626,7 @@
622 626 lineWidth: 1
623 627 },
624 628 keyframeAnimation: {
625   - duration: 3000,
  629 + duration: 1000,
626 630 loop: true,
627 631 keyframes: [
628 632 {
... ...
... ... @@ -225,6 +225,11 @@
225 225 LINE_CHART: 'lineChart',
226 226
227 227 /**
  228 + * @description 仪表盘 类型
  229 + */
  230 + DASHBOARD_CHART: 'dashboardChart',
  231 +
  232 + /**
228 233 * @description 柱状图类型
229 234 */
230 235 BAR_CHART: 'barChart',
... ... @@ -255,16 +260,22 @@
255 260 SWITCH_VALUE: 'switchValue',
256 261
257 262 /**
  263 + * @description 开关组件 下发值
  264 + */
  265 + SWITCH_SEND_VALUE: 'switchSendValue',
  266 +
  267 + /**
258 268 * @description 开关组件状态 {true | false | null}
259 269 */
260   - SWITCH_STATE: 'switchState'
  270 + SWITCH_STATE: 'switchState',
  271 +
261 272 }
262 273
263 274 Sidebar.prototype.enumComponentTypeValue = {
264 275 SWITCH_STATE_ENABLED: 'enabled',
265 276 SWITCH_STATE_CLOSE: 'close',
266 277 SWITCH_STATE_NONE: 'none',
267   - }
  278 + }
268 279
269 280 /**
270 281 * @description 组件权限map
... ... @@ -311,6 +322,11 @@
311 322 BAR_CHART_EXPAND: 'barChartExpandDataSource',
312 323
313 324 /**
  325 + * @description 仪表图
  326 + */
  327 + DASHBOARD_CHART_EXPAND: 'dashboradChartExpand',
  328 +
  329 + /**
314 330 * @descripton 交互
315 331 */
316 332 INTERACTION: 'interaction',
... ... @@ -700,8 +716,8 @@
700 716 //更多图形,显示出来的的标题跟id,同时包括图片
701 717
702 718 // TODO thingsKit 设置数据绑定展示面板
703   - const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL, SWITCH_STATE_SETTING, ONLY_SINGLE_EVENT, RUNNING_AND_STOP } = this.enumPermissionPanel
704   - const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO, SWITCH, PARAMS_SETTING_BUTTON } = this.enumComponentType
  719 + const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DASHBOARD_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL, SWITCH_STATE_SETTING, ONLY_SINGLE_EVENT, RUNNING_AND_STOP } = this.enumPermissionPanel
  720 + const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO, SWITCH, PARAMS_SETTING_BUTTON, DASHBOARD_CHART } = this.enumComponentType
705 721 this.setComponentPermission(LINE, [RUNNING_AND_STOP, DYNAMIC_EFFECT])
706 722 this.setComponentPermission(DEFAULT, [DYNAMIC_EFFECT])
707 723 this.setComponentPermission(REAL_TIME, [DYNAMIC_EFFECT])
... ... @@ -710,6 +726,7 @@
710 726 this.setComponentPermission(VARIABLE, [DATA_SOURCE, INTERACTION, DYNAMIC_EFFECT])
711 727 this.setComponentPermission(BAR_CHART, [DATA_SOURCE, BAR_CHART_EXPAND])
712 728 this.setComponentPermission(LINE_CHART, [DATA_SOURCE, LINE_CHART_EXPAND])
  729 + this.setComponentPermission(DASHBOARD_CHART, [DATA_SOURCE, DASHBOARD_CHART_EXPAND])
713 730 this.setComponentPermission(VIDEO, [VIDEO_PANEL])
714 731 this.setComponentPermission(SWITCH, [DATA_SOURCE, SWITCH_STATE_SETTING])
715 732 this.setComponentPermission(PARAMS_SETTING_BUTTON, [DATA_SOURCE, ONLY_SINGLE_EVENT])
... ...
... ... @@ -70,6 +70,11 @@
70 70 const cell = self.generatorCell(id, enumConst.CHART_IMG_PLACEHOLDER_SIZE, enumConst.CHART_IMG_PLACEHOLDER_SIZE, componentType.BAR_CHART, `${Proxy_Prefix}/images/thingskit/bar-chart.png`)
71 71 return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '柱状图');
72 72 })),
  73 + this.addEntry('dashboard chart', mxUtils.bind(this, function () {
  74 + const id = self.generatorChartsId()
  75 + const cell = self.generatorCell(id, enumConst.CHART_IMG_PLACEHOLDER_SIZE, enumConst.CHART_IMG_PLACEHOLDER_SIZE, componentType.DASHBOARD_CHART, `${Proxy_Prefix}/images/thingskit/dashboard-chart.png`)
  76 + return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '仪表盘');
  77 + }))
73 78 ];
74 79
75 80 this.addPaletteFunctions('charts', '图表', false, fns);
... ... @@ -89,42 +94,13 @@
89 94 */
90 95 Sidebar.prototype.chartOptionMapping = {
91 96 [Sidebar.prototype.enumComponentType.LINE_CHART]: function () {
92   - return {
93   - xAxis: {
94   - type: 'category',
95   - data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
96   - },
97   - yAxis: {
98   - type: 'value',
99   - },
100   - series: [
101   - {
102   - data: [150, 230, 224, 218, 135, 147, 260],
103   - type: 'line',
104   - },
105   - ],
106   - }
  97 + return getLineChartDefaultOption()
107 98 },
108 99 [Sidebar.prototype.enumComponentType.BAR_CHART]: function () {
109   - return {
110   - xAxis: {
111   - type: 'category',
112   - data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
113   - },
114   - yAxis: {
115   - type: 'value',
116   - },
117   - series: [
118   - {
119   - data: [120, 200, 150, 80, 70, 110, 130],
120   - type: 'bar',
121   - showBackground: true,
122   - backgroundStyle: {
123   - color: 'rgba(180, 180, 180, 0.2)',
124   - },
125   - },
126   - ],
127   - };
  100 + return getBarChartDefaultOption();
  101 + },
  102 + [Sidebar.prototype.enumComponentType.DASHBOARD_CHART]: function () {
  103 + return getDashboardDefaultOption()
128 104 },
129 105 }
130 106
... ... @@ -177,10 +153,11 @@
177 153 * @returns {boolean}
178 154 */
179 155 Sidebar.prototype.isChartCell = function (cell) {
180   - const basitAttr = this.enumCellBasicAttribute
  156 + const basicAttr = this.enumCellBasicAttribute
181 157 const componentType = this.enumComponentType
182   - const currentType = cell.getAttribute(basitAttr.COMPONENT_TYPE)
183   - return !!(currentType && (currentType === componentType.LINE_CHART || currentType === componentType.BAR_CHART))
  158 + const { LINE_CHART, BAR_CHART, DASHBOARD_CHART } = componentType
  159 + const currentType = cell.getAttribute(basicAttr.COMPONENT_TYPE)
  160 + return !!(currentType && ([LINE_CHART, BAR_CHART, DASHBOARD_CHART].includes(currentType)))
184 161 }
185 162
186 163 /**
... ... @@ -389,5 +366,119 @@
389 366 // Sidebar.prototype.initChartInstance(graph)
390 367 // }
391 368 // }
  369 + function getLineChartDefaultOption() {
  370 + return {
  371 + xAxis: {
  372 + type: 'category',
  373 + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
  374 + },
  375 + yAxis: {
  376 + type: 'value',
  377 + },
  378 + series: [
  379 + {
  380 + data: [150, 230, 224, 218, 135, 147, 260],
  381 + type: 'line',
  382 + },
  383 + ],
  384 + }
  385 + }
  386 +
  387 + function getBarChartDefaultOption() {
  388 + return {
  389 + xAxis: {
  390 + type: 'category',
  391 + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
  392 + },
  393 + yAxis: {
  394 + type: 'value',
  395 + },
  396 + series: [
  397 + {
  398 + data: [120, 200, 150, 80, 70, 110, 130],
  399 + type: 'bar',
  400 + showBackground: true,
  401 + backgroundStyle: {
  402 + color: 'rgba(180, 180, 180, 0.2)',
  403 + },
  404 + },
  405 + ],
  406 + }
  407 + }
  408 +
  409 + function getDashboardDefaultOption() {
  410 + return {
  411 + series: [
  412 + {
  413 + type: 'gauge',
  414 + center: ['50%', '60%'],
  415 + startAngle: 200,
  416 + endAngle: -20,
  417 + min: 0,
  418 + max: 100,
  419 + splitNumber: 10,
  420 + itemStyle: {
  421 + color: '#FFAB91'
  422 + },
  423 + progress: {
  424 + show: true,
  425 + width: 30
  426 + },
  427 + pointer: {
  428 + show: false
  429 + },
  430 + axisLine: {
  431 + lineStyle: {
  432 + width: 30
  433 + }
  434 + },
  435 + axisTick: {
  436 + distance: -45,
  437 + splitNumber: 5,
  438 + lineStyle: {
  439 + width: 2,
  440 + color: '#999'
  441 + }
  442 + },
  443 + splitLine: {
  444 + distance: -52,
  445 + length: 14,
  446 + lineStyle: {
  447 + width: 3,
  448 + color: '#999'
  449 + }
  450 + },
  451 + axisLabel: {
  452 + distance: -20,
  453 + color: '#999',
  454 + fontSize: 20
  455 + },
  456 + anchor: {
  457 + show: false
  458 + },
  459 + title: {
  460 + show: false
  461 + },
  462 + detail: {
  463 + valueAnimation: true,
  464 + width: '60%',
  465 + lineHeight: 40,
  466 + borderRadius: 8,
  467 + offsetCenter: [0, '-15%'],
  468 + fontSize: 25,
  469 + fontWeight: 'bolder',
  470 + formatter: '{value} °C',
  471 + color: 'auto'
  472 + },
  473 + data: [
  474 + {
  475 + value: 20
  476 + }
  477 + ]
  478 + },
  479 + ]
  480 + }
  481 + }
  482 +
392 483 })();
393 484
... ...
... ... @@ -5123,12 +5123,13 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5123 5123 async function initNode() {
5124 5124 const basicAttr = sidebarInstance.enumCellBasicAttribute
5125 5125 const permissionKey = sidebarInstance.enumPermissionPanel
5126   -
  5126 + const { LINE_CHART, BAR_CHART, DASHBOARD_CHART } = Sidebar.prototype.enumComponentType
5127 5127
5128 5128 const renderMapping = {
5129 5129 [permissionKey.DATA_SOURCE]: createDataSourcePanel,
5130   - [permissionKey.LINE_CHART_EXPAND]: createLineChartPanel,
5131   - [permissionKey.BAR_CHART_EXPAND]: createBarChartPanel,
  5130 + [permissionKey.LINE_CHART_EXPAND]: createChartBindPanel.bind(this, LINE_CHART),
  5131 + [permissionKey.BAR_CHART_EXPAND]: createChartBindPanel.bind(this, BAR_CHART),
  5132 + [permissionKey.DASHBOARD_CHART_EXPAND]: createChartBindPanel.bind(this, DASHBOARD_CHART),
5132 5133 [permissionKey.INTERACTION]: createInteractionPanel,
5133 5134 [permissionKey.DYNAMIC_EFFECT]: createDynamicEffectPanel,
5134 5135 [permissionKey.VAR_IMAGE]: createVarImagePanel,
... ... @@ -5259,13 +5260,20 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5259 5260 }
5260 5261
5261 5262 function createLineChartPanel() {
  5263 + const { LINE_CHART } = Sidebar.prototype.enumComponentType
5262 5264 createChartBindPanel(true)
5263 5265 }
5264 5266
5265 5267 function createBarChartPanel() {
  5268 + const { LINE_CHART } = Sidebar.prototype.enumComponentType
  5269 +
5266 5270 createChartBindPanel(false)
5267 5271 }
5268 5272
  5273 + function createDashboardPanel() {
  5274 + const { LINE_CHART } = Sidebar.prototype.enumComponentType
  5275 +
  5276 + }
5269 5277 /**
5270 5278 * @description 创建视频绑定面板
5271 5279 */
... ... @@ -5427,7 +5435,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5427 5435 * @description 是否是折线图
5428 5436 * @param {boolean} isLineChart
5429 5437 */
5430   - function createChartBindPanel(isLineChart) {
  5438 + function createChartBindPanel(chartType) {
5431 5439 const fragment = document.createDocumentFragment()
5432 5440 const chartBindContainer = document.createElement('div')
5433 5441 chartBindContainer.setAttribute('class', 'chart-panel__style')
... ... @@ -5438,8 +5446,12 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5438 5446 const enumActionEL = {
5439 5447 SCOPE_FILTER: 'bindChartScopeFilter',
5440 5448
5441   - INTERVAL_EL: 'bindChartIntervalSelect'
  5449 + INTERVAL_EL: 'bindChartIntervalSelect',
  5450 +
  5451 + UNIT_EL: 'bindChartUnit'
5442 5452 }
  5453 + const { LINE_CHART, BAR_CHART, DASHBOARD_CHART } = Sidebar.prototype.enumComponentType
  5454 +
5443 5455 const enumBindKey = HandleDataSource.enumConst
5444 5456 const enumDataType = HandleDataSource.enumDataBindType
5445 5457 const enumConst = {
... ... @@ -5462,7 +5474,12 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5462 5474 /**
5463 5475 * @description 间隔
5464 5476 */
5465   - INTERVAL: enumBindKey.INTERVAL
  5477 + INTERVAL: enumBindKey.INTERVAL,
  5478 +
  5479 + /**
  5480 + * @description 单位
  5481 + */
  5482 + UNIT: enumBindKey.UNIT
5466 5483 }
5467 5484
5468 5485 const enumTimeUnit = {
... ... @@ -5705,14 +5722,26 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5705 5722 { id: 'NONE', name: '空' },
5706 5723 ]
5707 5724
  5725 + function generateDataType() {
  5726 + const realOption = (checked) => `<input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.REAL}" title="实时" ${checked ? 'checked' : ''}>`
  5727 + const historyOption = (checked) => `<input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.HISTORY}" title="历史" ${checked ? 'checked' : ''}>`
  5728 +
  5729 + if (chartType === LINE_CHART) {
  5730 + return realOption() + historyOption(true)
  5731 + } else if (chartType === BAR_CHART) {
  5732 + return historyOption(true)
  5733 + } else if (chartType === DASHBOARD_CHART) {
  5734 + return realOption(true)
  5735 + }
  5736 + return realOption() + historyOption(true)
  5737 + }
  5738 +
5708 5739 function createSwitchBindTypeRadio() {
5709   - const realOption = `<input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.REAL}" title="实时">`
5710 5740 return `
5711 5741 <div class="layui-form-item">
5712 5742 <label class="layui-form-label">数据类型</label>
5713 5743 <div class="layui-input-block">
5714   - ${isLineChart ? realOption : ''}
5715   - <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.HISTORY}" title="历史" checked>
  5744 + ${generateDataType()}
5716 5745 </div>
5717 5746 </div>`
5718 5747 }
... ... @@ -5761,6 +5790,16 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5761 5790 </div>`
5762 5791 }
5763 5792
  5793 + function createUnitInput() {
  5794 + return `
  5795 + <div class="layui-form-item">
  5796 + <label class="layui-form-label">单位</label>
  5797 + <div class="layui-input-block" style="flex: 1;">
  5798 + <input id="${enumActionEL.UNIT_EL}" class="layui-input" value="°C" name="${enumConst.UNIT}" lay-filter="${enumConst.UNIT}" />
  5799 + </div>
  5800 + </div>`
  5801 + }
  5802 +
5764 5803 function generatorEventlisten() {
5765 5804 form.on(`select(${enumActionEL.SCOPE_FILTER})`, event => {
5766 5805 const value = event.value || 0
... ... @@ -5800,6 +5839,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5800 5839 $(chartBindContainer).append(createQueryScopeSelect())
5801 5840 $(chartBindContainer).append(createAggregationSelect())
5802 5841 $(chartBindContainer).append(createIntervalSelect())
  5842 + chartType === DASHBOARD_CHART && $(chartBindContainer).append(createUnitInput())
5803 5843 fragment.append(chartBindContainer)
5804 5844 $(container).append(fragment)
5805 5845 generatorEventlisten()
... ... @@ -5882,6 +5922,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5882 5922 [componentType.REAL_TIME]: getSubmitValue,
5883 5923 [componentType.LINE_CHART]: getSubmitValue,
5884 5924 [componentType.BAR_CHART]: getSubmitValue,
  5925 + [componentType.DASHBOARD_CHART]: getSubmitValue,
5885 5926 [componentType.DEFAULT]: getSubmitValue,
5886 5927 [componentType.VIDEO]: getVideoSubmitValue,
5887 5928 [componentType.SWITCH]: getSwitchSubmitValue,
... ... @@ -5911,7 +5952,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5911 5952 [additionalKey.AGG]: field[additionalKey.AGG],
5912 5953 [additionalKey.DATA_TYPE]: field[additionalKey.DATA_TYPE],
5913 5954 [additionalKey.INTERVAL]: field[additionalKey.INTERVAL],
5914   - [additionalKey.EFFECT_SCOPE]: field[additionalKey.EFFECT_SCOPE]
  5955 + [additionalKey.EFFECT_SCOPE]: field[additionalKey.EFFECT_SCOPE],
  5956 + ...(field[additionalKey.UNIT] ? { [additionalKey.UNIT]: field[additionalKey.UNIT] } : {})
5915 5957 } : null
5916 5958 },
5917 5959 }
... ... @@ -13204,6 +13246,11 @@ class HandleDataSource {
13204 13246 INTERVAL: 'interval',
13205 13247
13206 13248 /**
  13249 + * @description 单位
  13250 + */
  13251 + UNIT: 'unit',
  13252 +
  13253 + /**
13207 13254 * @description 开始时间
13208 13255 */
13209 13256 STARTTs: 'startTs',
... ... @@ -13286,6 +13333,10 @@ class HandleDataSource {
13286 13333 return Sidebar.prototype.enumComponentType
13287 13334 }
13288 13335
  13336 + get contentAllCell() {
  13337 + return this.graph.getDefaultParent().children || []
  13338 + }
  13339 +
13289 13340 /**
13290 13341 * @description 生成普通数据源绑定映射关系
13291 13342 * @param dataSources
... ... @@ -13405,17 +13456,23 @@ class HandleDataSource {
13405 13456 const { condition = [] } = switchConfig || {}
13406 13457 let reg = /image=[^;]+/g
13407 13458 let flag = false
13408   - const { SWITCH_STATE, SWITCH_VALUE } = Sidebar.prototype.enumComponentType
  13459 + const { SWITCH_STATE, SWITCH_VALUE, SWITCH_SEND_VALUE } = Sidebar.prototype.enumComponentType
13409 13460 const { SWITCH_STATE_NONE } = Sidebar.prototype.enumComponentTypeValue
  13461 +
  13462 + const getSendValue = (type) => {
  13463 + return (condition.find(item => item.type !== type) || {}).value
  13464 + }
13410 13465 for (const item of condition) {
13411 13466 const { value, imagePath, type } = item || {}
13412 13467 if (Number(receiveValue) === Number(value)) {
13413 13468 flag = true
13414 13469 this.updatePage(() => {
13415 13470 const style = node.getStyle()
  13471 + const sendValue = getSendValue(type)
13416 13472 node.setStyle(style.replace(reg, `image=${imagePath}`))
13417 13473 node.setAttribute('label', '')
13418 13474 node.setAttribute(SWITCH_VALUE, receiveValue)
  13475 + node.setAttribute(SWITCH_SEND_VALUE, sendValue)
13419 13476 node.setAttribute(SWITCH_STATE, type)
13420 13477 }, node)
13421 13478 break
... ... @@ -13430,6 +13487,7 @@ class HandleDataSource {
13430 13487 node.setAttribute(SWITCH_STATE, SWITCH_STATE_NONE)
13431 13488 }, node)
13432 13489 }
  13490 +
13433 13491 }
13434 13492
13435 13493 handleParamSettingButton(message) {
... ... @@ -13458,139 +13516,21 @@ class HandleDataSource {
13458 13516 const instance = chartInstanceMap.get(chartInstanceId)
13459 13517 const { attr = [[]] } = this.getBindData(subscriptionId)
13460 13518 const realDataList = data[attr] || []
13461   - const showNumberOf = 4
13462   - const action = agg === 'NONE' ? 'unshift' : 'push'
13463 13519
13464   - // const chartWidth = node.getAttribute('width')
13465   - // const chartHeight = node.getAttribute('height')
  13520 + const action = agg === 'NONE' ? 'unshift' : 'push'
13466 13521
13467 13522 // chart insstance 是否已经接受过一次消息推送
13468 13523 const isActive = instance.isActive
13469 13524 if (!isActive) {
13470 13525 instance.isActive = true
13471   - const xAxisData = []
13472   - const seriesValue = []
13473   - const chartOption = {
13474   - title: {
13475   - subtext: realDataList.length ? '' : '暂无数据',
13476   - x: 'center',
13477   - y: 'center',
13478   - itemGap: -20,
13479   - subtextStyle: {
13480   - fontSize: 16
13481   - }
13482   - },
13483   - tooltip: {
13484   - trigger: 'axis',
13485   - axisPointer: {
13486   - type: 'shadow'
13487   - }
13488   - },
13489   - grid: {
13490   - left: '3%',
13491   - right: '3%',
13492   - bottom: '3%',
13493   - containLabel: true,
13494   - },
13495   - xAxis: {
13496   - type: 'category',
13497   - data: xAxisData,
13498   - boundaryGap: true,
13499   - axisLabel: {
13500   - rotate: 70
13501   - },
13502   - axisPointer: {
13503   - label: {
13504   - formatter() {
13505   - return attr
13506   - }
13507   - }
13508   - }
13509   - },
13510   - yAxis: {
13511   - type: 'value'
13512   - },
13513   - series: [
13514   - {
13515   - data: seriesValue,
13516   - type: chartInstanceType.includes('bar') ? 'bar' : 'line'
13517   - }
13518   - ],
13519   - dataZoom: [
13520   - {
13521   - show: true,
13522   - type: 'inside',
13523   - // endValue: showNumberOf
13524   - }
13525   - ]
13526   - }
13527   -
13528   - // for (let i = realDataList.length - 1; i >= 0; i--) {
13529   - // const [timespan, value] = realDataList[i]
13530   - // xAxisData.push(new Date(Number(timespan)).toLocaleTimeString())
13531   - // seriesValue.push(Number(value))
13532   - // }
13533   - realDataList.forEach(item => {
13534   - const [timespan, value] = item
13535   - xAxisData[action](new Date(Number(timespan)).toLocaleTimeString())
13536   - seriesValue[action](Number(value))
13537   - })
13538   -
  13526 + const chartOption = this.getChartComponentOption(chartInstanceType, { chartType: chartInstanceType, attr, dataList: realDataList, action, nodeId: node.id })
13539 13527 instance.setOption(chartOption)
13540 13528
13541 13529 } else {
13542 13530 const oldOptions = instance.getOption()
13543   - const xAxisData = oldOptions.xAxis[0].data || []
13544   - const seriesValue = oldOptions.series[0].data || []
13545   - const oldEndValue = Number(oldOptions.dataZoom[0].endValue) || 0
13546   - const oldStartValue = Number(oldOptions.dataZoom[0].startValue) || 0
13547   -
13548   - for (let i = realDataList.length - 1; i >= 0; i--) {
13549   - const [timespan, value] = realDataList[i]
13550   - xAxisData.push(new Date(Number(timespan)).toLocaleTimeString())
13551   - seriesValue.push(Number(value))
13552   - }
13553   -
13554   - if (Number(oldOptions.dataZoom[0].endValue) === seriesValue.length - 1) {
13555   - oldOptions.dataZoom[0].endValue = showNumberOf
13556   - oldOptions.dataZoom[0].startValue = 0
13557   - } else {
13558   - oldOptions.dataZoom[0].endValue = oldOptions.dataZoom[0].endValue + 1
13559   - oldOptions.dataZoom[0].startValue = oldOptions.dataZoom[0].startValue + 1
13560   - }
13561   -
  13531 + const options = this.getRealTimeUpdateChartOption(chartInstanceType, { oldOptions, dataList: realDataList })
13562 13532 if (!instance) clearInterval(interval)
13563   - instance && instance.setOption({
13564   - title: {
13565   - subtext: ''
13566   - },
13567   - xAxis: {
13568   - data: xAxisData
13569   - },
13570   - series: [
13571   - {
13572   - data: seriesValue
13573   - }
13574   - ],
13575   - dataZoom: [
13576   - {
13577   - show: true,
13578   - type: 'inside',
13579   - }
13580   - // {
13581   - // startValue: seriesValue.length - 1 > showNumberOf
13582   - // ? oldStartValue === seriesValue.length - 1
13583   - // ? 0
13584   - // : oldStartValue + 1
13585   - // : 0,
13586   - // endValue: seriesValue.length - 1 > showNumberOf
13587   - // ? oldEndValue === seriesValue.length - 1
13588   - // ? showNumberOf
13589   - // : oldEndValue + 1
13590   - // : showNumberOf
13591   - // }
13592   - ]
13593   - })
  13533 + instance && instance.setOption(options)
13594 13534 }
13595 13535 }
13596 13536
... ... @@ -13611,12 +13551,91 @@ class HandleDataSource {
13611 13551 const showNumberOf = 4
13612 13552 const action = agg === 'NONE' ? 'unshift' : 'push'
13613 13553
  13554 + const chartOption = this.getChartComponentOption(chartInstanceType, { dataList: historyDataList, attr, chartType: chartInstanceType, action })
  13555 +
  13556 + let interval
  13557 + // TODO 清除定时器
  13558 + function autoMove() {
  13559 + if (seriesValue.length <= 5) return
  13560 + interval = setInterval(() => {
  13561 + if (Number(chartOption.dataZoom[0].endValue) === seriesValue.length - 1) {
  13562 + chartOption.dataZoom[0].endValue = showNumberOf
  13563 + chartOption.dataZoom[0].startValue = 0
  13564 + } else {
  13565 + chartOption.dataZoom[0].endValue = chartOption.dataZoom[0].endValue + 1
  13566 + chartOption.dataZoom[0].startValue = chartOption.dataZoom[0].startValue + 1
  13567 + }
  13568 + if (!chartInstanceMap.has(chartInstanceId)) {
  13569 + clearInterval(interval)
  13570 + return
  13571 + }
  13572 + instance && instance.setOption(chartOption)
  13573 +
  13574 + }, 2000);
  13575 + }
  13576 +
  13577 + function stop() {
  13578 + clearInterval(interval)
  13579 + }
  13580 +
  13581 + function goMove() {
  13582 + autoMove()
  13583 + }
  13584 +
  13585 + instance.setOption(chartOption)
  13586 + // instance.on('mouseover', stop)
  13587 + // instance.on('mouseout', goMove)
  13588 + // autoMove()
  13589 + }
  13590 +
  13591 + getChartComponentOption(chartInstanceType, params) {
  13592 + const { LINE_CHART, BAR_CHART, DASHBOARD_CHART } = Sidebar.prototype.enumComponentType
  13593 + switch (chartInstanceType) {
  13594 + case LINE_CHART:
  13595 + return this.getBasicChartOption(Object.assign(params, { chartType: 'line' }))
  13596 + case BAR_CHART:
  13597 + return this.getBasicChartOption(Object.assign(params, { chartType: 'bar' }))
  13598 + case DASHBOARD_CHART:
  13599 + return this.getDashboardChartOption(params)
  13600 + default:
  13601 + return {}
  13602 + }
  13603 + }
  13604 +
  13605 + getRealTimeUpdateChartOption(chartInstanceType, params) {
  13606 + const { LINE_CHART, BAR_CHART, DASHBOARD_CHART } = Sidebar.prototype.enumComponentType
  13607 + switch (chartInstanceType) {
  13608 + case LINE_CHART:
  13609 + return this.getRealTimeUpdateBasicChartOption(params)
  13610 + case BAR_CHART:
  13611 + return this.getRealTimeUpdateBasicChartOption(params)
  13612 + case DASHBOARD_CHART:
  13613 + return this.getRealTimeUpdateDashboardChartOption(params)
  13614 + default:
  13615 + return {}
  13616 + }
  13617 + }
  13618 +
  13619 + /**
  13620 + *
  13621 + * @param {@} params
  13622 + * @returns
  13623 + */
  13624 + getBasicChartOption(params = { dataList: [], attr: '', chartType: 'bar', action }) {
  13625 + const { dataList = [], attr = '', chartType = 'bar', action } = params
13614 13626
13615 13627 const xAxisData = []
13616 13628 const seriesValue = []
13617   - const chartOption = {
  13629 +
  13630 + dataList.forEach(item => {
  13631 + const [timespan, value] = item
  13632 + xAxisData[action](new Date(Number(timespan)).toLocaleTimeString())
  13633 + seriesValue[action](Number(value))
  13634 + })
  13635 +
  13636 + return {
13618 13637 title: {
13619   - subtext: historyDataList.length ? '' : '暂无数据',
  13638 + subtext: dataList.length ? '' : '暂无数据',
13620 13639 x: 'center',
13621 13640 y: 'center',
13622 13641 itemGap: -20,
... ... @@ -13658,59 +13677,157 @@ class HandleDataSource {
13658 13677 series: [
13659 13678 {
13660 13679 data: seriesValue,
13661   - type: chartInstanceType.includes('bar') ? 'bar' : 'line',
  13680 + type: chartType,
13662 13681 }
13663 13682 ],
13664 13683 dataZoom: [
13665 13684 {
13666   - // xAxisIndex: 0,
13667 13685 show: true,
13668   - type: 'inside',
13669   - // startValue: 0,
13670   - // endValue: showNumberOf
  13686 + type: 'inside'
13671 13687 }
13672 13688 ]
13673 13689 }
  13690 + }
13674 13691
13675   - historyDataList.forEach(item => {
13676   - const [timespan, value] = item
13677   - xAxisData[action](new Date(Number(timespan)).toLocaleTimeString())
13678   - seriesValue[action](Number(value))
13679   - })
  13692 + getRealTimeUpdateBasicChartOption(params = { oldOptions: {}, dataList: [] }) {
  13693 + const { oldOptions, dataList } = params
  13694 + const xAxisData = oldOptions.xAxis[0].data || []
  13695 + const seriesValue = oldOptions.series[0].data || []
  13696 + const oldEndValue = Number(oldOptions.dataZoom[0].endValue) || 0
  13697 + const oldStartValue = Number(oldOptions.dataZoom[0].startValue) || 0
  13698 + const showNumberOf = 4
13680 13699
13681   - let interval
13682   - // TODO 清除定时器
13683   - function autoMove() {
13684   - if (seriesValue.length <= 5) return
13685   - interval = setInterval(() => {
13686   - if (Number(chartOption.dataZoom[0].endValue) === seriesValue.length - 1) {
13687   - chartOption.dataZoom[0].endValue = showNumberOf
13688   - chartOption.dataZoom[0].startValue = 0
13689   - } else {
13690   - chartOption.dataZoom[0].endValue = chartOption.dataZoom[0].endValue + 1
13691   - chartOption.dataZoom[0].startValue = chartOption.dataZoom[0].startValue + 1
13692   - }
13693   - if (!chartInstanceMap.has(chartInstanceId)) {
13694   - clearInterval(interval)
13695   - return
13696   - }
13697   - instance && instance.setOption(chartOption)
  13700 + for (let i = dataList.length - 1; i >= 0; i--) {
  13701 + const [timespan, value] = dataList[i]
  13702 + xAxisData.push(new Date(Number(timespan)).toLocaleTimeString())
  13703 + seriesValue.push(Number(value))
  13704 + }
13698 13705
13699   - }, 2000);
  13706 + if (Number(oldOptions.dataZoom[0].endValue) === seriesValue.length - 1) {
  13707 + oldOptions.dataZoom[0].endValue = showNumberOf
  13708 + oldOptions.dataZoom[0].startValue = 0
  13709 + } else {
  13710 + oldOptions.dataZoom[0].endValue = oldOptions.dataZoom[0].endValue + 1
  13711 + oldOptions.dataZoom[0].startValue = oldOptions.dataZoom[0].startValue + 1
13700 13712 }
13701 13713
13702   - function stop() {
13703   - clearInterval(interval)
  13714 + return {
  13715 + title: {
  13716 + subtext: ''
  13717 + },
  13718 + xAxis: {
  13719 + data: xAxisData
  13720 + },
  13721 + series: [
  13722 + {
  13723 + data: seriesValue
  13724 + }
  13725 + ],
  13726 + dataZoom: [
  13727 + {
  13728 + show: true,
  13729 + type: 'inside',
  13730 + }
  13731 + ]
13704 13732 }
  13733 + }
13705 13734
13706   - function goMove() {
13707   - autoMove()
  13735 + getDashboardChartOption(params = { dataList: [], nodeId }) {
  13736 + const { dataList = [], nodeId } = params
  13737 + const dataSource = this.DispatchInstance.contentData.dataSources.find(item => item.nodeId === nodeId) || {}
  13738 + const { additional: { unit = '°C' } = {} } = dataSource
  13739 +
  13740 + const [timespan, value] = dataList[0] || []
  13741 + return {
  13742 + series: [
  13743 + {
  13744 + type: 'gauge',
  13745 + center: ['50%', '60%'],
  13746 + startAngle: 200,
  13747 + endAngle: -20,
  13748 + min: 0,
  13749 + max: 100,
  13750 + splitNumber: 10,
  13751 + itemStyle: {
  13752 + color: '#FFAB91'
  13753 + },
  13754 + progress: {
  13755 + show: true,
  13756 + width: 30
  13757 + },
  13758 + pointer: {
  13759 + show: false
  13760 + },
  13761 + axisLine: {
  13762 + lineStyle: {
  13763 + width: 30
  13764 + }
  13765 + },
  13766 + axisTick: {
  13767 + distance: -45,
  13768 + splitNumber: 5,
  13769 + lineStyle: {
  13770 + width: 2,
  13771 + color: '#999'
  13772 + }
  13773 + },
  13774 + splitLine: {
  13775 + distance: -52,
  13776 + length: 14,
  13777 + lineStyle: {
  13778 + width: 3,
  13779 + color: '#999'
  13780 + }
  13781 + },
  13782 + axisLabel: {
  13783 + distance: -20,
  13784 + color: '#999',
  13785 + fontSize: 20
  13786 + },
  13787 + anchor: {
  13788 + show: false
  13789 + },
  13790 + title: {
  13791 + show: false
  13792 + },
  13793 + detail: {
  13794 + valueAnimation: true,
  13795 + width: '60%',
  13796 + lineHeight: 40,
  13797 + borderRadius: 8,
  13798 + offsetCenter: [0, '-15%'],
  13799 + fontSize: 25,
  13800 + fontWeight: 'bolder',
  13801 + formatter: `{value} ${unit}`,
  13802 + color: 'auto'
  13803 + },
  13804 + data: [
  13805 + {
  13806 + value
  13807 + }
  13808 + ]
  13809 + }
  13810 + ]
13708 13811 }
  13812 + }
13709 13813
13710   - instance.setOption(chartOption)
13711   - // instance.on('mouseover', stop)
13712   - // instance.on('mouseout', goMove)
13713   - // autoMove()
  13814 + /**
  13815 + * @description 获取仪表盘配置
  13816 + */
  13817 + getRealTimeUpdateDashboardChartOption(params = { dataList: [] }) {
  13818 + const { dataList = [] } = params
  13819 + const [timespan, value] = dataList[0] || []
  13820 + return {
  13821 + series: [
  13822 + {
  13823 + data: [
  13824 + {
  13825 + value
  13826 + }
  13827 + ]
  13828 + },
  13829 + ]
  13830 + }
13714 13831 }
13715 13832
13716 13833 /**
... ... @@ -13750,7 +13867,7 @@ class HandleDataSource {
13750 13867 */
13751 13868 getNodeByCmdId(subscriptionId) {
13752 13869 const nodeId = this.getNodeIdByCmdId(subscriptionId)
13753   - return this.DispatchInstance.contentAllCell.find(item => item.id === nodeId)
  13870 + return this.contentAllCell.find(item => item.id === nodeId)
13754 13871 }
13755 13872
13756 13873 getComponentType(node) {
... ... @@ -13831,6 +13948,10 @@ class HandleDataInteraction {
13831 13948 return DispatchCenter.instance.contentData
13832 13949 }
13833 13950
  13951 + get contentAllCell() {
  13952 + return this.graph.getDefaultParent().children || []
  13953 + }
  13954 +
13834 13955 /**
13835 13956 * @description 事件映射
13836 13957 */
... ... @@ -14027,11 +14148,11 @@ class HandleDataInteraction {
14027 14148 */
14028 14149 paramsSetting(nodeId, content) {
14029 14150 const { layer, jquery: $, form } = layui
14030   - const { SWITCH_STATE, SWITCH_VALUE, SWITCH, PARAMS_SETTING_BUTTON } = Sidebar.prototype.enumComponentType
14031   - const { SWITCH_STATE_ENABLED, SWITCH_STATE_NONE, SWITCH_STATE_CLOSE } = Sidebar.prototype.enumComponentTypeValue
  14151 + const { SWITCH_STATE, SWITCH_VALUE, SWITCH_SEND_VALUE, SWITCH, PARAMS_SETTING_BUTTON } = Sidebar.prototype.enumComponentType
  14152 + const { SWITCH_STATE_NONE } = Sidebar.prototype.enumComponentTypeValue
14032 14153 const { COMPONENT_TYPE } = Sidebar.prototype.enumCellBasicAttribute
14033 14154 const contentData = this.contentData
14034   - const currentNode = this.DispatchInstance.contentAllCell.find(item => item.id === nodeId)
  14155 + const currentNode = this.contentAllCell.find(item => item.id === nodeId)
14035 14156
14036 14157 const enumConst = {
14037 14158 VALUE: 'value',
... ... @@ -14072,39 +14193,12 @@ class HandleDataInteraction {
14072 14193
14073 14194 function handleSwitchComponent() {
14074 14195 const state = currentNode.getAttribute(SWITCH_STATE)
14075   - const value = currentNode.getAttribute(SWITCH_VALUE)
  14196 + const value = currentNode.getAttribute(SWITCH_SEND_VALUE)
14076 14197 if (state === SWITCH_STATE_NONE) {
14077 14198 return
14078 14199 }
14079 14200 layer.confirm('是否确认下发命令?', async function (index) {
14080   - let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {}
14081   - let { command, way } = content
14082   - const validate = new Validate([
14083   - { value, required: true, message: '下发值是必填项' },
14084   - { value: deviceId, required: true, message: '未绑定设备' },
14085   - { value: way, required: true, message: '未绑定指令下发方式(单向/双向)' },
14086   - { value: command, required: true, message: '未设置下发命令' },
14087   - { value: attr, required: true, message: '未绑定设备属性' },
14088   - ])
14089   - if (!validate.begin()) return
14090   - if (typeof command === 'string') command = jsonParse(command)
14091   - const data = replaceAttrPlaceholder(command, attr, value)
14092   - const instructionData = {
14093   - method: "methodThingskit",
14094   - params: data,
14095   - }
14096   -
14097   - const [err, res = []] = await to(ConfigurationNodeApi.deviceIsOnLine(deviceId))
14098   - const { value: onlineFlag } = res[0] || {}
14099   - if (onlineFlag) {
14100   - const [err, res] = await to(ConfigurationNodeApi.sendInstruction(way, deviceId, instructionData))
14101   - if (!err) {
14102   - UseLayUi.topSuccessMsg('操作成功')
14103   - layer.close(index);
14104   - }
14105   - } else {
14106   - UseLayUi.topErrorMsg('设备不在线!')
14107   - }
  14201 + defaultHandler(value, () => layer.close(index))
14108 14202 });
14109 14203
14110 14204
... ... @@ -14131,6 +14225,10 @@ class HandleDataInteraction {
14131 14225 const submitThrottle = this.throttle(submit)
14132 14226 async function submit(callback) {
14133 14227 const { value } = form.val(enumActionEl.ISSUED_WAY_FILTER)
  14228 + defaultHandler(value, callback)
  14229 + }
  14230 +
  14231 + async function defaultHandler(value, callback) {
14134 14232 let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {}
14135 14233 let { command, way } = content
14136 14234 const validate = new Validate([
... ... @@ -14154,7 +14252,7 @@ class HandleDataInteraction {
14154 14252 const [err, res] = await to(ConfigurationNodeApi.sendInstruction(way, deviceId, instructionData))
14155 14253 if (!err) {
14156 14254 UseLayUi.topSuccessMsg('操作成功')
14157   - callback()
  14255 + callback && typeof callback === 'function' && callback()
14158 14256 }
14159 14257 } else {
14160 14258 UseLayUi.topErrorMsg('设备不在线!')
... ... @@ -14197,7 +14295,6 @@ class HandleDataInteraction {
14197 14295
14198 14296 }
14199 14297 }
14200   - console.log('enter')
14201 14298 startProcess()
14202 14299 }
14203 14300 }
... ... @@ -14353,6 +14450,10 @@ class HandleDynamicEffect {
14353 14450 return this.DispatchInstance.updateQueueInstance.delUpdateFn.bind(this.DispatchInstance.updateQueueInstance)
14354 14451 }
14355 14452
  14453 + get contentAllCell() {
  14454 + return this.graph.getDefaultParent().children || []
  14455 + }
  14456 +
14356 14457 /**
14357 14458 * @description 筛选出视频数据源
14358 14459 */
... ... @@ -14368,7 +14469,7 @@ class HandleDynamicEffect {
14368 14469 getEnableActList() {
14369 14470 const { act = [] } = this.DispatchInstance.contentData
14370 14471 // 过滤页面中没有的节点及未开启动效的节点
14371   - this.enableActList = act.filter(item => this.DispatchInstance.contentAllCell.find(each => each.id === item.id) && item.enabled)
  14472 + this.enableActList = act.filter(item => this.contentAllCell.find(each => each.id === item.id) && item.enabled)
14372 14473 // this.enableActList = act.filter(item => item.enabled)
14373 14474 }
14374 14475
... ... @@ -14640,7 +14741,6 @@ class HandleDynamicEffect {
14640 14741 const { geometry = {} } = cell
14641 14742 const { width, height } = geometry
14642 14743 const idEl = getIdEl()
14643   - console.log({ idEl })
14644 14744 graph.getModel().beginUpdate()
14645 14745 try {
14646 14746 let type
... ... @@ -14676,7 +14776,7 @@ class HandleDynamicEffect {
14676 14776 * @description 获取cell 通过cell id
14677 14777 */
14678 14778 getCellByCellId(id) {
14679   - const allCell = this.DispatchInstance.contentAllCell || []
  14779 + const allCell = this.contentAllCell || []
14680 14780 return allCell.find(item => item.id === id)
14681 14781 }
14682 14782
... ... @@ -14742,7 +14842,7 @@ class HandleDynamicEffect {
14742 14842 */
14743 14843 getNodeByCmdId(subscriptionId) {
14744 14844 const nodeId = this.getNodeIdByCmdId(subscriptionId)
14745   - return this.DispatchInstance.contentAllCell.find(item => item.id === nodeId)
  14845 + return this.contentAllCell.find(item => item.id === nodeId)
14746 14846 }
14747 14847
14748 14848 /**
... ...
... ... @@ -482,7 +482,7 @@
482 482 }
483 483
484 484 .chart-panel__style .layui-form-label {
485   - width: 60px;
  485 + flex: 0 0 60px;
486 486 box-sizing: border-box;
487 487 padding: 9px 10px 9px 0;
488 488 }
... ...