Commit 485ac3c3b2af9055c8fa524b0a7c2e07b9a4b9f3

Authored by ww
1 parent 97ae6841

wip: chart basic implement

@@ -195,12 +195,13 @@ LocalFile.prototype.saveFile = function (title, revision, success, error, useCur @@ -195,12 +195,13 @@ LocalFile.prototype.saveFile = function (title, revision, success, error, useCur
195 this.removeDraft(); 195 this.removeDraft();
196 Editor.defaultContent = savedData; 196 Editor.defaultContent = savedData;
197 var configurationContentList = []; 197 var configurationContentList = [];
198 - console.log('EditorUi', this.ui.editor.graph.getDefaultParent().children)  
199 const basicAttr = Sidebar.prototype.enumCellBasicAttribute 198 const basicAttr = Sidebar.prototype.enumCellBasicAttribute
200 const allCell = (this.ui.editor.graph.getDefaultParent().children || []).filter(item => item.getAttribute(basicAttr.COMPONENT_TYPE)) 199 const allCell = (this.ui.editor.graph.getDefaultParent().children || []).filter(item => item.getAttribute(basicAttr.COMPONENT_TYPE))
  200 + const contentId = this.ui.currentPage.node.id
201 var configurationContent = { 201 var configurationContent = {
202 name: "第 1 页", 202 name: "第 1 页",
203 id: Editor.configurationContentId, 203 id: Editor.configurationContentId,
  204 + contentId,
204 content: savedData, 205 content: savedData,
205 type: 1, 206 type: 1,
206 nodeIds: allCell.map(item => item.id) 207 nodeIds: allCell.map(item => item.id)
@@ -166,7 +166,12 @@ @@ -166,7 +166,12 @@
166 /** 166 /**
167 * @description 组件类型 167 * @description 组件类型
168 */ 168 */
169 - COMPONENT_TYPE: 'componentType' 169 + COMPONENT_TYPE: 'componentType',
  170 +
  171 + /**
  172 + * @description 图表实例ID
  173 + */
  174 + CHART_INSTANCE_ID: 'chartInstanceId'
170 } 175 }
171 176
172 /** 177 /**
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 /** 24 /**
25 * @description cell id key 25 * @description cell id key
26 */ 26 */
27 - CHART_CELL_ID: 'chartInstanceId', 27 + CHART_INSTANCE_ID: 'chartInstanceId',
28 28
29 /** 29 /**
30 * @description 图表容器 class name 30 * @description 图表容器 class name
@@ -143,7 +143,7 @@ @@ -143,7 +143,7 @@
143 const basicAttr = this.enumCellBasicAttribute 143 const basicAttr = this.enumCellBasicAttribute
144 this.setCellAttributes(cell, { 144 this.setCellAttributes(cell, {
145 [basicAttr.COMPONENT_TYPE]: chartType, 145 [basicAttr.COMPONENT_TYPE]: chartType,
146 - [enumConst.CHART_CELL_ID]: id, 146 + [basicAttr.CHART_INSTANCE_ID]: id,
147 [enumConst.CHART_CELL_WIDTH]: width, 147 [enumConst.CHART_CELL_WIDTH]: width,
148 [enumConst.CHART_CELL_HEIGHT]: height, 148 [enumConst.CHART_CELL_HEIGHT]: height,
149 }) 149 })
@@ -208,7 +208,8 @@ @@ -208,7 +208,8 @@
208 * @returns {*} 208 * @returns {*}
209 */ 209 */
210 Sidebar.prototype.getCellId = function (cell) { 210 Sidebar.prototype.getCellId = function (cell) {
211 - return this.graph.getAttributeForCell(cell, enumConst.CHART_CELL_ID) 211 + const basicAttr = this.enumCellBasicAttribute
  212 + return this.graph.getAttributeForCell(cell, basicAttr.CHART_INSTANCE_ID)
212 } 213 }
213 214
214 /** 215 /**
@@ -238,7 +239,7 @@ @@ -238,7 +239,7 @@
238 const id = self.generatorChartsId() 239 const id = self.generatorChartsId()
239 const geo = Object.assign(graph.model.getGeometry(cell), { width: 400, height: 400 }) 240 const geo = Object.assign(graph.model.getGeometry(cell), { width: 400, height: 400 })
240 cell.setGeometry(geo) 241 cell.setGeometry(geo)
241 - self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_ID, id); 242 + self.graph.setAttributeForCell(cell, basicAttr.CHART_INSTANCE_ID, id);
242 self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_WIDTH, enumConst.CHART_CELL_DEFAULT_WIDTH); 243 self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_WIDTH, enumConst.CHART_CELL_DEFAULT_WIDTH);
243 self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT, enumConst.CHART_CELL_DEFAULT_HEIGHT); 244 self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT, enumConst.CHART_CELL_DEFAULT_HEIGHT);
244 self.graph.setAttributeForCell(cell, 'label', self.createChartsNode(id)) 245 self.graph.setAttributeForCell(cell, 'label', self.createChartsNode(id))
@@ -331,7 +332,7 @@ @@ -331,7 +332,7 @@
331 const allCell = graph.getDefaultParent().children || [] 332 const allCell = graph.getDefaultParent().children || []
332 const domIdMapping = new Map() 333 const domIdMapping = new Map()
333 for (const cell of allCell) { 334 for (const cell of allCell) {
334 - const chartInstanceId = graph.getAttributeForCell(cell, enumConst.CHART_CELL_ID) 335 + const chartInstanceId = graph.getAttributeForCell(cell, basicAttr.CHART_INSTANCE_ID)
335 if (Sidebar.prototype.isChartCell(cell) && chartInstanceId) { 336 if (Sidebar.prototype.isChartCell(cell) && chartInstanceId) {
336 const width = graph.getAttributeForCell(cell, enumConst.CHART_CELL_WIDTH) 337 const width = graph.getAttributeForCell(cell, enumConst.CHART_CELL_WIDTH)
337 const height = graph.getAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT) 338 const height = graph.getAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT)
@@ -4935,7 +4935,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -4935,7 +4935,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
4935 4935
4936 /** 4936 /**
4937 * @description 当前节点绑定数据 4937 * @description 当前节点绑定数据
4938 - * @type {null | {act: [], event: []}} 4938 + * @type {null | {act: [], event: [], dataSources: []}}
4939 */ 4939 */
4940 let currentNodeData = null 4940 let currentNodeData = null
4941 4941
@@ -5040,6 +5040,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5040,6 +5040,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5040 SLAVE_DEVICE_ID: 'slaveDeviceId', 5040 SLAVE_DEVICE_ID: 'slaveDeviceId',
5041 ATTR: 'attr', 5041 ATTR: 'attr',
5042 GATEWAY: 'GATEWAY', 5042 GATEWAY: 'GATEWAY',
  5043 + ADDITIONAL: 'additional'
5043 } 5044 }
5044 5045
5045 /** 5046 /**
@@ -5101,7 +5102,6 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5101,7 +5102,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5101 function permissionRender() { 5102 function permissionRender() {
5102 const cell = vertices[0] 5103 const cell = vertices[0]
5103 const permission = graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE) 5104 const permission = graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE)
5104 - console.log(graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE))  
5105 const needDisplayPanel = sidebarInstance.getComponentPermission(permission) 5105 const needDisplayPanel = sidebarInstance.getComponentPermission(permission)
5106 for (const key of needDisplayPanel) { 5106 for (const key of needDisplayPanel) {
5107 renderMapping[key]() 5107 renderMapping[key]()
@@ -5207,6 +5207,14 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5207,6 +5207,14 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5207 mount() 5207 mount()
5208 } 5208 }
5209 5209
  5210 + function createLineChartPanel() {
  5211 +
  5212 + }
  5213 +
  5214 + function createBarChartPanel() {
  5215 +
  5216 + }
  5217 +
5210 function createChartBindPanel() { 5218 function createChartBindPanel() {
5211 const fragment = document.createDocumentFragment() 5219 const fragment = document.createDocumentFragment()
5212 const chartBindContainer = document.createElement('div') 5220 const chartBindContainer = document.createElement('div')
@@ -5220,28 +5228,29 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5220,28 +5228,29 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5220 5228
5221 INTERVAL_EL: 'bindChartIntervalSelect' 5229 INTERVAL_EL: 'bindChartIntervalSelect'
5222 } 5230 }
5223 - 5231 + const enumBindKey = HandleDataSource.enumConst
  5232 + const enumDataType = HandleDataSource.enumDataBindType
5224 const enumConst = { 5233 const enumConst = {
5225 - DATA_TYPE: 'dataType', 5234 + DATA_TYPE: enumBindKey.DATA_TYPE,
5226 5235
5227 - REAL: 'REAL', 5236 + REAL: enumDataType.REAL,
5228 5237
5229 - HISTORY: 'HISTORY', 5238 + HISTORY: enumDataType.HISTORY,
5230 5239
5231 /** 5240 /**
5232 * @description 范围 5241 * @description 范围
5233 */ 5242 */
5234 - SCOPE: 'scope', 5243 + EFFECT_SCOPE: enumBindKey.EFFECT_SCOPE,
5235 5244
5236 /** 5245 /**
5237 * @description 聚合 5246 * @description 聚合
5238 */ 5247 */
5239 - AGGREGATION: 'aggregation', 5248 + AGG: enumBindKey.AGG,
5240 5249
5241 /** 5250 /**
5242 * @description 间隔 5251 * @description 间隔
5243 */ 5252 */
5244 - INTERVAL: 'interval' 5253 + INTERVAL: enumBindKey.INTERVAL
5245 } 5254 }
5246 5255
5247 const enumTimeUnit = { 5256 const enumTimeUnit = {
@@ -5251,6 +5260,20 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5251,6 +5260,20 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5251 DAY: 'DAY', 5260 DAY: 'DAY',
5252 } 5261 }
5253 5262
  5263 + const unitMapping = {
  5264 + [enumTimeUnit.SECOND]: '秒',
  5265 + [enumTimeUnit.MINUTE]: '分',
  5266 + [enumTimeUnit.HOUR]: '小时',
  5267 + [enumTimeUnit.DAY]: '天',
  5268 + }
  5269 +
  5270 + const unitConversion = {
  5271 + [enumTimeUnit.SECOND]: 1 * 1000,
  5272 + [enumTimeUnit.MINUTE]: 1 * 60 * 1000,
  5273 + [enumTimeUnit.HOUR]: 1 * 60 * 60 * 1000,
  5274 + [enumTimeUnit.DAY]: 1 * 60 * 60 * 24 * 1000,
  5275 + }
  5276 +
5254 const defaultIntervalOptions = [ 5277 const defaultIntervalOptions = [
5255 { 5278 {
5256 id: 1, 5279 id: 1,
@@ -5448,32 +5471,29 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5448,32 +5471,29 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5448 { id: 1, unit: enumTimeUnit.DAY }, 5471 { id: 1, unit: enumTimeUnit.DAY },
5449 ] 5472 ]
5450 }, 5473 },
5451 - ]  
5452 -  
5453 - 5474 + ].map(item => {
  5475 + return {
  5476 + id: item.id * unitConversion[item.unit],
  5477 + name: item.id + unitMapping[item.unit],
  5478 + linkage: item.linkage.map(item => {
  5479 + return {
  5480 + id: item.id * unitConversion[item.unit],
  5481 + name: item.id + unitMapping[item.unit],
  5482 + }
  5483 + })
  5484 + }
  5485 + })
5454 5486
5455 const aggergationOptions = [ 5487 const aggergationOptions = [
5456 - { id: '1', name: '最小值' },  
5457 - { id: '2', name: '最大值' },  
5458 - { id: '3', name: '平均值' },  
5459 - { id: '4', name: '求和' },  
5460 - { id: '5', name: '计数' },  
5461 - { id: '6', name: '空' }, 5488 + { id: 'MIN', name: '最小值' },
  5489 + { id: 'MAX', name: '最大值' },
  5490 + { id: 'AVG', name: '平均值' },
  5491 + { id: 'SUM', name: '求和' },
  5492 + { id: 'COUNT', name: '计数' },
  5493 + { id: 'NONE', name: '空' },
5462 ] 5494 ]
5463 5495
5464 - const unitMapping = {  
5465 - [enumTimeUnit.SECOND]: '秒',  
5466 - [enumTimeUnit.MINUTE]: '分',  
5467 - [enumTimeUnit.HOUR]: '小时',  
5468 - [enumTimeUnit.DAY]: '天',  
5469 - }  
5470 5496
5471 - const unitConversion = {  
5472 - [enumTimeUnit.SECOND]: 1,  
5473 - [enumTimeUnit.MINUTE]: 1 * 60,  
5474 - [enumTimeUnit.HOUR]: 1 * 60 * 60,  
5475 - [enumTimeUnit.DAY]: 1 * 60 * 60 * 24,  
5476 - }  
5477 5497
5478 function createSwitchBindTypeRadio() { 5498 function createSwitchBindTypeRadio() {
5479 return ` 5499 return `
@@ -5483,21 +5503,19 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5483,21 +5503,19 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5483 <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.REAL}" title="实时"> 5503 <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.REAL}" title="实时">
5484 <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.HISTORY}" title="历史" checked> 5504 <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.HISTORY}" title="历史" checked>
5485 </div> 5505 </div>
5486 - </div>  
5487 - ` 5506 + </div>`
5488 } 5507 }
5489 5508
5490 function createQueryScopeSelect() { 5509 function createQueryScopeSelect() {
5491 - const options = defaultIntervalOptions.map((item, index) => ({ id: index, name: item.id + unitMapping[item.unit] }))  
5492 const template = UseLayUi.generateOptionTemplate({ 5510 const template = UseLayUi.generateOptionTemplate({
5493 - dataSource: options, 5511 + dataSource: defaultIntervalOptions,
5494 addPlaceholderOption: false 5512 addPlaceholderOption: false
5495 }) 5513 })
5496 return ` 5514 return `
5497 <div class="layui-form-item"> 5515 <div class="layui-form-item">
5498 <label class="layui-form-label">时间周期</label> 5516 <label class="layui-form-label">时间周期</label>
5499 <div class="layui-input-block"> 5517 <div class="layui-input-block">
5500 - <select name="${enumConst.SCOPE}" lay-filter="${enumActionEL.SCOPE_FILTER}"> 5518 + <select name="${enumConst.EFFECT_SCOPE}" lay-filter="${enumActionEL.SCOPE_FILTER}">
5501 ${template} 5519 ${template}
5502 </select> 5520 </select>
5503 </div> 5521 </div>
@@ -5513,7 +5531,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5513,7 +5531,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5513 <div class="layui-form-item"> 5531 <div class="layui-form-item">
5514 <label class="layui-form-label">聚合方式</label> 5532 <label class="layui-form-label">聚合方式</label>
5515 <div class="layui-input-block"> 5533 <div class="layui-input-block">
5516 - <select name="${enumConst.AGGREGATION}"> 5534 + <select name="${enumConst.AGG}">
5517 ${template} 5535 ${template}
5518 </select> 5536 </select>
5519 </div> 5537 </div>
@@ -5526,7 +5544,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5526,7 +5544,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5526 <label class="layui-form-label">间隔时间</label> 5544 <label class="layui-form-label">间隔时间</label>
5527 <div class="layui-input-block"> 5545 <div class="layui-input-block">
5528 <select id="${enumActionEL.INTERVAL_EL}" name="${enumConst.INTERVAL}" lay-filter="${enumConst.INTERVAL}"> 5546 <select id="${enumActionEL.INTERVAL_EL}" name="${enumConst.INTERVAL}" lay-filter="${enumConst.INTERVAL}">
5529 - <option value="1">1</option> 5547 + <option value="1000">1</option>
5530 </select> 5548 </select>
5531 </div> 5549 </div>
5532 </div>` 5550 </div>`
@@ -5535,14 +5553,35 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5535,14 +5553,35 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5535 function generatorEventlisten() { 5553 function generatorEventlisten() {
5536 form.on(`select(${enumActionEL.SCOPE_FILTER})`, event => { 5554 form.on(`select(${enumActionEL.SCOPE_FILTER})`, event => {
5537 const value = event.value || 0 5555 const value = event.value || 0
5538 - const options = defaultIntervalOptions[value].linkage.map(item => ({ id: item.id * unitConversion[item.unit], name: item.id + unitMapping[item.unit] }))  
5539 - const template = UseLayUi.generateOptionTemplate({  
5540 - dataSource: options,  
5541 - addPlaceholderOption: false  
5542 - })  
5543 - $(`#${enumActionEL.INTERVAL_EL}`).html(template)  
5544 - form.render('select') 5556 + linkageIntervalSelect(value)
  5557 + })
  5558 + }
  5559 +
  5560 + function linkageIntervalSelect(value) {
  5561 + const options = defaultIntervalOptions.find(item => Number(item.id) === Number(value))?.linkage
  5562 + const template = UseLayUi.generateOptionTemplate({
  5563 + dataSource: options,
  5564 + addPlaceholderOption: false
5545 }) 5565 })
  5566 + $(`#${enumActionEL.INTERVAL_EL}`).html(template)
  5567 + form.render('select')
  5568 + }
  5569 +
  5570 + /**
  5571 + * @description 回显
  5572 + */
  5573 + function echoData() {
  5574 + const { dataSources = [] } = currentNodeData
  5575 + const { additional = {} } = dataSources[0] || {}
  5576 + const { [enumBindKey.EFFECT_SCOPE]: effectScope } = additional
  5577 + linkageIntervalSelect(effectScope)
  5578 + form.val(CONTAINER_FILTER, additional)
  5579 + }
  5580 +
  5581 + const refresh = echoRefreshFn
  5582 + echoRefreshFn = function () {
  5583 + refresh.apply(this, arguments)
  5584 + echoData()
5546 } 5585 }
5547 5586
5548 fragment.append(title) 5587 fragment.append(title)
@@ -5607,6 +5646,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5607,6 +5646,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5607 const panel = createPanel() 5646 const panel = createPanel()
5608 $(panel).addClass('data-source__submit-panel').append(`<button type="button" lay-submit lay-filter="formDataSource" class="layui-btn">保存</button>`) 5647 $(panel).addClass('data-source__submit-panel').append(`<button type="button" lay-submit lay-filter="formDataSource" class="layui-btn">保存</button>`)
5609 $(container).append(panel) 5648 $(container).append(panel)
  5649 + const additionalKey = HandleDataSource.enumConst
5610 form.on('submit(formDataSource)', async function (data) { 5650 form.on('submit(formDataSource)', async function (data) {
5611 const ENABLED_FLAG = 'on' 5651 const ENABLED_FLAG = 'on'
5612 const { field } = data 5652 const { field } = data
@@ -5619,8 +5659,15 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5619,8 +5659,15 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5619 [enumCategory.DATA_SOURCE]: { 5659 [enumCategory.DATA_SOURCE]: {
5620 [enumDataSourceConst.ORG_ID]: field[enumDataSourceConst.ORG_ID], 5660 [enumDataSourceConst.ORG_ID]: field[enumDataSourceConst.ORG_ID],
5621 [enumDataSourceConst.DEVICE_ID]: field[enumDataSourceConst.DEVICE_ID], 5661 [enumDataSourceConst.DEVICE_ID]: field[enumDataSourceConst.DEVICE_ID],
5622 - ...(field[enumDataSourceConst.SLAVE_DEVICE_ID] && { [enumDataSourceConst.SLAVE_DEVICE_ID]: field[enumDataSourceConst.SLAVE_DEVICE_ID] }), 5662 + // ...(field[enumDataSourceConst.SLAVE_DEVICE_ID] && { [enumDataSourceConst.SLAVE_DEVICE_ID]: field[enumDataSourceConst.SLAVE_DEVICE_ID] }),
  5663 + [enumDataSourceConst.SLAVE_DEVICE_ID]: field[enumDataSourceConst.SLAVE_DEVICE_ID] ? [enumDataSourceConst.SLAVE_DEVICE_ID] : '',
5623 [enumDataSourceConst.ATTR]: field[enumDataSourceConst.ATTR], 5664 [enumDataSourceConst.ATTR]: field[enumDataSourceConst.ATTR],
  5665 + [enumDataSourceConst.ADDITIONAL]: field[additionalKey.DATA_TYPE] ? {
  5666 + [additionalKey.AGG]: field[additionalKey.AGG],
  5667 + [additionalKey.DATA_TYPE]: field[additionalKey.DATA_TYPE],
  5668 + [additionalKey.INTERVAL]: field[additionalKey.INTERVAL],
  5669 + [additionalKey.EFFECT_SCOPE]: field[additionalKey.EFFECT_SCOPE]
  5670 + } : null
5624 }, 5671 },
5625 } 5672 }
5626 const allType = [...interactionList, ...dynamicEffectList] 5673 const allType = [...interactionList, ...dynamicEffectList]
@@ -7111,6 +7158,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7111,6 +7158,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7111 [enumDataSourceConst.SLAVE_DEVICE_ID]: null, 7158 [enumDataSourceConst.SLAVE_DEVICE_ID]: null,
7112 [enumDataSourceConst.ATTR]: null, 7159 [enumDataSourceConst.ATTR]: null,
7113 }) 7160 })
  7161 + if (!selected) return
7114 if (selected.deviceType === enumDataSourceConst.GATEWAY) { 7162 if (selected.deviceType === enumDataSourceConst.GATEWAY) {
7115 $(`#${componentId}`).find(`select[name="${enumDataSourceConst.SLAVE_DEVICE_ID}"]`) 7163 $(`#${componentId}`).find(`select[name="${enumDataSourceConst.SLAVE_DEVICE_ID}"]`)
7116 .attr('lay-verify', 'required').attr('lay-verType', 'tips') 7164 .attr('lay-verify', 'required').attr('lay-verType', 'tips')
@@ -7411,7 +7459,6 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7411,7 +7459,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7411 function switchUploadImgTypeEventListener() { 7459 function switchUploadImgTypeEventListener() {
7412 form.on(`radio(${enumActionEl.SWITCH_IMG_ORIGIN_FILTER})`, event => { 7460 form.on(`radio(${enumActionEl.SWITCH_IMG_ORIGIN_FILTER})`, event => {
7413 const { value } = event 7461 const { value } = event
7414 - console.log('event', event)  
7415 imageState = {} 7462 imageState = {}
7416 if (value === enumImageOriginType.LOCAL) { 7463 if (value === enumImageOriginType.LOCAL) {
7417 $(`#${enumActionEl.IMG_SELECT_CONTAINER_EL}`).html(createLocalFileContainer()) 7464 $(`#${enumActionEl.IMG_SELECT_CONTAINER_EL}`).html(createLocalFileContainer())
@@ -12093,10 +12140,17 @@ class DispatchCenter { @@ -12093,10 +12140,17 @@ class DispatchCenter {
12093 12140
12094 /** 12141 /**
12095 * @description 页面数据 12142 * @description 页面数据
  12143 + * @type {{dataSources: [], act: [], event: []}}
12096 */ 12144 */
12097 contentData 12145 contentData
12098 12146
12099 /** 12147 /**
  12148 + * @description 处理数据源实例
  12149 + * @type {HandleDataSource}
  12150 + */
  12151 + dataSourceHandlerInstance
  12152 +
  12153 + /**
12100 * @description 处理数据动效实例 12154 * @description 处理数据动效实例
12101 * @type {HandleDynamicEffect} 12155 * @type {HandleDynamicEffect}
12102 */ 12156 */
@@ -12171,6 +12225,7 @@ class DispatchCenter { @@ -12171,6 +12225,7 @@ class DispatchCenter {
12171 this.saveContentInfo(editorUi, currentPage) 12225 this.saveContentInfo(editorUi, currentPage)
12172 this.connectSocket() 12226 this.connectSocket()
12173 await this.getContentDataNode() 12227 await this.getContentDataNode()
  12228 + this.dataSourceHandlerInstance = new HandleDataSource(this)
12174 this.dataInteractionInstance = new HandleDataInteraction(this) 12229 this.dataInteractionInstance = new HandleDataInteraction(this)
12175 this.dynamicEffectInstance = new HandleDynamicEffect(this) 12230 this.dynamicEffectInstance = new HandleDynamicEffect(this)
12176 this.updateQueueInstance = new UpdateQueue(this) 12231 this.updateQueueInstance = new UpdateQueue(this)
@@ -12220,9 +12275,10 @@ class DispatchCenter { @@ -12220,9 +12275,10 @@ class DispatchCenter {
12220 const { node: { id } = {} } = this.currentPage 12275 const { node: { id } = {} } = this.currentPage
12221 if (!id) return 12276 if (!id) return
12222 const [err, res] = await to(ConfigurationNodeApi.getConfigurationInfo('CONTENT', id)) 12277 const [err, res] = await to(ConfigurationNodeApi.getConfigurationInfo('CONTENT', id))
12223 - const { dataSources, event, act } = this.contentData = res  
12224 - const tsSubCmds = this.generatorDataSourceMapping(dataSources)  
12225 - this.sendMessageToGetRealTimeData({ tsSubCmds }) 12278 + this.contentData = res
  12279 + // const { dataSources } = this.contentData = res
  12280 + // const tsSubCmds = this.generatorDataSourceMapping(dataSources)
  12281 + // this.sendMessageToGetRealTimeData({ tsSubCmds })
12226 } 12282 }
12227 12283
12228 /** 12284 /**
@@ -12329,6 +12385,481 @@ class DispatchCenter { @@ -12329,6 +12385,481 @@ class DispatchCenter {
12329 12385
12330 } 12386 }
12331 12387
  12388 +class HandleDataSource {
  12389 +
  12390 + static enumConst = {
  12391 +
  12392 + /**
  12393 + * @description 聚合方式
  12394 + */
  12395 + AGG: 'agg',
  12396 +
  12397 + /**
  12398 + * @description 间隔方式
  12399 + */
  12400 + INTERVAL: 'interval',
  12401 +
  12402 + /**
  12403 + * @description 开始时间
  12404 + */
  12405 + STARTTs: 'startTs',
  12406 +
  12407 + /**
  12408 + * @description 结束时间
  12409 + */
  12410 + ENDTs: 'endTs',
  12411 +
  12412 + /**
  12413 + * @description 范围
  12414 + */
  12415 + EFFECT_SCOPE: 'effectScope',
  12416 +
  12417 + /**
  12418 + * @description 绑定数据类型
  12419 + */
  12420 + DATA_TYPE: 'dataType'
  12421 + }
  12422 +
  12423 +
  12424 + static enumDataBindType = {
  12425 +
  12426 + /**
  12427 + * @description 历史
  12428 + */
  12429 + HISTORY: 'historyCmds',
  12430 +
  12431 + /**
  12432 + * @description 事实
  12433 + */
  12434 + REAL: 'tsSubCmds'
  12435 + }
  12436 +
  12437 + /**
  12438 + * @description 数据源节点映射
  12439 + * @type {Map<string, object>}
  12440 + */
  12441 + dataSourceNodeMapping = new Map()
  12442 +
  12443 + /**
  12444 + * @description 派发队列
  12445 + * @type {DispatchCenter}
  12446 + */
  12447 + DispatchInstance
  12448 +
  12449 + constructor(DispatchInstance) {
  12450 + this.DispatchInstance = DispatchInstance
  12451 + this.generatorCommonDataSourceMapping()
  12452 + this.generatorChartDataSourceMapping()
  12453 + }
  12454 +
  12455 + get graph() {
  12456 + return this.DispatchInstance.graph
  12457 + }
  12458 +
  12459 + /**
  12460 + * @description 普通数据源绑定列表
  12461 + */
  12462 + get commonDataSourceBindList() {
  12463 + return this.DispatchInstance.contentData.dataSources.filter(item => !item.additional)
  12464 + }
  12465 +
  12466 + /**
  12467 + * @description 图表数据源绑定列表
  12468 + */
  12469 + get chartDataSourceBindList() {
  12470 + return this.DispatchInstance.contentData.dataSources.filter(item => item.additional)
  12471 + }
  12472 +
  12473 + get cmdIdMapping() {
  12474 + return this.DispatchInstance.cmdIdMapping
  12475 + }
  12476 +
  12477 + /**
  12478 + * @description 生成普通数据源绑定映射关系
  12479 + * @param dataSources
  12480 + * @return {{cmdId: number, entityType: string, keys: *, scope: string, entityId: *}[]}
  12481 + */
  12482 + generatorCommonDataSourceMapping() {
  12483 + const msg = this.commonDataSourceBindList.map((datum) => {
  12484 + const { deviceId, attr, nodeId, slaveDeviceId } = datum
  12485 + const cmdId = this.getCmdId(nodeId)
  12486 + const sendMsgTemplate = {
  12487 + entityType: "DEVICE",
  12488 + entityId: slaveDeviceId ? slaveDeviceId : deviceId,
  12489 + scope: "LATEST_TELEMETRY",
  12490 + cmdId,
  12491 + keys: attr,
  12492 + }
  12493 + this.dataSourceNodeMapping.set(nodeId, datum)
  12494 + this.subscribeEvent(cmdId, this.updateCommonDataSource.bind(this))
  12495 + return sendMsgTemplate
  12496 + })
  12497 + const { REAL } = HandleDataSource.enumDataBindType
  12498 + if (msg.length) this.sendMsg({ [REAL]: msg })
  12499 + }
  12500 +
  12501 +
  12502 + /**
  12503 + * @description 图表数据源绑定关系
  12504 + * @param {any[]} dataSource
  12505 + */
  12506 + generatorChartDataSourceMapping() {
  12507 + const realList = []
  12508 + const historyList = []
  12509 + const { HISTORY, REAL } = HandleDataSource.enumDataBindType
  12510 + const { STARTTs, ENDTs } = HandleDataSource.enumConst
  12511 + for (const item of this.chartDataSourceBindList) {
  12512 + const { additional = {}, deviceId, attr, nodeId, slaveDeviceId } = item
  12513 + if (!attr) continue
  12514 + const { agg, interval = 1000, dataType, effectScope = 0 } = additional
  12515 + const cmdId = this.getCmdId(nodeId)
  12516 + const template = {
  12517 + entityType: "DEVICE",
  12518 + entityId: slaveDeviceId ? slaveDeviceId : deviceId,
  12519 + cmdId,
  12520 + interval: Number(interval),
  12521 + agg,
  12522 + keys: attr,
  12523 + }
  12524 + let scope = isNaN(effectScope) ? 0 : Number(effectScope)
  12525 + if (dataType === HISTORY) {
  12526 + template[STARTTs] = Date.now() - scope
  12527 + template[ENDTs] = Date.now()
  12528 + historyList.push(template)
  12529 + this.subscribeEvent(cmdId, this.updateHistoryDataSource.bind(this))
  12530 + }
  12531 + else if (dataType === REAL) {
  12532 + template[STARTTs] = Date.now() - scope
  12533 + template['scope'] = 'LATEST_TELEMETRY'
  12534 + realList.push(template)
  12535 + this.subscribeEvent(cmdId, this.updateRealTimeDataSource.bind(this))
  12536 + }
  12537 + this.dataSourceNodeMapping.set(nodeId, item)
  12538 + }
  12539 +
  12540 + if (historyList.length || realList.length) this.sendMsg({ [HISTORY]: historyList, [REAL]: realList })
  12541 + }
  12542 +
  12543 + /**
  12544 + * @description 订阅事件 绑定回调
  12545 + * @param eventName
  12546 + * @param callback
  12547 + */
  12548 + subscribeEvent(eventName, callback) {
  12549 + this.DispatchInstance.eventBus.on(eventName, callback)
  12550 + }
  12551 +
  12552 + updateCommonDataSource(message) {
  12553 + const { subscriptionId } = message
  12554 + const node = this.getNodeByCmdId(subscriptionId)
  12555 + const { attr } = this.getBindData(subscriptionId)
  12556 + node && this.updatePage(() => {
  12557 + const { data } = message
  12558 + const [[timespan, value]] = data[attr]
  12559 + node.setValue(value)
  12560 + }, node)
  12561 + }
  12562 +
  12563 + updateChartDataSource(message) {
  12564 + const { data = {}, subscriptionId } = message
  12565 + const node = this.getNodeByCmdId(subscriptionId)
  12566 + if (!node) return
  12567 + const enumConst = Sidebar.prototype.enumCellBasicAttribute
  12568 + const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping
  12569 + const chartInstanceId = node.getAttribute(enumConst.CHART_INSTANCE_ID)
  12570 + const instance = chartInstanceMap.get(chartInstanceId)
  12571 + const { attr = [[]] } = this.getBindData(subscriptionId)
  12572 + const [timespan, value] = data[attr][0]
  12573 + console.log('timespan', timespan)
  12574 + console.log('value', value)
  12575 + console.log(instance)
  12576 + console.log('chart', arguments)
  12577 + }
  12578 +
  12579 + /**
  12580 + * @description 更新实时数据
  12581 + * @param {} message
  12582 + */
  12583 + updateRealTimeDataSource(message) {
  12584 + const { data = {}, subscriptionId } = message
  12585 + const node = this.getNodeByCmdId(subscriptionId)
  12586 + if (!node) return
  12587 + const enumConst = Sidebar.prototype.enumCellBasicAttribute
  12588 + const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping
  12589 + const chartInstanceId = node.getAttribute(enumConst.CHART_INSTANCE_ID)
  12590 + const chartInstanceType = node.getAttribute(enumConst.COMPONENT_TYPE)
  12591 + const instance = chartInstanceMap.get(chartInstanceId)
  12592 + const { attr = [[]] } = this.getBindData(subscriptionId)
  12593 + const historyDataList = data[attr]
  12594 +
  12595 + // chart insstance 是否已经接受过一次消息推送
  12596 + const isActive = instance.isActive
  12597 + if (!isActive) {
  12598 + instance.isActive = true
  12599 + const xAxisData = []
  12600 + const seriesValue = []
  12601 + const chartOption = {
  12602 + tooltip: {
  12603 + trigger: 'axis',
  12604 + axisPointer: {
  12605 + type: 'shadow'
  12606 + }
  12607 + },
  12608 + grid: {
  12609 + left: '3%',
  12610 + right: '3%',
  12611 + bottom: '3%',
  12612 + containLabel: true,
  12613 + },
  12614 + xAxis: {
  12615 + type: 'category',
  12616 + data: xAxisData,
  12617 + boundaryGap: true,
  12618 + axisLabel: {
  12619 + rotate: 70
  12620 + },
  12621 + axisPointer: {
  12622 + label: {
  12623 + formatter() {
  12624 + return attr
  12625 + }
  12626 + }
  12627 + }
  12628 + },
  12629 + yAxis: {
  12630 + type: 'value'
  12631 + },
  12632 + series: [
  12633 + {
  12634 + data: seriesValue,
  12635 + type: chartInstanceType.includes('bar') ? 'bar' : 'line'
  12636 + }
  12637 + ],
  12638 + dataZoom: [
  12639 + {
  12640 + xAxisIndex: 0,
  12641 + // show: false,
  12642 + type: 'slider',
  12643 + startValue: 0,
  12644 + endValue: 4
  12645 + }
  12646 + ]
  12647 + }
  12648 +
  12649 + for (let i = historyDataList.length - 1; i >= 0; i--) {
  12650 + const [timespan, value] = historyDataList[i]
  12651 + xAxisData.push(new Date(Number(timespan)).toLocaleTimeString())
  12652 + seriesValue.push(Number(value))
  12653 + }
  12654 +
  12655 + instance.setOption(chartOption)
  12656 +
  12657 + } else {
  12658 + const oldOptions = instance.getOption()
  12659 + const xAxisData = oldOptions.xAxis[0].data || []
  12660 + const seriesValue = oldOptions.series[0].data || []
  12661 + const oldEndValue = Number(oldOptions.dataZoom[0].endValue) || 0
  12662 + const oldStartValue = Number(oldOptions.dataZoom[0].startValue) || 0
  12663 +
  12664 + for (let i = historyDataList.length - 1; i >= 0; i--) {
  12665 + const [timespan, value] = historyDataList[i]
  12666 + xAxisData.push(new Date(Number(timespan)).toLocaleTimeString())
  12667 + seriesValue.push(Number(value))
  12668 + }
  12669 +
  12670 + if (Number(oldOptions.dataZoom[0].endValue) === seriesValue.length - 1) {
  12671 + oldOptions.dataZoom[0].endValue = 4
  12672 + oldOptions.dataZoom[0].startValue = 0
  12673 + } else {
  12674 + oldOptions.dataZoom[0].endValue = oldOptions.dataZoom[0].endValue + 1
  12675 + oldOptions.dataZoom[0].startValue = oldOptions.dataZoom[0].startValue + 1
  12676 + }
  12677 +
  12678 + if (!instance) clearInterval(interval)
  12679 + instance && instance.setOption({
  12680 + xAxis: {
  12681 + data: xAxisData
  12682 + },
  12683 + series: [
  12684 + {
  12685 + data: seriesValue
  12686 + }
  12687 + ],
  12688 + dataZoom: [
  12689 + {
  12690 + startValue: seriesValue.length > 5
  12691 + ? oldStartValue === seriesValue.length - 1
  12692 + ? 0
  12693 + : oldStartValue + 1
  12694 + : 0,
  12695 + endValue: seriesValue.length > 5
  12696 + ? oldEndValue === seriesValue.length - 1
  12697 + ? 4
  12698 + : oldEndValue + 1
  12699 + : 4
  12700 + }
  12701 + ]
  12702 + })
  12703 + }
  12704 + }
  12705 +
  12706 + /**
  12707 + * @description 更新历史数据
  12708 + */
  12709 + updateHistoryDataSource(message) {
  12710 + const { data = {}, subscriptionId } = message
  12711 + const node = this.getNodeByCmdId(subscriptionId)
  12712 + if (!node) return
  12713 + const enumConst = Sidebar.prototype.enumCellBasicAttribute
  12714 + const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping
  12715 + const chartInstanceId = node.getAttribute(enumConst.CHART_INSTANCE_ID)
  12716 + const chartInstanceType = node.getAttribute(enumConst.COMPONENT_TYPE)
  12717 + const instance = chartInstanceMap.get(chartInstanceId)
  12718 + const { attr = [[]] } = this.getBindData(subscriptionId)
  12719 + const historyDataList = data[attr]
  12720 +
  12721 + const xAxisData = []
  12722 + const seriesValue = []
  12723 + const chartOption = {
  12724 + tooltip: {
  12725 + trigger: 'axis',
  12726 + axisPointer: {
  12727 + type: 'shadow'
  12728 + }
  12729 + },
  12730 + grid: {
  12731 + left: '3%',
  12732 + right: '3%',
  12733 + bottom: '3%',
  12734 + containLabel: true,
  12735 + },
  12736 + xAxis: {
  12737 + name: '时间',
  12738 + type: 'category',
  12739 + data: xAxisData,
  12740 + boundaryGap: true,
  12741 + axisLabel: {
  12742 + rotate: 70
  12743 + },
  12744 + axisPointer: {
  12745 + label: {
  12746 + formatter() {
  12747 + return attr
  12748 + }
  12749 + }
  12750 + }
  12751 + },
  12752 + yAxis: {
  12753 + type: 'value'
  12754 + },
  12755 + series: [
  12756 + {
  12757 + data: seriesValue,
  12758 + type: chartInstanceType.includes('bar') ? 'bar' : 'line',
  12759 + }
  12760 + ],
  12761 + dataZoom: [
  12762 + {
  12763 + xAxisIndex: 0,
  12764 + show: false,
  12765 + type: 'slider',
  12766 + startValue: 0,
  12767 + endValue: 4
  12768 + }
  12769 + ]
  12770 + }
  12771 +
  12772 + for (let i = historyDataList.length - 1; i >= 0; i--) {
  12773 + const [timespan, value] = historyDataList[i]
  12774 + xAxisData.push(new Date(Number(timespan)).toLocaleTimeString())
  12775 + seriesValue.push(Number(value))
  12776 + }
  12777 +
  12778 + let interval
  12779 + // TODO 清除定时器
  12780 + function autoMove() {
  12781 + interval = setInterval(() => {
  12782 + if (Number(chartOption.dataZoom[0].endValue) === seriesValue.length - 1) {
  12783 + chartOption.dataZoom[0].endValue = 4
  12784 + chartOption.dataZoom[0].startValue = 0
  12785 + } else {
  12786 + chartOption.dataZoom[0].endValue = chartOption.dataZoom[0].endValue + 1
  12787 + chartOption.dataZoom[0].startValue = chartOption.dataZoom[0].startValue + 1
  12788 + }
  12789 +
  12790 + if (!instance) clearInterval(interval)
  12791 + instance && instance.setOption(chartOption)
  12792 + }, 2000);
  12793 + }
  12794 +
  12795 + function stop() {
  12796 + clearInterval(interval)
  12797 + }
  12798 +
  12799 + function goMove() {
  12800 + autoMove()
  12801 + }
  12802 +
  12803 + instance.setOption(chartOption)
  12804 + instance.on('mouseover', stop)
  12805 + instance.on('mouseout', goMove)
  12806 + autoMove()
  12807 + }
  12808 +
  12809 + /**
  12810 + * @description 获取绑定的数据
  12811 + * @param subscriptionId
  12812 + * @param actionType
  12813 + * @return {*}
  12814 + */
  12815 + getBindData(subscriptionId) {
  12816 + const nodeId = this.getNodeIdByCmdId(subscriptionId)
  12817 + const temp = this.dataSourceNodeMapping.get(nodeId) || {}
  12818 + return temp
  12819 + }
  12820 +
  12821 + /**
  12822 + * @description 获取cmdId
  12823 + * @param {string} nodeId
  12824 + * @returns
  12825 + */
  12826 + getCmdId(nodeId) {
  12827 + return this.DispatchInstance.getCmdId(nodeId)
  12828 + }
  12829 +
  12830 + /**
  12831 + * @description 通过cmdID获取节点id
  12832 + * @param subscriptionId
  12833 + * @return {string}
  12834 + */
  12835 + getNodeIdByCmdId(subscriptionId) {
  12836 + return this.DispatchInstance.cmdIdMapping.get(subscriptionId)
  12837 + }
  12838 +
  12839 + /**
  12840 + * @description 通过cmdID 获取节点
  12841 + * @param subscriptionId
  12842 + * @return {*}
  12843 + */
  12844 + getNodeByCmdId(subscriptionId) {
  12845 + const nodeId = this.getNodeIdByCmdId(subscriptionId)
  12846 + return this.DispatchInstance.contentAllCell.find(item => item.id === nodeId)
  12847 + }
  12848 +
  12849 + /**
  12850 + * @description 发送socket 消息
  12851 + * @param {any} msg
  12852 + * @returns
  12853 + */
  12854 + sendMsg(msg) {
  12855 + return this.DispatchInstance.sendMessageToGetRealTimeData(msg)
  12856 + }
  12857 +
  12858 + updatePage(callback, cell) {
  12859 + return this.DispatchInstance.updatePage(callback, cell)
  12860 + }
  12861 +}
  12862 +
12332 class HandleDataInteraction { 12863 class HandleDataInteraction {
12333 /** 12864 /**
12334 * @description 事件分发中心实例 12865 * @description 事件分发中心实例
@@ -12400,7 +12931,6 @@ class HandleDataInteraction { @@ -12400,7 +12931,6 @@ class HandleDataInteraction {
12400 graphDblClick.apply(this.graph, args) 12931 graphDblClick.apply(this.graph, args)
12401 } 12932 }
12402 12933
12403 -  
12404 const graphClick = this.graph.click; 12934 const graphClick = this.graph.click;
12405 this.graph.click = (...args) => { 12935 this.graph.click = (...args) => {
12406 this.handleClickEvent(...args) 12936 this.handleClickEvent(...args)
@@ -12534,7 +13064,7 @@ class HandleDataInteraction { @@ -12534,7 +13064,7 @@ class HandleDataInteraction {
12534 } 13064 }
12535 13065
12536 /** 13066 /**
12537 - * @description 处理数据 13067 + * @description 处理数据动效
12538 */ 13068 */
12539 class HandleDynamicEffect { 13069 class HandleDynamicEffect {
12540 13070
@@ -12557,12 +13087,6 @@ class HandleDynamicEffect { @@ -12557,12 +13087,6 @@ class HandleDynamicEffect {
12557 actNodeMapping = new Map() 13087 actNodeMapping = new Map()
12558 13088
12559 /** 13089 /**
12560 - * @description cmdID 与 nodeID 关系映射  
12561 - * @type {Map<number, string>}  
12562 - */  
12563 - cmdIdMapping = new Map()  
12564 -  
12565 - /**  
12566 * @description clear setInterval 13090 * @description clear setInterval
12567 */ 13091 */
12568 cleanSetInterval 13092 cleanSetInterval
@@ -12777,7 +13301,6 @@ class HandleDynamicEffect { @@ -12777,7 +13301,6 @@ class HandleDynamicEffect {
12777 node.setVisible(flashFlag) 13301 node.setVisible(flashFlag)
12778 flashFlag = !flashFlag 13302 flashFlag = !flashFlag
12779 } 13303 }
12780 - console.log(this.actNodeMapping)  
12781 const key = node.id + DispatchCenter.enumDynamicEffectType.FLASH 13304 const key = node.id + DispatchCenter.enumDynamicEffectType.FLASH
12782 if (!flag) { 13305 if (!flag) {
12783 flashFlag = true 13306 flashFlag = true
@@ -12847,7 +13370,7 @@ class HandleDynamicEffect { @@ -12847,7 +13370,7 @@ class HandleDynamicEffect {
12847 getBindData(subscriptionId, actionType) { 13370 getBindData(subscriptionId, actionType) {
12848 const nodeId = this.getNodeIdByCmdId(subscriptionId) 13371 const nodeId = this.getNodeIdByCmdId(subscriptionId)
12849 const temp = this.actNodeMapping.get(nodeId) 13372 const temp = this.actNodeMapping.get(nodeId)
12850 - return temp.get(actionTypxe) 13373 + return temp.get(actionType)
12851 } 13374 }
12852 13375
12853 /** 13376 /**