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 195 this.removeDraft();
196 196 Editor.defaultContent = savedData;
197 197 var configurationContentList = [];
198   - console.log('EditorUi', this.ui.editor.graph.getDefaultParent().children)
199 198 const basicAttr = Sidebar.prototype.enumCellBasicAttribute
200 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 201 var configurationContent = {
202 202 name: "第 1 页",
203 203 id: Editor.configurationContentId,
  204 + contentId,
204 205 content: savedData,
205 206 type: 1,
206 207 nodeIds: allCell.map(item => item.id)
... ...
... ... @@ -166,7 +166,12 @@
166 166 /**
167 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 24 /**
25 25 * @description cell id key
26 26 */
27   - CHART_CELL_ID: 'chartInstanceId',
  27 + CHART_INSTANCE_ID: 'chartInstanceId',
28 28
29 29 /**
30 30 * @description 图表容器 class name
... ... @@ -143,7 +143,7 @@
143 143 const basicAttr = this.enumCellBasicAttribute
144 144 this.setCellAttributes(cell, {
145 145 [basicAttr.COMPONENT_TYPE]: chartType,
146   - [enumConst.CHART_CELL_ID]: id,
  146 + [basicAttr.CHART_INSTANCE_ID]: id,
147 147 [enumConst.CHART_CELL_WIDTH]: width,
148 148 [enumConst.CHART_CELL_HEIGHT]: height,
149 149 })
... ... @@ -208,7 +208,8 @@
208 208 * @returns {*}
209 209 */
210 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 239 const id = self.generatorChartsId()
239 240 const geo = Object.assign(graph.model.getGeometry(cell), { width: 400, height: 400 })
240 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 243 self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_WIDTH, enumConst.CHART_CELL_DEFAULT_WIDTH);
243 244 self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT, enumConst.CHART_CELL_DEFAULT_HEIGHT);
244 245 self.graph.setAttributeForCell(cell, 'label', self.createChartsNode(id))
... ... @@ -331,7 +332,7 @@
331 332 const allCell = graph.getDefaultParent().children || []
332 333 const domIdMapping = new Map()
333 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 336 if (Sidebar.prototype.isChartCell(cell) && chartInstanceId) {
336 337 const width = graph.getAttributeForCell(cell, enumConst.CHART_CELL_WIDTH)
337 338 const height = graph.getAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT)
... ...
... ... @@ -4935,7 +4935,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
4935 4935
4936 4936 /**
4937 4937 * @description 当前节点绑定数据
4938   - * @type {null | {act: [], event: []}}
  4938 + * @type {null | {act: [], event: [], dataSources: []}}
4939 4939 */
4940 4940 let currentNodeData = null
4941 4941
... ... @@ -5040,6 +5040,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5040 5040 SLAVE_DEVICE_ID: 'slaveDeviceId',
5041 5041 ATTR: 'attr',
5042 5042 GATEWAY: 'GATEWAY',
  5043 + ADDITIONAL: 'additional'
5043 5044 }
5044 5045
5045 5046 /**
... ... @@ -5101,7 +5102,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5101 5102 function permissionRender() {
5102 5103 const cell = vertices[0]
5103 5104 const permission = graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE)
5104   - console.log(graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE))
5105 5105 const needDisplayPanel = sidebarInstance.getComponentPermission(permission)
5106 5106 for (const key of needDisplayPanel) {
5107 5107 renderMapping[key]()
... ... @@ -5207,6 +5207,14 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5207 5207 mount()
5208 5208 }
5209 5209
  5210 + function createLineChartPanel() {
  5211 +
  5212 + }
  5213 +
  5214 + function createBarChartPanel() {
  5215 +
  5216 + }
  5217 +
5210 5218 function createChartBindPanel() {
5211 5219 const fragment = document.createDocumentFragment()
5212 5220 const chartBindContainer = document.createElement('div')
... ... @@ -5220,28 +5228,29 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5220 5228
5221 5229 INTERVAL_EL: 'bindChartIntervalSelect'
5222 5230 }
5223   -
  5231 + const enumBindKey = HandleDataSource.enumConst
  5232 + const enumDataType = HandleDataSource.enumDataBindType
5224 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 5241 * @description 范围
5233 5242 */
5234   - SCOPE: 'scope',
  5243 + EFFECT_SCOPE: enumBindKey.EFFECT_SCOPE,
5235 5244
5236 5245 /**
5237 5246 * @description 聚合
5238 5247 */
5239   - AGGREGATION: 'aggregation',
  5248 + AGG: enumBindKey.AGG,
5240 5249
5241 5250 /**
5242 5251 * @description 间隔
5243 5252 */
5244   - INTERVAL: 'interval'
  5253 + INTERVAL: enumBindKey.INTERVAL
5245 5254 }
5246 5255
5247 5256 const enumTimeUnit = {
... ... @@ -5251,6 +5260,20 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5251 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 5277 const defaultIntervalOptions = [
5255 5278 {
5256 5279 id: 1,
... ... @@ -5448,32 +5471,29 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5448 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 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 5498 function createSwitchBindTypeRadio() {
5479 5499 return `
... ... @@ -5483,21 +5503,19 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5483 5503 <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.REAL}" title="实时">
5484 5504 <input type="radio" name="${enumConst.DATA_TYPE}" value="${enumConst.HISTORY}" title="历史" checked>
5485 5505 </div>
5486   - </div>
5487   - `
  5506 + </div>`
5488 5507 }
5489 5508
5490 5509 function createQueryScopeSelect() {
5491   - const options = defaultIntervalOptions.map((item, index) => ({ id: index, name: item.id + unitMapping[item.unit] }))
5492 5510 const template = UseLayUi.generateOptionTemplate({
5493   - dataSource: options,
  5511 + dataSource: defaultIntervalOptions,
5494 5512 addPlaceholderOption: false
5495 5513 })
5496 5514 return `
5497 5515 <div class="layui-form-item">
5498 5516 <label class="layui-form-label">时间周期</label>
5499 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 5519 ${template}
5502 5520 </select>
5503 5521 </div>
... ... @@ -5513,7 +5531,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5513 5531 <div class="layui-form-item">
5514 5532 <label class="layui-form-label">聚合方式</label>
5515 5533 <div class="layui-input-block">
5516   - <select name="${enumConst.AGGREGATION}">
  5534 + <select name="${enumConst.AGG}">
5517 5535 ${template}
5518 5536 </select>
5519 5537 </div>
... ... @@ -5526,7 +5544,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5526 5544 <label class="layui-form-label">间隔时间</label>
5527 5545 <div class="layui-input-block">
5528 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 5548 </select>
5531 5549 </div>
5532 5550 </div>`
... ... @@ -5535,14 +5553,35 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5535 5553 function generatorEventlisten() {
5536 5554 form.on(`select(${enumActionEL.SCOPE_FILTER})`, event => {
5537 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 5587 fragment.append(title)
... ... @@ -5607,6 +5646,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5607 5646 const panel = createPanel()
5608 5647 $(panel).addClass('data-source__submit-panel').append(`<button type="button" lay-submit lay-filter="formDataSource" class="layui-btn">保存</button>`)
5609 5648 $(container).append(panel)
  5649 + const additionalKey = HandleDataSource.enumConst
5610 5650 form.on('submit(formDataSource)', async function (data) {
5611 5651 const ENABLED_FLAG = 'on'
5612 5652 const { field } = data
... ... @@ -5619,8 +5659,15 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5619 5659 [enumCategory.DATA_SOURCE]: {
5620 5660 [enumDataSourceConst.ORG_ID]: field[enumDataSourceConst.ORG_ID],
5621 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 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 5673 const allType = [...interactionList, ...dynamicEffectList]
... ... @@ -7111,6 +7158,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7111 7158 [enumDataSourceConst.SLAVE_DEVICE_ID]: null,
7112 7159 [enumDataSourceConst.ATTR]: null,
7113 7160 })
  7161 + if (!selected) return
7114 7162 if (selected.deviceType === enumDataSourceConst.GATEWAY) {
7115 7163 $(`#${componentId}`).find(`select[name="${enumDataSourceConst.SLAVE_DEVICE_ID}"]`)
7116 7164 .attr('lay-verify', 'required').attr('lay-verType', 'tips')
... ... @@ -7411,7 +7459,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7411 7459 function switchUploadImgTypeEventListener() {
7412 7460 form.on(`radio(${enumActionEl.SWITCH_IMG_ORIGIN_FILTER})`, event => {
7413 7461 const { value } = event
7414   - console.log('event', event)
7415 7462 imageState = {}
7416 7463 if (value === enumImageOriginType.LOCAL) {
7417 7464 $(`#${enumActionEl.IMG_SELECT_CONTAINER_EL}`).html(createLocalFileContainer())
... ... @@ -12093,10 +12140,17 @@ class DispatchCenter {
12093 12140
12094 12141 /**
12095 12142 * @description 页面数据
  12143 + * @type {{dataSources: [], act: [], event: []}}
12096 12144 */
12097 12145 contentData
12098 12146
12099 12147 /**
  12148 + * @description 处理数据源实例
  12149 + * @type {HandleDataSource}
  12150 + */
  12151 + dataSourceHandlerInstance
  12152 +
  12153 + /**
12100 12154 * @description 处理数据动效实例
12101 12155 * @type {HandleDynamicEffect}
12102 12156 */
... ... @@ -12171,6 +12225,7 @@ class DispatchCenter {
12171 12225 this.saveContentInfo(editorUi, currentPage)
12172 12226 this.connectSocket()
12173 12227 await this.getContentDataNode()
  12228 + this.dataSourceHandlerInstance = new HandleDataSource(this)
12174 12229 this.dataInteractionInstance = new HandleDataInteraction(this)
12175 12230 this.dynamicEffectInstance = new HandleDynamicEffect(this)
12176 12231 this.updateQueueInstance = new UpdateQueue(this)
... ... @@ -12220,9 +12275,10 @@ class DispatchCenter {
12220 12275 const { node: { id } = {} } = this.currentPage
12221 12276 if (!id) return
12222 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 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 12863 class HandleDataInteraction {
12333 12864 /**
12334 12865 * @description 事件分发中心实例
... ... @@ -12400,7 +12931,6 @@ class HandleDataInteraction {
12400 12931 graphDblClick.apply(this.graph, args)
12401 12932 }
12402 12933
12403   -
12404 12934 const graphClick = this.graph.click;
12405 12935 this.graph.click = (...args) => {
12406 12936 this.handleClickEvent(...args)
... ... @@ -12534,7 +13064,7 @@ class HandleDataInteraction {
12534 13064 }
12535 13065
12536 13066 /**
12537   - * @description 处理数据
  13067 + * @description 处理数据动效
12538 13068 */
12539 13069 class HandleDynamicEffect {
12540 13070
... ... @@ -12557,12 +13087,6 @@ class HandleDynamicEffect {
12557 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 13090 * @description clear setInterval
12567 13091 */
12568 13092 cleanSetInterval
... ... @@ -12777,7 +13301,6 @@ class HandleDynamicEffect {
12777 13301 node.setVisible(flashFlag)
12778 13302 flashFlag = !flashFlag
12779 13303 }
12780   - console.log(this.actNodeMapping)
12781 13304 const key = node.id + DispatchCenter.enumDynamicEffectType.FLASH
12782 13305 if (!flag) {
12783 13306 flashFlag = true
... ... @@ -12847,7 +13370,7 @@ class HandleDynamicEffect {
12847 13370 getBindData(subscriptionId, actionType) {
12848 13371 const nodeId = this.getNodeIdByCmdId(subscriptionId)
12849 13372 const temp = this.actNodeMapping.get(nodeId)
12850   - return temp.get(actionTypxe)
  13373 + return temp.get(actionType)
12851 13374 }
12852 13375
12853 13376 /**
... ...