evui 3.4.154 → 3.4.155
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/dist/evui.common.js +111 -68
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +111 -68
- package/dist/evui.umd.js.map +1 -1
- package/dist/evui.umd.min.js +1 -1
- package/dist/evui.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/chart/chart.core.js +17 -8
- package/src/components/chart/element/element.bar.js +18 -17
- package/src/components/chart/element/element.tip.js +1 -1
- package/src/components/chart/plugins/plugins.scrollbar.js +57 -26
package/package.json
CHANGED
|
@@ -268,7 +268,13 @@ class EvChart {
|
|
|
268
268
|
|
|
269
269
|
this.axesRange = this.getAxesRange();
|
|
270
270
|
this.labelOffset = this.getLabelOffset();
|
|
271
|
+
|
|
271
272
|
this.labelRange = this.getAxesLabelRange();
|
|
273
|
+
|
|
274
|
+
if (this.scrollbar?.x?.use || this.scrollbar?.y?.use) {
|
|
275
|
+
this.updateScrollbarPosition();
|
|
276
|
+
}
|
|
277
|
+
|
|
272
278
|
this.axesSteps = this.calculateSteps();
|
|
273
279
|
|
|
274
280
|
this.adjustXAndYAxisWidth();
|
|
@@ -276,10 +282,6 @@ class EvChart {
|
|
|
276
282
|
this.drawAxis(hitInfo);
|
|
277
283
|
this.drawSeries(hitInfo);
|
|
278
284
|
|
|
279
|
-
if (this.scrollbar?.x?.use || this.scrollbar?.y?.use) {
|
|
280
|
-
this.updateScrollbarPosition();
|
|
281
|
-
}
|
|
282
|
-
|
|
283
285
|
this.drawTip();
|
|
284
286
|
|
|
285
287
|
if (
|
|
@@ -856,12 +858,18 @@ class EvChart {
|
|
|
856
858
|
* @param {boolean} updateData is update data
|
|
857
859
|
* @returns {undefined}
|
|
858
860
|
*/
|
|
859
|
-
updateScrollbar(updateData) {
|
|
860
|
-
|
|
861
|
+
updateScrollbar(updateData, updateByScrollbar) {
|
|
862
|
+
const isForceUpdate = updateByScrollbar || updateData;
|
|
863
|
+
const xUse = this.options.axesX?.[0]?.scrollbar?.use ?? false;
|
|
864
|
+
const yUse = this.options.axesY?.[0]?.scrollbar?.use ?? false;
|
|
865
|
+
const prevXUse = this.scrollbar?.x?.use ?? false;
|
|
866
|
+
const prevYUse = this.scrollbar?.y?.use ?? false;
|
|
867
|
+
|
|
868
|
+
if (xUse !== prevXUse || xUse || (isForceUpdate && xUse)) {
|
|
861
869
|
this.updateScrollbarInfo('x', updateData);
|
|
862
870
|
}
|
|
863
871
|
|
|
864
|
-
if (
|
|
872
|
+
if (yUse !== prevYUse || yUse || (isForceUpdate && yUse)) {
|
|
865
873
|
this.updateScrollbarInfo('y', updateData);
|
|
866
874
|
}
|
|
867
875
|
}
|
|
@@ -886,13 +894,14 @@ class EvChart {
|
|
|
886
894
|
updateData,
|
|
887
895
|
updateTooltip,
|
|
888
896
|
lightUpdate,
|
|
897
|
+
updateByScrollbar,
|
|
889
898
|
} = updateInfo;
|
|
890
899
|
|
|
891
900
|
if (!this.isInit) {
|
|
892
901
|
return;
|
|
893
902
|
}
|
|
894
903
|
|
|
895
|
-
this.updateScrollbar(updateData);
|
|
904
|
+
this.updateScrollbar(updateData, updateByScrollbar);
|
|
896
905
|
|
|
897
906
|
this.resetProps();
|
|
898
907
|
|
|
@@ -115,13 +115,12 @@ class Bar {
|
|
|
115
115
|
const startIndex = truthyNumber(minIndex) ? minIndex : 0;
|
|
116
116
|
const endIndex = truthyNumber(maxIndex) ? maxIndex : this.data.length - 1;
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
this.visibleStartIndex = startIndex;
|
|
119
|
+
|
|
119
120
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
120
|
-
const screenIndex = i - startIndex;
|
|
121
|
-
const item = this.data[i];
|
|
121
|
+
const screenIndex = i - startIndex;
|
|
122
|
+
const item = this.data[i];
|
|
122
123
|
if (item) {
|
|
123
|
-
// 스크롤 offset(minIndex)만큼 보정해서 그리기
|
|
124
|
-
|
|
125
124
|
const categoryPoint = isHorizontal
|
|
126
125
|
? ysp - (cArea * screenIndex) - cPad
|
|
127
126
|
: xsp + (cArea * screenIndex) + cPad;
|
|
@@ -214,11 +213,7 @@ class Bar {
|
|
|
214
213
|
item.yp = y; // eslint-disable-line
|
|
215
214
|
item.w = w; // eslint-disable-line
|
|
216
215
|
item.h = isHorizontal ? -h : h; // eslint-disable-line
|
|
217
|
-
item.index = i;
|
|
218
|
-
|
|
219
|
-
// 검색(hitInfo) 로직은 this.data[0..filteredCount-1] 범위만 검사하므로,
|
|
220
|
-
// 현재 화면에 그린 항목을 배열 앞쪽으로 매핑해준다.
|
|
221
|
-
this.data[screenIndex] = item;
|
|
216
|
+
item.index = i;
|
|
222
217
|
}
|
|
223
218
|
}
|
|
224
219
|
}
|
|
@@ -294,13 +289,18 @@ class Bar {
|
|
|
294
289
|
*/
|
|
295
290
|
findGraphData(offset, isHorizontal, dataIndex, useIndicatorOnLabel) {
|
|
296
291
|
if (typeof dataIndex === 'number' && this.show && useIndicatorOnLabel) {
|
|
297
|
-
const
|
|
292
|
+
const barData = this.data;
|
|
298
293
|
const item = { data: null, hit: false, color: this.color };
|
|
299
294
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
295
|
+
// dataIndex를 현재 화면에 보이는 범위로 clamp하여 stale xp/yp 참조 방지
|
|
296
|
+
const visStart = this.visibleStartIndex ?? 0;
|
|
297
|
+
const visEnd = visStart + (this.filteredCount ?? barData.length) - 1;
|
|
298
|
+
const clampedIndex = Math.max(visStart, Math.min(dataIndex, visEnd));
|
|
299
|
+
|
|
300
|
+
if (barData[clampedIndex]) {
|
|
301
|
+
item.data = barData[clampedIndex];
|
|
302
|
+
item.index = clampedIndex;
|
|
303
|
+
item.hit = this.isPointInBar(offset, barData[clampedIndex]);
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
return item;
|
|
@@ -326,10 +326,11 @@ class Bar {
|
|
|
326
326
|
const [xp, yp] = offset;
|
|
327
327
|
const item = { data: null, hit: false, color: this.color };
|
|
328
328
|
const gdata = this.data;
|
|
329
|
+
const startIdx = this.visibleStartIndex ?? 0;
|
|
329
330
|
const totalCount = this.filteredCount ?? gdata.length;
|
|
330
331
|
|
|
331
|
-
let s =
|
|
332
|
-
let e = totalCount - 1;
|
|
332
|
+
let s = startIdx;
|
|
333
|
+
let e = startIdx + totalCount - 1;
|
|
333
334
|
|
|
334
335
|
while (s <= e) {
|
|
335
336
|
const m = Math.floor((s + e) / 2);
|
|
@@ -339,7 +339,7 @@ const modules = {
|
|
|
339
339
|
let labelCount = labelAxes.labels.length;
|
|
340
340
|
if (scrollbarOpt?.use) {
|
|
341
341
|
const { range, interval, type } = scrollbarOpt;
|
|
342
|
-
const [min, max] = range;
|
|
342
|
+
const [min, max] = range ?? [];
|
|
343
343
|
if (truthyNumber(min) && truthyNumber(max)) {
|
|
344
344
|
labelCount = Math.floor((+max - +min) / interval) + 1;
|
|
345
345
|
startIndex = type === 'step' ? min : labelAxes.labels.findIndex(v => v === +min);
|
|
@@ -29,11 +29,15 @@ const module = {
|
|
|
29
29
|
scrollbarOpt[key] = merged[key];
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
if (scrollbarOpt.resetPosition) {
|
|
33
|
+
scrollbarOpt.range = axisOpt?.[0]?.range?.length ? [...axisOpt?.[0]?.range] : null;
|
|
34
|
+
this.resetScrollbarSavedPositions(dir);
|
|
35
|
+
}
|
|
33
36
|
|
|
34
37
|
if (!scrollbarOpt.isInit) {
|
|
35
38
|
scrollbarOpt.type = axisOpt?.[0]?.type;
|
|
36
39
|
scrollbarOpt.range = axisOpt?.[0]?.range?.length ? [...axisOpt?.[0]?.range] : null;
|
|
40
|
+
this.resetScrollbarSavedPositions(dir);
|
|
37
41
|
|
|
38
42
|
this.initScrollbarRange(dir);
|
|
39
43
|
this.createScrollbarLayout(dir);
|
|
@@ -104,16 +108,18 @@ const module = {
|
|
|
104
108
|
const axisOpt = dir === 'x' ? this.axesX : this.axesY;
|
|
105
109
|
const isUpdateAxesRange = !isEqual(newOpt?.[0]?.range, axisOpt?.[0]?.range);
|
|
106
110
|
if (isUpdateAxesRange || updateData) {
|
|
107
|
-
const isResetPosition = dir === 'x'
|
|
108
|
-
|
|
111
|
+
const isResetPosition = dir === 'x'
|
|
112
|
+
? this.options.axesX?.[0]?.scrollbar?.resetPosition
|
|
113
|
+
: this.options.axesY?.[0]?.scrollbar?.resetPosition;
|
|
114
|
+
|
|
115
|
+
if (isUpdateAxesRange) {
|
|
109
116
|
this.scrollbar[dir].range = newOpt?.[0]?.range?.length ? [...newOpt?.[0]?.range] : null;
|
|
110
|
-
// range가 업데이트되면 저장된 스크롤 위치를 초기화
|
|
111
|
-
delete this.scrollbar[dir].savedPosition;
|
|
112
|
-
} else if (updateData) {
|
|
113
|
-
// 데이터가 업데이트되면 저장된 픽셀 위치는 더 이상 유효하지 않으므로 삭제하여
|
|
114
|
-
// 논리적 범위에 따라 다시 계산하도록 합니다.
|
|
115
|
-
delete this.scrollbar[dir].savedPosition;
|
|
116
117
|
}
|
|
118
|
+
|
|
119
|
+
if (isResetPosition || updateData) {
|
|
120
|
+
this.resetScrollbarSavedPositions(dir);
|
|
121
|
+
}
|
|
122
|
+
|
|
117
123
|
this.initScrollbarRange(dir);
|
|
118
124
|
}
|
|
119
125
|
this.scrollbar[dir].use = !!newOpt?.[0].scrollbar?.use;
|
|
@@ -244,16 +250,29 @@ const module = {
|
|
|
244
250
|
const buttonSize = scrollbarOpt.showButton ? scrollHeight : 0;
|
|
245
251
|
const trackSize = fullSize - (buttonSize * 2);
|
|
246
252
|
|
|
247
|
-
|
|
248
|
-
let savedThumbPosition = null;
|
|
249
|
-
if (preservePosition && scrollbarOpt.savedPosition !== undefined) {
|
|
250
|
-
savedThumbPosition = scrollbarOpt.savedPosition;
|
|
251
|
-
}
|
|
253
|
+
const thumbSize = this.getScrollbarThumbSize(dir, trackSize);
|
|
252
254
|
|
|
253
|
-
|
|
255
|
+
// 비율로 저장된 위치가 있으면 새 track 크기에 맞게 복원
|
|
256
|
+
if (preservePosition && scrollbarOpt.savedPositionRatio !== undefined) {
|
|
257
|
+
const maxPosition = Math.max(0, trackSize - thumbSize.size);
|
|
258
|
+
if (scrollbarOpt.savedAtStart) {
|
|
259
|
+
thumbSize.position = 0;
|
|
260
|
+
} else if (scrollbarOpt.savedAtEnd) {
|
|
261
|
+
thumbSize.position = maxPosition;
|
|
262
|
+
} else {
|
|
263
|
+
thumbSize.position = Math.min(scrollbarOpt.savedPositionRatio * trackSize, maxPosition);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
254
266
|
|
|
255
|
-
//
|
|
256
|
-
|
|
267
|
+
// 위치를 비율 및 처음/끝 고정 여부로 저장
|
|
268
|
+
// currentMaxPosition === 0 (thumbSize >= trackSize) 인 경우 저장하지 않음
|
|
269
|
+
// → trackSize가 다시 커졌을 때 이전 savedAtEnd/savedAtStart/savedPositionRatio 상태를 유지
|
|
270
|
+
const currentMaxPosition = Math.max(0, trackSize - thumbSize.size);
|
|
271
|
+
if (currentMaxPosition > 0) {
|
|
272
|
+
scrollbarOpt.savedPositionRatio = thumbSize.position / trackSize;
|
|
273
|
+
scrollbarOpt.savedAtStart = thumbSize.position <= 0;
|
|
274
|
+
scrollbarOpt.savedAtEnd = thumbSize.position >= currentMaxPosition;
|
|
275
|
+
}
|
|
257
276
|
|
|
258
277
|
let scrollbarStyle = 'display: block;';
|
|
259
278
|
let scrollbarTrackStyle;
|
|
@@ -328,9 +347,8 @@ const module = {
|
|
|
328
347
|
* get scrollbar thumb size
|
|
329
348
|
* @param dir axis direction ('x' | 'y')
|
|
330
349
|
* @param trackSize scrollbar track size
|
|
331
|
-
* @param savedThumbPosition 기존 위치를 보존해야 하는 경우 저장된 위치
|
|
332
350
|
*/
|
|
333
|
-
getScrollbarThumbSize(dir, trackSize
|
|
351
|
+
getScrollbarThumbSize(dir, trackSize) {
|
|
334
352
|
const scrollbarOpt = this.scrollbar[dir];
|
|
335
353
|
const [min, max] = scrollbarOpt.range;
|
|
336
354
|
const axesType = scrollbarOpt.type;
|
|
@@ -374,11 +392,6 @@ const module = {
|
|
|
374
392
|
scrollbarOpt.steps = steps;
|
|
375
393
|
scrollbarOpt.interval = interval;
|
|
376
394
|
|
|
377
|
-
// 기존 위치를 보존해야 하는 경우 저장된 위치를 사용
|
|
378
|
-
if (savedThumbPosition !== null) {
|
|
379
|
-
thumbPosition = savedThumbPosition;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
395
|
return {
|
|
383
396
|
size: thumbSize,
|
|
384
397
|
position: thumbPosition,
|
|
@@ -438,16 +451,32 @@ const module = {
|
|
|
438
451
|
scrollbarOpt.range = [minValue, maxValue];
|
|
439
452
|
|
|
440
453
|
// 사용자가 스크롤할 때는 저장된 위치를 초기화
|
|
441
|
-
|
|
454
|
+
this.resetScrollbarSavedPositions(dir);
|
|
442
455
|
|
|
443
456
|
this.update({
|
|
444
457
|
updateSeries: false,
|
|
445
458
|
updateSelTip: { update: false, keepDomain: false },
|
|
446
459
|
lightUpdate: minValue > 1,
|
|
460
|
+
updateByScrollbar: true,
|
|
447
461
|
});
|
|
448
462
|
}
|
|
449
463
|
},
|
|
450
464
|
|
|
465
|
+
/**
|
|
466
|
+
* reset scrollbar saved positions
|
|
467
|
+
* @param dir axis direction ('x' | 'y')
|
|
468
|
+
*/
|
|
469
|
+
resetScrollbarSavedPositions(dir) {
|
|
470
|
+
const scrollbarOpt = this.scrollbar[dir];
|
|
471
|
+
if (!scrollbarOpt) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
delete scrollbarOpt.savedPositionRatio;
|
|
476
|
+
delete scrollbarOpt.savedAtStart;
|
|
477
|
+
delete scrollbarOpt.savedAtEnd;
|
|
478
|
+
},
|
|
479
|
+
|
|
451
480
|
/**
|
|
452
481
|
* create scroll event
|
|
453
482
|
*/
|
|
@@ -662,11 +691,13 @@ const module = {
|
|
|
662
691
|
this.scrollbar[dir].range = [movedMin, movedMax];
|
|
663
692
|
|
|
664
693
|
// 사용자가 드래그로 스크롤할 때는 저장된 위치를 초기화
|
|
665
|
-
|
|
694
|
+
this.resetScrollbarSavedPositions(dir);
|
|
666
695
|
|
|
667
696
|
this.update({
|
|
668
697
|
updateSeries: false,
|
|
669
698
|
updateSelTip: { update: false, keepDomain: false },
|
|
699
|
+
lightUpdate: movedMin > 1,
|
|
700
|
+
updateByScrollbar: true,
|
|
670
701
|
});
|
|
671
702
|
},
|
|
672
703
|
|