@flexem/fc-gui 3.0.0-alpha.180 → 3.0.0-alpha.182
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.
- package/bundles/@flexem/fc-gui.umd.js +727 -293
- package/bundles/@flexem/fc-gui.umd.js.map +1 -1
- package/bundles/@flexem/fc-gui.umd.min.js +4 -4
- package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
- package/config/variable/variable-store.d.ts +4 -0
- package/elements/alarm/alarm-element.d.ts +20 -0
- package/elements/alarm/alarm-element.js +312 -70
- package/elements/alarm/alarm-element.metadata.json +1 -1
- package/elements/base/state-control-element.d.ts +10 -0
- package/elements/base/state-control-element.js +21 -3
- package/elements/base/state-control-element.metadata.json +1 -1
- package/elements/character-display/character-display-element.d.ts +12 -2
- package/elements/character-display/character-display-element.js +30 -3
- package/elements/character-display/character-display-element.metadata.json +1 -1
- package/elements/historical-curve/historical-curve.element.d.ts +1 -0
- package/elements/historical-curve/historical-curve.element.js +35 -22
- package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
- package/elements/main-element.js +3 -2
- package/elements/numerical-display/numerical-display-element.d.ts +9 -0
- package/elements/numerical-display/numerical-display-element.js +19 -1
- package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
- package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +9 -0
- package/elements/switch-indicator-light/switch-indicator-light-element.js +20 -1
- package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
- package/elements/view-operation/view-operation.element.js +7 -2
- package/gui/gui-view.d.ts +15 -1
- package/gui/gui-view.js +78 -4
- package/gui/gui-view.metadata.json +1 -1
- package/modal/verify-password/verify-password-modal.component.d.ts +6 -2
- package/modal/verify-password/verify-password-modal.component.html +2 -2
- package/modal/verify-password/verify-password-modal.component.js +11 -5
- package/modal/verify-password/verify-password-modal.component.less +9 -0
- package/modal/verify-password/verify-password-modal.component.metadata.json +1 -1
- package/modal/write-character/write-character-modal-args.d.ts +3 -1
- package/modal/write-character/write-character-modal-args.js +2 -1
- package/modal/write-character/write-character-modal-args.metadata.json +1 -1
- package/modal/write-character/write-character-modal.component.d.ts +1 -0
- package/modal/write-character/write-character-modal.component.js +5 -1
- package/modal/write-character/write-character-modal.component.metadata.json +1 -1
- package/modal/write-value/write-value-modal.component.d.ts +1 -0
- package/modal/write-value/write-value-modal.component.js +5 -1
- package/modal/write-value/write-value-modal.component.metadata.json +1 -1
- package/model/alarm/alarm.model.d.ts +1 -0
- package/model/character-display/character-display.d.ts +1 -0
- package/model/historical-curve/historical-curve.display-settings.d.ts +1 -0
- package/model/numerical-display/numerical-display.d.ts +1 -0
- package/model/settings/popup/view-popup-location-type.d.ts +2 -1
- package/model/settings/popup/view-popup-location-type.js +1 -0
- package/model/settings/popup/view-popup-location-type.metadata.json +1 -1
- package/model/switch-indicator-light/switch-indicator-light.d.ts +1 -0
- package/package.json +1 -1
- package/view/popup-view.service.d.ts +1 -1
|
@@ -29,6 +29,12 @@ export declare class AlarmElement extends ConditionalDisplayElement {
|
|
|
29
29
|
private totalCount;
|
|
30
30
|
private pageSize;
|
|
31
31
|
private getAlarmDataId;
|
|
32
|
+
private readonly maxVisibleRows;
|
|
33
|
+
private scrollIntervalId;
|
|
34
|
+
private scrollContainer;
|
|
35
|
+
private hoverTarget;
|
|
36
|
+
private rowHeight;
|
|
37
|
+
private isDisposed;
|
|
32
38
|
constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, alarmsStore: AlarmsStore, signalRAppId: string, systemTextLibraryService?: SystemTextLibraryService, languageService?: LanguageService, guiContext?: GuiContext);
|
|
33
39
|
dispose(): void;
|
|
34
40
|
/**
|
|
@@ -54,7 +60,21 @@ export declare class AlarmElement extends ConditionalDisplayElement {
|
|
|
54
60
|
*/
|
|
55
61
|
private getTimePeriodText;
|
|
56
62
|
private getAlarmData;
|
|
63
|
+
private refreshCurrentPageData;
|
|
64
|
+
private updateTableContent;
|
|
65
|
+
private getIconScale;
|
|
57
66
|
private renderElement;
|
|
67
|
+
private buildHeaderRow;
|
|
68
|
+
private buildDataRow;
|
|
69
|
+
private renderPlainTable;
|
|
70
|
+
private renderScrollableTable;
|
|
71
|
+
private bindScrollHoverEvents;
|
|
72
|
+
private unbindScrollHoverEvents;
|
|
73
|
+
private readonly handleScrollMouseEnter;
|
|
74
|
+
private readonly handleScrollMouseLeave;
|
|
75
|
+
private startAutoScroll;
|
|
76
|
+
private scrollOneRow;
|
|
77
|
+
private autoNextPage;
|
|
58
78
|
private renderOperationArea;
|
|
59
79
|
private updateTimeRange;
|
|
60
80
|
private updateQueryTimeRange;
|
|
@@ -37,6 +37,15 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
37
37
|
this.page = 0;
|
|
38
38
|
this.totalCount = 0;
|
|
39
39
|
this.pageSize = 5;
|
|
40
|
+
this.maxVisibleRows = 15;
|
|
41
|
+
this.rowHeight = 0;
|
|
42
|
+
this.isDisposed = false;
|
|
43
|
+
this.handleScrollMouseEnter = () => {
|
|
44
|
+
clearInterval(this.scrollIntervalId);
|
|
45
|
+
};
|
|
46
|
+
this.handleScrollMouseLeave = () => {
|
|
47
|
+
this.startAutoScroll();
|
|
48
|
+
};
|
|
40
49
|
this.rootElement.selectAll('*').remove();
|
|
41
50
|
this.setStatusAsLoading();
|
|
42
51
|
this.logger = injector.get(LOGGER_SERVICE_TOKEN);
|
|
@@ -51,7 +60,14 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
51
60
|
this.updateQueryTimeRange();
|
|
52
61
|
if (this.model.filterSetting.alarmType) {
|
|
53
62
|
this.refreshIntervalId = setInterval(() => {
|
|
54
|
-
this.
|
|
63
|
+
if (this.model.generalSetting.autoScroll) {
|
|
64
|
+
// 开启滚动时,仅更新数据不重渲染,保持滚动进度
|
|
65
|
+
this.refreshCurrentPageData();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// 未开启滚动时,返回第一页
|
|
69
|
+
this.loadFirstPage();
|
|
70
|
+
}
|
|
55
71
|
this.logger.debug(`[GUI]Refresh Alarm Table:${d3.time.format('%x %X')(new Date())}`);
|
|
56
72
|
}, this.model.filterSetting.refreshCycle * 60 * 1000);
|
|
57
73
|
}
|
|
@@ -59,7 +75,14 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
59
75
|
variableCommunicator.subscribeUserDeviceAlarms(signalRAppId).subscribe(alarms => {
|
|
60
76
|
alarms.forEach(alarm => {
|
|
61
77
|
if (this.alarmNames.indexOf(alarm.name) !== -1) {
|
|
62
|
-
this.
|
|
78
|
+
if (this.model.generalSetting.autoScroll) {
|
|
79
|
+
// 开启滚动时,刷新当前页并保持滚动进度
|
|
80
|
+
this.refreshCurrentPageData();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// 未开启滚动时,刷新当前页(原有逻辑)
|
|
84
|
+
this.getAlarmData();
|
|
85
|
+
}
|
|
63
86
|
return;
|
|
64
87
|
}
|
|
65
88
|
});
|
|
@@ -74,10 +97,11 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
74
97
|
}
|
|
75
98
|
}
|
|
76
99
|
dispose() {
|
|
100
|
+
this.isDisposed = true;
|
|
77
101
|
clearInterval(this.refreshIntervalId);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
102
|
+
clearInterval(this.scrollIntervalId);
|
|
103
|
+
clearTimeout(this.getAlarmDataId);
|
|
104
|
+
this.unbindScrollHoverEvents();
|
|
81
105
|
// 取消语种变化订阅
|
|
82
106
|
if (this.languageChangeSubscription) {
|
|
83
107
|
this.languageChangeSubscription.unsubscribe();
|
|
@@ -199,15 +223,21 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
199
223
|
return '';
|
|
200
224
|
}
|
|
201
225
|
getAlarmData() {
|
|
226
|
+
clearInterval(this.scrollIntervalId);
|
|
227
|
+
this.unbindScrollHoverEvents();
|
|
202
228
|
this.rootElement.selectAll('*').remove();
|
|
203
229
|
this.setStatusAsLoading();
|
|
204
230
|
clearTimeout(this.getAlarmDataId);
|
|
205
231
|
this.getAlarmDataId = setTimeout(() => {
|
|
232
|
+
if (this.isDisposed)
|
|
233
|
+
return;
|
|
206
234
|
this.timePeriods = this.getValidTimePeriods();
|
|
207
235
|
if (this.model.filterSetting.alarmType) {
|
|
208
236
|
this.updateQueryTimeRange();
|
|
209
237
|
const input = new GetAlarmsArgs(this.alarmNames, this.startTime, this.endTime, this.pageSize, this.page * this.pageSize);
|
|
210
238
|
this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
|
|
239
|
+
if (this.isDisposed)
|
|
240
|
+
return;
|
|
211
241
|
if (!result.error) {
|
|
212
242
|
this.totalCount = result.totalCount;
|
|
213
243
|
this.alarmList = result.items.map(item => [
|
|
@@ -223,6 +253,8 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
223
253
|
else {
|
|
224
254
|
const input = new GetAlarmsArgs(this.alarmNames, undefined, undefined, this.pageSize, this.page * this.pageSize);
|
|
225
255
|
this.alarmsStore.getCurrentAlarms(input).subscribe(result => {
|
|
256
|
+
if (this.isDisposed)
|
|
257
|
+
return;
|
|
226
258
|
if (!result.error) {
|
|
227
259
|
this.totalCount = result.totalCount;
|
|
228
260
|
this.currentAlarmList = result.items;
|
|
@@ -243,16 +275,124 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
243
275
|
}
|
|
244
276
|
}, 500);
|
|
245
277
|
}
|
|
278
|
+
refreshCurrentPageData() {
|
|
279
|
+
var _a;
|
|
280
|
+
if (this.isDisposed)
|
|
281
|
+
return;
|
|
282
|
+
const currentScrollTop = ((_a = this.scrollContainer) === null || _a === void 0 ? void 0 : _a.scrollTop) || 0;
|
|
283
|
+
if (this.model.filterSetting.alarmType) {
|
|
284
|
+
this.updateQueryTimeRange();
|
|
285
|
+
const input = new GetAlarmsArgs(this.alarmNames, this.startTime, this.endTime, this.pageSize, this.page * this.pageSize);
|
|
286
|
+
this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
|
|
287
|
+
if (this.isDisposed)
|
|
288
|
+
return;
|
|
289
|
+
if (!result.error) {
|
|
290
|
+
this.totalCount = result.totalCount;
|
|
291
|
+
this.alarmList = result.items.map(item => [
|
|
292
|
+
item.name,
|
|
293
|
+
item.message,
|
|
294
|
+
item.alarmLevel,
|
|
295
|
+
item.triggeredTime.format('YYYY-MM-DD HH:mm:ss')
|
|
296
|
+
]);
|
|
297
|
+
this.updateTableContent();
|
|
298
|
+
if (this.scrollContainer) {
|
|
299
|
+
this.scrollContainer.scrollTop = currentScrollTop;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
const input = new GetAlarmsArgs(this.alarmNames, undefined, undefined, this.pageSize, this.page * this.pageSize);
|
|
306
|
+
this.alarmsStore.getCurrentAlarms(input).subscribe(result => {
|
|
307
|
+
if (this.isDisposed)
|
|
308
|
+
return;
|
|
309
|
+
if (!result.error) {
|
|
310
|
+
this.totalCount = result.totalCount;
|
|
311
|
+
this.currentAlarmList = result.items;
|
|
312
|
+
if (!result.items.length && result.totalCount) {
|
|
313
|
+
this.page = 0;
|
|
314
|
+
this.refreshCurrentPageData();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
this.alarmList = this.currentAlarmList.map(item => [
|
|
318
|
+
item.name,
|
|
319
|
+
item.message,
|
|
320
|
+
item.alarmLevel,
|
|
321
|
+
item.triggeredTime.format('YYYY-MM-DD HH:mm:ss')
|
|
322
|
+
]);
|
|
323
|
+
this.updateTableContent();
|
|
324
|
+
if (this.scrollContainer) {
|
|
325
|
+
this.scrollContainer.scrollTop = currentScrollTop;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
updateTableContent() {
|
|
332
|
+
if (!this.element)
|
|
333
|
+
return;
|
|
334
|
+
const useScroll = this.pageSize > this.maxVisibleRows;
|
|
335
|
+
const dataRowHeight = this.model.heights[1] || this.model.heights[0];
|
|
336
|
+
// 查找表格主体
|
|
337
|
+
let tbody;
|
|
338
|
+
if (useScroll) {
|
|
339
|
+
const bodyContainer = this.element.querySelector('div > div:nth-child(2)');
|
|
340
|
+
if (!bodyContainer)
|
|
341
|
+
return;
|
|
342
|
+
const bodyTable = bodyContainer.querySelector('table');
|
|
343
|
+
if (!bodyTable)
|
|
344
|
+
return;
|
|
345
|
+
tbody = bodyTable;
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
const table = this.element.querySelector('table');
|
|
349
|
+
if (!table)
|
|
350
|
+
return;
|
|
351
|
+
tbody = table;
|
|
352
|
+
}
|
|
353
|
+
// 清除现有数据行(保留表头)
|
|
354
|
+
const rows = Array.from(tbody.querySelectorAll('tr'));
|
|
355
|
+
rows.forEach((row, index) => {
|
|
356
|
+
if (index > 0 || useScroll) { // 对于 scrollable 模式,表头在另一个 table,所以这里全部清除
|
|
357
|
+
row.remove();
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
// 重新生成数据行
|
|
361
|
+
for (let row = 0; row < this.pageSize; row++) {
|
|
362
|
+
const rowHeight = useScroll ? dataRowHeight : this.model.heights[row + 1];
|
|
363
|
+
tbody.appendChild(this.buildDataRow(row, rowHeight));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
getIconScale() {
|
|
367
|
+
const initSize = this.model.initSize;
|
|
368
|
+
if (!initSize || !initSize.width || !initSize.height) {
|
|
369
|
+
return 1;
|
|
370
|
+
}
|
|
371
|
+
const scaleX = this.model.size.width / initSize.width;
|
|
372
|
+
const scaleY = this.model.size.height / initSize.height;
|
|
373
|
+
return Math.min(scaleX, scaleY);
|
|
374
|
+
}
|
|
246
375
|
renderElement() {
|
|
247
376
|
const elementHeight = this.model.size.height;
|
|
248
377
|
this.element = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
|
|
249
378
|
this.element.setAttribute('width', this.model.size.width.toString());
|
|
250
379
|
this.element.setAttribute('height', elementHeight.toString());
|
|
251
380
|
this.$element.append(this.element);
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
381
|
+
const scale = this.getIconScale();
|
|
382
|
+
// 表格与底部操作区之间的预留高度,需要与操作区渲染时使用的同一个 scale 保持一致,
|
|
383
|
+
// 否则表格按未缩放高度占满后,缩放后的操作区会超出元件整体高度
|
|
384
|
+
const operationAreaReservedHeight = 39 * scale;
|
|
385
|
+
const useScroll = this.pageSize > this.maxVisibleRows;
|
|
386
|
+
if (useScroll) {
|
|
387
|
+
this.renderScrollableTable(elementHeight, operationAreaReservedHeight);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
this.renderPlainTable(elementHeight, operationAreaReservedHeight);
|
|
391
|
+
}
|
|
392
|
+
this.renderOperationArea(this.model.size.width, elementHeight - operationAreaReservedHeight, scale);
|
|
393
|
+
}
|
|
394
|
+
buildHeaderRow() {
|
|
395
|
+
const tr = document.createElement('tr');
|
|
256
396
|
let fontString = '';
|
|
257
397
|
if (this.model.generalSetting.headerFont.isItalic) {
|
|
258
398
|
fontString += 'italic ';
|
|
@@ -277,56 +417,34 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
277
417
|
border-left-width: ${!col || this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;`;
|
|
278
418
|
tr.appendChild(th);
|
|
279
419
|
}
|
|
280
|
-
|
|
420
|
+
return tr;
|
|
421
|
+
}
|
|
422
|
+
buildDataRow(row, rowHeight) {
|
|
281
423
|
const levelColors = ['#3695FF', '#FFE900', '#FFA800', '#E84F4F'];
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
const alarmLevel = document.createElement('div');
|
|
303
|
-
let alarmHeight = parseInt(this.model.generalSetting.fontSize) + 15;
|
|
304
|
-
if (alarmHeight > this.model.heights[row + 1])
|
|
305
|
-
alarmHeight = this.model.heights[row + 1];
|
|
306
|
-
let margin = '0 15px';
|
|
307
|
-
if (this.model.generalSetting.textAlign === 'left') {
|
|
308
|
-
margin = '0 30px 0 0';
|
|
309
|
-
}
|
|
310
|
-
else if (this.model.generalSetting.textAlign === 'right') {
|
|
311
|
-
margin = '0 0 0 30px';
|
|
312
|
-
}
|
|
313
|
-
alarmLevel.style.cssText = `margin: ${margin};
|
|
314
|
-
border-radius: 5px;
|
|
315
|
-
background: ${levelColors[this.alarmList[row][col]]};
|
|
316
|
-
color: #ffffff;
|
|
317
|
-
width: ${this.model.widths[col] - 30}px;
|
|
318
|
-
height: ${alarmHeight}px;
|
|
319
|
-
max-height: ${this.model.heights[row + 1]}px;
|
|
320
|
-
display: flex;
|
|
321
|
-
justify-content: center;
|
|
322
|
-
align-items: center;
|
|
323
|
-
${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
|
|
324
|
-
alarmLevel.innerHTML = this.model.levelText[this.alarmList[row][col]];
|
|
325
|
-
td.appendChild(alarmLevel);
|
|
326
|
-
}
|
|
424
|
+
const tr = document.createElement('tr');
|
|
425
|
+
tr.style.cssText = `height: ${rowHeight}px;
|
|
426
|
+
background: ${this.model.generalSetting.tableFillColor};
|
|
427
|
+
font: ${this.model.generalSetting.fontStyle};
|
|
428
|
+
color: ${this.model.generalSetting.fontColor};
|
|
429
|
+
text-align: ${this.model.generalSetting.textAlign};
|
|
430
|
+
vertical-align: middle;`;
|
|
431
|
+
for (let col = 0; col < 4; col++) {
|
|
432
|
+
const td = document.createElement('td');
|
|
433
|
+
td.style.cssText = `width: ${this.model.widths[col] / this.model.size.width * 100}%;
|
|
434
|
+
border-style: solid;
|
|
435
|
+
border-color: ${this.model.generalSetting.splitLine};
|
|
436
|
+
border-top-width: ${this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;
|
|
437
|
+
border-left-width: ${!col || this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;`;
|
|
438
|
+
if (this.alarmList[row]) {
|
|
439
|
+
if (col !== 2) {
|
|
440
|
+
td.innerHTML = this.alarmList[row][col];
|
|
441
|
+
td.style.cssText += `${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
|
|
327
442
|
}
|
|
328
|
-
else
|
|
443
|
+
else {
|
|
329
444
|
const alarmLevel = document.createElement('div');
|
|
445
|
+
let alarmHeight = parseInt(this.model.generalSetting.fontSize) + 15;
|
|
446
|
+
if (alarmHeight > rowHeight)
|
|
447
|
+
alarmHeight = rowHeight;
|
|
330
448
|
let margin = '0 15px';
|
|
331
449
|
if (this.model.generalSetting.textAlign === 'left') {
|
|
332
450
|
margin = '0 30px 0 0';
|
|
@@ -335,24 +453,144 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
335
453
|
margin = '0 0 0 30px';
|
|
336
454
|
}
|
|
337
455
|
alarmLevel.style.cssText = `margin: ${margin};
|
|
338
|
-
|
|
456
|
+
border-radius: 5px;
|
|
457
|
+
background: ${levelColors[this.alarmList[row][col]]};
|
|
458
|
+
color: #ffffff;
|
|
459
|
+
width: ${this.model.widths[col] - 30}px;
|
|
460
|
+
height: ${alarmHeight}px;
|
|
461
|
+
max-height: ${rowHeight}px;
|
|
462
|
+
display: flex;
|
|
463
|
+
justify-content: center;
|
|
464
|
+
align-items: center;
|
|
465
|
+
${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
|
|
466
|
+
alarmLevel.innerHTML = this.model.levelText[this.alarmList[row][col]];
|
|
339
467
|
td.appendChild(alarmLevel);
|
|
340
468
|
}
|
|
341
|
-
tr.appendChild(td);
|
|
342
469
|
}
|
|
343
|
-
|
|
470
|
+
else if (col === 2) {
|
|
471
|
+
const alarmLevel = document.createElement('div');
|
|
472
|
+
let margin = '0 15px';
|
|
473
|
+
if (this.model.generalSetting.textAlign === 'left') {
|
|
474
|
+
margin = '0 30px 0 0';
|
|
475
|
+
}
|
|
476
|
+
else if (this.model.generalSetting.textAlign === 'right') {
|
|
477
|
+
margin = '0 0 0 30px';
|
|
478
|
+
}
|
|
479
|
+
alarmLevel.style.cssText = `margin: ${margin};
|
|
480
|
+
width: ${this.model.widths[col] - 30}px;`;
|
|
481
|
+
td.appendChild(alarmLevel);
|
|
482
|
+
}
|
|
483
|
+
tr.appendChild(td);
|
|
484
|
+
}
|
|
485
|
+
return tr;
|
|
486
|
+
}
|
|
487
|
+
renderPlainTable(elementHeight, operationAreaReservedHeight) {
|
|
488
|
+
this.scrollContainer = null;
|
|
489
|
+
const table = document.createElement('table');
|
|
490
|
+
table.style.cssText = `border: 2px solid ${this.model.generalSetting.stroke};
|
|
491
|
+
height: ${elementHeight - operationAreaReservedHeight}px;`;
|
|
492
|
+
table.appendChild(this.buildHeaderRow());
|
|
493
|
+
for (let row = 0; row < this.pageSize; row++) {
|
|
494
|
+
table.appendChild(this.buildDataRow(row, this.model.heights[row + 1]));
|
|
344
495
|
}
|
|
345
496
|
this.element.appendChild(table);
|
|
346
|
-
this.
|
|
497
|
+
this.hoverTarget = table;
|
|
498
|
+
this.bindScrollHoverEvents();
|
|
499
|
+
this.startAutoScroll();
|
|
500
|
+
}
|
|
501
|
+
renderScrollableTable(elementHeight, operationAreaReservedHeight) {
|
|
502
|
+
const dataRowHeight = this.model.heights[1] || this.model.heights[0];
|
|
503
|
+
this.rowHeight = dataRowHeight;
|
|
504
|
+
const wrapper = document.createElement('div');
|
|
505
|
+
wrapper.style.cssText = `display: flex;
|
|
506
|
+
flex-direction: column;
|
|
507
|
+
box-sizing: border-box;
|
|
508
|
+
border: 2px solid ${this.model.generalSetting.stroke};
|
|
509
|
+
height: ${elementHeight - operationAreaReservedHeight}px;
|
|
510
|
+
overflow: hidden;`;
|
|
511
|
+
const headerWrapper = document.createElement('div');
|
|
512
|
+
headerWrapper.style.cssText = 'flex: none; box-sizing: border-box; overflow: hidden;';
|
|
513
|
+
const headerTable = document.createElement('table');
|
|
514
|
+
headerTable.style.cssText = 'width: 100%; table-layout: fixed;';
|
|
515
|
+
headerTable.appendChild(this.buildHeaderRow());
|
|
516
|
+
headerWrapper.appendChild(headerTable);
|
|
517
|
+
const bodyContainer = document.createElement('div');
|
|
518
|
+
bodyContainer.style.cssText = `flex: none;
|
|
519
|
+
overflow-y: auto;
|
|
520
|
+
overflow-x: hidden;
|
|
521
|
+
height: ${dataRowHeight * this.maxVisibleRows}px;`;
|
|
522
|
+
const bodyTable = document.createElement('table');
|
|
523
|
+
bodyTable.style.cssText = 'width: 100%; table-layout: fixed;';
|
|
524
|
+
for (let row = 0; row < this.pageSize; row++) {
|
|
525
|
+
bodyTable.appendChild(this.buildDataRow(row, dataRowHeight));
|
|
526
|
+
}
|
|
527
|
+
bodyContainer.appendChild(bodyTable);
|
|
528
|
+
wrapper.appendChild(headerWrapper);
|
|
529
|
+
wrapper.appendChild(bodyContainer);
|
|
530
|
+
this.element.appendChild(wrapper);
|
|
531
|
+
this.scrollContainer = bodyContainer;
|
|
532
|
+
requestAnimationFrame(() => {
|
|
533
|
+
const scrollbarWidth = bodyContainer.offsetWidth - bodyContainer.clientWidth;
|
|
534
|
+
if (scrollbarWidth > 0) {
|
|
535
|
+
headerWrapper.style.paddingRight = scrollbarWidth + 'px';
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
this.hoverTarget = bodyContainer;
|
|
539
|
+
this.bindScrollHoverEvents();
|
|
540
|
+
this.startAutoScroll();
|
|
541
|
+
}
|
|
542
|
+
bindScrollHoverEvents() {
|
|
543
|
+
if (!this.hoverTarget)
|
|
544
|
+
return;
|
|
545
|
+
this.hoverTarget.addEventListener('mouseenter', this.handleScrollMouseEnter);
|
|
546
|
+
this.hoverTarget.addEventListener('mouseleave', this.handleScrollMouseLeave);
|
|
547
|
+
}
|
|
548
|
+
unbindScrollHoverEvents() {
|
|
549
|
+
if (!this.hoverTarget)
|
|
550
|
+
return;
|
|
551
|
+
this.hoverTarget.removeEventListener('mouseenter', this.handleScrollMouseEnter);
|
|
552
|
+
this.hoverTarget.removeEventListener('mouseleave', this.handleScrollMouseLeave);
|
|
553
|
+
this.hoverTarget = null;
|
|
554
|
+
}
|
|
555
|
+
startAutoScroll() {
|
|
556
|
+
clearInterval(this.scrollIntervalId);
|
|
557
|
+
if (!this.model.generalSetting.autoScroll)
|
|
558
|
+
return;
|
|
559
|
+
const totalPages = Math.max(1, Math.ceil(this.totalCount / this.pageSize));
|
|
560
|
+
if (totalPages <= 1 && !this.scrollContainer)
|
|
561
|
+
return;
|
|
562
|
+
const duration = (this.model.generalSetting.scrollDuration || 10) * 1000;
|
|
563
|
+
this.scrollIntervalId = setInterval(() => this.scrollOneRow(), duration);
|
|
564
|
+
}
|
|
565
|
+
scrollOneRow() {
|
|
566
|
+
const el = this.scrollContainer;
|
|
567
|
+
if (!el) {
|
|
568
|
+
this.autoNextPage();
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
const maxScrollTop = el.scrollHeight - el.clientHeight;
|
|
572
|
+
if (maxScrollTop <= 1 || el.scrollTop >= maxScrollTop - 1) {
|
|
573
|
+
this.autoNextPage();
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
el.scrollTop = Math.min(el.scrollTop + this.rowHeight, maxScrollTop);
|
|
577
|
+
}
|
|
578
|
+
autoNextPage() {
|
|
579
|
+
const totalPages = Math.max(1, Math.ceil(this.totalCount / this.pageSize));
|
|
580
|
+
if (totalPages <= 1)
|
|
581
|
+
return;
|
|
582
|
+
const lastPage = totalPages - 1;
|
|
583
|
+
this.page = this.page < lastPage ? this.page + 1 : 0;
|
|
584
|
+
this.getAlarmData();
|
|
347
585
|
}
|
|
348
|
-
renderOperationArea(chartWidth, chartHeight) {
|
|
586
|
+
renderOperationArea(chartWidth, chartHeight, scale = 1) {
|
|
349
587
|
var _a;
|
|
350
|
-
const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop})`)
|
|
351
|
-
.append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight).attr('fill', 'none')
|
|
352
|
-
.append('xhtml:div').style('height', (this.displayOption.operationAreaHeight - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
|
|
588
|
+
const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop * scale})`)
|
|
589
|
+
.append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight * scale).attr('fill', 'none')
|
|
590
|
+
.append('xhtml:div').style('height', (this.displayOption.operationAreaHeight * scale - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
|
|
353
591
|
if ((_a = this.model.filterSetting) === null || _a === void 0 ? void 0 : _a.alarmType) {
|
|
354
|
-
const selectElement = operationArea.append('select').style('margin-left', this.displayOption.marginLeft + 'px')
|
|
355
|
-
.style('font-size', this.displayOption.operationSelectFontSize).on('change', () => {
|
|
592
|
+
const selectElement = operationArea.append('select').style('margin-left', (this.displayOption.marginLeft * scale) + 'px')
|
|
593
|
+
.style('font-size', (parseFloat(this.displayOption.operationSelectFontSize) * scale) + 'px').on('change', () => {
|
|
356
594
|
const displayTimePeriod = this.rootElement.select('select').property('value');
|
|
357
595
|
this.updateTimeRange(displayTimePeriod);
|
|
358
596
|
this.getAlarmData();
|
|
@@ -360,24 +598,28 @@ export class AlarmElement extends ConditionalDisplayElement {
|
|
|
360
598
|
const options = selectElement.selectAll('option').data(this.timePeriods).enter().append('option');
|
|
361
599
|
options.text(d => d.name).attr('value', d => d.key).property('selected', d => d.key === Number(this.currentTimePeriod));
|
|
362
600
|
}
|
|
363
|
-
const buttonWidth = this.displayOption.operationButtonWidth + 'px', buttonHeight = this.displayOption.operationButtonHeight + 'px';
|
|
601
|
+
const buttonWidth = (this.displayOption.operationButtonWidth * scale) + 'px', buttonHeight = (this.displayOption.operationButtonHeight * scale) + 'px';
|
|
364
602
|
operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
|
|
365
603
|
.style('float', 'right').style('background-image', 'url(assets/img/last_page.svg)')
|
|
604
|
+
.style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
|
|
366
605
|
.style('background-color', 'inherit')
|
|
367
606
|
.on('click', () => { this.loadLastPage(); });
|
|
368
607
|
operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
|
|
369
608
|
.style('float', 'right').style('background-image', 'url(assets/img/next_page.svg)')
|
|
370
|
-
.style('
|
|
609
|
+
.style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
|
|
610
|
+
.style('margin', `0 ${this.displayOption.operationButtonMargin * scale}px 0 0`)
|
|
371
611
|
.style('background-color', 'inherit')
|
|
372
612
|
.on('click', () => { this.loadNextPage(); });
|
|
373
613
|
operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
|
|
374
614
|
.style('float', 'right').style('background-image', 'url(assets/img/previous_page.svg)')
|
|
375
|
-
.style('
|
|
615
|
+
.style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
|
|
616
|
+
.style('margin', `0 ${this.displayOption.operationButtonMargin * scale}px 0 0`)
|
|
376
617
|
.style('background-color', 'inherit')
|
|
377
618
|
.on('click', () => { this.loadPreviousPage(); });
|
|
378
619
|
operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
|
|
379
620
|
.style('float', 'right').style('background-image', 'url(assets/img/first_page.svg)')
|
|
380
|
-
.style('
|
|
621
|
+
.style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
|
|
622
|
+
.style('margin', `0 ${this.displayOption.operationButtonMargin * scale}px 0 0`)
|
|
381
623
|
.style('background-color', 'inherit')
|
|
382
624
|
.on('click', () => { this.loadFirstPage(); });
|
|
383
625
|
this.setStatusAsNormal();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"__symbolic":"module","version":4,"metadata":{"AlarmElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":21,"character":34},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":
|
|
1
|
+
[{"__symbolic":"module","version":4,"metadata":{"AlarmElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":21,"character":34},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":61,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":62,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":63,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":64,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":65,"character":23},{"__symbolic":"reference","module":"../../config","name":"AlarmsStore","line":66,"character":38},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"SystemTextLibraryService","line":68,"character":52},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":69,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":70,"character":38}]}],"dispose":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"updateLanguageTexts":[{"__symbolic":"method"}],"getCurrentCulture":[{"__symbolic":"method"}],"getHeaderTextByColumn":[{"__symbolic":"method"}],"getValidTimePeriods":[{"__symbolic":"method"}],"getTimePeriodText":[{"__symbolic":"method"}],"getAlarmData":[{"__symbolic":"method"}],"refreshCurrentPageData":[{"__symbolic":"method"}],"updateTableContent":[{"__symbolic":"method"}],"getIconScale":[{"__symbolic":"method"}],"renderElement":[{"__symbolic":"method"}],"buildHeaderRow":[{"__symbolic":"method"}],"buildDataRow":[{"__symbolic":"method"}],"renderPlainTable":[{"__symbolic":"method"}],"renderScrollableTable":[{"__symbolic":"method"}],"bindScrollHoverEvents":[{"__symbolic":"method"}],"unbindScrollHoverEvents":[{"__symbolic":"method"}],"startAutoScroll":[{"__symbolic":"method"}],"scrollOneRow":[{"__symbolic":"method"}],"autoNextPage":[{"__symbolic":"method"}],"renderOperationArea":[{"__symbolic":"method"}],"updateTimeRange":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"loadFirstPage":[{"__symbolic":"method"}],"loadNextPage":[{"__symbolic":"method"}],"loadPreviousPage":[{"__symbolic":"method"}],"loadLastPage":[{"__symbolic":"method"}],"setStatusAsNormal":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}]}}}}]
|
|
@@ -14,6 +14,16 @@ export declare abstract class StateControlElement extends ConditionalDynamicDisp
|
|
|
14
14
|
currentRect: JQuery;
|
|
15
15
|
preState: State;
|
|
16
16
|
constructor(element: HTMLElement, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, localization: Localization, signalRAppId: string);
|
|
17
|
+
/**
|
|
18
|
+
* 子类可覆盖此方法提供元件当前大小和初始大小,用于状态图标缩放计算
|
|
19
|
+
* @returns {{ width: number, height: number, initWidth?: number, initHeight?: number }}
|
|
20
|
+
*/
|
|
21
|
+
protected getElementSizeForIconScale(): {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
initWidth?: number;
|
|
25
|
+
initHeight?: number;
|
|
26
|
+
} | null;
|
|
17
27
|
initState(): void;
|
|
18
28
|
updateElementStates(newElementStates: VariableState[]): void;
|
|
19
29
|
addElementState(newElementState: VariableState): void;
|
|
@@ -9,6 +9,13 @@ export class StateControlElement extends ConditionalDynamicDisplayElement {
|
|
|
9
9
|
this.isEnable = true;
|
|
10
10
|
this.elementStates = [];
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 子类可覆盖此方法提供元件当前大小和初始大小,用于状态图标缩放计算
|
|
14
|
+
* @returns {{ width: number, height: number, initWidth?: number, initHeight?: number }}
|
|
15
|
+
*/
|
|
16
|
+
getElementSizeForIconScale() {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
12
19
|
initState() {
|
|
13
20
|
if (!this.elementStates.length) {
|
|
14
21
|
return;
|
|
@@ -159,7 +166,18 @@ export class StateControlElement extends ConditionalDynamicDisplayElement {
|
|
|
159
166
|
const imgObj = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
|
160
167
|
if (imgObj) {
|
|
161
168
|
const currentRectElement = this.currentRect[0];
|
|
162
|
-
|
|
169
|
+
// 计算图标缩放比例
|
|
170
|
+
const baseIconSize = 20;
|
|
171
|
+
let iconSize = baseIconSize;
|
|
172
|
+
const sizeInfo = this.getElementSizeForIconScale();
|
|
173
|
+
if (sizeInfo && sizeInfo.initWidth && sizeInfo.initHeight) {
|
|
174
|
+
const scaleX = sizeInfo.width / sizeInfo.initWidth;
|
|
175
|
+
const scaleY = sizeInfo.height / sizeInfo.initHeight;
|
|
176
|
+
// 取较小值,避免图标超出元件边界
|
|
177
|
+
const scale = Math.min(scaleX, scaleY);
|
|
178
|
+
iconSize = baseIconSize * scale;
|
|
179
|
+
}
|
|
180
|
+
let x = Number(currentRectElement.getAttribute('width')) - iconSize;
|
|
163
181
|
const currentRectX = currentRectElement.getAttribute('x');
|
|
164
182
|
if (currentRectX !== null) {
|
|
165
183
|
x += Number(currentRectX);
|
|
@@ -170,8 +188,8 @@ export class StateControlElement extends ConditionalDynamicDisplayElement {
|
|
|
170
188
|
imgObj.setAttributeNS(null, 'id', 'StateImage');
|
|
171
189
|
imgObj.setAttributeNS(null, 'x', x.toString());
|
|
172
190
|
imgObj.setAttributeNS(null, 'y', '0');
|
|
173
|
-
imgObj.setAttributeNS(null, 'height', '
|
|
174
|
-
imgObj.setAttributeNS(null, 'width', '
|
|
191
|
+
imgObj.setAttributeNS(null, 'height', iconSize + 'px');
|
|
192
|
+
imgObj.setAttributeNS(null, 'width', iconSize + 'px');
|
|
175
193
|
const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');
|
|
176
194
|
const text = document.createTextNode(title);
|
|
177
195
|
titleElement.appendChild(text);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"__symbolic":"module","version":4,"metadata":{"StateControlElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"./conditional-dynamic-display-element","name":"ConditionalDynamicDisplayElement","line":8,"character":50},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":16,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":16,"character":57},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":16,"character":98},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":17,"character":23},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":17,"character":71},{"__symbolic":"reference","name":"string"}]}],"initState":[{"__symbolic":"method"}],"updateElementStates":[{"__symbolic":"method"}],"addElementState":[{"__symbolic":"method"}],"changeStates":[{"__symbolic":"method"}],"getState":[{"__symbolic":"method"}],"changeState":[{"__symbolic":"method"}],"loadStateData":[{"__symbolic":"method"}],"setState":[{"__symbolic":"method"}],"clearTip":[{"__symbolic":"method"}]}}}}]
|
|
1
|
+
[{"__symbolic":"module","version":4,"metadata":{"StateControlElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"./conditional-dynamic-display-element","name":"ConditionalDynamicDisplayElement","line":8,"character":50},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":16,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":16,"character":57},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":16,"character":98},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":17,"character":23},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":17,"character":71},{"__symbolic":"reference","name":"string"}]}],"getElementSizeForIconScale":[{"__symbolic":"method"}],"initState":[{"__symbolic":"method"}],"updateElementStates":[{"__symbolic":"method"}],"addElementState":[{"__symbolic":"method"}],"changeStates":[{"__symbolic":"method"}],"getState":[{"__symbolic":"method"}],"changeState":[{"__symbolic":"method"}],"loadStateData":[{"__symbolic":"method"}],"setState":[{"__symbolic":"method"}],"clearTip":[{"__symbolic":"method"}]}}}}]
|