@flexem/fc-gui 3.0.0-alpha.120 → 3.0.0-alpha.121

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.
@@ -29,6 +29,7 @@ import { VideoElement } from './video/video-element';
29
29
  import { WeatherElement } from './weather/weater-element';
30
30
  import { AirQualityElement } from './air-quality/air-quality-element';
31
31
  import { AlarmElement } from './alarm/alarm-element';
32
+ import { ScrollAlarmElement } from './scroll-alarm/scroll-alarm-element';
32
33
  export class MainElement {
33
34
  constructor(injector, bsModalService, context, variableCommunicator, popupViewService, signalRAppId) {
34
35
  this.injector = injector;
@@ -133,6 +134,9 @@ export class MainElement {
133
134
  case GuiConsts.components.alarmKey:
134
135
  this.elements.push(new AlarmElement(element, this.injector, this.context.permissionChecker, this.variableCommunicator, this.context.configStore.variableStore, this.context.configStore.alarmsStore, this.signalRAppId));
135
136
  break;
137
+ case GuiConsts.components.scrollAlarmKey:
138
+ this.elements.push(new ScrollAlarmElement(element, this.injector, this.context.permissionChecker, this.variableCommunicator, this.context.configStore.variableStore, this.context.configStore.alarmsStore, this.signalRAppId));
139
+ break;
136
140
  }
137
141
  });
138
142
  this.initBackground();
@@ -298,7 +302,7 @@ export class MainElement {
298
302
  each(this.elements, e => {
299
303
  if (e instanceof HistoricalCurveElement || e instanceof VideoElement
300
304
  || e instanceof WeatherElement || e instanceof NumericalDisplayElement || e instanceof TextElement
301
- || e instanceof AirQualityElement) {
305
+ || e instanceof AirQualityElement || e instanceof ScrollAlarmElement) {
302
306
  e.dispose();
303
307
  }
304
308
  });
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"MainElement":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":55,"character":43},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":56,"character":41},{"__symbolic":"reference","module":"../gui/gui-context","name":"GuiContext","line":57,"character":34},{"__symbolic":"reference","module":"../communication","name":"VariableCommunicator","line":58,"character":47},{"__symbolic":"reference","module":"../view/popup-view.service","name":"PopupViewService","line":59,"character":43},null]}],"load":[{"__symbolic":"method"}],"uniformStretch":[{"__symbolic":"method"}],"changeVideoStyle":[{"__symbolic":"method"}],"horizontalStretch":[{"__symbolic":"method"}],"initElementState":[{"__symbolic":"method"}],"getVariableNames":[{"__symbolic":"method"}],"reportVariableStates":[{"__symbolic":"method"}],"getVirtualDeviceIdFromRect":[{"__symbolic":"method"}],"reportVariableValues":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}],"checkIsLoaded":[{"__symbolic":"method"}],"initBackground":[{"__symbolic":"method"}],"getImageEl":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"MainElement":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":56,"character":43},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":57,"character":41},{"__symbolic":"reference","module":"../gui/gui-context","name":"GuiContext","line":58,"character":34},{"__symbolic":"reference","module":"../communication","name":"VariableCommunicator","line":59,"character":47},{"__symbolic":"reference","module":"../view/popup-view.service","name":"PopupViewService","line":60,"character":43},null]}],"load":[{"__symbolic":"method"}],"uniformStretch":[{"__symbolic":"method"}],"changeVideoStyle":[{"__symbolic":"method"}],"horizontalStretch":[{"__symbolic":"method"}],"initElementState":[{"__symbolic":"method"}],"getVariableNames":[{"__symbolic":"method"}],"reportVariableStates":[{"__symbolic":"method"}],"getVirtualDeviceIdFromRect":[{"__symbolic":"method"}],"reportVariableValues":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}],"checkIsLoaded":[{"__symbolic":"method"}],"initBackground":[{"__symbolic":"method"}],"getImageEl":[{"__symbolic":"method"}]}}}}]
@@ -0,0 +1,50 @@
1
+ import { Injector } from '@angular/core';
2
+ import { PermissionChecker } from '../../service';
3
+ import { VariableCommunicator } from '../../communication';
4
+ import { ConditionalDynamicDisplayElement } from '../base/conditional-dynamic-display-element';
5
+ import { ScrollAlarmModel } from '../../model/scroll-alarm/scroll-alarm.model';
6
+ import { AlarmsStore, VariableStore } from '../../config';
7
+ export declare class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
8
+ private readonly alarmsStore;
9
+ readonly model: ScrollAlarmModel;
10
+ private readonly logger;
11
+ readonly variableCommunicator: VariableCommunicator;
12
+ private elementStatus;
13
+ private element;
14
+ private scrollIntervalId;
15
+ private alarmNames;
16
+ private startTime;
17
+ private endTime;
18
+ private getAlarmDataId;
19
+ private isScrolling;
20
+ private isDisposed;
21
+ private currentPage;
22
+ private maxResultCount;
23
+ private displayedItems;
24
+ private pageWidths;
25
+ private totalWidth;
26
+ private container;
27
+ private allAlarmsContainer;
28
+ private currentLeft;
29
+ private autoCycle;
30
+ private hasMoreData;
31
+ private isLoadingNextPage;
32
+ private headerFont;
33
+ private fontString;
34
+ constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, alarmsStore: AlarmsStore, signalRAppId: string);
35
+ dispose(): void;
36
+ private getAlarmData;
37
+ private initDisplayContainer;
38
+ private renderNewPage;
39
+ private removeOldestPage;
40
+ private resetToFirstPage;
41
+ private scrollContent;
42
+ private initScrolling;
43
+ private pauseScroll;
44
+ private resumeScroll;
45
+ private updateQueryTimeRange;
46
+ private setStatusAsNormal;
47
+ private setStatusAsLoading;
48
+ private renderStatus;
49
+ private clearStatus;
50
+ }
@@ -0,0 +1,421 @@
1
+ import * as d3 from 'd3';
2
+ import { ConditionalDynamicDisplayElement } from '../base/conditional-dynamic-display-element';
3
+ import { GetAlarmsArgs } from '../../config';
4
+ import * as moment from 'moment';
5
+ import { LOGGER_SERVICE_TOKEN } from '../../logger';
6
+ var ScrollAlarmElementStatus;
7
+ (function (ScrollAlarmElementStatus) {
8
+ ScrollAlarmElementStatus[ScrollAlarmElementStatus["Normal"] = 0] = "Normal";
9
+ ScrollAlarmElementStatus[ScrollAlarmElementStatus["Loading"] = 1] = "Loading"; // 加载中
10
+ })(ScrollAlarmElementStatus || (ScrollAlarmElementStatus = {}));
11
+ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
12
+ constructor(element, injector, permissionChecker, variableCommunicator, variableStore, alarmsStore, signalRAppId) {
13
+ var _a, _b, _c, _d, _e;
14
+ super(element, permissionChecker, variableCommunicator, variableStore, signalRAppId);
15
+ this.alarmsStore = alarmsStore;
16
+ this.elementStatus = ScrollAlarmElementStatus.Loading;
17
+ this.alarmNames = [];
18
+ this.isScrolling = false;
19
+ this.isDisposed = false;
20
+ // 新的分页和滚动逻辑变量
21
+ this.currentPage = 1;
22
+ this.maxResultCount = 3; // 每页数据量
23
+ this.displayedItems = []; // 当前显示的所有数据
24
+ this.pageWidths = []; // 存储每页的宽度
25
+ this.totalWidth = 0; // 所有显示数据的总宽度
26
+ this.currentLeft = 0;
27
+ this.autoCycle = true;
28
+ this.hasMoreData = true;
29
+ this.isLoadingNextPage = false;
30
+ this.rootElement.selectAll('*').remove();
31
+ this.setStatusAsLoading();
32
+ this.logger = injector.get(LOGGER_SERVICE_TOKEN);
33
+ this.variableCommunicator = variableCommunicator;
34
+ this.autoCycle = (_b = (_a = this.model.generalSetting) === null || _a === void 0 ? void 0 : _a.autoCycle) !== null && _b !== void 0 ? _b : true;
35
+ this.maxResultCount = (_d = (_c = this.model.generalSetting) === null || _c === void 0 ? void 0 : _c.pageSize) !== null && _d !== void 0 ? _d : 3;
36
+ if (this.model.filterSetting) {
37
+ this.alarmNames = this.model.filterSetting.detailsData.map(item => item.name);
38
+ this.updateQueryTimeRange();
39
+ // 监听告警更新
40
+ // variableCommunicator.subscribeUserDeviceAlarms(signalRAppId).subscribe(alarms => {
41
+ // alarms.forEach(alarm => {
42
+ // if (this.alarmNames.indexOf(alarm.name) !== -1) {
43
+ // this.getAlarmData();
44
+ // return;
45
+ // }
46
+ // });
47
+ // });
48
+ // 初始化显示容器
49
+ this.initDisplayContainer();
50
+ // 获取字体设置
51
+ this.headerFont = ((_e = this.model.generalSetting) === null || _e === void 0 ? void 0 : _e.headerFont) || {};
52
+ const fontStyle = [];
53
+ if (this.headerFont.isBold)
54
+ fontStyle.push('bold');
55
+ if (this.headerFont.isItalic)
56
+ fontStyle.push('italic');
57
+ if (this.headerFont.isUnderline)
58
+ fontStyle.push('underline');
59
+ fontStyle.push(`${this.headerFont.fontSize || '16px'}`);
60
+ fontStyle.push(`${this.headerFont.fontFamily || 'Microsoft YaHei'}`);
61
+ this.fontString = fontStyle.join(' ');
62
+ this.getAlarmData();
63
+ }
64
+ else {
65
+ this.displayedItems = [];
66
+ if (this.allAlarmsContainer) {
67
+ this.allAlarmsContainer.innerHTML = '';
68
+ this.totalWidth = 0;
69
+ this.pageWidths = [];
70
+ }
71
+ }
72
+ }
73
+ dispose() {
74
+ this.isDisposed = true;
75
+ clearInterval(this.scrollIntervalId);
76
+ clearTimeout(this.getAlarmDataId);
77
+ if (this.element && this.element.tooltip) {
78
+ this.element.tooltip.hidden(true);
79
+ }
80
+ this.logger.debug(`[GUI]Dispose Scroll Alarm Refresh Interval:${d3.time.format('%x %X')(new Date())}`);
81
+ // 重置所有状态
82
+ this.isScrolling = false;
83
+ }
84
+ getAlarmData() {
85
+ if (this.isDisposed || this.isLoadingNextPage)
86
+ return;
87
+ this.isLoadingNextPage = true;
88
+ // Only show loading for the first page load
89
+ if (this.currentPage === 1 && this.displayedItems.length === 0) {
90
+ this.setStatusAsLoading();
91
+ }
92
+ clearTimeout(this.getAlarmDataId);
93
+ this.getAlarmDataId = setTimeout(() => {
94
+ this.updateQueryTimeRange();
95
+ const skipCount = (this.currentPage - 1) * this.maxResultCount;
96
+ const input = new GetAlarmsArgs(this.alarmNames, this.startTime, this.endTime, this.maxResultCount, skipCount);
97
+ this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
98
+ this.isLoadingNextPage = false;
99
+ if (!result.error && result.items && result.items.length > 0) {
100
+ const newPage = result.items;
101
+ // 检查是否还有更多数据
102
+ if (!this.autoCycle && newPage.length < this.maxResultCount) {
103
+ this.hasMoreData = false;
104
+ }
105
+ else {
106
+ this.hasMoreData = true;
107
+ }
108
+ // 添加新页数据
109
+ this.displayedItems = this.displayedItems.concat(newPage);
110
+ // 渲染新页
111
+ this.renderNewPage(newPage);
112
+ // 更新页码
113
+ this.currentPage++;
114
+ // 检查是否需要删除旧页(保持最多3页)
115
+ if (this.currentPage > 4) {
116
+ this.removeOldestPage();
117
+ }
118
+ // 如果是首次加载或还没有开始滚动,初始化滚动
119
+ if (!this.isScrolling && this.displayedItems.length > 0) {
120
+ this.initScrolling();
121
+ }
122
+ this.setStatusAsNormal();
123
+ }
124
+ else {
125
+ // 如果没有数据且自动循环开启,循环回到第一页而不清空数据
126
+ if (this.autoCycle) {
127
+ // 直接跳转到第一页
128
+ this.currentPage = 1;
129
+ // 继续加载数据(会自动添加到末尾)
130
+ this.getAlarmData();
131
+ }
132
+ else {
133
+ this.hasMoreData = false;
134
+ this.setStatusAsNormal();
135
+ }
136
+ }
137
+ }, error => {
138
+ this.isLoadingNextPage = false;
139
+ this.setStatusAsNormal();
140
+ this.logger.error('Failed to get alarm data:', error);
141
+ });
142
+ }, 500);
143
+ }
144
+ initDisplayContainer() {
145
+ var _a;
146
+ const elementHeight = this.model.size.height;
147
+ const elementWidth = this.model.size.width;
148
+ // 创建foreignObject作为容器
149
+ this.element = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
150
+ this.element.setAttribute('width', elementWidth.toString());
151
+ this.element.setAttribute('height', elementHeight.toString());
152
+ this.$element.append(this.element);
153
+ // 创建背景容器,应用headerFillColor背景色
154
+ this.container = document.createElement('div');
155
+ this.container.style.cssText = `
156
+ height: ${elementHeight}px;
157
+ width: 100%;
158
+ background-color: ${((_a = this.model.generalSetting) === null || _a === void 0 ? void 0 : _a.headerFillColor) || '#ffffff'};
159
+ display: flex;
160
+ align-items: center;
161
+ overflow: hidden;
162
+ position: relative;
163
+ border: 1px solid #8ea0aa;
164
+ `;
165
+ this.element.appendChild(this.container);
166
+ // 创建一个大容器来包含所有告警项,初始位置在左侧
167
+ this.allAlarmsContainer = document.createElement('div');
168
+ this.allAlarmsContainer.style.cssText = `
169
+ position: absolute;
170
+ left: 0px;
171
+ top: 50%;
172
+ transform: translateY(-50%);
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 80px;
176
+ `;
177
+ this.container.appendChild(this.allAlarmsContainer);
178
+ // 添加鼠标悬停暂停和恢复滚动功能
179
+ this.container.addEventListener('mouseenter', () => this.pauseScroll());
180
+ this.container.addEventListener('mouseleave', () => this.resumeScroll());
181
+ }
182
+ renderNewPage(pageData) {
183
+ let pageWidth = 0;
184
+ // 为每个告警数据创建文本容器
185
+ pageData.forEach((alarm) => {
186
+ var _a, _b, _c, _d, _e, _f, _g, _h;
187
+ // 创建告警文本容器
188
+ const textContainer = document.createElement('div');
189
+ textContainer.style.cssText = `
190
+ font: ${this.fontString};
191
+ color: ${this.headerFont.color || '#E95F5F'};
192
+ white-space: nowrap;
193
+ overflow: visible;
194
+ `;
195
+ // 构建告警信息内容,根据配置决定显示哪些字段
196
+ const contentParts = [];
197
+ // 显示触发时间
198
+ if (((_a = this.model.generalSetting) === null || _a === void 0 ? void 0 : _a.showTriggerTime) && alarm.triggeredTime) {
199
+ const formattedTime = moment(alarm.triggeredTime).format('YYYY/MM/DD HH:mm:ss');
200
+ contentParts.push(formattedTime);
201
+ }
202
+ // 获取当前语言环境
203
+ const language = ((_d = (_c = (_b = window.abp) === null || _b === void 0 ? void 0 : _b.localization) === null || _c === void 0 ? void 0 : _c.currentLanguage) === null || _d === void 0 ? void 0 : _d.name) || 'zh-Hans';
204
+ const isChinese = language === 'zh-Hans' || language === 'zh';
205
+ // 显示告警等级
206
+ if (((_e = this.model.generalSetting) === null || _e === void 0 ? void 0 : _e.showAlarmLevel) && alarm.alarmLevel !== undefined) {
207
+ const levelMap = isChinese ? ['警告', '次要', '主要', '严重'] : ['Warning', 'Minor', 'Major', 'Critical'];
208
+ const alarmLevel = levelMap[alarm.alarmLevel] || (isChinese ? '警告' : 'Warning');
209
+ contentParts.push(alarmLevel);
210
+ }
211
+ // 显示告警名称
212
+ if (((_f = this.model.generalSetting) === null || _f === void 0 ? void 0 : _f.showAlarmName) && alarm.name) {
213
+ contentParts.push(alarm.name);
214
+ }
215
+ // 显示告警状态
216
+ if (((_g = this.model.generalSetting) === null || _g === void 0 ? void 0 : _g.showAlarmState) && alarm.state !== undefined) {
217
+ const stateMap = isChinese ? ['触发/未确认', '触发/已确认', '恢复/未确认', '恢复/已确认'] : ['Triggered/Unconfirmed', 'Triggered/Confirmed', 'Restored/Unconfirmed', 'Restored/Confirmed'];
218
+ const alarmState = stateMap[alarm.state] || (isChinese ? '触发/未确认' : 'Triggered/Unconfirmed');
219
+ contentParts.push(alarmState);
220
+ }
221
+ // 显示告警内容
222
+ if (((_h = this.model.generalSetting) === null || _h === void 0 ? void 0 : _h.showAlarmContent) && alarm.message) {
223
+ contentParts.push(alarm.message);
224
+ }
225
+ // 将所有显示字段用空格连接,确保一行显示
226
+ const textContent = contentParts.join(' ');
227
+ textContainer.textContent = textContent;
228
+ this.allAlarmsContainer.appendChild(textContainer);
229
+ // 计算文本宽度
230
+ const textWidth = textContainer.offsetWidth;
231
+ pageWidth += textWidth + 80; // 80是gap大小
232
+ });
233
+ // 移除最后一个gap
234
+ if (pageWidth > 0) {
235
+ pageWidth -= 80;
236
+ }
237
+ // 保存页宽度
238
+ this.pageWidths.push(pageWidth);
239
+ this.totalWidth += pageWidth;
240
+ }
241
+ removeOldestPage() {
242
+ // 移除最旧的一页数据
243
+ this.displayedItems.splice(0, this.maxResultCount);
244
+ const oldPageWidth = this.pageWidths.shift() || 0;
245
+ // 更新总宽度
246
+ this.totalWidth -= oldPageWidth;
247
+ // 从DOM中移除最旧的元素
248
+ const elementsToRemove = Array.from(this.allAlarmsContainer.children).slice(0, this.maxResultCount);
249
+ elementsToRemove.forEach(element => {
250
+ this.allAlarmsContainer.removeChild(element);
251
+ });
252
+ // 调整当前left位置(保持视觉位置不变)- 这里需要等DOM更新完成后再调整
253
+ requestAnimationFrame(() => {
254
+ this.currentLeft += oldPageWidth;
255
+ this.allAlarmsContainer.style.left = `${this.currentLeft}px`;
256
+ });
257
+ }
258
+ resetToFirstPage() {
259
+ // 重置到第一页,但保持现有数据和位置(无缝循环)
260
+ this.currentPage = 1;
261
+ this.hasMoreData = true;
262
+ // 直接加载第一页数据,不需要清空现有内容
263
+ this.getAlarmData();
264
+ }
265
+ scrollContent() {
266
+ if (this.displayedItems.length <= 0)
267
+ return;
268
+ // 每次滚动的距离
269
+ const scrollStep = 2; // 减小滚动步长,使滚动更平滑
270
+ // 更新位置 - 从右往左滚动
271
+ this.currentLeft -= scrollStep;
272
+ // 检查是否需要加载下一页
273
+ if (this.hasMoreData && !this.isLoadingNextPage) {
274
+ const currentPosition = Math.abs(this.currentLeft);
275
+ const loadedWidth = this.totalWidth - (this.pageWidths[this.pageWidths.length - 1] || 0);
276
+ // 当滚动到已加载内容的60%时,加载下一页(提前预加载,确保无缝衔接)
277
+ if (currentPosition > loadedWidth * 0.6) {
278
+ this.getAlarmData();
279
+ }
280
+ }
281
+ // 如果所有内容完全滚动出容器左侧,根据autoCycle决定是否重置
282
+ // 添加额外的偏移量(比如100px),确保最后两个字也能完全滚出视图
283
+ if (Math.abs(this.currentLeft) > this.totalWidth + 100) {
284
+ if (this.autoCycle) {
285
+ if (this.hasMoreData) {
286
+ // 加载下一页
287
+ this.getAlarmData();
288
+ }
289
+ else {
290
+ // 重置到第一页
291
+ this.resetToFirstPage();
292
+ }
293
+ // 计算新加载页面的宽度(如果有)
294
+ const newPageWidth = this.pageWidths[this.pageWidths.length - 1] || 0;
295
+ // 设置位置到新加载页面的起始位置,实现无缝衔接
296
+ this.currentLeft = -(this.totalWidth - newPageWidth);
297
+ this.allAlarmsContainer.style.left = `${this.currentLeft}px`;
298
+ }
299
+ else {
300
+ // 非循环滚动:停止滚动
301
+ clearInterval(this.scrollIntervalId);
302
+ this.isScrolling = false;
303
+ }
304
+ }
305
+ else {
306
+ this.allAlarmsContainer.style.left = `${this.currentLeft}px`;
307
+ }
308
+ }
309
+ initScrolling() {
310
+ clearInterval(this.scrollIntervalId);
311
+ // 如果没有滚动设置或自动播放为false,则不启动滚动
312
+ if (this.displayedItems.length === 0) {
313
+ return;
314
+ }
315
+ const scrollInterval = 100; // 默认100ms,滚动更流畅
316
+ // 如果当前位置在容器右侧,延迟启动滚动确保内容渲染完成
317
+ if (this.currentLeft > this.container.clientWidth * 0.5) {
318
+ setTimeout(() => {
319
+ this.isScrolling = true;
320
+ this.scrollIntervalId = setInterval(() => {
321
+ if (this.isScrolling) {
322
+ this.scrollContent();
323
+ }
324
+ }, scrollInterval);
325
+ }, 500);
326
+ }
327
+ else {
328
+ this.isScrolling = true;
329
+ this.scrollIntervalId = setInterval(() => {
330
+ if (this.isScrolling) {
331
+ this.scrollContent();
332
+ }
333
+ }, scrollInterval);
334
+ }
335
+ }
336
+ pauseScroll() {
337
+ this.isScrolling = false;
338
+ }
339
+ resumeScroll() {
340
+ this.isScrolling = true;
341
+ }
342
+ updateQueryTimeRange() {
343
+ this.endTime = moment();
344
+ console.log(this.model.generalSetting, 1);
345
+ switch (this.model.generalSetting.displayPeriod) {
346
+ case 1:
347
+ this.startTime = moment().subtract(1, 'hours');
348
+ break;
349
+ case 3:
350
+ this.startTime = moment().subtract(7, 'days');
351
+ break;
352
+ case 4:
353
+ this.startTime = moment().subtract(30, 'days');
354
+ break;
355
+ case 5:
356
+ this.startTime = moment().subtract(1, 'years');
357
+ break;
358
+ case 6:
359
+ this.startTime = moment().subtract(30, 'minutes');
360
+ break;
361
+ case 7:
362
+ this.startTime = moment().subtract(8, 'hours');
363
+ break;
364
+ default:
365
+ this.startTime = moment().subtract(1, 'days');
366
+ }
367
+ }
368
+ setStatusAsNormal() {
369
+ this.elementStatus = ScrollAlarmElementStatus.Normal;
370
+ this.clearStatus();
371
+ }
372
+ setStatusAsLoading() {
373
+ this.elementStatus = ScrollAlarmElementStatus.Loading;
374
+ this.renderStatus('assets/img/loading.svg', '#226abc');
375
+ }
376
+ renderStatus(icon, stroke) {
377
+ if (this.elementStatus === ScrollAlarmElementStatus.Normal) {
378
+ this.clearStatus();
379
+ return;
380
+ }
381
+ this.rootElement.append('rect').attr('id', 'StateFrame').attr('fill', 'transparent')
382
+ .attr('width', this.model.size.width)
383
+ .attr('height', this.model.size.height);
384
+ const document = this.$element[0].ownerDocument;
385
+ const currentRect = this.$element.find('rect#StateFrame').first();
386
+ if (!currentRect.length) {
387
+ return;
388
+ }
389
+ this.$element.find('image#StateImage').remove();
390
+ const imgObj = document.createElementNS('http://www.w3.org/2000/svg', 'image');
391
+ if (imgObj) {
392
+ let x = Number(currentRect[0].getAttribute('width')) - 20;
393
+ const currentRectX = currentRect[0].getAttribute('x');
394
+ if (currentRectX !== null) {
395
+ x += Number(currentRectX);
396
+ }
397
+ currentRect[0].setAttribute('stroke', stroke);
398
+ currentRect[0].setAttribute('stroke-opacity', '0.5');
399
+ imgObj.href.baseVal = icon;
400
+ imgObj.setAttributeNS(null, 'id', 'StateImage');
401
+ imgObj.setAttributeNS(null, 'x', x.toString());
402
+ imgObj.setAttributeNS(null, 'y', '0');
403
+ imgObj.setAttributeNS(null, 'height', '20px');
404
+ imgObj.setAttributeNS(null, 'width', '20px');
405
+ const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');
406
+ imgObj.appendChild(titleElement);
407
+ this.$element.append(imgObj);
408
+ }
409
+ }
410
+ clearStatus() {
411
+ const currentRect = this.$element.find('rect#StateFrame').first();
412
+ if (!currentRect.length) {
413
+ return;
414
+ }
415
+ const stroke = currentRect[0].getAttribute('stroke');
416
+ if (stroke) {
417
+ currentRect[0].removeAttribute('stroke');
418
+ }
419
+ this.$element.find('image#StateImage').remove();
420
+ }
421
+ }
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{"ScrollAlarmElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-dynamic-display-element","name":"ConditionalDynamicDisplayElement","line":17,"character":40},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":47,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":48,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":49,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":50,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":51,"character":23},{"__symbolic":"reference","module":"../../config","name":"AlarmsStore","line":52,"character":38},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"getAlarmData":[{"__symbolic":"method"}],"initDisplayContainer":[{"__symbolic":"method"}],"renderNewPage":[{"__symbolic":"method"}],"removeOldestPage":[{"__symbolic":"method"}],"resetToFirstPage":[{"__symbolic":"method"}],"scrollContent":[{"__symbolic":"method"}],"initScrolling":[{"__symbolic":"method"}],"pauseScroll":[{"__symbolic":"method"}],"resumeScroll":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"setStatusAsNormal":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}]}}}}]
@@ -0,0 +1,21 @@
1
+ import { ConditionalDynamicDisplayModel } from '../base/conditional-dynamic-display-model';
2
+ import { Point, Size } from '../shared';
3
+ import { DynamicDisplayModel } from '../shared/dynamic-display/dynamic-display-model';
4
+ export interface ScrollAlarmModel extends ConditionalDynamicDisplayModel {
5
+ readonly version: number;
6
+ readonly size: Size;
7
+ readonly location: Point;
8
+ readonly generalSetting?: any;
9
+ readonly filterSetting?: any;
10
+ readonly widths: number[];
11
+ readonly heights: number[];
12
+ readonly columLabels: string[];
13
+ readonly levelText: string[];
14
+ readonly scrollSetting?: {
15
+ readonly scrollInterval?: number;
16
+ readonly scrollDirection?: 'vertical' | 'horizontal';
17
+ readonly pauseOnHover?: boolean;
18
+ readonly autoPlay?: boolean;
19
+ };
20
+ readonly dynamicSetting?: DynamicDisplayModel;
21
+ }
File without changes
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{"ScrollAlarmModel":{"__symbolic":"interface"}}}]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "main": "bundles/fc-gui.umd.js",
3
- "version": "3.0.0-alpha.120",
3
+ "version": "3.0.0-alpha.121",
4
4
  "module": "public_api.js",
5
5
  "typings": "public_api.d.ts",
6
6
  "license": "UNLICENSED",
@@ -28,5 +28,6 @@ export declare class GuiConsts {
28
28
  weatherKey: string;
29
29
  airQualityKey: string;
30
30
  alarmKey: string;
31
+ scrollAlarmKey: string;
31
32
  };
32
33
  }
@@ -28,5 +28,6 @@ GuiConsts.components = {
28
28
  tableKey: 'Table',
29
29
  weatherKey: 'Weather',
30
30
  airQualityKey: 'AirQualityIndex',
31
- alarmKey: 'Alarm'
31
+ alarmKey: 'Alarm',
32
+ scrollAlarmKey: 'ScrollAlarm'
32
33
  };
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"GuiConsts":{"__symbolic":"class","statics":{"components":{"imageKey":"Image","numericalDisplayKey":"NumericalDisplay","textKey":"Text","hyperlinkKey":"Hyperlink","meterKey":"Meter","pipeKey":"Pipe","switchIndicatorLightKey":"SwitchIndicatorLight","barGraphKey":"BarGraph","toggleViewKey":"ToggleView","characterKey":"Character","straightLineKey":"StraightLine","polyLineKey":"PolyLine","rectangleKey":"Rectangle","sectorkey":"Sector","ellipseKey":"Ellipse","datetimeDisplayKey":"DatetimeDisplay","historicalCurveKey":"HistoricalCurve","ringGraphKey":"RingGraph","viewOperationElement":"ViewOperation","polygonKey":"Polygon","videokey":"Video","tableKey":"Table","weatherKey":"Weather","airQualityKey":"AirQualityIndex","alarmKey":"Alarm"}}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"GuiConsts":{"__symbolic":"class","statics":{"components":{"imageKey":"Image","numericalDisplayKey":"NumericalDisplay","textKey":"Text","hyperlinkKey":"Hyperlink","meterKey":"Meter","pipeKey":"Pipe","switchIndicatorLightKey":"SwitchIndicatorLight","barGraphKey":"BarGraph","toggleViewKey":"ToggleView","characterKey":"Character","straightLineKey":"StraightLine","polyLineKey":"PolyLine","rectangleKey":"Rectangle","sectorkey":"Sector","ellipseKey":"Ellipse","datetimeDisplayKey":"DatetimeDisplay","historicalCurveKey":"HistoricalCurve","ringGraphKey":"RingGraph","viewOperationElement":"ViewOperation","polygonKey":"Polygon","videokey":"Video","tableKey":"Table","weatherKey":"Weather","airQualityKey":"AirQualityIndex","alarmKey":"Alarm","scrollAlarmKey":"ScrollAlarm"}}}}}]