@flexem/fc-gui 3.0.0-alpha.137 → 3.0.0-alpha.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/bundles/@flexem/fc-gui.umd.js +251 -230
  2. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  3. package/bundles/@flexem/fc-gui.umd.min.js +3 -3
  4. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  5. package/config/history-data/get-history-data-args.d.ts +3 -14
  6. package/config/history-data/get-history-data-args.js +3 -5
  7. package/config/history-data/get-history-data-args.metadata.json +1 -1
  8. package/config/history-data/history-data.model.d.ts +1 -7
  9. package/config/history-data/history-data.model.js +1 -9
  10. package/config/history-data/history-data.model.metadata.json +1 -1
  11. package/config/history-data/index.d.ts +1 -1
  12. package/config/history-data/index.js +1 -1
  13. package/config/history-data/index.metadata.json +1 -1
  14. package/elements/historical-curve/historical-curve.element.d.ts +0 -6
  15. package/elements/historical-curve/historical-curve.element.js +21 -162
  16. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  17. package/elements/main-element.js +1 -1
  18. package/elements/shared/graph/graph-state-element.d.ts +1 -0
  19. package/elements/shared/graph/graph-state-element.js +30 -1
  20. package/elements/shared/graph/graph-state-element.metadata.json +1 -1
  21. package/elements/shared/text/text-state-element.d.ts +3 -1
  22. package/elements/shared/text/text-state-element.js +55 -10
  23. package/elements/shared/text/text-state-element.metadata.json +1 -1
  24. package/elements/static-elements/hyperlink-element.js +37 -7
  25. package/elements/static-elements/text-element.d.ts +1 -0
  26. package/elements/static-elements/text-element.js +38 -7
  27. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +1 -0
  28. package/elements/switch-indicator-light/switch-indicator-light-element.js +15 -2
  29. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  30. package/elements/view-operation/view-operation.element.js +34 -7
  31. package/model/base/font-setting-model.d.ts +6 -1
  32. package/model/base/font-setting-model.metadata.json +1 -1
  33. package/model/historical-curve/historical-curve.data-settings.d.ts +1 -18
  34. package/model/historical-curve/historical-curve.data-settings.metadata.json +1 -1
  35. package/package.json +1 -1
@@ -1,14 +1,5 @@
1
1
  import * as moment from 'moment';
2
2
  import { HistoricalCurveTimeRange } from './historical-curve.time-range';
3
- /**
4
- * 单个历史数据条目查询参数
5
- */
6
- export interface HistoryDataItemArgs {
7
- /** 历史数据条目名称 */
8
- dataItemName: string;
9
- /** 该条目下的通道名称列表 */
10
- channelNames: Array<string>;
11
- }
12
3
  export declare class GetHistoryDataArgs {
13
4
  readonly dataSourceCode: number;
14
5
  readonly dataItemName: string;
@@ -17,17 +8,15 @@ export declare class GetHistoryDataArgs {
17
8
  readonly endTime: moment.Moment;
18
9
  readonly limit: number;
19
10
  readonly rangeType: HistoricalCurveTimeRange;
20
- readonly historyDataItems?: Array<HistoryDataItemArgs>;
21
11
  /**
22
12
  * 获取历史数据参数
23
13
  * @param dataSourceCode 数据源编码
24
- * @param dataItemName 历史数据条目名称(单条目模式,兼容旧版)
25
- * @param channelNames 通道名称(单条目模式,兼容旧版)
14
+ * @param dataItemName 历史数据条目名称
15
+ * @param channelNames 通道名称
26
16
  * @param startTime 开始时间
27
17
  * @param endTime 结束时间
28
18
  * @param limit 获取数据数量,为负数则倒叙
29
19
  * @param rangeType 区间类型
30
- * @param historyDataItems 多条目模式:多个历史数据条目及其通道配置
31
20
  */
32
- constructor(dataSourceCode: number, dataItemName: string, channelNames: Array<string>, startTime: moment.Moment, endTime: moment.Moment, limit: number, rangeType: HistoricalCurveTimeRange, historyDataItems?: Array<HistoryDataItemArgs>);
21
+ constructor(dataSourceCode: number, dataItemName: string, channelNames: Array<string>, startTime: moment.Moment, endTime: moment.Moment, limit: number, rangeType: HistoricalCurveTimeRange);
33
22
  }
@@ -2,15 +2,14 @@ export class GetHistoryDataArgs {
2
2
  /**
3
3
  * 获取历史数据参数
4
4
  * @param dataSourceCode 数据源编码
5
- * @param dataItemName 历史数据条目名称(单条目模式,兼容旧版)
6
- * @param channelNames 通道名称(单条目模式,兼容旧版)
5
+ * @param dataItemName 历史数据条目名称
6
+ * @param channelNames 通道名称
7
7
  * @param startTime 开始时间
8
8
  * @param endTime 结束时间
9
9
  * @param limit 获取数据数量,为负数则倒叙
10
10
  * @param rangeType 区间类型
11
- * @param historyDataItems 多条目模式:多个历史数据条目及其通道配置
12
11
  */
13
- constructor(dataSourceCode, dataItemName, channelNames, startTime, endTime, limit, rangeType, historyDataItems) {
12
+ constructor(dataSourceCode, dataItemName, channelNames, startTime, endTime, limit, rangeType) {
14
13
  this.dataSourceCode = dataSourceCode;
15
14
  this.dataItemName = dataItemName;
16
15
  this.channelNames = channelNames;
@@ -18,6 +17,5 @@ export class GetHistoryDataArgs {
18
17
  this.endTime = endTime;
19
18
  this.limit = limit;
20
19
  this.rangeType = rangeType;
21
- this.historyDataItems = historyDataItems;
22
20
  }
23
21
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"HistoryDataItemArgs":{"__symbolic":"interface"},"GetHistoryDataArgs":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","name":"any"}]},{"__symbolic":"reference","module":"moment","name":"Moment","line":28,"character":28},{"__symbolic":"reference","module":"moment","name":"Moment","line":29,"character":26},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","module":"./historical-curve.time-range","name":"HistoricalCurveTimeRange","line":31,"character":28},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","name":"any"}]}]}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"GetHistoryDataArgs":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","name":"string"}]},{"__symbolic":"reference","module":"moment","name":"Moment","line":17,"character":28},{"__symbolic":"reference","module":"moment","name":"Moment","line":18,"character":26},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","module":"./historical-curve.time-range","name":"HistoricalCurveTimeRange","line":20,"character":28}]}]}}}}]
@@ -3,11 +3,5 @@ export declare class HistoryDataModel {
3
3
  readonly error: string;
4
4
  readonly isUnbind: boolean;
5
5
  readonly values: Array<HistoryDataValue>;
6
- readonly historyDataItems?: Array<HistoryDataItemModel>;
7
- constructor(error: string, isUnbind: boolean, values: Array<HistoryDataValue>, historyDataItems?: Array<HistoryDataItemModel>);
8
- }
9
- export declare class HistoryDataItemModel {
10
- readonly itemName: string;
11
- readonly rows: Array<HistoryDataValue>;
12
- constructor(itemName: string, rows: Array<HistoryDataValue>);
6
+ constructor(error: string, isUnbind: boolean, values: Array<HistoryDataValue>);
13
7
  }
@@ -1,15 +1,7 @@
1
1
  export class HistoryDataModel {
2
- constructor(error, isUnbind, values, historyDataItems // 新增:多条目独立数据
3
- ) {
2
+ constructor(error, isUnbind, values) {
4
3
  this.error = error;
5
4
  this.isUnbind = isUnbind;
6
5
  this.values = values;
7
- this.historyDataItems = historyDataItems;
8
- }
9
- }
10
- export class HistoryDataItemModel {
11
- constructor(itemName, rows) {
12
- this.itemName = itemName;
13
- this.rows = rows;
14
6
  }
15
7
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"HistoryDataModel":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"boolean"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"./history-data-value","name":"HistoryDataValue","line":6,"character":31}]},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"./history-data-value","name":"HistoryDataValue","line":6,"character":31}]}]}]}},"HistoryDataItemModel":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"./history-data-value","name":"HistoryDataValue","line":6,"character":31}]}]}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"HistoryDataModel":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"boolean"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"./history-data-value","name":"HistoryDataValue","line":3,"character":91}]}]}]}}}}]
@@ -1,4 +1,4 @@
1
1
  export { HistoryDataStore } from './history-data.store';
2
- export { HistoryDataModel, HistoryDataItemModel } from './history-data.model';
2
+ export { HistoryDataModel } from './history-data.model';
3
3
  export { HistoryDataValue } from './history-data-value';
4
4
  export { GetHistoryDataArgs } from './get-history-data-args';
@@ -1,3 +1,3 @@
1
- export { HistoryDataModel, HistoryDataItemModel } from './history-data.model';
1
+ export { HistoryDataModel } from './history-data.model';
2
2
  export { HistoryDataValue } from './history-data-value';
3
3
  export { GetHistoryDataArgs } from './get-history-data-args';
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{},"exports":[{"from":"./history-data.store","export":["HistoryDataStore"]},{"from":"./history-data.model","export":["HistoryDataModel","HistoryDataItemModel"]},{"from":"./history-data-value","export":["HistoryDataValue"]},{"from":"./get-history-data-args","export":["GetHistoryDataArgs"]}]}]
1
+ [{"__symbolic":"module","version":4,"metadata":{},"exports":[{"from":"./history-data.store","export":["HistoryDataStore"]},{"from":"./history-data.model","export":["HistoryDataModel"]},{"from":"./history-data-value","export":["HistoryDataValue"]},{"from":"./get-history-data-args","export":["GetHistoryDataArgs"]}]}]
@@ -67,14 +67,8 @@ export declare class HistoricalCurveElement extends ConditionalDisplayElement {
67
67
  private updateQueryTimeRange;
68
68
  private reRenderElement;
69
69
  private renderElement;
70
- private handleQueryResult;
71
70
  setupTooltipAutoHide(chart: any): void;
72
71
  private renderChart;
73
- /**
74
- * 【新格式】多条目独立数据的曲线渲染
75
- * 每个条目独立保持自己的时间戳,不会出现时间戳混乱的问题
76
- */
77
- private renderChartWithMultiItems;
78
72
  initPoint(): void;
79
73
  private getLineChart;
80
74
  private getMultiBarWithFocusChart;
@@ -215,95 +215,30 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
215
215
  if (!this.model.dataSetting) {
216
216
  return;
217
217
  }
218
+ const dataItemName = this.model.dataSetting.dataName;
218
219
  const dataSourceCode = this.model.dataSetting.dataSourceCode;
220
+ const channelNames = this.model.dataSetting.channels.map(c => c.name);
219
221
  this.updateElementStatus(HistoricalCurveElementStatus.Loading);
220
- // 【新格式】如果有多条目配置,使用多条目查询
221
- if (this.model.dataSetting.dataItems && this.model.dataSetting.dataItems.length > 0) {
222
- const historyDataItems = this.model.dataSetting.dataItems.map(item => ({
223
- dataItemName: item.dataName,
224
- channelNames: item.channels.map(c => c.name)
225
- }));
226
- // 使用第一个条目的信息作为兼容参数
227
- const firstItem = this.model.dataSetting.dataItems[0];
228
- const input = new GetHistoryDataArgs(dataSourceCode, firstItem.dataName, firstItem.channels.map(c => c.name), startTime, endTime, limit, rangeType, historyDataItems // 传递多条目参数
229
- );
230
- this.historyDataStore.getHistoryData(input).subscribe(result => {
231
- this.handleQueryResult(result);
232
- });
233
- }
234
- // 【旧格式】单条目模式
235
- else {
236
- const dataItemName = this.model.dataSetting.dataName;
237
- const channelNames = this.model.dataSetting.channels.map(c => c.name);
238
- const input = new GetHistoryDataArgs(dataSourceCode, dataItemName, channelNames, startTime, endTime, limit, rangeType);
239
- this.historyDataStore.getHistoryData(input).subscribe(result => {
240
- this.handleQueryResult(result);
241
- });
242
- }
243
- }
244
- handleQueryResult(result) {
245
- this.timePeriods = this.getValidTimePeriods();
246
- // 【新格式】多条目模式下的错误处理
247
- if (result.historyDataItems && result.historyDataItems.length > 0) {
248
- // 只要有条目正常返回(即使没有数据),就走正常逻辑
249
- // 这样可以确保即使部分条目失败,只要有条目成功返回,就显示正常状态
250
- this.clearStatus();
251
- if (result.isUnbind) {
252
- this.updateElementStatus(HistoricalCurveElementStatus.Unbound);
253
- }
254
- else {
255
- this.updateElementStatus(HistoricalCurveElementStatus.Normal);
256
- }
257
- // 如果有错误信息,在控制台输出警告
222
+ const input = new GetHistoryDataArgs(dataSourceCode, dataItemName, channelNames, startTime, endTime, limit, rangeType);
223
+ this.historyDataStore.getHistoryData(input).subscribe(result => {
258
224
  if (result.error) {
259
- this.logger.warn(`[历史曲线] 部分条目查询失败: ${result.error}`);
260
- }
261
- // 检查是否有任何条目有数据
262
- const hasAnyData = result.historyDataItems.some(item => item.rows && item.rows.length > 0);
263
- if (hasAnyData) {
264
- // 有数据,计算所有条目的最小和最大时间,确保时间轴覆盖所有数据
265
- let globalMinTime = null;
266
- let globalMaxTime = null;
267
- result.historyDataItems.forEach(item => {
268
- if (item.rows && item.rows.length > 0) {
269
- const itemMinTime = moment(first(item.rows).time);
270
- const itemMaxTime = moment(last(item.rows).time);
271
- if (!globalMinTime || itemMinTime.isBefore(globalMinTime)) {
272
- globalMinTime = itemMinTime;
273
- }
274
- if (!globalMaxTime || itemMaxTime.isAfter(globalMaxTime)) {
275
- globalMaxTime = itemMaxTime;
276
- }
277
- }
278
- });
279
- // 设置全局时间范围
280
- if (globalMinTime && globalMaxTime) {
281
- this.currentStartTime = globalMinTime;
282
- this.currentEndTime = globalMaxTime;
283
- }
284
- }
285
- // 无论是否有数据,都渲染曲线(没有数据会显示空曲线)
286
- this.chartElement = this.renderChartWithMultiItems(result.historyDataItems);
287
- }
288
- // 【旧格式】单条目模式的错误处理
289
- else if (result.error) {
290
- this.updateElementStatus(HistoricalCurveElementStatus.LoadFailed, result.error);
291
- }
292
- else {
293
- this.clearStatus();
294
- if (result.isUnbind) {
295
- this.updateElementStatus(HistoricalCurveElementStatus.Unbound);
225
+ this.updateElementStatus(HistoricalCurveElementStatus.LoadFailed, result.error);
296
226
  }
297
227
  else {
298
- this.updateElementStatus(HistoricalCurveElementStatus.Normal);
299
- }
300
- // 【旧格式】单条目数据,使用原有渲染方式
301
- if (result.values.length) {
302
- this.currentStartTime = moment(first(result.values).time);
303
- this.currentEndTime = moment(last(result.values).time);
228
+ this.clearStatus();
229
+ if (result.isUnbind) {
230
+ this.updateElementStatus(HistoricalCurveElementStatus.Unbound);
231
+ }
232
+ else {
233
+ this.updateElementStatus(HistoricalCurveElementStatus.Normal);
234
+ }
235
+ if (result.values.length) {
236
+ this.currentStartTime = moment(first(result.values).time);
237
+ this.currentEndTime = moment(last(result.values).time);
238
+ }
239
+ this.chartElement = this.renderChart(result.values);
304
240
  }
305
- this.chartElement = this.renderChart(result.values);
306
- }
241
+ });
307
242
  }
308
243
  setupTooltipAutoHide(chart) {
309
244
  const chartContainer = this.rootElement.select('.nv-focus').node();
@@ -331,58 +266,10 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
331
266
  const chartWidth = this.model.displaySetting.size.width;
332
267
  const chartHeight = this.model.displaySetting.size.height - this.displayOption.operationAreaHeight - this.displayOption.operationAreaMarginTop;
333
268
  const data = new Array();
334
- // 【旧格式】单条目模式:只显示通道名
335
269
  each(this.model.dataSetting.channels, (channel, key) => {
336
270
  const values = new Array();
337
271
  each(result, v => values.push({ x: moment(v.time).local().toDate().valueOf(), y: v.values[key] }));
338
- const displayName = channel.name;
339
- data.push({ key: displayName, area: channel.projectEnabled, values: values });
340
- });
341
- this.data = data;
342
- let chart;
343
- if (this.model.displaySetting.curveType === CurveType.BarGroup || this.model.displaySetting.curveType === CurveType.BarStack) {
344
- chart = this.getMultiBarWithFocusChart(chartWidth, chartHeight, data);
345
- }
346
- else {
347
- chart = this.getLineChart(chartWidth, chartHeight, data);
348
- }
349
- // 设置 tooltip 自动隐藏逻辑
350
- this.setupTooltipAutoHide(chart);
351
- return chart;
352
- }
353
- /**
354
- * 【新格式】多条目独立数据的曲线渲染
355
- * 每个条目独立保持自己的时间戳,不会出现时间戳混乱的问题
356
- */
357
- renderChartWithMultiItems(historyDataItems) {
358
- const chartWidth = this.model.displaySetting.size.width;
359
- const chartHeight = this.model.displaySetting.size.height - this.displayOption.operationAreaHeight - this.displayOption.operationAreaMarginTop;
360
- const data = new Array();
361
- // 创建一个 Map 用于快速查找条目数据
362
- const itemDataMap = new Map();
363
- each(historyDataItems, item => {
364
- if (item && item.itemName) {
365
- itemDataMap.set(item.itemName, item.rows || []);
366
- }
367
- });
368
- // 判断是否只有一个条目
369
- const isSingleItem = this.model.dataSetting.dataItems && this.model.dataSetting.dataItems.length === 1;
370
- // 为每个条目的每个通道创建独立的曲线
371
- each(this.model.dataSetting.dataItems, (dataItem) => {
372
- const itemName = dataItem.dataName;
373
- // 通过 itemName 匹配数据,而不是通过索引
374
- const itemRows = itemDataMap.get(itemName) || [];
375
- each(dataItem.channels, (channel, channelIdx) => {
376
- const values = new Array();
377
- // 每个条目使用自己的时间戳和数据
378
- each(itemRows, row => {
379
- const value = row.values && row.values[channelIdx] !== undefined ? row.values[channelIdx] : null;
380
- values.push({ x: moment(row.time).local().toDate().valueOf(), y: value });
381
- });
382
- // 只有多个条目时才使用"条目名-通道名"格式,单条目时只显示通道名
383
- const displayName = isSingleItem ? channel.name : `${itemName}-${channel.name}`;
384
- data.push({ key: displayName, area: channel.projectEnabled, values: values });
385
- });
272
+ data.push({ key: channel.name, area: channel.projectEnabled, values: values });
386
273
  });
387
274
  this.data = data;
388
275
  let chart;
@@ -402,22 +289,8 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
402
289
  .find('.nv-legend')
403
290
  .find('.nv-series');
404
291
  let hiddenCount = 0;
405
- // 获取所有通道(支持多条目和单条目模式)
406
- const allChannels = [];
407
- if (this.model.dataSetting.dataItems && this.model.dataSetting.dataItems.length > 0) {
408
- // 【新格式】多条目模式:收集所有条目的所有通道
409
- each(this.model.dataSetting.dataItems, dataItem => {
410
- each(dataItem.channels, channel => {
411
- allChannels.push(channel);
412
- });
413
- });
414
- }
415
- else {
416
- // 【旧格式】单条目模式
417
- allChannels.push(...this.model.dataSetting.channels);
418
- }
419
292
  for (let i = 0; i < this.data.length; i++) {
420
- const channel = allChannels[i];
293
+ const channel = this.model.dataSetting.channels[i];
421
294
  if (legendList.eq(i).children().eq(0).css('fill-opacity') === '1') {
422
295
  const pointList = this.$element
423
296
  .find('.nv-scatterWrap')
@@ -559,21 +432,7 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
559
432
  }
560
433
  chart.width(chartWidth);
561
434
  chart.height(chartHeight);
562
- // 获取所有通道的颜色(支持多条目和单条目模式)
563
- let channelColors = [];
564
- if (this.model.dataSetting.dataItems && this.model.dataSetting.dataItems.length > 0) {
565
- // 【新格式】多条目模式:收集所有条目的所有通道颜色
566
- each(this.model.dataSetting.dataItems, dataItem => {
567
- each(dataItem.channels, channel => {
568
- channelColors.push(channel.connectorColor);
569
- });
570
- });
571
- }
572
- else {
573
- // 【旧格式】单条目模式
574
- channelColors = this.model.dataSetting.channels.map(c => c.connectorColor);
575
- }
576
- chart.color(channelColors);
435
+ chart.color(this.model.dataSetting.channels.map(c => c.connectorColor));
577
436
  this.rootElement.append('g').datum(data).call(chart);
578
437
  this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
579
438
  this.resizeEventListener = nv.utils.windowResize(() => {
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"HistoricalCurveElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":23,"character":44},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":71,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":72,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":73,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":74,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":75,"character":23},{"__symbolic":"reference","module":"../../config","name":"HistoryDataStore","line":76,"character":43},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"SystemTextLibraryService","line":78,"character":52},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":79,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":80,"character":38}]}],"dispose":[{"__symbolic":"method"}],"initKeyboardListener":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"updateLanguageTexts":[{"__symbolic":"method"}],"getCurrentCulture":[{"__symbolic":"method"}],"getValidTimePeriods":[{"__symbolic":"method"}],"getTimePeriodText":[{"__symbolic":"method"}],"updateTimeRange":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"reRenderElement":[{"__symbolic":"method"}],"renderElement":[{"__symbolic":"method"}],"handleQueryResult":[{"__symbolic":"method"}],"setupTooltipAutoHide":[{"__symbolic":"method"}],"renderChart":[{"__symbolic":"method"}],"renderChartWithMultiItems":[{"__symbolic":"method"}],"initPoint":[{"__symbolic":"method"}],"getLineChart":[{"__symbolic":"method"}],"getMultiBarWithFocusChart":[{"__symbolic":"method"}],"renderCommonProperty":[{"__symbolic":"method"}],"renderOperationArea":[{"__symbolic":"method"}],"timeFormat":[{"__symbolic":"method"}],"loadFirstPage":[{"__symbolic":"method"}],"loadNextPage":[{"__symbolic":"method"}],"loadPreviousPage":[{"__symbolic":"method"}],"loadLastPage":[{"__symbolic":"method"}],"initElementStatus":[{"__symbolic":"method"}],"updateElementStatus":[{"__symbolic":"method"}],"setStatusAsUnbound":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"setStatusAsLoadFailed":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"HistoricalCurveElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":23,"character":44},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":71,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":72,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":73,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":74,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":75,"character":23},{"__symbolic":"reference","module":"../../config","name":"HistoryDataStore","line":76,"character":43},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"SystemTextLibraryService","line":78,"character":52},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":79,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":80,"character":38}]}],"dispose":[{"__symbolic":"method"}],"initKeyboardListener":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"updateLanguageTexts":[{"__symbolic":"method"}],"getCurrentCulture":[{"__symbolic":"method"}],"getValidTimePeriods":[{"__symbolic":"method"}],"getTimePeriodText":[{"__symbolic":"method"}],"updateTimeRange":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"reRenderElement":[{"__symbolic":"method"}],"renderElement":[{"__symbolic":"method"}],"setupTooltipAutoHide":[{"__symbolic":"method"}],"renderChart":[{"__symbolic":"method"}],"initPoint":[{"__symbolic":"method"}],"getLineChart":[{"__symbolic":"method"}],"getMultiBarWithFocusChart":[{"__symbolic":"method"}],"renderCommonProperty":[{"__symbolic":"method"}],"renderOperationArea":[{"__symbolic":"method"}],"timeFormat":[{"__symbolic":"method"}],"loadFirstPage":[{"__symbolic":"method"}],"loadNextPage":[{"__symbolic":"method"}],"loadPreviousPage":[{"__symbolic":"method"}],"loadLastPage":[{"__symbolic":"method"}],"initElementStatus":[{"__symbolic":"method"}],"updateElementStatus":[{"__symbolic":"method"}],"setStatusAsUnbound":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"setStatusAsLoadFailed":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}]}}}}]
@@ -302,7 +302,7 @@ export class MainElement {
302
302
  each(this.elements, e => {
303
303
  if (e instanceof HistoricalCurveElement || e instanceof VideoElement
304
304
  || e instanceof WeatherElement || e instanceof NumericalDisplayElement || e instanceof TextElement
305
- || e instanceof AirQualityElement || e instanceof ScrollAlarmElement) {
305
+ || e instanceof AirQualityElement || e instanceof SwitchIndicatorLightElement || e instanceof ScrollAlarmElement) {
306
306
  e.dispose();
307
307
  }
308
308
  });
@@ -24,4 +24,5 @@ export declare class GraphStateElement {
24
24
  private removeImageElement;
25
25
  private doFaultFlicker;
26
26
  private clearFlickerInterval;
27
+ dispose(): void;
27
28
  }
@@ -42,12 +42,19 @@ export class GraphStateElement {
42
42
  }
43
43
  }
44
44
  changeGraph(stateId, graphResult) {
45
+ // 检查元素是否已被销毁
46
+ if (!this._element) {
47
+ return;
48
+ }
45
49
  if (!graphResult.failed) {
46
50
  const graph = graphResult.graph;
47
51
  switch (graph.graphType) {
48
52
  case GraphType.Image:
49
53
  case GraphType.SVG:
50
54
  const imageElement = this.getImageElement();
55
+ if (!imageElement) {
56
+ return;
57
+ }
51
58
  imageElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', graph.source);
52
59
  this.doFaultFlicker(imageElement, stateId);
53
60
  break;
@@ -63,6 +70,10 @@ export class GraphStateElement {
63
70
  }
64
71
  getImageElement() {
65
72
  if (!this.imageElement) {
73
+ // 检查 _element 是否已被销毁
74
+ if (!this._element) {
75
+ return null;
76
+ }
66
77
  this.imageElement = document.createElementNS('http://www.w3.org/2000/svg', 'image');
67
78
  this.imageElement.setAttribute('width', this.width + '');
68
79
  this.imageElement.setAttribute('height', this.height + '');
@@ -74,7 +85,7 @@ export class GraphStateElement {
74
85
  return this.imageElement;
75
86
  }
76
87
  removeImageElement() {
77
- if (this.imageElement) {
88
+ if (this.imageElement && this._element) {
78
89
  this._element.removeChild(this.imageElement);
79
90
  delete this.imageElement;
80
91
  }
@@ -107,4 +118,22 @@ export class GraphStateElement {
107
118
  }
108
119
  }
109
120
  }
121
+ dispose() {
122
+ // 清理定时器
123
+ if (this.faultFlickerInterval) {
124
+ clearInterval(this.faultFlickerInterval);
125
+ this.faultFlickerInterval = undefined;
126
+ }
127
+ // 移除图片元素
128
+ this.removeImageElement();
129
+ // 清理图形缓存
130
+ if (this.graphs) {
131
+ this.graphs.clear();
132
+ }
133
+ // 清理 SVG 元素
134
+ if (this._element && this._element.parentNode) {
135
+ this._element.parentNode.removeChild(this._element);
136
+ }
137
+ this._element = null;
138
+ }
110
139
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"GraphStateElement":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../../../model","name":"GraphSetting","line":21,"character":47},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","module":"../../../config","name":"GraphStore","line":24,"character":37},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":25,"character":33},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"../../../model/switch-indicator-light/indicator-light-fault-flicker","name":"IndicatorLightFaultFlicker","line":27,"character":41}]}]}],"switchToState":[{"__symbolic":"method"}],"changeGraph":[{"__symbolic":"method"}],"getImageElement":[{"__symbolic":"method"}],"removeImageElement":[{"__symbolic":"method"}],"doFaultFlicker":[{"__symbolic":"method"}],"clearFlickerInterval":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"GraphStateElement":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../../../model","name":"GraphSetting","line":21,"character":47},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","module":"../../../config","name":"GraphStore","line":24,"character":37},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":25,"character":33},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"../../../model/switch-indicator-light/indicator-light-fault-flicker","name":"IndicatorLightFaultFlicker","line":27,"character":41}]}]}],"switchToState":[{"__symbolic":"method"}],"changeGraph":[{"__symbolic":"method"}],"getImageElement":[{"__symbolic":"method"}],"removeImageElement":[{"__symbolic":"method"}],"doFaultFlicker":[{"__symbolic":"method"}],"clearFlickerInterval":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
@@ -15,6 +15,7 @@ export declare class TextStateElement {
15
15
  private readonly textLibraryService?;
16
16
  private readonly languageService?;
17
17
  private readonly guiContext?;
18
+ private readonly allowEmpty;
18
19
  private textElement;
19
20
  private _element;
20
21
  get Element(): SVGElement;
@@ -22,7 +23,7 @@ export declare class TextStateElement {
22
23
  private faultFlickerInterval;
23
24
  private currentStateId;
24
25
  private languageChangeSubscription?;
25
- constructor(textStates: TextState[], width: number, height: number, logger: LoggerService, version?: number, faultFlickers?: IndicatorLightFaultFlicker[], textLibrarySetting?: TextLibrarySetting, textLibraryService?: TextLibraryService, languageService?: LanguageService, guiContext?: GuiContext);
26
+ constructor(textStates: TextState[], width: number, height: number, logger: LoggerService, version?: number, faultFlickers?: IndicatorLightFaultFlicker[], textLibrarySetting?: TextLibrarySetting, textLibraryService?: TextLibraryService, languageService?: LanguageService, guiContext?: GuiContext, allowEmpty?: boolean);
26
27
  switchToState(stateId: number): void;
27
28
  /**
28
29
  * 订阅语种变化事件
@@ -40,6 +41,7 @@ export declare class TextStateElement {
40
41
  /**
41
42
  * 获取显示文本
42
43
  * 如果配置了文本库,则根据状态ID和当前语种ID从文本库中获取对应语种的文本
44
+ * 如果是多语种自定义文本,则根据当前语种ID获取对应语种的文本
43
45
  * 否则返回默认文本
44
46
  */
45
47
  private getDisplayText;
@@ -1,6 +1,6 @@
1
1
  import { Flicker } from '../../../model';
2
2
  export class TextStateElement {
3
- constructor(textStates, width, height, logger, version, faultFlickers, textLibrarySetting, textLibraryService, languageService, guiContext) {
3
+ constructor(textStates, width, height, logger, version, faultFlickers, textLibrarySetting, textLibraryService, languageService, guiContext, allowEmpty = false) {
4
4
  this.textStates = textStates;
5
5
  this.width = width;
6
6
  this.height = height;
@@ -11,6 +11,7 @@ export class TextStateElement {
11
11
  this.textLibraryService = textLibraryService;
12
12
  this.languageService = languageService;
13
13
  this.guiContext = guiContext;
14
+ this.allowEmpty = allowEmpty;
14
15
  this.faultFlickerStatus = false;
15
16
  this.faultFlickerInterval = undefined;
16
17
  this._element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
@@ -79,10 +80,6 @@ export class TextStateElement {
79
80
  * 当设备的语种ID改变时,重新渲染当前状态的文本
80
81
  */
81
82
  subscribeLanguageChange() {
82
- // 只有使用文本库时才需要订阅语种变化
83
- if (!this.textLibrarySetting || this.textLibrarySetting.labelType !== 'textLibrary') {
84
- return;
85
- }
86
83
  if (this.guiContext && this.guiContext.languageChanged$) {
87
84
  this.languageChangeSubscription = this.guiContext.languageChanged$.subscribe(() => {
88
85
  // 如果当前有状态,重新渲染
@@ -156,10 +153,11 @@ export class TextStateElement {
156
153
  /**
157
154
  * 获取显示文本
158
155
  * 如果配置了文本库,则根据状态ID和当前语种ID从文本库中获取对应语种的文本
156
+ * 如果是多语种自定义文本,则根据当前语种ID获取对应语种的文本
159
157
  * 否则返回默认文本
160
158
  */
161
159
  getDisplayText(stateId, defaultContent) {
162
- var _a, _b, _c, _d, _e, _f;
160
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
163
161
  // 检查是否使用文本库
164
162
  if (this.textLibrarySetting && this.textLibrarySetting.labelType === 'textLibrary') {
165
163
  const textLibraryId = this.textLibrarySetting.selectedTextLibraryItem;
@@ -200,12 +198,59 @@ export class TextStateElement {
200
198
  return '';
201
199
  }
202
200
  }
201
+ // 文本库中未找到对应的状态ID(可能是"其他"状态)
202
+ // 继续检查 defaultContent 中是否有多语种数据
203
+ }
204
+ }
205
+ // 文本库模式下,如果文本库中没有找到数据,继续尝试从 defaultContent 获取
206
+ // 这样可以支持"其他"状态的多语种显示
207
+ }
208
+ // 处理自定义文本(支持多语种)
209
+ if (defaultContent) {
210
+ // 检查是否为多语种格式
211
+ if (typeof defaultContent === 'object' && defaultContent.cultures) {
212
+ // 新格式:多语种对象
213
+ // 获取当前语种ID
214
+ const currentLanguageId = (_j = (_h = (_g = this.guiContext) === null || _g === void 0 ? void 0 : _g.getCurrentLanguageId) === null || _h === void 0 ? void 0 : _h.call(_g)) !== null && _j !== void 0 ? _j : null;
215
+ // 确定要使用的语种代码(culture)
216
+ let targetLanguage;
217
+ const defaultLanguage = ((_k = this.languageService) === null || _k === void 0 ? void 0 : _k.getDefaultLanguage()) || 'zh-CN';
218
+ if (currentLanguageId === null || currentLanguageId === undefined) {
219
+ // 设备未设置当前语种,使用默认语种
220
+ targetLanguage = defaultLanguage;
221
+ }
222
+ else {
223
+ // 设备已设置当前语种,获取对应的语种代码
224
+ const currentLanguage = (_m = (_l = this.guiContext) === null || _l === void 0 ? void 0 : _l.getLanguageCultureById) === null || _m === void 0 ? void 0 : _m.call(_l, currentLanguageId);
225
+ if (currentLanguage) {
226
+ targetLanguage = currentLanguage;
227
+ }
228
+ else {
229
+ targetLanguage = defaultLanguage;
230
+ }
231
+ }
232
+ // 返回对应语种的文本
233
+ // 如果没有对应语种的内容:
234
+ // - allowEmpty=true(开关指示灯):返回空字符串
235
+ // - allowEmpty=false(文本元件):返回默认文本
236
+ if (defaultContent.cultures[targetLanguage]) {
237
+ return defaultContent.cultures[targetLanguage];
203
238
  }
239
+ else if (this.allowEmpty) {
240
+ return '';
241
+ }
242
+ else {
243
+ // 获取当前语言环境,显示默认文本
244
+ const language = ((_q = (_p = (_o = window.abp) === null || _o === void 0 ? void 0 : _o.localization) === null || _p === void 0 ? void 0 : _p.currentLanguage) === null || _q === void 0 ? void 0 : _q.name) || 'zh-Hans';
245
+ const isChinese = language === 'zh-Hans' || language === 'zh';
246
+ return isChinese ? '文本' : 'Text';
247
+ }
248
+ }
249
+ else if (typeof defaultContent === 'string') {
250
+ // 旧格式:字符串
251
+ return defaultContent;
204
252
  }
205
- // 文本库配置但未找到数据,返回空字符串
206
- return '';
207
253
  }
208
- // 默认返回文本内容
209
- return defaultContent || '';
254
+ return '';
210
255
  }
211
256
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"TextStateElement":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"./text-state.model","name":"TextState","line":23,"character":45}]},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":26,"character":33},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"../../../model/switch-indicator-light/indicator-light-fault-flicker","name":"IndicatorLightFaultFlicker","line":28,"character":41}]},{"__symbolic":"reference","module":"../../../model/base/font-setting-model","name":"TextLibrarySetting","line":29,"character":46},{"__symbolic":"reference","module":"../../../service","name":"TextLibraryService","line":30,"character":46},{"__symbolic":"reference","module":"../../../service","name":"LanguageService","line":31,"character":43},{"__symbolic":"reference","module":"../../../gui/gui-context","name":"GuiContext","line":32,"character":38}]}],"switchToState":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}],"getforeignObjectElement":[{"__symbolic":"method"}],"removeForeignObjectlement":[{"__symbolic":"method"}],"doFaultFlicker":[{"__symbolic":"method"}],"clearFlickerInterval":[{"__symbolic":"method"}],"getDisplayText":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"TextStateElement":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"./text-state.model","name":"TextState","line":23,"character":45}]},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":26,"character":33},{"__symbolic":"reference","name":"number"},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"../../../model/switch-indicator-light/indicator-light-fault-flicker","name":"IndicatorLightFaultFlicker","line":28,"character":41}]},{"__symbolic":"reference","module":"../../../model/base/font-setting-model","name":"TextLibrarySetting","line":29,"character":46},{"__symbolic":"reference","module":"../../../service","name":"TextLibraryService","line":30,"character":46},{"__symbolic":"reference","module":"../../../service","name":"LanguageService","line":31,"character":43},{"__symbolic":"reference","module":"../../../gui/gui-context","name":"GuiContext","line":32,"character":38},{"__symbolic":"reference","name":"boolean"}]}],"switchToState":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}],"getforeignObjectElement":[{"__symbolic":"method"}],"removeForeignObjectlement":[{"__symbolic":"method"}],"doFaultFlicker":[{"__symbolic":"method"}],"clearFlickerInterval":[{"__symbolic":"method"}],"getDisplayText":[{"__symbolic":"method"}]}}}}]