@flexem/fc-gui 3.0.0-alpha.158 → 3.0.0-alpha.159
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 +314 -23
- 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/elements/historical-curve/historical-curve.element.d.ts +8 -1
- package/elements/historical-curve/historical-curve.element.js +306 -22
- package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
- package/gui/gui-context.d.ts +7 -0
- package/localization/localization.service.d.ts +3 -0
- package/localization/localization.service.js +3 -0
- package/localization/localization.service.metadata.json +1 -1
- package/localization/localization.service.zh_CN.js +3 -0
- package/localization/localization.service.zh_CN.metadata.json +1 -1
- package/package.json +1 -1
- package/service/system-text-library.service.d.ts +1 -0
- package/service/system-text-library.service.js +2 -1
- package/service/system-text-library.service.metadata.json +1 -1
|
@@ -33,6 +33,8 @@ export declare class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
33
33
|
*/
|
|
34
34
|
private currentEndTime;
|
|
35
35
|
private currentTimePeriod;
|
|
36
|
+
private customStartTime;
|
|
37
|
+
private customEndTime;
|
|
36
38
|
private refreshIntervalId;
|
|
37
39
|
private elementStatus;
|
|
38
40
|
private chartElement;
|
|
@@ -42,6 +44,8 @@ export declare class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
42
44
|
private resizeEventListener;
|
|
43
45
|
private isAndroid;
|
|
44
46
|
private needResize;
|
|
47
|
+
private dropdownListEl;
|
|
48
|
+
private dropdownTriggerEl;
|
|
45
49
|
constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, historyDataStore: HistoryDataStore, signalRAppId: string, systemTextLibraryService?: SystemTextLibraryService, languageService?: LanguageService, guiContext?: GuiContext);
|
|
46
50
|
dispose(): void;
|
|
47
51
|
private initKeyboardListener;
|
|
@@ -60,7 +64,7 @@ export declare class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
60
64
|
private getCurrentCulture;
|
|
61
65
|
private getValidTimePeriods;
|
|
62
66
|
/**
|
|
63
|
-
*
|
|
67
|
+
* 获取时间段文案(从系统文本库获取多语种翻译,fallback 到 localization)
|
|
64
68
|
*/
|
|
65
69
|
private getTimePeriodText;
|
|
66
70
|
private updateTimeRange;
|
|
@@ -75,6 +79,9 @@ export declare class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
75
79
|
private renderCommonProperty;
|
|
76
80
|
private renderOperationArea;
|
|
77
81
|
private timeFormat;
|
|
82
|
+
private fmtDatetimeLocal;
|
|
83
|
+
private showCustomTimeRangeModal;
|
|
84
|
+
private showCustomTimeRangeModalFallback;
|
|
78
85
|
private loadFirstPage;
|
|
79
86
|
private loadNextPage;
|
|
80
87
|
private loadPreviousPage;
|
|
@@ -32,9 +32,13 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
32
32
|
operationButtonHeight: 24,
|
|
33
33
|
operationButtonMargin: 4
|
|
34
34
|
};
|
|
35
|
+
this.customStartTime = null;
|
|
36
|
+
this.customEndTime = null;
|
|
35
37
|
this.elementStatus = HistoricalCurveElementStatus.Loading;
|
|
36
38
|
this.data = [];
|
|
37
39
|
this.needResize = true;
|
|
40
|
+
this.dropdownListEl = null;
|
|
41
|
+
this.dropdownTriggerEl = null;
|
|
38
42
|
this.setNeedResize = () => {
|
|
39
43
|
this.needResize = false;
|
|
40
44
|
setTimeout(() => this.needResize = true, 500);
|
|
@@ -118,21 +122,43 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
118
122
|
* 更新语种相关的文案(时间段选择器)
|
|
119
123
|
*/
|
|
120
124
|
updateLanguageTexts() {
|
|
121
|
-
// 重新生成时间段数据
|
|
122
125
|
const updatedTimePeriods = this.getValidTimePeriods();
|
|
123
126
|
this.timePeriods = updatedTimePeriods;
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const options = nativeSelectEl.find('option');
|
|
129
|
-
options.each(function (i) {
|
|
127
|
+
// 更新下拉列表各选项文字
|
|
128
|
+
if (this.dropdownListEl) {
|
|
129
|
+
const items = this.dropdownListEl.querySelectorAll('.hc-dropdown-item');
|
|
130
|
+
items.forEach((item, i) => {
|
|
130
131
|
if (i < updatedTimePeriods.length) {
|
|
131
|
-
|
|
132
|
+
item.textContent = updatedTimePeriods[i].name;
|
|
132
133
|
}
|
|
133
134
|
});
|
|
135
|
+
// 文字更新后重新测量宽度,修正首次加载时文字为空导致宽度过小的问题
|
|
136
|
+
const prevDisplay = this.dropdownListEl.style.display;
|
|
137
|
+
const prevVisibility = this.dropdownListEl.style.visibility;
|
|
138
|
+
this.dropdownListEl.style.display = 'block';
|
|
139
|
+
this.dropdownListEl.style.visibility = 'hidden';
|
|
140
|
+
this.dropdownListEl.style.width = '';
|
|
141
|
+
const newWidth = this.dropdownListEl.offsetWidth;
|
|
142
|
+
this.dropdownListEl.style.display = prevDisplay;
|
|
143
|
+
this.dropdownListEl.style.visibility = prevVisibility;
|
|
144
|
+
this.dropdownListEl.style.width = newWidth + 'px';
|
|
145
|
+
if (this.dropdownTriggerEl) {
|
|
146
|
+
this.dropdownTriggerEl.style.width = newWidth + 'px';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// 更新触发按钮文字(显示当前选中项的最新语言文案)
|
|
150
|
+
if (this.dropdownTriggerEl) {
|
|
151
|
+
const selected = updatedTimePeriods.find(p => p.key === Number(this.currentTimePeriod));
|
|
152
|
+
if (selected) {
|
|
153
|
+
const textNode = Array.from(this.dropdownTriggerEl.childNodes).find(n => n.nodeType === Node.TEXT_NODE);
|
|
154
|
+
if (textNode) {
|
|
155
|
+
textNode.textContent = selected.name;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
this.dropdownTriggerEl.insertBefore(document.createTextNode(selected.name), this.dropdownTriggerEl.firstChild);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
134
161
|
}
|
|
135
|
-
// 如果 select 元素不存在,timePeriods 已更新,下次 renderOperationArea 时会使用新的文本
|
|
136
162
|
}
|
|
137
163
|
/**
|
|
138
164
|
* 获取当前语种的 culture 代码
|
|
@@ -168,12 +194,13 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
168
194
|
timePeriods.push({ key: 3, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_SEVEN_DAYS) });
|
|
169
195
|
timePeriods.push({ key: 4, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_DAYS) });
|
|
170
196
|
timePeriods.push({ key: 5, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_YEAR) });
|
|
197
|
+
timePeriods.push({ key: 8, name: this.getTimePeriodText(TIME_PERIOD_KEYS.CUSTOM, this.localization.customTimeRange) });
|
|
171
198
|
return timePeriods;
|
|
172
199
|
}
|
|
173
200
|
/**
|
|
174
|
-
*
|
|
201
|
+
* 获取时间段文案(从系统文本库获取多语种翻译,fallback 到 localization)
|
|
175
202
|
*/
|
|
176
|
-
getTimePeriodText(textKey) {
|
|
203
|
+
getTimePeriodText(textKey, fallback = '') {
|
|
177
204
|
const currentCulture = this.getCurrentCulture();
|
|
178
205
|
const systemType = SYSTEM_TEXT_LIBRARY_TYPES.COMPONENT_BUILTIN;
|
|
179
206
|
if (this.systemTextLibraryService) {
|
|
@@ -182,13 +209,20 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
182
209
|
return translation;
|
|
183
210
|
}
|
|
184
211
|
}
|
|
185
|
-
return
|
|
212
|
+
return fallback;
|
|
186
213
|
}
|
|
187
214
|
updateTimeRange(timePeriodType) {
|
|
188
215
|
this.currentTimePeriod = +timePeriodType;
|
|
189
216
|
this.updateQueryTimeRange();
|
|
190
217
|
}
|
|
191
218
|
updateQueryTimeRange() {
|
|
219
|
+
if (this.currentTimePeriod === 8) {
|
|
220
|
+
if (this.customStartTime && this.customEndTime) {
|
|
221
|
+
this.startTime = this.customStartTime.clone();
|
|
222
|
+
this.endTime = this.customEndTime.clone();
|
|
223
|
+
}
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
192
226
|
this.endTime = moment();
|
|
193
227
|
switch (this.currentTimePeriod) {
|
|
194
228
|
case 1:
|
|
@@ -563,18 +597,143 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
563
597
|
const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop})`)
|
|
564
598
|
.append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight).attr('fill', 'none')
|
|
565
599
|
.append('xhtml:div').style('height', (this.displayOption.operationAreaHeight - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
|
|
566
|
-
const selectElement = operationArea.append('select').style('margin-left', this.displayOption.marginLeft + 'px')
|
|
567
|
-
.style('background-color', backgroundColor)
|
|
568
|
-
.style('font-size', this.displayOption.operationSelectFontSize).on('change', () => {
|
|
569
|
-
const displayTimePeriod = this.rootElement.select('select').property('value');
|
|
570
|
-
this.updateTimeRange(displayTimePeriod);
|
|
571
|
-
this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
|
|
572
|
-
});
|
|
573
600
|
const rect = this.$element.parent().parent().find('rect');
|
|
574
601
|
const fillColor = rect.attr('fill');
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
.style('
|
|
602
|
+
const dropdownBg = this.model.displaySetting.axisSetting.filterBackgroudColor || fillColor || '#fff';
|
|
603
|
+
const dropdownWrapper = operationArea.append('div')
|
|
604
|
+
.style('display', 'inline-block')
|
|
605
|
+
.style('position', 'relative')
|
|
606
|
+
.style('margin-left', this.displayOption.marginLeft + 'px')
|
|
607
|
+
.style('vertical-align', 'middle');
|
|
608
|
+
const selectedText = this.timePeriods.find(t => t.key === Number(this.currentTimePeriod));
|
|
609
|
+
const dropdownTrigger = dropdownWrapper.append('div')
|
|
610
|
+
.attr('class', 'hc-dropdown-trigger')
|
|
611
|
+
.style('background-color', backgroundColor)
|
|
612
|
+
.style('font-size', this.displayOption.operationSelectFontSize)
|
|
613
|
+
.style('cursor', 'pointer')
|
|
614
|
+
.style('padding', '0 18px 0 4px')
|
|
615
|
+
.style('border', '1px solid #ccc')
|
|
616
|
+
.style('border-radius', '2px')
|
|
617
|
+
.style('position', 'relative')
|
|
618
|
+
.style('white-space', 'nowrap')
|
|
619
|
+
.style('line-height', (this.displayOption.operationAreaHeight - 8) + 'px')
|
|
620
|
+
.style('min-height', (this.displayOption.operationAreaHeight - 8) + 'px')
|
|
621
|
+
.text(selectedText ? selectedText.name : '');
|
|
622
|
+
dropdownTrigger.append('span')
|
|
623
|
+
.style('position', 'absolute')
|
|
624
|
+
.style('right', '4px')
|
|
625
|
+
.style('top', '50%')
|
|
626
|
+
.style('transform', 'translateY(-50%)')
|
|
627
|
+
.style('font-size', '10px')
|
|
628
|
+
.style('pointer-events', 'none')
|
|
629
|
+
.text('▼');
|
|
630
|
+
const dropdownListEl = document.createElement('div');
|
|
631
|
+
dropdownListEl.style.cssText = 'display:none;position:fixed;background:' + dropdownBg
|
|
632
|
+
+ ';border:1px solid #ccc;border-radius:2px;z-index:9999;box-shadow:0 2px 6px rgba(0,0,0,0.15);';
|
|
633
|
+
document.body.appendChild(dropdownListEl);
|
|
634
|
+
this.dropdownListEl = dropdownListEl;
|
|
635
|
+
this.dropdownTriggerEl = dropdownTrigger.node();
|
|
636
|
+
const dropdownList = d3.select(dropdownListEl);
|
|
637
|
+
this.timePeriods.forEach(tp => {
|
|
638
|
+
dropdownList.append('div')
|
|
639
|
+
.attr('class', 'hc-dropdown-item')
|
|
640
|
+
.style('padding', '4px 8px')
|
|
641
|
+
.style('cursor', 'pointer')
|
|
642
|
+
.style('white-space', 'nowrap')
|
|
643
|
+
.style('font-size', this.displayOption.operationSelectFontSize)
|
|
644
|
+
.style('line-height', (this.displayOption.operationAreaHeight - 8) + 'px')
|
|
645
|
+
.style('min-height', (this.displayOption.operationAreaHeight - 8) + 'px')
|
|
646
|
+
.style('background', tp.key === Number(this.currentTimePeriod) ? '#1890ff' : 'transparent')
|
|
647
|
+
.style('color', tp.key === Number(this.currentTimePeriod) ? '#fff' : '#333')
|
|
648
|
+
.text(tp.name)
|
|
649
|
+
.on('mouseover', function () {
|
|
650
|
+
const el = d3.select(this);
|
|
651
|
+
if (!el.classed('hc-dropdown-selected')) {
|
|
652
|
+
el.style('background', '#e6f7ff').style('color', '#333');
|
|
653
|
+
}
|
|
654
|
+
})
|
|
655
|
+
.on('mouseout', function () {
|
|
656
|
+
const el = d3.select(this);
|
|
657
|
+
if (!el.classed('hc-dropdown-selected')) {
|
|
658
|
+
el.style('background', 'transparent').style('color', '#333');
|
|
659
|
+
}
|
|
660
|
+
})
|
|
661
|
+
.on('click', () => {
|
|
662
|
+
dropdownListEl.style.display = 'none';
|
|
663
|
+
// 从 this.timePeriods 实时查找,确保语种切换后显示最新文案
|
|
664
|
+
const currentPeriod = this.timePeriods.find(p => p.key === tp.key);
|
|
665
|
+
const currentName = currentPeriod ? currentPeriod.name : tp.name;
|
|
666
|
+
dropdownTrigger.text(currentName);
|
|
667
|
+
dropdownTrigger.append('span')
|
|
668
|
+
.style('position', 'absolute')
|
|
669
|
+
.style('right', '4px')
|
|
670
|
+
.style('top', '50%')
|
|
671
|
+
.style('transform', 'translateY(-50%)')
|
|
672
|
+
.style('font-size', '10px')
|
|
673
|
+
.style('pointer-events', 'none')
|
|
674
|
+
.text('▼');
|
|
675
|
+
// 更新选中状态
|
|
676
|
+
dropdownList.selectAll('.hc-dropdown-item')
|
|
677
|
+
.classed('hc-dropdown-selected', false)
|
|
678
|
+
.style('background', 'transparent')
|
|
679
|
+
.style('color', '#333');
|
|
680
|
+
d3.select(d3.event.currentTarget)
|
|
681
|
+
.classed('hc-dropdown-selected', true)
|
|
682
|
+
.style('background', '#1890ff')
|
|
683
|
+
.style('color', '#fff');
|
|
684
|
+
if (tp.key === 8) {
|
|
685
|
+
this.showCustomTimeRangeModal();
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
this.updateTimeRange(tp.key);
|
|
689
|
+
this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
// 测量下拉列表最大宽度,让 trigger 和列表宽度一致
|
|
693
|
+
dropdownListEl.style.display = 'block';
|
|
694
|
+
dropdownListEl.style.visibility = 'hidden';
|
|
695
|
+
const listContentWidth = dropdownListEl.offsetWidth;
|
|
696
|
+
dropdownListEl.style.display = 'none';
|
|
697
|
+
dropdownListEl.style.visibility = '';
|
|
698
|
+
dropdownListEl.style.width = listContentWidth + 'px';
|
|
699
|
+
dropdownTrigger.node().style.width = listContentWidth + 'px';
|
|
700
|
+
dropdownTrigger.node().style.boxSizing = 'border-box';
|
|
701
|
+
const hideDropdown = () => { dropdownListEl.style.display = 'none'; };
|
|
702
|
+
dropdownTrigger.on('click', () => {
|
|
703
|
+
const isVisible = dropdownListEl.style.display !== 'none';
|
|
704
|
+
if (isVisible) {
|
|
705
|
+
hideDropdown();
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
const triggerNode = dropdownTrigger.node();
|
|
709
|
+
const triggerRect = triggerNode.getBoundingClientRect();
|
|
710
|
+
// 设置宽度至少和 trigger 一样宽
|
|
711
|
+
dropdownListEl.style.minWidth = triggerRect.width + 'px';
|
|
712
|
+
dropdownListEl.style.left = triggerRect.left + 'px';
|
|
713
|
+
dropdownListEl.style.display = 'block';
|
|
714
|
+
const listHeight = dropdownListEl.offsetHeight;
|
|
715
|
+
const spaceBelow = window.innerHeight - triggerRect.bottom;
|
|
716
|
+
if (spaceBelow < listHeight) {
|
|
717
|
+
// 向上展开
|
|
718
|
+
dropdownListEl.style.top = '';
|
|
719
|
+
dropdownListEl.style.bottom = (window.innerHeight - triggerRect.top) + 'px';
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
// 向下展开
|
|
723
|
+
dropdownListEl.style.bottom = '';
|
|
724
|
+
dropdownListEl.style.top = triggerRect.bottom + 'px';
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
// 点击外部收起
|
|
729
|
+
document.addEventListener('click', (event) => {
|
|
730
|
+
const triggerNode = dropdownTrigger.node();
|
|
731
|
+
if (!dropdownListEl.contains(event.target) && !triggerNode.contains(event.target)) {
|
|
732
|
+
hideDropdown();
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
// 滚动时收起
|
|
736
|
+
document.addEventListener('scroll', hideDropdown, true);
|
|
578
737
|
const buttonWidth = this.displayOption.operationButtonWidth + 'px', buttonHeight = this.displayOption.operationButtonHeight + 'px';
|
|
579
738
|
operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
|
|
580
739
|
.style('float', 'right').style('background-image', 'url(assets/img/black_last_page.png)')
|
|
@@ -599,6 +758,131 @@ export class HistoricalCurveElement extends ConditionalDisplayElement {
|
|
|
599
758
|
timeFormat(datetime, specifier) {
|
|
600
759
|
return d3.time.format(specifier)(new Date(datetime));
|
|
601
760
|
}
|
|
761
|
+
fmtDatetimeLocal(d) {
|
|
762
|
+
const p2 = (n) => (n < 10 ? '0' : '') + n;
|
|
763
|
+
return d.getFullYear() + '-' + p2(d.getMonth() + 1) + '-' + p2(d.getDate())
|
|
764
|
+
+ 'T' + p2(d.getHours()) + ':' + p2(d.getMinutes()) + ':' + p2(d.getSeconds());
|
|
765
|
+
}
|
|
766
|
+
showCustomTimeRangeModal() {
|
|
767
|
+
const now = new Date();
|
|
768
|
+
const defaultStart = this.customStartTime ? this.customStartTime.toDate()
|
|
769
|
+
: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
|
|
770
|
+
const defaultEnd = this.customEndTime ? this.customEndTime.toDate()
|
|
771
|
+
: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);
|
|
772
|
+
if (this.guiContext && this.guiContext.showCustomTimeRangeModal) {
|
|
773
|
+
this.guiContext.showCustomTimeRangeModal({ startTime: defaultStart, endTime: defaultEnd }).then(result => {
|
|
774
|
+
if (result) {
|
|
775
|
+
const momentAny = moment;
|
|
776
|
+
this.customStartTime = momentAny(result.startTime);
|
|
777
|
+
this.customEndTime = momentAny(result.endTime);
|
|
778
|
+
this.updateTimeRange(8);
|
|
779
|
+
this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
this.showCustomTimeRangeModalFallback();
|
|
785
|
+
}
|
|
786
|
+
showCustomTimeRangeModalFallback() {
|
|
787
|
+
const prevTimePeriod = this.currentTimePeriod;
|
|
788
|
+
const now = new Date();
|
|
789
|
+
const defaultStart = this.fmtDatetimeLocal(this.customStartTime ? this.customStartTime.toDate()
|
|
790
|
+
: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0));
|
|
791
|
+
const defaultEnd = this.fmtDatetimeLocal(this.customEndTime ? this.customEndTime.toDate()
|
|
792
|
+
: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59));
|
|
793
|
+
const overlay = document.createElement('div');
|
|
794
|
+
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:9999;';
|
|
795
|
+
const modal = document.createElement('div');
|
|
796
|
+
const modalCss = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);'
|
|
797
|
+
+ 'background:#fff;border-radius:4px;min-width:460px;'
|
|
798
|
+
+ 'box-shadow:0 4px 12px rgba(0,0,0,0.15);font-family:inherit;font-size:14px;';
|
|
799
|
+
modal.style.cssText = modalCss;
|
|
800
|
+
const header = document.createElement('div');
|
|
801
|
+
header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #e8e8e8;';
|
|
802
|
+
const title = document.createElement('span');
|
|
803
|
+
title.style.cssText = 'font-size:16px;font-weight:500;color:#333;';
|
|
804
|
+
title.textContent = this.localization.customTimeRange || '自定义';
|
|
805
|
+
const closeBtn = document.createElement('span');
|
|
806
|
+
closeBtn.style.cssText = 'cursor:pointer;font-size:18px;color:#999;line-height:1;';
|
|
807
|
+
closeBtn.textContent = '×';
|
|
808
|
+
header.appendChild(title);
|
|
809
|
+
header.appendChild(closeBtn);
|
|
810
|
+
const body = document.createElement('div');
|
|
811
|
+
body.style.cssText = 'padding:20px 16px;display:flex;align-items:center;flex-wrap:wrap;gap:8px;';
|
|
812
|
+
const label = document.createElement('span');
|
|
813
|
+
label.style.cssText = 'color:#333;white-space:nowrap;';
|
|
814
|
+
label.textContent = '时间范围:';
|
|
815
|
+
const inputStyle = 'border:1px solid #d9d9d9;border-radius:4px;padding:4px 8px;font-size:14px;height:32px;outline:none;color:#333;';
|
|
816
|
+
const startInput = document.createElement('input');
|
|
817
|
+
startInput.type = 'datetime-local';
|
|
818
|
+
startInput.setAttribute('step', '1');
|
|
819
|
+
startInput.value = defaultStart;
|
|
820
|
+
startInput.style.cssText = inputStyle;
|
|
821
|
+
const separator = document.createElement('span');
|
|
822
|
+
separator.textContent = ' - ';
|
|
823
|
+
separator.style.cssText = 'color:#333;';
|
|
824
|
+
const endInput = document.createElement('input');
|
|
825
|
+
endInput.type = 'datetime-local';
|
|
826
|
+
endInput.setAttribute('step', '1');
|
|
827
|
+
endInput.value = defaultEnd;
|
|
828
|
+
endInput.style.cssText = inputStyle;
|
|
829
|
+
body.appendChild(label);
|
|
830
|
+
body.appendChild(startInput);
|
|
831
|
+
body.appendChild(separator);
|
|
832
|
+
body.appendChild(endInput);
|
|
833
|
+
const footer = document.createElement('div');
|
|
834
|
+
footer.style.cssText = 'display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid #e8e8e8;';
|
|
835
|
+
const cancelBtn = document.createElement('button');
|
|
836
|
+
cancelBtn.textContent = this.localization.cancel || '取消';
|
|
837
|
+
cancelBtn.style.cssText = 'padding:5px 16px;border:1px solid #d9d9d9;border-radius:4px;background:#fff;cursor:pointer;font-size:14px;color:#333;';
|
|
838
|
+
const saveBtn = document.createElement('button');
|
|
839
|
+
saveBtn.textContent = '保存';
|
|
840
|
+
saveBtn.style.cssText = 'padding:5px 16px;border:none;border-radius:4px;background:#1890ff;color:#fff;cursor:pointer;font-size:14px;';
|
|
841
|
+
footer.appendChild(cancelBtn);
|
|
842
|
+
footer.appendChild(saveBtn);
|
|
843
|
+
modal.appendChild(header);
|
|
844
|
+
modal.appendChild(body);
|
|
845
|
+
modal.appendChild(footer);
|
|
846
|
+
overlay.appendChild(modal);
|
|
847
|
+
document.body.appendChild(overlay);
|
|
848
|
+
const close = (revert) => {
|
|
849
|
+
document.body.removeChild(overlay);
|
|
850
|
+
if (revert) {
|
|
851
|
+
const selectEl = this.$element && this.$element.find('select');
|
|
852
|
+
if (selectEl && selectEl.length) {
|
|
853
|
+
selectEl.val(prevTimePeriod.toString());
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
closeBtn.addEventListener('click', () => close(true));
|
|
858
|
+
cancelBtn.addEventListener('click', () => close(true));
|
|
859
|
+
saveBtn.addEventListener('click', () => {
|
|
860
|
+
const startVal = startInput.value;
|
|
861
|
+
const endVal = endInput.value;
|
|
862
|
+
if (!startVal) {
|
|
863
|
+
startInput.style.borderColor = 'red';
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
const startDate = new Date(startVal);
|
|
867
|
+
const endDate = endVal
|
|
868
|
+
? new Date(endVal)
|
|
869
|
+
: new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate(), 23, 59, 59);
|
|
870
|
+
if (isNaN(startDate.getTime())) {
|
|
871
|
+
startInput.style.borderColor = 'red';
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
if (endDate.getTime() <= startDate.getTime()) {
|
|
875
|
+
endInput.style.borderColor = 'red';
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
const momentAny = moment;
|
|
879
|
+
this.customStartTime = momentAny(startDate);
|
|
880
|
+
this.customEndTime = momentAny(endDate);
|
|
881
|
+
close(false);
|
|
882
|
+
this.updateTimeRange(8);
|
|
883
|
+
this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
|
|
884
|
+
});
|
|
885
|
+
}
|
|
602
886
|
loadFirstPage() {
|
|
603
887
|
this.updateQueryTimeRange();
|
|
604
888
|
this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"__symbolic":"module","version":4,"metadata":{"HistoricalCurveElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":23,"character":44},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":
|
|
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":75,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":76,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":77,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":78,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":79,"character":23},{"__symbolic":"reference","module":"../../config","name":"HistoryDataStore","line":80,"character":43},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"SystemTextLibraryService","line":82,"character":52},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":83,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":84,"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"}],"fmtDatetimeLocal":[{"__symbolic":"method"}],"showCustomTimeRangeModal":[{"__symbolic":"method"}],"showCustomTimeRangeModalFallback":[{"__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"}]}}}}]
|
package/gui/gui-context.d.ts
CHANGED
|
@@ -22,5 +22,12 @@ export interface GuiContext {
|
|
|
22
22
|
getDefaultLanguageId?(): number;
|
|
23
23
|
getLanguageCultureById?(languageId: number | null): string | null;
|
|
24
24
|
updateCurrentLanguageId?(languageId: number | null): Promise<void>;
|
|
25
|
+
showCustomTimeRangeModal?(config: {
|
|
26
|
+
startTime?: Date;
|
|
27
|
+
endTime?: Date;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
startTime: Date;
|
|
30
|
+
endTime: Date;
|
|
31
|
+
} | null>;
|
|
25
32
|
dispose(): void;
|
|
26
33
|
}
|
|
@@ -40,6 +40,9 @@ export const DefaultLocalization = {
|
|
|
40
40
|
lastSevenDays: 'Last 7 days',
|
|
41
41
|
lastThirtyDays: 'Last 30 days',
|
|
42
42
|
lastOneYear: 'Last 1 year',
|
|
43
|
+
customTimeRange: 'Custom',
|
|
44
|
+
startTime: 'Start Time',
|
|
45
|
+
endTime: 'End Time',
|
|
43
46
|
grouped: 'Grouped',
|
|
44
47
|
stacked: 'Stacked',
|
|
45
48
|
passwordVerify: 'Password verifiers',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"__symbolic":"module","version":4,"metadata":{"LOCALIZATION":{"__symbolic":"new","expression":{"__symbolic":"reference","module":"@angular/core","name":"InjectionToken","line":2,"character":32},"arguments":["fc.gui.loc"]},"Localization":{"__symbolic":"interface"},"DefaultLocalization":{"loadFailed":"Load failed.","setting":"Setting","submit":"Submit","submitting":"Submitting···","numericalValueRequired":"Numerical value can't be emtpy","invalidNumericalValue":"Numerical value is not valid","writeValueTimeout":"Write value error: Timeout","binaryType":"Binary","decimalType":"Decimal","hexadecimalType":"Hexadecimal","stringType":"String","numericalValueTooLong":"Numerical value too long","fractionDigitsMustLessThan":"Fraction digits must be less than ","canNotBeNegative":"Can not be negative","valueOutOfRange":"Numerical value is out of range","timeout":"timeout","confirmOperationPrompt":"Are you sure you want to perform this operation?","confirm":"Yes","cancel":"Cancel","characterInputRequired":"Character input can't be empty","character":"(Character)","characterOutofRange":"Character length is out of range","writeValueRange":"Write value range","loading":"Loading","unbind":"Unbind","offline":"Offline","abnormal":"Data abnormal","disable":"Disable","invalidMonitor":"Element binding monitor point is invalid","permissiontip":"You have no permission to operate.","conditionIsNotMetTip":"Operation conditions not met or variable anomalies.","chartNoData":"No Data Available","lastThirtyMinutes":"Last thirty minutes","lastOneHour":"Last one hour","lastEightHour":"Last eight hours","lastTwentyFourHours":"Last 24 hours","lastSevenDays":"Last 7 days","lastThirtyDays":"Last 30 days","lastOneYear":"Last 1 year","grouped":"Grouped","stacked":"Stacked","passwordVerify":"Password verifiers","passwordError":"Password error","password":"Password","passwordToolTip":"Password error, please re-enter","passwordRequired":"Password can't be empty","invalidVideoAddress":"Invalid video address","unconfiguredVideoAddress":"Unconfigured Video Address","weatherNotSupport":"Location not supported","weatherNotAddress":"Address not configured","weatherNotAvailable":"Address not yet available","airQualityNotSupport":"Location not supported","airQualityNotAddress":"Address not configured","airQualityNotAvailable":"Address not yet available"}}}]
|
|
1
|
+
[{"__symbolic":"module","version":4,"metadata":{"LOCALIZATION":{"__symbolic":"new","expression":{"__symbolic":"reference","module":"@angular/core","name":"InjectionToken","line":2,"character":32},"arguments":["fc.gui.loc"]},"Localization":{"__symbolic":"interface"},"DefaultLocalization":{"loadFailed":"Load failed.","setting":"Setting","submit":"Submit","submitting":"Submitting···","numericalValueRequired":"Numerical value can't be emtpy","invalidNumericalValue":"Numerical value is not valid","writeValueTimeout":"Write value error: Timeout","binaryType":"Binary","decimalType":"Decimal","hexadecimalType":"Hexadecimal","stringType":"String","numericalValueTooLong":"Numerical value too long","fractionDigitsMustLessThan":"Fraction digits must be less than ","canNotBeNegative":"Can not be negative","valueOutOfRange":"Numerical value is out of range","timeout":"timeout","confirmOperationPrompt":"Are you sure you want to perform this operation?","confirm":"Yes","cancel":"Cancel","characterInputRequired":"Character input can't be empty","character":"(Character)","characterOutofRange":"Character length is out of range","writeValueRange":"Write value range","loading":"Loading","unbind":"Unbind","offline":"Offline","abnormal":"Data abnormal","disable":"Disable","invalidMonitor":"Element binding monitor point is invalid","permissiontip":"You have no permission to operate.","conditionIsNotMetTip":"Operation conditions not met or variable anomalies.","chartNoData":"No Data Available","lastThirtyMinutes":"Last thirty minutes","lastOneHour":"Last one hour","lastEightHour":"Last eight hours","lastTwentyFourHours":"Last 24 hours","lastSevenDays":"Last 7 days","lastThirtyDays":"Last 30 days","lastOneYear":"Last 1 year","customTimeRange":"Custom","startTime":"Start Time","endTime":"End Time","grouped":"Grouped","stacked":"Stacked","passwordVerify":"Password verifiers","passwordError":"Password error","password":"Password","passwordToolTip":"Password error, please re-enter","passwordRequired":"Password can't be empty","invalidVideoAddress":"Invalid video address","unconfiguredVideoAddress":"Unconfigured Video Address","weatherNotSupport":"Location not supported","weatherNotAddress":"Address not configured","weatherNotAvailable":"Address not yet available","airQualityNotSupport":"Location not supported","airQualityNotAddress":"Address not configured","airQualityNotAvailable":"Address not yet available"}}}]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"__symbolic":"module","version":4,"metadata":{"Localization_zh_CN":{"loadFailed":"加载失败.","setting":"设置","submit":"提交","submitting":"提交中···","numericalValueRequired":"数值不能为空","invalidNumericalValue":"数值格式不正确","writeValueTimeout":"写值错误:超时","binaryType":"二进制","decimalType":"十进制","hexadecimalType":"十六进制","stringType":"字符串","numericalValueTooLong":"数值超长","fractionDigitsMustLessThan":"小数位不能超过","canNotBeNegative":"不能为负数","valueOutOfRange":"数值超出范围","timeout":"超时","confirmOperationPrompt":"是否确认要执行此操作?","confirm":"确定","cancel":"取消","characterInputRequired":"请输入至少一个字符","character":"(字符串)","characterOutofRange":"字符长度超限","writeValueRange":"写值范围","loading":"加载中","unbind":"未绑定","offline":"离线","abnormal":"数据异常","disable":"禁用","invalidMonitor":"元件绑定的监控点无效","permissiontip":"您无权限执行此操作","conditionIsNotMetTip":"操作条件不满足或逻辑控制变量异常","chartNoData":"无数据","lastThirtyMinutes":"最近30分钟","lastOneHour":"最近1小时","lastEightHour":"最近8小时","lastTwentyFourHours":"最近24小时","lastSevenDays":"最近7天","lastThirtyDays":"最近30天","lastOneYear":"最近1年","grouped":"分组","stacked":"叠加","passwordVerify":"密码校验","passwordError":"密码错误","password":"密码","passwordToolTip":"密码错误,请重新输入","passwordRequired":"密码不能为空","invalidVideoAddress":"无效的视频地址","unconfiguredVideoAddress":"未配置视频地址","weatherNotSupport":"当前位置暂不支持","weatherNotAddress":"当前设备未设置地址","weatherNotAvailable":"暂未获取设备地址","airQualityNotSupport":"当前位置暂不支持","airQualityNotAddress":"当前设备未设置地址","airQualityNotAvailable":"暂未获取设备地址"}}}]
|
|
1
|
+
[{"__symbolic":"module","version":4,"metadata":{"Localization_zh_CN":{"loadFailed":"加载失败.","setting":"设置","submit":"提交","submitting":"提交中···","numericalValueRequired":"数值不能为空","invalidNumericalValue":"数值格式不正确","writeValueTimeout":"写值错误:超时","binaryType":"二进制","decimalType":"十进制","hexadecimalType":"十六进制","stringType":"字符串","numericalValueTooLong":"数值超长","fractionDigitsMustLessThan":"小数位不能超过","canNotBeNegative":"不能为负数","valueOutOfRange":"数值超出范围","timeout":"超时","confirmOperationPrompt":"是否确认要执行此操作?","confirm":"确定","cancel":"取消","characterInputRequired":"请输入至少一个字符","character":"(字符串)","characterOutofRange":"字符长度超限","writeValueRange":"写值范围","loading":"加载中","unbind":"未绑定","offline":"离线","abnormal":"数据异常","disable":"禁用","invalidMonitor":"元件绑定的监控点无效","permissiontip":"您无权限执行此操作","conditionIsNotMetTip":"操作条件不满足或逻辑控制变量异常","chartNoData":"无数据","lastThirtyMinutes":"最近30分钟","lastOneHour":"最近1小时","lastEightHour":"最近8小时","lastTwentyFourHours":"最近24小时","lastSevenDays":"最近7天","lastThirtyDays":"最近30天","lastOneYear":"最近1年","customTimeRange":"自定义","startTime":"开始时间","endTime":"结束时间","grouped":"分组","stacked":"叠加","passwordVerify":"密码校验","passwordError":"密码错误","password":"密码","passwordToolTip":"密码错误,请重新输入","passwordRequired":"密码不能为空","invalidVideoAddress":"无效的视频地址","unconfiguredVideoAddress":"未配置视频地址","weatherNotSupport":"当前位置暂不支持","weatherNotAddress":"当前设备未设置地址","weatherNotAvailable":"暂未获取设备地址","airQualityNotSupport":"当前位置暂不支持","airQualityNotAddress":"当前设备未设置地址","airQualityNotAvailable":"暂未获取设备地址"}}}]
|
package/package.json
CHANGED
|
@@ -24,5 +24,6 @@ export const TIME_PERIOD_KEYS = {
|
|
|
24
24
|
LAST_TWENTY_FOUR_HOURS: 'HistoricalCurve.TimeFilter.Last24Hours',
|
|
25
25
|
LAST_SEVEN_DAYS: 'HistoricalCurve.TimeFilter.Last7Days',
|
|
26
26
|
LAST_THIRTY_DAYS: 'HistoricalCurve.TimeFilter.Last30Days',
|
|
27
|
-
LAST_ONE_YEAR: 'HistoricalCurve.TimeFilter.Last1Year'
|
|
27
|
+
LAST_ONE_YEAR: 'HistoricalCurve.TimeFilter.Last1Year',
|
|
28
|
+
CUSTOM: 'HistoricalCurve.TimeFilter.Custom'
|
|
28
29
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"__symbolic":"module","version":4,"metadata":{"SystemTextEntry":{"__symbolic":"interface"},"SystemTextLibraryCacheData":{"__symbolic":"interface"},"SYSTEM_TEXT_LIBRARY_TYPES":{"COMPONENT_BUILTIN":"ComponentBuiltIn"},"ALARM_TABLE_HEADER_KEYS":{"ALARM_NAME":"AlarmTable.Header.AlarmName","ALARM_MESSAGE":"AlarmTable.Header.AlarmMessage","ALARM_LEVEL":"AlarmTable.Header.AlarmLevel","TIME":"AlarmTable.Header.Time"},"TIME_PERIOD_KEYS":{"LAST_THIRTY_MINUTES":"HistoricalCurve.TimeFilter.Last30Minutes","LAST_ONE_HOUR":"HistoricalCurve.TimeFilter.Last1Hour","LAST_EIGHT_HOURS":"HistoricalCurve.TimeFilter.Last8Hours","LAST_TWENTY_FOUR_HOURS":"HistoricalCurve.TimeFilter.Last24Hours","LAST_SEVEN_DAYS":"HistoricalCurve.TimeFilter.Last7Days","LAST_THIRTY_DAYS":"HistoricalCurve.TimeFilter.Last30Days","LAST_ONE_YEAR":"HistoricalCurve.TimeFilter.Last1Year"},"SystemTextLibraryService":{"__symbolic":"interface"}}}]
|
|
1
|
+
[{"__symbolic":"module","version":4,"metadata":{"SystemTextEntry":{"__symbolic":"interface"},"SystemTextLibraryCacheData":{"__symbolic":"interface"},"SYSTEM_TEXT_LIBRARY_TYPES":{"COMPONENT_BUILTIN":"ComponentBuiltIn"},"ALARM_TABLE_HEADER_KEYS":{"ALARM_NAME":"AlarmTable.Header.AlarmName","ALARM_MESSAGE":"AlarmTable.Header.AlarmMessage","ALARM_LEVEL":"AlarmTable.Header.AlarmLevel","TIME":"AlarmTable.Header.Time"},"TIME_PERIOD_KEYS":{"LAST_THIRTY_MINUTES":"HistoricalCurve.TimeFilter.Last30Minutes","LAST_ONE_HOUR":"HistoricalCurve.TimeFilter.Last1Hour","LAST_EIGHT_HOURS":"HistoricalCurve.TimeFilter.Last8Hours","LAST_TWENTY_FOUR_HOURS":"HistoricalCurve.TimeFilter.Last24Hours","LAST_SEVEN_DAYS":"HistoricalCurve.TimeFilter.Last7Days","LAST_THIRTY_DAYS":"HistoricalCurve.TimeFilter.Last30Days","LAST_ONE_YEAR":"HistoricalCurve.TimeFilter.Last1Year","CUSTOM":"HistoricalCurve.TimeFilter.Custom"},"SystemTextLibraryService":{"__symbolic":"interface"}}}]
|