evui 3.4.149 → 3.4.151

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evui",
3
- "version": "3.4.149",
3
+ "version": "3.4.151",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -207,8 +207,8 @@ class EvChart {
207
207
  return result;
208
208
  };
209
209
 
210
- const adjustedRange = {
211
- x: this.axesRange?.x?.map((value, index) => {
210
+ const remeasureRange = currentRange => ({
211
+ x: currentRange?.x?.map((value, index) => {
212
212
  const axis = this.axesX[index];
213
213
  const axesSteps = this.axesSteps?.x[index];
214
214
  const notFormattedLabels = getNotFormattedLabels(axesSteps, 'x', axis);
@@ -226,7 +226,7 @@ class EvChart {
226
226
  },
227
227
  };
228
228
  }),
229
- y: this.axesRange?.y?.map((value, index) => {
229
+ y: currentRange?.y?.map((value, index) => {
230
230
  const axis = this.axesY[index];
231
231
  const axesSteps = this.axesSteps?.y[index];
232
232
  const notFormattedLabels = getNotFormattedLabels(axesSteps, 'y', axis);
@@ -244,12 +244,17 @@ class EvChart {
244
244
  },
245
245
  };
246
246
  }),
247
- };
247
+ });
248
248
 
249
- this.axesRange = adjustedRange;
250
- this.labelOffset = this.getLabelOffset(adjustedRange);
249
+ this.axesRange = remeasureRange(this.axesRange);
250
+ this.labelOffset = this.getLabelOffset(this.axesRange);
251
251
  this.labelRange = this.getAxesLabelRange();
252
252
  this.axesSteps = this.calculateSteps();
253
+
254
+ // 새로운 step 기준으로 라벨 너비를 다시 측정하여 잘림 방지
255
+ // TODO: 추후 개선 (3.4.200 이후 버전)
256
+ this.axesRange = remeasureRange(this.axesRange);
257
+ this.labelOffset = this.getLabelOffset(this.axesRange);
253
258
  }
254
259
 
255
260
  /**
@@ -96,13 +96,13 @@ const modules = {
96
96
  const key = keys[x];
97
97
  const data = datas[key];
98
98
  const storeLength = data?.length;
99
- let lastTime = 0;
100
99
 
101
- if (!this.isInit || this.updateSeries) {
100
+ // 1) init / updateSeries 시 dataset shape 보장
101
+ if (!this.isInit || this.updateSeries || !this.dataSet[key]) {
102
102
  const defaultValues = {
103
103
  dataGroup: [],
104
104
  startIndex: 0,
105
- endIndex: 0,
105
+ endIndex: null,
106
106
  length: 0,
107
107
  fromTime: 0,
108
108
  toTime: 0,
@@ -114,122 +114,126 @@ const modules = {
114
114
  };
115
115
  }
116
116
 
117
- this.dataSet[key].length = this.options.realTimeScatter.range || 300;
117
+ const dataset = this.dataSet[key];
118
+ const dataGroup = dataset.dataGroup;
119
+
120
+ // 2) range(length) 결정 + 변경 감지
121
+ const nextLength = this.options.realTimeScatter.range || 300;
122
+ const lengthChanged = dataset.length !== nextLength;
123
+ dataset.length = nextLength;
124
+ const length = dataset.length;
118
125
 
126
+ // 3) 이번 배치의 lastTime(초 단위) 계산
127
+ let lastTime = 0;
119
128
  for (let i = 0; i < storeLength; i++) {
120
129
  const item = data[i];
121
-
122
- if (lastTime < item.x) {
130
+ if (item && lastTime < item.x) {
123
131
  lastTime = item.x;
124
132
  }
125
133
  }
126
134
 
127
- lastTime = Math.floor(lastTime / 1000) * 1000;
135
+ lastTime = lastTime ? Math.floor(lastTime / 1000) * 1000 : 0;
128
136
 
129
- const dataGroupLastTime = this.dataSet[key].dataGroup.at(-1)?.data?.at(-1)?.x || Date.now();
137
+ const dataGroupLastTime = dataGroup.at(-1)?.data?.at(-1)?.x || Date.now();
138
+ const fallbackTime = Math.floor(dataGroupLastTime / 1000) * 1000;
130
139
 
131
- this.dataSet[key].toTime = lastTime
132
- || (dataGroupLastTime ? Math.floor(dataGroupLastTime / 1000) * 1000 : 0);
133
- this.dataSet[key].fromTime = this.dataSet[key].toTime - this.dataSet[key].length * 1000;
134
- this.dataSet[key].endIndex = this.dataSet[key].length - 1;
140
+ // 4) prevToTime은 덮기 전 값 (없으면 fallback)
141
+ const prevToTime = dataset.toTime || fallbackTime;
135
142
 
136
- if (
137
- (this.dataSet[key].toTime - lastTime) / 1000
138
- > this.dataSet[key].length && key === ''
139
- ) {
140
- return;
141
- }
143
+ // 5) nextToTime 결정: 새 데이터가 있으면 lastTime, 없으면 이전 유지
144
+ const nextToTime = lastTime || prevToTime;
142
145
 
143
- let gapCount = (lastTime - this.dataSet[key].toTime) / 1000;
144
- if (gapCount > 0) {
145
- this.dataSet[key].toTime = lastTime;
146
- this.dataSet[key].fromTime = lastTime
147
- - this.dataSet[key].length * 1000;
146
+ // 6) endIndex/startIndex 초기화 (최초 1회) + length 변경 시 재구성
147
+ if (dataset.endIndex == null || lengthChanged) {
148
+ dataset.startIndex = 0;
149
+ dataset.endIndex = length - 1;
150
+
151
+ // dataGroup 크기 맞추고 모두 reset
152
+ dataGroup.length = length;
153
+ for (let i = 0; i < length; i++) {
154
+ dataGroup[i] = dataGroup[i] || { data: [], max: 0, min: Infinity };
155
+ dataGroup[i].data.length = 0;
156
+ dataGroup[i].max = 0;
157
+ dataGroup[i].min = Infinity;
158
+ }
159
+
160
+ // toTime/fromTime도 새 기준으로 맞춤
161
+ dataset.toTime = nextToTime;
162
+ dataset.fromTime = dataset.toTime - length * 1000;
148
163
  }
149
164
 
150
- for (let i = 0; i < this.dataSet[key].length; i++) {
151
- const defaultValues = {
152
- data: [],
153
- max: 0,
154
- min: Infinity,
155
- };
165
+ // 7) gapCount 계산 (반드시 정수) prevToTime 기준
166
+ const rawGap = (nextToTime - prevToTime) / 1000;
167
+ const gapCount = Number.isFinite(rawGap) ? Math.max(0, Math.floor(rawGap)) : 0;
156
168
 
157
- this.dataSet[key].dataGroup[i] = {
158
- ...defaultValues,
159
- ...this.dataSet[key].dataGroup[i],
160
- };
169
+ // 8) to/from 갱신
170
+ dataset.toTime = nextToTime;
171
+ dataset.fromTime = dataset.toTime - length * 1000;
172
+
173
+ // (원래 코드에 있던 early return 유지)
174
+ if (lastTime && (dataset.toTime - lastTime) / 1000 > length && key === '') {
175
+ return;
161
176
  }
162
- if (gapCount > 0) {
163
- if (gapCount >= this.dataSet[key].length) {
164
- for (let i = 0; i < this.dataSet[key].length; i++) {
165
- this.dataSet[key].dataGroup[i].data.length = 0;
166
- this.dataSet[key].dataGroup[i].max = 0;
167
- this.dataSet[key].dataGroup[i].min = Infinity;
168
- }
169
177
 
170
- this.dataSet[key].startIndex = 0;
171
- this.dataSet[key].endIndex = this.dataSet[key].length - 1;
172
- } else {
173
- while (gapCount > 0) {
174
- if (
175
- this.dataSet[key].dataGroup[this.dataSet[key].startIndex]
176
- === null
177
- ) {
178
- this.dataSet[key].dataGroup[this.dataSet[key].startIndex] = {
179
- data: [],
180
- max: 0,
181
- min: Infinity,
182
- };
183
- } else {
184
- this.dataSet[key]
185
- .dataGroup[this.dataSet[key].startIndex].data.length = 0;
186
- this.dataSet[key]
187
- .dataGroup[this.dataSet[key].startIndex].max = 0;
188
- this.dataSet[key]
189
- .dataGroup[this.dataSet[key].startIndex].min = Infinity;
190
- }
178
+ const resetDataGroup = (group) => {
179
+ group.data.length = 0;
180
+ group.max = 0;
181
+ group.min = Infinity;
182
+ };
191
183
 
192
- ++this.dataSet[key].startIndex;
184
+ // 9) dataGroup 슬롯 확보
185
+ for (let i = 0; i < length; i++) {
186
+ if (!dataGroup[i]) {
187
+ dataGroup[i] = { data: [], max: 0, min: Infinity };
188
+ } else if (!dataGroup[i].data) {
189
+ dataGroup[i].data = [];
190
+ dataGroup[i].max = 0;
191
+ dataGroup[i].min = Infinity;
192
+ }
193
+ }
193
194
 
194
- if (this.dataSet[key].startIndex >= this.dataSet[key].length) {
195
- this.dataSet[key].startIndex = 0;
196
- }
195
+ // 10) gap만큼 전진 + 지나간 버킷 clear
196
+ if (gapCount > 0) {
197
+ if (gapCount >= length) {
198
+ for (let i = 0; i < length; i++) resetDataGroup(dataGroup[i]);
199
+ dataset.startIndex = 0;
200
+ dataset.endIndex = length - 1;
201
+ } else {
202
+ let currentStart = dataset.startIndex;
203
+ let currentEnd = dataset.endIndex;
197
204
 
198
- ++this.dataSet[key].endIndex;
199
- if (this.dataSet[key].endIndex >= this.dataSet[key].length) {
200
- this.dataSet[key].endIndex = 0;
201
- }
202
- --gapCount;
205
+ for (let i = 0; i < gapCount; i++) {
206
+ resetDataGroup(dataGroup[currentStart]);
207
+ currentStart = (currentStart + 1) % length;
208
+ currentEnd = (currentEnd + 1) % length;
203
209
  }
210
+
211
+ dataset.startIndex = currentStart;
212
+ dataset.endIndex = currentEnd;
204
213
  }
205
214
  }
206
215
 
216
+ // 11) 데이터 push (윈도우 안에 들어오는 것만)
207
217
  for (let i = 0; i < storeLength; i++) {
208
218
  const item = data[i];
209
- const xAxisTime = Math.floor(item.x / 1000) * 1000;
219
+ if (item) {
220
+ const xAxisTime = Math.floor(item.x / 1000) * 1000;
221
+
222
+ if (dataset.fromTime <= xAxisTime) {
223
+ let index = dataset.endIndex - (dataset.toTime - xAxisTime) / 1000;
224
+ if (index < 0) index = length + index;
225
+
226
+ const group = dataGroup[index];
227
+ group.data.push({
228
+ x: item.x,
229
+ y: item.y,
230
+ o: item.value ?? item.y,
231
+ color: item.color,
232
+ });
210
233
 
211
- if (this.dataSet[key].fromTime <= xAxisTime) {
212
- let index = this.dataSet[key].endIndex
213
- - (this.dataSet[key].toTime - xAxisTime) / 1000;
214
- if (index < 0) {
215
- index = this.dataSet[key].length + index;
234
+ group.max = Math.max(group.max, item.y);
235
+ group.min = Math.min(group.min, item.y);
216
236
  }
217
-
218
- this.dataSet[key].dataGroup[index].data.push({
219
- x: item.x,
220
- y: item.y,
221
- o: item.value ?? item.y,
222
- color: item.color,
223
- });
224
-
225
- this.dataSet[key].dataGroup[index].max = Math.max(
226
- this.dataSet[key].dataGroup[index].max,
227
- item.y,
228
- );
229
- this.dataSet[key].dataGroup[index].min = Math.min(
230
- this.dataSet[key].dataGroup[index].min,
231
- item.y,
232
- );
233
237
  }
234
238
  }
235
239
 
@@ -239,10 +243,10 @@ const modules = {
239
243
  minY: Infinity,
240
244
  };
241
245
 
242
- const { fromTime, toTime } = this.dataSet[key];
246
+ const { fromTime, toTime } = dataset;
243
247
 
244
- for (let i = 0; i < this.dataSet[key].length; i++) {
245
- const groupData = this.dataSet[key].dataGroup[i].data;
248
+ for (let i = 0; i < length; i++) {
249
+ const groupData = dataGroup[i].data;
246
250
  for (let j = 0; j < groupData.length; j++) {
247
251
  const item = groupData[j];
248
252
  // 현재 시간 범위 내의 데이터만 minMax 계산에 포함
@@ -267,8 +271,8 @@ const modules = {
267
271
 
268
272
  minMaxValues.maxY = Math.max(minMaxValues.maxY, tempMinMax.maxY);
269
273
  minMaxValues.minY = Math.min(minMaxValues.minY, tempMinMax.minY);
270
- minMaxValues.fromTime = this.dataSet[key].fromTime;
271
- minMaxValues.toTime = this.dataSet[key].toTime;
274
+ minMaxValues.fromTime = dataset.fromTime;
275
+ minMaxValues.toTime = dataset.toTime;
272
276
  }
273
277
 
274
278
  this.seriesInfo.charts.scatter.forEach((seriesID) => {