@flexem/fc-gui 3.0.0-alpha.15 → 3.0.0-alpha.151

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 (172) hide show
  1. package/CHANGELOG.md +429 -1
  2. package/assets/img/black_first_page.png +0 -0
  3. package/assets/img/black_last_page.png +0 -0
  4. package/assets/img/black_next_page.png +0 -0
  5. package/assets/img/black_previous_page.png +0 -0
  6. package/bundles/@flexem/fc-gui.umd.js +24059 -19951
  7. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  8. package/bundles/@flexem/fc-gui.umd.min.js +5 -5
  9. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  10. package/communication/variable/variable-communicator.d.ts +4 -0
  11. package/communication/variable/variable-value.d.ts +4 -1
  12. package/communication/variable/variable-value.js +4 -1
  13. package/communication/variable/variable-value.metadata.json +1 -1
  14. package/config/alarm/alarm.store.d.ts +6 -0
  15. package/config/alarm/alarm.store.js +0 -0
  16. package/config/alarm/alarm.store.metadata.json +1 -0
  17. package/config/alarm/get-alarms-args.d.ts +12 -0
  18. package/config/alarm/get-alarms-args.js +13 -0
  19. package/config/alarm/get-alarms-args.metadata.json +1 -0
  20. package/config/alarm/index.d.ts +2 -0
  21. package/config/alarm/index.js +1 -0
  22. package/config/alarm/index.metadata.json +1 -0
  23. package/config/config-store.d.ts +2 -0
  24. package/config/index.d.ts +1 -0
  25. package/config/index.js +1 -0
  26. package/config/index.metadata.json +1 -1
  27. package/elements/air-quality/air-quality-element.d.ts +31 -0
  28. package/elements/air-quality/air-quality-element.js +194 -0
  29. package/elements/air-quality/air-quality-element.metadata.json +1 -0
  30. package/elements/alarm/alarm-element.d.ts +69 -0
  31. package/elements/alarm/alarm-element.js +497 -0
  32. package/elements/alarm/alarm-element.metadata.json +1 -0
  33. package/elements/bar-graph-element.d.ts +10 -2
  34. package/elements/bar-graph-element.js +135 -5
  35. package/elements/bar-graph-element.metadata.json +1 -1
  36. package/elements/base/readable-element.d.ts +6 -1
  37. package/elements/base/readable-element.js +65 -2
  38. package/elements/base/readable-element.metadata.json +1 -1
  39. package/elements/base/state-control-element.d.ts +3 -1
  40. package/elements/base/state-control-element.js +3 -0
  41. package/elements/datetime-display/datetime-display-element.d.ts +1 -0
  42. package/elements/datetime-display/datetime-display-element.js +10 -2
  43. package/elements/datetime-display/datetime-display-element.metadata.json +1 -1
  44. package/elements/datetime-display/time-zone-select-json.d.ts +8 -0
  45. package/elements/datetime-display/time-zone-select-json.js +558 -0
  46. package/elements/historical-curve/historical-curve.element.d.ts +33 -3
  47. package/elements/historical-curve/historical-curve.element.js +368 -26
  48. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  49. package/elements/main-element.d.ts +1 -0
  50. package/elements/main-element.js +59 -9
  51. package/elements/main-element.metadata.json +1 -1
  52. package/elements/meter-element.d.ts +7 -1
  53. package/elements/meter-element.js +76 -7
  54. package/elements/meter-element.metadata.json +1 -1
  55. package/elements/numerical-display/numerical-display-element.d.ts +16 -3
  56. package/elements/numerical-display/numerical-display-element.js +83 -11
  57. package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
  58. package/elements/per-view-variable-communicator.d.ts +3 -0
  59. package/elements/per-view-variable-communicator.js +15 -1
  60. package/elements/per-view-variable-communicator.metadata.json +1 -1
  61. package/elements/ring-graph/ring-graph-element.d.ts +13 -1
  62. package/elements/ring-graph/ring-graph-element.js +164 -3
  63. package/elements/ring-graph/ring-graph-element.metadata.json +1 -1
  64. package/elements/scroll-alarm/scroll-alarm-element.d.ts +74 -0
  65. package/elements/scroll-alarm/scroll-alarm-element.js +761 -0
  66. package/elements/scroll-alarm/scroll-alarm-element.metadata.json +1 -0
  67. package/elements/shared/graph/graph-state-element.d.ts +1 -0
  68. package/elements/shared/graph/graph-state-element.js +30 -4
  69. package/elements/shared/graph/graph-state-element.metadata.json +1 -1
  70. package/elements/shared/text/text-element.d.ts +9 -0
  71. package/elements/shared/text/text-element.js +34 -3
  72. package/elements/shared/text/text-element.metadata.json +1 -1
  73. package/elements/shared/text/text-state-element.d.ts +28 -2
  74. package/elements/shared/text/text-state-element.js +188 -65
  75. package/elements/shared/text/text-state-element.metadata.json +1 -1
  76. package/elements/static-elements/hyperlink-element.d.ts +24 -2
  77. package/elements/static-elements/hyperlink-element.js +124 -3
  78. package/elements/static-elements/hyperlink-element.metadata.json +1 -1
  79. package/elements/static-elements/text-element.d.ts +24 -2
  80. package/elements/static-elements/text-element.js +120 -3
  81. package/elements/static-elements/text-element.metadata.json +1 -1
  82. package/elements/switch-indicator-light/bit-indicator-light-operator.d.ts +1 -0
  83. package/elements/switch-indicator-light/bit-indicator-light-operator.js +5 -2
  84. package/elements/switch-indicator-light/bit-indicator-light-operator.metadata.json +1 -1
  85. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +11 -2
  86. package/elements/switch-indicator-light/switch-indicator-light-element.js +55 -11
  87. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  88. package/elements/switch-indicator-light/word-indicator-light-operator.d.ts +1 -0
  89. package/elements/switch-indicator-light/word-indicator-light-operator.js +5 -2
  90. package/elements/switch-indicator-light/word-indicator-light-operator.metadata.json +1 -1
  91. package/elements/video/video-element.d.ts +10 -0
  92. package/elements/video/video-element.js +119 -21
  93. package/elements/video/video-element.metadata.json +1 -1
  94. package/elements/view-operation/view-operation.element.d.ts +24 -2
  95. package/elements/view-operation/view-operation.element.js +128 -4
  96. package/elements/view-operation/view-operation.element.metadata.json +1 -1
  97. package/elements/weather/weater-element.js +0 -1
  98. package/gui/gui-context.d.ts +12 -2
  99. package/gui/gui-host.d.ts +1 -1
  100. package/gui/gui-view.d.ts +4 -1
  101. package/gui/gui-view.js +51 -7
  102. package/gui/gui-view.metadata.json +1 -1
  103. package/gui/gui.component.d.ts +3 -0
  104. package/gui/gui.component.js +15 -2
  105. package/gui/gui.component.metadata.json +1 -1
  106. package/localization/localization.service.d.ts +7 -0
  107. package/localization/localization.service.js +10 -3
  108. package/localization/localization.service.metadata.json +1 -1
  109. package/localization/localization.service.zh_CN.js +8 -1
  110. package/localization/localization.service.zh_CN.metadata.json +1 -1
  111. package/modal/write-value/write-value-modal-args.d.ts +5 -1
  112. package/modal/write-value/write-value-modal-args.js +3 -1
  113. package/modal/write-value/write-value-modal-args.metadata.json +1 -1
  114. package/modal/write-value/write-value-modal.component.d.ts +13 -7
  115. package/modal/write-value/write-value-modal.component.html +10 -5
  116. package/modal/write-value/write-value-modal.component.js +87 -15
  117. package/modal/write-value/write-value-modal.component.metadata.json +1 -1
  118. package/model/air-quality/air-quality-info.d.ts +23 -0
  119. package/model/air-quality/air-quality-info.js +4 -0
  120. package/model/air-quality/air-quality-info.metadata.json +1 -0
  121. package/model/air-quality/air-quality.model.d.ts +7 -0
  122. package/model/air-quality/air-quality.model.js +0 -0
  123. package/model/air-quality/air-quality.model.metadata.json +1 -0
  124. package/model/alarm/alarm.model.d.ts +13 -0
  125. package/model/alarm/alarm.model.js +0 -0
  126. package/model/alarm/alarm.model.metadata.json +1 -0
  127. package/model/bar-graph/bar-graph.d.ts +4 -0
  128. package/model/base/font-setting-model.d.ts +12 -1
  129. package/model/base/font-setting-model.metadata.json +1 -1
  130. package/model/base/readable-model.d.ts +4 -0
  131. package/model/datetime-display/datetime-display.d.ts +1 -0
  132. package/model/historical-curve/historical-curve-axis-settings.d.ts +11 -0
  133. package/model/historical-curve/historical-curve-axis-settings.js +5 -0
  134. package/model/historical-curve/historical-curve-axis-settings.metadata.json +1 -1
  135. package/model/historical-curve/historical-curve-chanel.model.d.ts +8 -0
  136. package/model/meter/meter.d.ts +4 -0
  137. package/model/ring-graph/ring-graph.model.d.ts +8 -0
  138. package/model/scroll-alarm/scroll-alarm.model.d.ts +21 -0
  139. package/model/scroll-alarm/scroll-alarm.model.js +0 -0
  140. package/model/scroll-alarm/scroll-alarm.model.metadata.json +1 -0
  141. package/model/shared/text/text.d.ts +3 -0
  142. package/model/switch-indicator-light/switch-indicator-light.d.ts +2 -0
  143. package/model/view-operation/view-operation-element.model.d.ts +7 -1
  144. package/package.json +1 -1
  145. package/public_api.js +1 -0
  146. package/remote/communication/variable/remote-variable-communicator.d.ts +27 -0
  147. package/remote/communication/variable/remote-variable-communicator.js +148 -3
  148. package/remote/communication/variable/remote-variable-communicator.metadata.json +1 -1
  149. package/remote/communication/variable/remote-variable-protocol.d.ts +5 -0
  150. package/service/index.d.ts +4 -0
  151. package/service/index.js +1 -0
  152. package/service/index.metadata.json +1 -1
  153. package/service/language.service.d.ts +37 -0
  154. package/service/language.service.js +0 -0
  155. package/service/language.service.metadata.json +1 -0
  156. package/service/released-variable/index.d.ts +1 -0
  157. package/service/released-variable/index.js +0 -0
  158. package/service/released-variable/index.metadata.json +1 -0
  159. package/service/released-variable/released-variable.service.d.ts +4 -0
  160. package/service/released-variable/released-variable.service.js +0 -0
  161. package/service/released-variable/released-variable.service.metadata.json +1 -0
  162. package/service/system-text-library.service.d.ts +76 -0
  163. package/service/system-text-library.service.js +28 -0
  164. package/service/system-text-library.service.metadata.json +1 -0
  165. package/service/text-library.service.d.ts +49 -0
  166. package/service/text-library.service.js +0 -0
  167. package/service/text-library.service.metadata.json +1 -0
  168. package/service/weather.service.d.ts +1 -0
  169. package/shared/gui-consts.d.ts +3 -0
  170. package/shared/gui-consts.js +3 -0
  171. package/shared/gui-consts.metadata.json +1 -1
  172. package/utils/data-type/fbox-data-type.service.js +40 -0
@@ -5,15 +5,20 @@ import * as nv from 'nvd3';
5
5
  import { GetHistoryDataArgs } from '../../config';
6
6
  import { HistoricalCurveTimeRange } from '../../config/history-data/historical-curve.time-range';
7
7
  import { LOCALIZATION } from '../../localization';
8
+ import { SYSTEM_TEXT_LIBRARY_TYPES, TIME_PERIOD_KEYS } from '../../service';
8
9
  import { ConditionalDisplayElement } from '../base/conditional-display-element';
9
10
  import { HistoricalCurveElementStatus } from './historical-curve-element-status';
10
11
  import { LOGGER_SERVICE_TOKEN } from '../../logger';
11
12
  import { GlobalSettings, DisplayMode } from '../../settings';
12
13
  import { CurveType } from '../../model/historical-curve/curve-type';
14
+ import { AxisRangeType } from '../../model/historical-curve/historical-curve-axis-settings';
13
15
  export class HistoricalCurveElement extends ConditionalDisplayElement {
14
- constructor(element, injector, permissionChecker, variableCommunicator, variableStore, historyDataStore, signalRAppId) {
16
+ constructor(element, injector, permissionChecker, variableCommunicator, variableStore, historyDataStore, signalRAppId, systemTextLibraryService, languageService, guiContext) {
15
17
  super(element, permissionChecker, variableCommunicator, variableStore, signalRAppId);
16
18
  this.historyDataStore = historyDataStore;
19
+ this.systemTextLibraryService = systemTextLibraryService;
20
+ this.languageService = languageService;
21
+ this.guiContext = guiContext;
17
22
  this.displayOption = {
18
23
  dataLimit: 500,
19
24
  dataZoomHeight: 32,
@@ -21,16 +26,21 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
21
26
  marginRight: 20,
22
27
  mobileMinWidth: 450,
23
28
  operationAreaHeight: 32,
24
- operationAreaMarginTop: 10,
29
+ operationAreaMarginTop: 25,
25
30
  operationSelectFontSize: '16px',
26
31
  operationButtonWidth: 24,
27
32
  operationButtonHeight: 24,
28
33
  operationButtonMargin: 4
29
34
  };
30
35
  this.elementStatus = HistoricalCurveElementStatus.Loading;
36
+ this.data = [];
37
+ this.needResize = true;
38
+ this.setNeedResize = () => {
39
+ this.needResize = false;
40
+ setTimeout(() => this.needResize = true, 500);
41
+ };
31
42
  this.logger = injector.get(LOGGER_SERVICE_TOKEN);
32
43
  this.localization = injector.get(LOCALIZATION);
33
- this.timePeriods = this.getValidTimePeriods();
34
44
  this.updateTimeRange(this.model.displaySetting.displayTimePeriod);
35
45
  this.refreshIntervalId = setInterval(() => {
36
46
  this.loadFirstPage();
@@ -38,7 +48,7 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
38
48
  }, this.model.displaySetting.refreshInterval * 1000);
39
49
  this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
40
50
  if (this.isMobileMode) {
41
- this.displayOption.operationAreaMarginTop = 20;
51
+ this.displayOption.operationAreaMarginTop = 35;
42
52
  if (this.model.displaySetting.size.width >= this.displayOption.mobileMinWidth) {
43
53
  this.displayOption.operationAreaHeight = 68;
44
54
  this.displayOption.operationSelectFontSize = '24px';
@@ -47,24 +57,133 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
47
57
  this.displayOption.operationButtonMargin = 6;
48
58
  }
49
59
  }
60
+ // 初始化时间段数据(此时文本库可能未加载,先填充空文本占位)
61
+ this.timePeriods = this.getValidTimePeriods();
50
62
  this.loadFirstPage();
63
+ this.initKeyboardListener();
64
+ // 订阅语种变化事件 和 文本库缓存更新事件
65
+ this.subscribeLanguageChange();
51
66
  }
52
67
  dispose() {
53
68
  clearInterval(this.refreshIntervalId);
54
69
  if (this.chartElement) {
55
70
  this.chartElement.tooltip.hidden(true);
56
71
  }
72
+ if (this.resizeEventListener) {
73
+ this.resizeEventListener.clear();
74
+ }
75
+ if (this.isAndroid) {
76
+ window.removeEventListener('native.keyboardshow', this.setNeedResize);
77
+ window.removeEventListener('native.keyboardhide', this.setNeedResize);
78
+ }
79
+ // 取消语种变化订阅
80
+ if (this.languageChangeSubscription) {
81
+ this.languageChangeSubscription.unsubscribe();
82
+ this.languageChangeSubscription = undefined;
83
+ }
57
84
  this.logger.debug(`[GUI]Dispose Histoical Curve Refresh Interval:${d3.time.format('%x %X')(new Date())}`);
58
85
  }
86
+ initKeyboardListener() {
87
+ this.isAndroid = !!navigator.userAgent.match(/(Android)/i);
88
+ if (this.isAndroid) {
89
+ window.addEventListener('native.keyboardshow', this.setNeedResize);
90
+ window.addEventListener('native.keyboardhide', this.setNeedResize);
91
+ }
92
+ }
93
+ /**
94
+ * 订阅语种变化事件
95
+ */
96
+ subscribeLanguageChange() {
97
+ var _a;
98
+ if (this.guiContext && this.guiContext.languageChanged$) {
99
+ this.languageChangeSubscription = this.guiContext.languageChanged$.subscribe(() => {
100
+ // 只更新时间段选择器的文案,不重新查询数据
101
+ this.updateLanguageTexts();
102
+ });
103
+ }
104
+ // 订阅文本库缓存更新事件,解决首次加载时文本库未就绪导致下拉选项为空的问题
105
+ if ((_a = this.systemTextLibraryService) === null || _a === void 0 ? void 0 : _a.cacheUpdated) {
106
+ const cacheSubscription = this.systemTextLibraryService.cacheUpdated.subscribe(() => {
107
+ this.updateLanguageTexts();
108
+ });
109
+ if (this.languageChangeSubscription) {
110
+ this.languageChangeSubscription.add(cacheSubscription);
111
+ }
112
+ else {
113
+ this.languageChangeSubscription = cacheSubscription;
114
+ }
115
+ }
116
+ }
117
+ /**
118
+ * 更新语种相关的文案(时间段选择器)
119
+ */
120
+ updateLanguageTexts() {
121
+ // 重新生成时间段数据
122
+ const updatedTimePeriods = this.getValidTimePeriods();
123
+ this.timePeriods = updatedTimePeriods;
124
+ // select 在 foreignObject 内部的 HTML 命名空间中,D3 的 rootElement.select('select') 无法跨命名空间查找
125
+ // 改用 jQuery 查找
126
+ const nativeSelectEl = this.$element && this.$element.find('select');
127
+ if (nativeSelectEl && nativeSelectEl.length > 0) {
128
+ const options = nativeSelectEl.find('option');
129
+ options.each(function (i) {
130
+ if (i < updatedTimePeriods.length) {
131
+ this.text = updatedTimePeriods[i].name;
132
+ }
133
+ });
134
+ }
135
+ // 如果 select 元素不存在,timePeriods 已更新,下次 renderOperationArea 时会使用新的文本
136
+ }
137
+ /**
138
+ * 获取当前语种的 culture 代码
139
+ */
140
+ getCurrentCulture() {
141
+ var _a, _b, _c, _d, _e, _f;
142
+ // 获取当前语种ID
143
+ const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
144
+ // 确定要使用的语种代码(culture)
145
+ const defaultLanguage = ((_d = this.languageService) === null || _d === void 0 ? void 0 : _d.getDefaultLanguage()) || 'zh-CN';
146
+ if (currentLanguageId === null || currentLanguageId === undefined) {
147
+ // 设备未设置当前语种,使用默认语种
148
+ return defaultLanguage;
149
+ }
150
+ else {
151
+ // 设备已设置当前语种,获取对应的语种代码
152
+ const currentLanguage = (_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId);
153
+ if (currentLanguage) {
154
+ return currentLanguage;
155
+ }
156
+ else {
157
+ // 无法获取语种代码,使用默认语种
158
+ return defaultLanguage;
159
+ }
160
+ }
161
+ }
59
162
  getValidTimePeriods() {
60
163
  const timePeriods = new Array();
61
- timePeriods.push({ key: 1, name: this.localization.lastOneHour });
62
- timePeriods.push({ key: 2, name: this.localization.lastTwentyFourHours });
63
- timePeriods.push({ key: 3, name: this.localization.lastSevenDays });
64
- timePeriods.push({ key: 4, name: this.localization.lastThirtyDays });
65
- timePeriods.push({ key: 5, name: this.localization.lastOneYear });
164
+ timePeriods.push({ key: 6, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_MINUTES) });
165
+ timePeriods.push({ key: 1, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_HOUR) });
166
+ timePeriods.push({ key: 7, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_EIGHT_HOURS) });
167
+ timePeriods.push({ key: 2, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_TWENTY_FOUR_HOURS) });
168
+ timePeriods.push({ key: 3, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_SEVEN_DAYS) });
169
+ timePeriods.push({ key: 4, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_DAYS) });
170
+ timePeriods.push({ key: 5, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_YEAR) });
66
171
  return timePeriods;
67
172
  }
173
+ /**
174
+ * 获取时间段文案(从系统文本库获取多语种翻译)
175
+ */
176
+ getTimePeriodText(textKey) {
177
+ const currentCulture = this.getCurrentCulture();
178
+ const systemType = SYSTEM_TEXT_LIBRARY_TYPES.COMPONENT_BUILTIN;
179
+ if (this.systemTextLibraryService) {
180
+ const translation = this.systemTextLibraryService.getSystemTextValue(systemType, textKey, currentCulture);
181
+ if (translation) {
182
+ return translation;
183
+ }
184
+ }
185
+ return '';
186
+ }
68
187
  updateTimeRange(timePeriodType) {
69
188
  this.currentTimePeriod = +timePeriodType;
70
189
  this.updateQueryTimeRange();
@@ -84,13 +203,29 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
84
203
  case 5:
85
204
  this.startTime = moment().subtract(1, 'years');
86
205
  break;
206
+ case 6:
207
+ this.startTime = moment().subtract(30, 'minutes');
208
+ break;
209
+ case 7:
210
+ this.startTime = moment().subtract(8, 'hours');
211
+ break;
87
212
  default:
88
213
  this.startTime = moment().subtract(1, 'days');
89
214
  }
90
215
  }
91
216
  reRenderElement(startTime, endTime, limit, rangeType) {
217
+ // 清理图表实例
218
+ if (this.chartElement) {
219
+ // 隐藏 tooltip
220
+ if (this.chartElement.tooltip) {
221
+ this.chartElement.tooltip.hidden(true);
222
+ }
223
+ // 清理图表引用
224
+ this.chartElement = null;
225
+ }
226
+ // 清除 DOM 元素
92
227
  this.rootElement.selectAll('*').remove();
93
- this.chartElement = null;
228
+ // 重新渲染
94
229
  this.renderElement(startTime, endTime, limit, rangeType);
95
230
  }
96
231
  renderElement(startTime, endTime, limit, rangeType) {
@@ -122,6 +257,28 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
122
257
  }
123
258
  });
124
259
  }
260
+ setupTooltipAutoHide(chart) {
261
+ const chartContainer = this.rootElement.select('.nv-focus').node();
262
+ if (!chartContainer || !chart)
263
+ return;
264
+ let timeoutId;
265
+ // 鼠标移入图表时显示 tooltip
266
+ chartContainer.addEventListener('mouseover', () => {
267
+ hideTooltipAfterDelay();
268
+ });
269
+ const clearTooltipTimeout = () => {
270
+ if (timeoutId) {
271
+ clearTimeout(timeoutId);
272
+ timeoutId = null;
273
+ }
274
+ };
275
+ const hideTooltipAfterDelay = () => {
276
+ clearTooltipTimeout();
277
+ timeoutId = setTimeout(() => {
278
+ chart.tooltip.hidden(true);
279
+ }, 2000); // 2秒延迟
280
+ };
281
+ }
125
282
  renderChart(result) {
126
283
  const chartWidth = this.model.displaySetting.size.width;
127
284
  const chartHeight = this.model.displaySetting.size.height - this.displayOption.operationAreaHeight - this.displayOption.operationAreaMarginTop;
@@ -131,19 +288,69 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
131
288
  each(result, v => values.push({ x: moment(v.time).local().toDate().valueOf(), y: v.values[key] }));
132
289
  data.push({ key: channel.name, area: channel.projectEnabled, values: values });
133
290
  });
134
- nv.addGraph(() => {
135
- if (this.model.displaySetting.curveType === CurveType.BarGroup || this.model.displaySetting.curveType === CurveType.BarStack) {
136
- return this.getMultiBarWithFocusChart(chartWidth, chartHeight, data);
137
- }
138
- else {
139
- return this.getLineChart(chartWidth, chartHeight, data);
291
+ this.data = data;
292
+ let chart;
293
+ if (this.model.displaySetting.curveType === CurveType.BarGroup || this.model.displaySetting.curveType === CurveType.BarStack) {
294
+ chart = this.getMultiBarWithFocusChart(chartWidth, chartHeight, data);
295
+ }
296
+ else {
297
+ chart = this.getLineChart(chartWidth, chartHeight, data);
298
+ }
299
+ // 设置 tooltip 自动隐藏逻辑
300
+ this.setupTooltipAutoHide(chart);
301
+ return chart;
302
+ }
303
+ initPoint() {
304
+ try {
305
+ const legendList = this.$element
306
+ .find('.nv-legend')
307
+ .find('.nv-series');
308
+ let hiddenCount = 0;
309
+ for (let i = 0; i < this.data.length; i++) {
310
+ const channel = this.model.dataSetting.channels[i];
311
+ if (legendList.eq(i).children().eq(0).css('fill-opacity') === '1') {
312
+ const pointList = this.$element
313
+ .find('.nv-scatterWrap')
314
+ .find('.nv-series-' + (i - hiddenCount))
315
+ .find('.nv-point');
316
+ if (pointList && pointList.length) {
317
+ for (let j = 0; j < pointList.length; j++) {
318
+ const point = pointList.eq(j);
319
+ const previousPoint = pointList.eq(j - 1);
320
+ if (j && point.attr('transform').split(',')[1] !== previousPoint.attr('transform').split(',')[1]) {
321
+ if (channel.enablePoint && channel.pointColor) {
322
+ const pointStyle = {
323
+ 'stroke-opacity': 1,
324
+ 'stroke-width': '2px',
325
+ 'stroke': channel.pointColor,
326
+ 'fill-opacity': 1,
327
+ 'fill': channel.pointColor
328
+ };
329
+ point.addClass('nv-mark-point');
330
+ point.css(pointStyle);
331
+ previousPoint.addClass('nv-mark-point');
332
+ previousPoint.css(pointStyle);
333
+ }
334
+ }
335
+ }
336
+ }
337
+ }
338
+ else {
339
+ hiddenCount++;
340
+ }
140
341
  }
141
- });
342
+ }
343
+ catch (e) {
344
+ console.log(e);
345
+ }
142
346
  }
143
347
  getLineChart(chartWidth, chartHeight, data) {
144
348
  const chart = nv.models.lineChart().showLegend(true)
145
349
  .margin({ top: 0, bottom: 0, left: this.displayOption.marginLeft, right: this.displayOption.marginRight })
146
350
  .noData(this.localization.chartNoData);
351
+ if (this.model.displaySetting.axisSetting.yAxisRangeType === AxisRangeType.Custom) {
352
+ chart.yDomain([this.model.displaySetting.axisSetting.yAxisMin, this.model.displaySetting.axisSetting.yAxisMax]);
353
+ }
147
354
  if (!this.isMobileMode) {
148
355
  chart.focusEnable(true);
149
356
  chart.focus.margin({ top: 10, right: 0, bottom: 0, left: 0 });
@@ -152,6 +359,19 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
152
359
  }
153
360
  this.renderCommonProperty(chart, chartWidth, chartHeight, data);
154
361
  this.renderOperationArea(chartWidth, chartHeight);
362
+ this.initPoint();
363
+ chart.legend.dispatch.on('legendClick', () => {
364
+ setTimeout(() => {
365
+ this.$element.find('.nv-mark-point').css({
366
+ 'stroke-opacity': 0,
367
+ 'stroke-width': 0,
368
+ 'stroke': 'unset',
369
+ 'fill-opacity': 0,
370
+ 'fill': 'unset'
371
+ }).removeClass('nv-mark-point');
372
+ this.initPoint();
373
+ }, 1);
374
+ });
155
375
  return chart;
156
376
  }
157
377
  getMultiBarWithFocusChart(chartWidth, chartHeight, data) {
@@ -168,6 +388,9 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
168
388
  chart.multibar.stacked(true);
169
389
  chart.multibar2.stacked(true);
170
390
  }
391
+ if (this.model.displaySetting.axisSetting.yAxisRangeType === AxisRangeType.Custom) {
392
+ chart.yDomain([this.model.displaySetting.axisSetting.yAxisMin, this.model.displaySetting.axisSetting.yAxisMax]);
393
+ }
171
394
  if (!this.isMobileMode) {
172
395
  chart.focusEnable(true);
173
396
  chart.focusShowAxisX(false);
@@ -188,9 +411,27 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
188
411
  return chart;
189
412
  }
190
413
  renderCommonProperty(chart, chartWidth, chartHeight, data) {
414
+ var _a, _b;
191
415
  chart.tooltip.headerFormatter(d => this.timeFormat(d, '%x %X'));
192
416
  if (this.model.displaySetting.showAxis) {
193
- chart.xAxis.showMaxMin(true).tickFormat(d => this.timeFormat(d, '%X'));
417
+ chart.xAxis.showMaxMin(true).tickFormat(d => {
418
+ this.$element.find('.nv-mark-point').css({
419
+ 'stroke-opacity': 0,
420
+ 'stroke-width': 0,
421
+ 'stroke': 'unset',
422
+ 'fill-opacity': 0,
423
+ 'fill': 'unset'
424
+ }).removeClass('nv-mark-point');
425
+ clearTimeout(this.timer);
426
+ this.timer = undefined;
427
+ this.timer = setTimeout(() => {
428
+ this.initPoint();
429
+ }, 100);
430
+ if (this.currentTimePeriod === 3 || this.currentTimePeriod === 4 || this.currentTimePeriod === 5) {
431
+ return this.timeFormat(d, '%y-%m-%d');
432
+ }
433
+ return this.timeFormat(Number(d), '%X');
434
+ });
194
435
  if (this.model.displaySetting.axisSetting) {
195
436
  if (this.model.displaySetting.axisSetting.showAxisLabel && this.model.displaySetting.axisSetting.axisLabelFont) {
196
437
  chart.xAxis.fontSize(this.model.displaySetting.axisSetting.axisLabelFont.fontSize);
@@ -211,47 +452,148 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
211
452
  chart.color(this.model.dataSetting.channels.map(c => c.connectorColor));
212
453
  this.rootElement.append('g').datum(data).call(chart);
213
454
  this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
214
- nv.utils.windowResize(() => {
455
+ this.resizeEventListener = nv.utils.windowResize(() => {
456
+ if (!this.needResize)
457
+ return;
215
458
  chart.update();
216
459
  this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
217
460
  });
461
+ const fontSize = (_b = (_a = this.model.displaySetting.axisSetting) === null || _a === void 0 ? void 0 : _a.axisLabelFont) === null || _b === void 0 ? void 0 : _b.fontSize;
218
462
  this.rootElement.selectAll('.domain').style('stroke-opacity', 1);
219
463
  if (this.model.displaySetting.showAxis && this.model.displaySetting.axisSetting) {
220
464
  const axisColor = this.model.displaySetting.axisSetting.axisColor;
221
465
  this.rootElement.selectAll('.domain').style('stroke', axisColor);
222
- if (this.model.displaySetting.axisSetting.showAxisLabel) {
223
- const fontSize = this.model.displaySetting.axisSetting.axisLabelFont.fontSize;
466
+ if (fontSize && this.model.displaySetting.axisSetting.showAxisLabel) {
224
467
  this.rootElement.selectAll('.nv-axisMaxMin').select('text').style('font-size', fontSize);
225
468
  }
226
469
  }
470
+ let strokeWidth = 0;
471
+ if (this.model.displaySetting.axisSetting.showTick !== false) {
472
+ strokeWidth = 1;
473
+ }
474
+ this.rootElement
475
+ .selectAll('.nv-x')
476
+ .selectAll('.tick')
477
+ .selectAll('line')
478
+ .attr('style', `stroke:${this.model.displaySetting.axisSetting.xAxisTickColor || 'rgb(127, 147, 159)'};stroke-width:${strokeWidth};`);
479
+ this.rootElement
480
+ .selectAll('.nv-y')
481
+ .selectAll('.tick')
482
+ .selectAll('line')
483
+ .attr('style', `stroke:${this.model.displaySetting.axisSetting.yAxisTickColor || 'rgb(127, 147, 159)'};stroke-width:${strokeWidth};`);
484
+ if (fontSize && this.currentTimePeriod === 3 || this.currentTimePeriod === 4 || this.currentTimePeriod === 5) {
485
+ const self = this;
486
+ this.rootElement
487
+ .selectAll('.nv-x')
488
+ .selectAll('.tick')
489
+ .selectAll('text')
490
+ .data(function (d) {
491
+ return [self.timeFormat(Number(d), '%y-%m-%d'), self.timeFormat(Number(d), '%H:%M:%S')];
492
+ })
493
+ .enter()
494
+ .append('text')
495
+ .attr('class', 'full-date')
496
+ .attr('x', 0)
497
+ .attr('y', 0)
498
+ .attr('dy', '2.3em')
499
+ .style('text-anchor', 'middle')
500
+ .style('font-size', fontSize)
501
+ .text((d) => d);
502
+ this.rootElement
503
+ .selectAll('.nv-axisMaxMin-x')
504
+ .selectAll('text')
505
+ .data(function (d) {
506
+ return [self.timeFormat(Number(d), '%y-%m-%d'), self.timeFormat(Number(d), '%H:%M:%S')];
507
+ })
508
+ .enter()
509
+ .append('text')
510
+ .attr('class', 'full-date')
511
+ .attr('x', 0)
512
+ .attr('y', 0)
513
+ .attr('dy', '2.3em')
514
+ .style('text-anchor', 'middle')
515
+ .style('font-size', fontSize)
516
+ .text((d) => d);
517
+ const focusWrap = this.rootElement.selectAll('.nv-focusWrap');
518
+ if (focusWrap.size()) {
519
+ let h = focusWrap.attr('transform');
520
+ if (h && h.length && h.indexOf(',') !== -1) {
521
+ h = h.slice(0, -1).split(',')[1];
522
+ this.rootElement
523
+ .selectAll('.nv-focusWrap')
524
+ .attr('transform', `translate(0,${Number(h) + 15})`);
525
+ }
526
+ }
527
+ const resizeObserver = new window.MutationObserver(() => {
528
+ this.rootElement
529
+ .selectAll('.nv-x')
530
+ .selectAll('.tick')
531
+ .selectAll('.full-date')
532
+ .remove();
533
+ this.rootElement
534
+ .selectAll('.nv-x')
535
+ .selectAll('.tick')
536
+ .selectAll('text')
537
+ .data(function (d) {
538
+ return [self.timeFormat(Number(d), '%y-%m-%d'), self.timeFormat(Number(d), '%H:%M:%S')];
539
+ })
540
+ .enter()
541
+ .append('text')
542
+ .attr('class', 'full-date')
543
+ .attr('x', 0)
544
+ .attr('y', 0)
545
+ .attr('dy', '2.3em')
546
+ .style('text-anchor', 'middle')
547
+ .style('font-size', fontSize)
548
+ .text((d) => d);
549
+ });
550
+ const extent = document.getElementsByClassName('extent');
551
+ if (extent.length) {
552
+ resizeObserver.observe(extent[0], { attributes: true });
553
+ }
554
+ }
555
+ else {
556
+ this.rootElement
557
+ .selectAll('.full-date')
558
+ .remove();
559
+ }
227
560
  }
228
561
  renderOperationArea(chartWidth, chartHeight) {
562
+ const backgroundColor = this.model.displaySetting.axisSetting.filterBackgroudColor || 'inherit';
229
563
  const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop})`)
230
564
  .append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight).attr('fill', 'none')
231
565
  .append('xhtml:div').style('height', (this.displayOption.operationAreaHeight - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
232
566
  const selectElement = operationArea.append('select').style('margin-left', this.displayOption.marginLeft + 'px')
567
+ .style('background-color', backgroundColor)
233
568
  .style('font-size', this.displayOption.operationSelectFontSize).on('change', () => {
234
569
  const displayTimePeriod = this.rootElement.select('select').property('value');
235
570
  this.updateTimeRange(displayTimePeriod);
236
571
  this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
237
572
  });
573
+ const rect = this.$element.parent().parent().find('rect');
574
+ const fillColor = rect.attr('fill');
238
575
  const options = selectElement.selectAll('option').data(this.timePeriods).enter().append('option');
239
- options.text(d => d.name).attr('value', d => d.key).property('selected', d => d.key === Number(this.currentTimePeriod));
576
+ options.text(d => d.name).attr('value', d => d.key).property('selected', d => d.key === Number(this.currentTimePeriod))
577
+ .style('background-color', this.model.displaySetting.axisSetting.filterBackgroudColor || fillColor);
240
578
  const buttonWidth = this.displayOption.operationButtonWidth + 'px', buttonHeight = this.displayOption.operationButtonHeight + 'px';
241
579
  operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
242
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/last_page.svg)')
580
+ .style('float', 'right').style('background-image', 'url(assets/img/black_last_page.png)')
581
+ .style('background-color', backgroundColor).style('background-size', 'cover')
243
582
  .on('click', () => { this.loadLastPage(); });
244
583
  operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
245
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/next_page.svg)')
584
+ .style('float', 'right').style('background-image', 'url(assets/img/black_next_page.png)')
246
585
  .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
586
+ .style('background-color', backgroundColor).style('background-size', 'cover')
247
587
  .on('click', () => { this.loadNextPage(); });
248
588
  operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
249
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/previous_page.svg)')
589
+ .style('float', 'right').style('background-image', 'url(assets/img/black_previous_page.png)')
250
590
  .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
591
+ .style('background-color', backgroundColor).style('background-size', 'cover')
251
592
  .on('click', () => { this.loadPreviousPage(); });
252
593
  operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
253
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/first_page.svg)')
594
+ .style('float', 'right').style('background-image', 'url(assets/img/black_first_page.png)')
254
595
  .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
596
+ .style('background-color', backgroundColor).style('background-size', 'cover')
255
597
  .on('click', () => { this.loadFirstPage(); });
256
598
  }
257
599
  timeFormat(datetime, specifier) {
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"HistoricalCurveElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":20,"character":44},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":62,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":63,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":64,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":65,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":66,"character":23},{"__symbolic":"reference","module":"../../config","name":"HistoryDataStore","line":67,"character":43},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"getValidTimePeriods":[{"__symbolic":"method"}],"updateTimeRange":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"reRenderElement":[{"__symbolic":"method"}],"renderElement":[{"__symbolic":"method"}],"renderChart":[{"__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"}]}}}}]
@@ -37,6 +37,7 @@ export declare class MainElement {
37
37
  initElementState(): void;
38
38
  getVariableNames(): Array<string>;
39
39
  reportVariableStates(states: VariableState[]): void;
40
+ getVirtualDeviceIdFromRect(rectElement: any): any;
40
41
  reportVariableValues(values: VariableValue[]): void;
41
42
  dispose(): void;
42
43
  private checkIsLoaded;