@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.
@@ -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
- // select 在 foreignObject 内部的 HTML 命名空间中,D3 的 rootElement.select('select') 无法跨命名空间查找
125
- // 改用 jQuery 查找
126
- const nativeSelectEl = this.$element && this.$element.find('select');
127
- if (nativeSelectEl && nativeSelectEl.length > 0) {
128
- const options = nativeSelectEl.find('option');
129
- options.each(function (i) {
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
- this.text = updatedTimePeriods[i].name;
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 options = selectElement.selectAll('option').data(this.timePeriods).enter().append('option');
576
- options.text(d => d.name).attr('value', d => d.key).property('selected', d => d.key === Number(this.currentTimePeriod))
577
- .style('background-color', this.model.displaySetting.axisSetting.filterBackgroudColor || fillColor);
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":71,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":72,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":73,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":74,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":75,"character":23},{"__symbolic":"reference","module":"../../config","name":"HistoryDataStore","line":76,"character":43},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"SystemTextLibraryService","line":78,"character":52},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":79,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":80,"character":38}]}],"dispose":[{"__symbolic":"method"}],"initKeyboardListener":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"updateLanguageTexts":[{"__symbolic":"method"}],"getCurrentCulture":[{"__symbolic":"method"}],"getValidTimePeriods":[{"__symbolic":"method"}],"getTimePeriodText":[{"__symbolic":"method"}],"updateTimeRange":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"reRenderElement":[{"__symbolic":"method"}],"renderElement":[{"__symbolic":"method"}],"setupTooltipAutoHide":[{"__symbolic":"method"}],"renderChart":[{"__symbolic":"method"}],"initPoint":[{"__symbolic":"method"}],"getLineChart":[{"__symbolic":"method"}],"getMultiBarWithFocusChart":[{"__symbolic":"method"}],"renderCommonProperty":[{"__symbolic":"method"}],"renderOperationArea":[{"__symbolic":"method"}],"timeFormat":[{"__symbolic":"method"}],"loadFirstPage":[{"__symbolic":"method"}],"loadNextPage":[{"__symbolic":"method"}],"loadPreviousPage":[{"__symbolic":"method"}],"loadLastPage":[{"__symbolic":"method"}],"initElementStatus":[{"__symbolic":"method"}],"updateElementStatus":[{"__symbolic":"method"}],"setStatusAsUnbound":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"setStatusAsLoadFailed":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}]}}}}]
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"}]}}}}]
@@ -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 interface Localization {
40
40
  lastSevenDays: any;
41
41
  lastThirtyDays: any;
42
42
  lastOneYear: any;
43
+ customTimeRange: any;
44
+ startTime: any;
45
+ endTime: any;
43
46
  grouped: any;
44
47
  stacked: any;
45
48
  passwordVerify: any;
@@ -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"}}}]
@@ -38,6 +38,9 @@ export const Localization_zh_CN = {
38
38
  lastSevenDays: '最近7天',
39
39
  lastThirtyDays: '最近30天',
40
40
  lastOneYear: '最近1年',
41
+ customTimeRange: '自定义',
42
+ startTime: '开始时间',
43
+ endTime: '结束时间',
41
44
  grouped: '分组',
42
45
  stacked: '叠加',
43
46
  passwordVerify: '密码校验',
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "main": "bundles/fc-gui.umd.js",
3
- "version": "3.0.0-alpha.158",
3
+ "version": "3.0.0-alpha.159",
4
4
  "module": "public_api.js",
5
5
  "typings": "public_api.d.ts",
6
6
  "license": "UNLICENSED",
@@ -47,6 +47,7 @@ export declare const TIME_PERIOD_KEYS: {
47
47
  LAST_SEVEN_DAYS: string;
48
48
  LAST_THIRTY_DAYS: string;
49
49
  LAST_ONE_YEAR: string;
50
+ CUSTOM: string;
50
51
  };
51
52
  /**
52
53
  * 系统文本库服务接口
@@ -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"}}}]