@refinitiv-ui/efx-grid 6.0.129 → 6.0.131

Sign up to get free protection for your applications and to get access to all the features.
@@ -258,6 +258,8 @@ declare class Grid extends EventDispatcher {
258
258
 
259
259
  public hasRic(): boolean;
260
260
 
261
+ public getRic(rowRef?: (string|number)|null): string;
262
+
261
263
  public setRowData(rowRef: Grid.RowReference|null, values: any): void;
262
264
 
263
265
  public setStaticRowData(rowRef: Grid.RowReference|null, values: any): void;
@@ -175,6 +175,14 @@ import { ElementWrapper } from "../../core/es6/grid/components/ElementWrapper.js
175
175
  * @description Fired only when a row will be removed through Grid's API and before occurring of the actual removal
176
176
  */
177
177
 
178
+ /** @event Grid#beforeUnlinked
179
+ * @description Trigger before unlinking a chain row.
180
+ * @type {Object}
181
+ * @property {RowDefinition} chain An row definition object of a chain row.
182
+ * @property {boolean} collapsed Collapsing state of a chain row.
183
+ * @property {Object} ridMap A map of constituent rics and row ids used to customize row ids.
184
+ */
185
+
178
186
  /** @private
179
187
  * @param {RowDefinition} rowDef
180
188
  * @return {Object}
@@ -609,11 +617,6 @@ Grid.prototype._topSection = true;
609
617
  * @private
610
618
  */
611
619
  Grid.prototype._focusingArgs = null;
612
- /** @type {boolean}
613
- * @private
614
- */
615
- Grid.prototype._unlinking = false;
616
-
617
620
 
618
621
  /** @public
619
622
  */
@@ -2842,13 +2845,41 @@ Grid.prototype.unlinkChain = function(rowRef) {
2842
2845
  return;
2843
2846
  }
2844
2847
 
2845
- this._unlinking = true;
2846
-
2847
2848
  let childRowDefs = rowDef.getDescendants(); // TODO: Support nested child
2848
2849
  if(childRowDefs) {
2849
- if(rowDef.isChainExpanded()) {
2850
- for(let i = 0; i < childRowDefs.length; i++) {
2851
- childRowDefs[i].toRealTimeRow();
2850
+ let len = childRowDefs.length;
2851
+ let ridMap = {};
2852
+ for(let i = 0; i < len; i++) {
2853
+ ridMap[childRowDefs[i].getRic()] = "";
2854
+ }
2855
+ let collapsed = rowDef.isChainCollapsed();
2856
+ let args = {
2857
+ chain: rowDef,
2858
+ collapsed: collapsed,
2859
+ ridMap: ridMap
2860
+ };
2861
+ this._dispatch("beforeUnlinked", args);
2862
+
2863
+ if(!collapsed) {
2864
+ let rowIdChanged = false;
2865
+ let ridPair = {};
2866
+ for(let i = 0; i < len; i++) {
2867
+ let childRowDef = childRowDefs[i];
2868
+ let mappedRowId = ridMap[childRowDef.getRic()];
2869
+ if(mappedRowId) {
2870
+ if(mappedRowId.match(RowDefinition.ROW_ID_PATTERN)) {
2871
+ console.warn("Please change the rowId format to avoid duplicated rows' id causing unexpected behavior.");
2872
+ mappedRowId = "";
2873
+ } else {
2874
+ rowIdChanged = true;
2875
+ ridPair[childRowDef.getRowId()] = mappedRowId;
2876
+ }
2877
+ }
2878
+ childRowDef.toRealTimeRow(mappedRowId);
2879
+ }
2880
+ if(rowIdChanged) {
2881
+ this._dc.replaceRowIds(ridPair);
2882
+ this._dt.replaceRowIds(ridPair);
2852
2883
  }
2853
2884
  } else {
2854
2885
  this._removeConstituentRows(childRowDefs);
@@ -2856,8 +2887,6 @@ Grid.prototype.unlinkChain = function(rowRef) {
2856
2887
  }
2857
2888
 
2858
2889
  rowDef.unlinkChain();
2859
-
2860
- this._unlinking = false;
2861
2890
  };
2862
2891
 
2863
2892
  /** Alias to setRic
@@ -3171,6 +3200,15 @@ Grid.prototype.getAllRics = function() {
3171
3200
  Grid.prototype.hasRic = function() {
3172
3201
  return this._connector.hasRic();
3173
3202
  };
3203
+ /** Returns RIC of given row reference.
3204
+ * @public
3205
+ * @param {(string|number)=} rowRef
3206
+ * @return {string}
3207
+ */
3208
+ Grid.prototype.getRic = function(rowRef) {
3209
+ let rowDef = this.getRowDefinition(rowRef);
3210
+ return rowDef.getRic();
3211
+ };
3174
3212
  /** A shorthand to set row data based on index of the specified row. It is better to keep rowDefinition object for updating data directly as row index can be changed by sorting and filtering.
3175
3213
  * @public
3176
3214
  * @param {Grid~RowReference} rowRef
@@ -102,7 +102,7 @@ declare class RowDefinition {
102
102
 
103
103
  public subscribeForUpdates(subs?: any): boolean;
104
104
 
105
- public unsubscribeForUpdates(): null;
105
+ public unsubscribeForUpdates(keepData?: boolean|null): null;
106
106
 
107
107
  public isSubscribing(): boolean;
108
108
 
@@ -48,12 +48,6 @@ const ROW_TYPES = {
48
48
  GROUP_MEMBER: "GROUP_MEMBER"
49
49
  };
50
50
 
51
- /** @type {RegExp}
52
- * @private
53
- * @const
54
- */
55
- const ROW_ID_PATTERN = /^_[^_]+_$/;
56
-
57
51
  /** @private
58
52
  * @function
59
53
  * @param {Object} obj
@@ -98,6 +92,11 @@ RowDefinition._runningId = 0;
98
92
  * @private
99
93
  */
100
94
  RowDefinition._childDataField = "CHILD_VALUES";
95
+ /** @type {RegExp}
96
+ * @private
97
+ * @const
98
+ */
99
+ RowDefinition.ROW_ID_PATTERN = /^_[^_]+_$/;
101
100
  //#region Private Members
102
101
  /** @type {string}
103
102
  * @private
@@ -253,7 +252,7 @@ RowDefinition.prototype.initialize = function(rowOptions) {
253
252
  if(!this._autoGenerated) {
254
253
  let userRowId = rowOptions["rowId"];
255
254
  if(userRowId && typeof userRowId === "string") {
256
- if(userRowId.match(ROW_ID_PATTERN)) {
255
+ if(userRowId.match(RowDefinition.ROW_ID_PATTERN)) {
257
256
  console.warn("Please change the rowId format to avoid duplicated rows' id causing unexpected behavior.");
258
257
  } else {
259
258
  this._rowId = userRowId;
@@ -904,12 +903,7 @@ RowDefinition.prototype.isRealTimeRow = function() {
904
903
  * @return {boolean} If a subscription is made, return true.
905
904
  */
906
905
  RowDefinition.prototype.subscribeForUpdates = function(subs) {
907
- if(subs) {
908
- this._subs = subs;
909
- } else {
910
- subs = this._subs;
911
- }
912
- if(!subs) {
906
+ if(!(subs || this._subs)) {
913
907
  return false;
914
908
  }
915
909
  if(!this.isRealTimeRow() && !this.getPermId()) {
@@ -917,7 +911,11 @@ RowDefinition.prototype.subscribeForUpdates = function(subs) {
917
911
  }
918
912
  // TODO: Check if the same subscription is being made.
919
913
  this.unsubscribeForUpdates();
920
-
914
+ if(subs) {
915
+ this._subs = subs;
916
+ } else {
917
+ subs = this._subs;
918
+ }
921
919
  if(this.isChain()) {
922
920
  let symbol = this._chainRic;
923
921
  if(!symbol){
@@ -941,14 +939,17 @@ RowDefinition.prototype.subscribeForUpdates = function(subs) {
941
939
  };
942
940
  /** Unsubscribe existing real-time data service. Static data is maintained
943
941
  * @public
942
+ * @param {boolean=} keepData
944
943
  * @returns {null} Always return null
945
944
  */
946
- RowDefinition.prototype.unsubscribeForUpdates = function() {
945
+ RowDefinition.prototype.unsubscribeForUpdates = function(keepData) {
947
946
  if(this.isSubscribing()) { // Only normal real-time rows and chains have both subId and subscription object
948
947
  this._subs["removeSubscription"](this._subId);
949
948
  this._subId = "";
950
- this.resetUpdates();
951
- this.resetRowData(); // Real-time data is removed while static data is maintained
949
+ if(!keepData) {
950
+ this.resetUpdates();
951
+ this.resetRowData(); // Real-time data is removed while static data is maintained
952
+ }
952
953
  }
953
954
  return null;
954
955
  };
@@ -1167,8 +1168,9 @@ RowDefinition.prototype.addConstituent = function(ric) {
1167
1168
  /** Used to convert autogenerated row to regular real-time row
1168
1169
  * @public
1169
1170
  * @ignore
1171
+ * @param {string=} userRowId
1170
1172
  */
1171
- RowDefinition.prototype.toRealTimeRow = function() {
1173
+ RowDefinition.prototype.toRealTimeRow = function(userRowId) {
1172
1174
  if(!this.isConstituent()) {
1173
1175
  return; // Only a constituent can be converted to a real-time row
1174
1176
  }
@@ -1179,7 +1181,11 @@ RowDefinition.prototype.toRealTimeRow = function() {
1179
1181
  this._parent = null;
1180
1182
  this._depthLevel = 0;
1181
1183
 
1182
- this.resetRowData(); // WARNING: existing real-time data is lost after this line
1184
+ if(userRowId) {
1185
+ this._rowId = userRowId;
1186
+ this._userId = true;
1187
+ }
1188
+
1183
1189
  this.subscribeForUpdates(subs); // Static data remains intact
1184
1190
  };
1185
1191
 
@@ -1190,7 +1196,7 @@ RowDefinition.prototype.unlinkChain = function() {
1190
1196
  return;
1191
1197
  }
1192
1198
 
1193
- this.unsubscribeForUpdates(); // Static data remains intact
1199
+ this.unsubscribeForUpdates(true); // Static data remains intact
1194
1200
 
1195
1201
  let view = this._view;
1196
1202
  if(view) {
@@ -15,7 +15,8 @@ declare namespace ColumnGroupingPlugin {
15
15
  tooltip?: (boolean|string)|null,
16
16
  children: (string)[]|null,
17
17
  alignment?: string|null,
18
- render?: ((...params: any[]) => any)|null
18
+ render?: ((...params: any[]) => any)|null,
19
+ backgroundColor?: string|null
19
20
  };
20
21
 
21
22
  }
@@ -19,6 +19,7 @@ import { cloneObject, injectCss, prettifyCss, deepEqual } from "../../tr-grid-ut
19
19
  * @property {Array.<string>} children Child member in this group
20
20
  * @property {string=} alignment eg. left, center, right
21
21
  * @property {Function=} render render function handler
22
+ * @property {string=} backgroundColor Background color of group header
22
23
  */
23
24
 
24
25
  /** @constructor
@@ -501,7 +502,8 @@ ColumnGroupingPlugin.prototype._applyGrouping = function () {
501
502
  let rowCount = this._maxDepth + 1;
502
503
  let hostCount = this._hosts.length;
503
504
  for(i = hostCount; --i >= 0;) {
504
- section = this._hosts[i].getSection("title");
505
+ let host = this._hosts[i];
506
+ section = host.getSection("title");
505
507
  if(section) {
506
508
  section.setRowCount(rowCount); // This will cause postSectionRender event to be fired
507
509
  section.clearCellSpans();
@@ -522,6 +524,9 @@ ColumnGroupingPlugin.prototype._applyGrouping = function () {
522
524
  }
523
525
  }
524
526
  }
527
+ if(host.applyColumnsBackgroundColor) {
528
+ host.applyColumnsBackgroundColor(section);
529
+ }
525
530
 
526
531
  this._spanGroupVertically(section);
527
532
  // TODO: Some calculation in here should not be done in this loop
@@ -833,8 +838,9 @@ ColumnGroupingPlugin.prototype._spanGroupHorizontally = function (titleSection)
833
838
  section.setCellColSpan(start, groupDef["onRow"], end - start + 1);
834
839
  groupDef["colIndex"] = start;
835
840
 
841
+ let cell = section.getCell(start, groupDef["onRow"]);
842
+ cell.setStyle("backgroundColor", groupDef["backgroundColor"] || "");
836
843
  if(isAllSelected){
837
- let cell = section.getCell(start, groupDef["onRow"]);
838
844
  cell.addClass("selected-group");
839
845
  }
840
846
  }
@@ -0,0 +1,39 @@
1
+
2
+
3
+ declare namespace LEDGuage {
4
+
5
+ type RangeValues = {
6
+ low?: number|null,
7
+ last?: number|null,
8
+ high?: number|null,
9
+ close?: number|null,
10
+ vwap?: number|null,
11
+ tick?: number|null
12
+ };
13
+
14
+ }
15
+
16
+ declare class LEDGuage {
17
+
18
+ constructor();
19
+
20
+ public static createElementWithText(text?: string|null): Element|null;
21
+
22
+ public setPriceGraph(priceGraph?: boolean|null): void;
23
+
24
+ public setRangeValue(rangeBarData: LEDGuage.RangeValues|null): void;
25
+
26
+ public isNoRangeValue(): boolean;
27
+
28
+ public isHighLowEqual(): boolean;
29
+
30
+ public isInvalidRangeValue(): boolean;
31
+
32
+ public getEqualRangeElement(): Element|null;
33
+
34
+ public getLEDGuageElement(): Element|null;
35
+
36
+ }
37
+
38
+ export default LEDGuage;
39
+ export { LEDGuage };
@@ -0,0 +1,261 @@
1
+
2
+
3
+ const TICK_COLOR_MAPPING = ["var(--color-scheme-neutral)", "var(--color-scheme-tickup)", "var(--color-scheme-tickdown)"]; // ["level", "up", "down"]
4
+
5
+ /** @typedef {Object} LEDGuage~RangeValues
6
+ * @description Object of range values.
7
+ * @property {number=} low Field used as minimum range
8
+ * @property {number=} last Field used as current absolute value (white bar)
9
+ * @property {number=} high Field used as maximum range
10
+ * @property {number=} close Field used as close price
11
+ * @property {number=} vwap Field used as volume weighted average price (VWAP)
12
+ * @property {number=} tick Field used as tick color
13
+ */
14
+
15
+ /**
16
+ * @constructor
17
+ */
18
+ var LEDGuage = function () {
19
+ this._elem = document.createElement("ef-led-gauge");
20
+ this._elem.neutralColor = true; // TODO: Color should set by user
21
+ };
22
+
23
+ /** @private
24
+ * @type {number=}
25
+ */
26
+ LEDGuage.prototype._low = null;
27
+ /** @private
28
+ * @type {number=}
29
+ */
30
+ LEDGuage.prototype._last = null;
31
+ /** @private
32
+ * @type {number=}
33
+ */
34
+ LEDGuage.prototype._high = null;
35
+ /** @private
36
+ * @type {number=}
37
+ */
38
+ LEDGuage.prototype._close = null;
39
+ /** @private
40
+ * @type {number=}
41
+ */
42
+ LEDGuage.prototype._vwap = null;
43
+ /** @private
44
+ * @type {number=}
45
+ */
46
+ LEDGuage.prototype._tick = null;
47
+ /** @private
48
+ * @type {boolean}
49
+ */
50
+ LEDGuage.prototype._priceGraph = false;
51
+
52
+ /** @private
53
+ * @param {LEDGuage~RangeValues} rBarOpt range
54
+ * @param {!Object} rangeBarValues
55
+ * @return {string} tooltip string value
56
+ */
57
+ LEDGuage.calculateTooltip = function (rBarOpt, rangeBarValues) {
58
+ var low = rangeBarValues.low;
59
+ var last = rangeBarValues.last;
60
+ var high = rangeBarValues.high;
61
+ var vwap = rangeBarValues.vwap;
62
+ var close = rangeBarValues.close;
63
+ var priceGraph = rBarOpt.priceGraph;
64
+
65
+ var textTooltip;
66
+ if (rBarOpt["field"]) { // WARNING: Field overwrite low last high tooltip
67
+ textTooltip = (last != null ? last : '--');
68
+ } else { // provide low,last,high case
69
+ var lowValue = low != null ? low : '--';
70
+ var lastValue = last != null ? last : '--';
71
+ var highValue = high != null ? high : '--';
72
+ if (priceGraph) {
73
+ var vwapValue = vwap != null ? vwap : '--';
74
+ var closeValue = close != null ? close : '--';
75
+ textTooltip = 'Low: ' + lowValue + " " +
76
+ 'Last: ' + lastValue + " " +
77
+ 'High: ' + highValue + " " +
78
+ 'VWAP: ' + vwapValue + " " +
79
+ 'Close: ' + closeValue + " ";
80
+ } else {
81
+ textTooltip = 'Low: ' + lowValue + " " +
82
+ 'Last: ' + lastValue + " " +
83
+ 'High: ' + highValue;
84
+ }
85
+ }
86
+ return textTooltip;
87
+ };
88
+
89
+ /** Used for convert the rangeBarOption and rowData into an object that has the properties of low, last, and high.
90
+ * @private
91
+ * @param {LEDGuage~RangeValues} rBarOpt
92
+ * @param {Object} rowData
93
+ * @return {LEDGuage~RangeValues}
94
+ */
95
+ LEDGuage.getRangeBarData = function (rBarOpt, rowData) {
96
+ var low, high, last, close, vwap, tick;
97
+ if (rBarOpt.field) {
98
+ // Doesn't defined range bar data, use field instead
99
+ low = rBarOpt.start;
100
+ last = rowData[rBarOpt.field];
101
+ high = rBarOpt.end;
102
+ } else {
103
+ // Defined range bar data
104
+ low = rowData[rBarOpt.low];
105
+ last = rowData[rBarOpt.last];
106
+ high = rowData[rBarOpt.high];
107
+ close = rowData[rBarOpt.close];
108
+ vwap = rowData[rBarOpt.vwap];
109
+ tick = rowData[rBarOpt.tick];
110
+ }
111
+ return {
112
+ low: low,
113
+ last: last,
114
+ high: high,
115
+ close: close,
116
+ vwap: vwap,
117
+ tick: tick
118
+ };
119
+ };
120
+
121
+ /** Used for tranfrom value from raw value to normalize value (Percent value between -100 to 100)
122
+ * @private
123
+ * @param {number} low
124
+ * @param {number} current
125
+ * @param {number} high
126
+ * @return {number}
127
+ */
128
+ LEDGuage.normalizeValue = function (low, current, high) {
129
+ return ((low - current) * 200) / (low - high) - 100;
130
+ };
131
+
132
+ /** Create element and set given text.
133
+ * @public
134
+ * @param {string=} text="" Set text to element
135
+ * @return {Element}
136
+ */
137
+ LEDGuage.createElementWithText = function (text) {
138
+ let span = document.createElement("span");
139
+ span.textContent = text ? text : "";
140
+ return span;
141
+ };
142
+
143
+ /** Set price graph flag to render price graph mode
144
+ * @public
145
+ * @param {boolean=} priceGraph=false
146
+ */
147
+ LEDGuage.prototype.setPriceGraph = function (priceGraph) {
148
+ this._priceGraph = priceGraph;
149
+ };
150
+
151
+ /** Set value to render LED-Guage
152
+ * @public
153
+ * @param {LEDGuage~RangeValues} rangeBarData
154
+ */
155
+ LEDGuage.prototype.setRangeValue = function (rangeBarData) {
156
+ this._low = rangeBarData.low;
157
+ this._last = rangeBarData.last;
158
+ this._high = rangeBarData.high;
159
+ this._close = rangeBarData.close;
160
+ this._vwap = rangeBarData.vwap;
161
+ this._tick = rangeBarData.tick;
162
+ };
163
+
164
+ /**
165
+ * @public
166
+ * @return {boolean}
167
+ */
168
+ LEDGuage.prototype.isNoRangeValue = function () {
169
+ return this._high == null && this._low == null && this._last == null;
170
+ };
171
+
172
+ /**
173
+ * @public
174
+ * @return {boolean}
175
+ */
176
+ LEDGuage.prototype.isHighLowEqual = function () {
177
+ return this._high === this._low && this._high === this._last;
178
+ };
179
+
180
+ /**
181
+ * @public
182
+ * @return {boolean}
183
+ */
184
+ LEDGuage.prototype.isInvalidRangeValue = function () {
185
+ return this._high == null || this._low == null || this._high < this._low;
186
+ };
187
+
188
+ /**
189
+ * @public
190
+ * @return {Element} LEDGuage Element
191
+ */
192
+ LEDGuage.prototype.getEqualRangeElement = function () {
193
+ this._elem.range = [-100, 100];
194
+ this._elem.topValue = 0;
195
+ return this._elem;
196
+ };
197
+
198
+ /**
199
+ * @public
200
+ * @return {Element} LEDGuage Element
201
+ */
202
+ LEDGuage.prototype.getLEDGuageElement = function () {
203
+ let close = this._close;
204
+ let vwap = this._vwap;
205
+ let low = this._low;
206
+ let last = this._last;
207
+ let high = this._high;
208
+ let lastNormalize = LEDGuage.normalizeValue(low, last, high);
209
+ if (this._priceGraph) {
210
+ let vwapNormalize = LEDGuage.normalizeValue(low, vwap, high);
211
+ let rangeColor;
212
+ if (close > last) {
213
+ rangeColor = "var(--color-scheme-tickdown)";
214
+ } else {
215
+ rangeColor = "var(--color-scheme-tickup)";
216
+ }
217
+
218
+ let leftSegmentValue = LEDGuage.normalizeValue(low, close, high);
219
+ let rangeValue;
220
+ if (lastNormalize < leftSegmentValue) {
221
+ rangeValue = [lastNormalize, leftSegmentValue];
222
+ } else {
223
+ rangeValue = [leftSegmentValue, lastNormalize];
224
+ }
225
+ this._elem.range = rangeValue;
226
+ this._elem.topValue = lastNormalize;
227
+ this._elem.bottomValue = vwapNormalize;
228
+ this._elem.style.setProperty("--range-color", rangeColor);
229
+ this._elem.style.setProperty("--bottom-selected-color", "var(--neutral-color)");
230
+ this._elem.style.setProperty("--top-selected-color", TICK_COLOR_MAPPING[this._tick]);
231
+ this._elem.style.setProperty("--clash-color", "var(--color-scheme-secondary)");
232
+ } else {
233
+ // applied range when the last value out of range, by set new low/high with last value
234
+ if (last < low) {
235
+ let lowNormalize = LEDGuage.normalizeValue(last, low, high);
236
+ this._elem.range = [lastNormalize, lowNormalize];
237
+ } else if (last > high) {
238
+ let highNormalize = LEDGuage.normalizeValue(low, high, last);
239
+ this._elem.range = [highNormalize, lastNormalize];
240
+ }
241
+
242
+ if (low === high) { // low equal high case (avoid normalize to infinity)
243
+ this._elem.range = [-100, 100];
244
+ lastNormalize = last < low ? -100 : 100; // topValue will be left or right
245
+ }
246
+
247
+ if (last == null) { // only last is empty (low and high should have value)
248
+ this._elem.range = [];
249
+ lastNormalize = null;
250
+ }
251
+
252
+ this._elem.topValue = lastNormalize;
253
+ }
254
+
255
+ return this._elem;
256
+ };
257
+
258
+
259
+
260
+ export default LEDGuage;
261
+ export { LEDGuage };
@@ -1,7 +1,8 @@
1
- import {Ext} from '../../tr-grid-util/es6/Ext.js';
2
- import {GridPlugin} from '../../tr-grid-util/es6/GridPlugin.js';
3
- import {ElfUtil} from '../../tr-grid-util/es6/ElfUtil.js';
1
+ import { Ext } from '../../tr-grid-util/es6/Ext.js';
2
+ import { GridPlugin } from '../../tr-grid-util/es6/GridPlugin.js';
3
+ import { ElfUtil } from '../../tr-grid-util/es6/ElfUtil.js';
4
4
  import { injectCss, prettifyCss } from "../../tr-grid-util/es6/Util.js";
5
+ import { LEDGuage } from "./LEDGuage.js";
5
6
 
6
7
  declare namespace RangeBarPlugin {
7
8