evui 3.4.203 → 3.4.205
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 +741 -225
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +741 -225
- 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/element/element.bar.js +93 -80
- package/src/components/chart/element/element.line.js +184 -61
- package/src/components/chart/plugins/plugins.interaction.js +227 -6
- package/src/components/chart/plugins/plugins.tooltip.js +73 -3
package/dist/evui.common.js
CHANGED
|
@@ -11174,7 +11174,7 @@ module.exports = exports;
|
|
|
11174
11174
|
/***/ "9224":
|
|
11175
11175
|
/***/ (function(module) {
|
|
11176
11176
|
|
|
11177
|
-
module.exports = JSON.parse("{\"a\":\"3.4.
|
|
11177
|
+
module.exports = JSON.parse("{\"a\":\"3.4.205\"}");
|
|
11178
11178
|
|
|
11179
11179
|
/***/ }),
|
|
11180
11180
|
|
|
@@ -41715,6 +41715,9 @@ var TIME_INTERVALS = {
|
|
|
41715
41715
|
|
|
41716
41716
|
|
|
41717
41717
|
|
|
41718
|
+
|
|
41719
|
+
|
|
41720
|
+
|
|
41718
41721
|
|
|
41719
41722
|
|
|
41720
41723
|
var element_line_Line = /*#__PURE__*/function () {
|
|
@@ -42104,77 +42107,166 @@ var element_line_Line = /*#__PURE__*/function () {
|
|
|
42104
42107
|
var gdata = this.data.filter(function (data) {
|
|
42105
42108
|
return !helpers_util.isNullOrUndefined(data.x);
|
|
42106
42109
|
});
|
|
42107
|
-
var SPARE_XP = 0.5;
|
|
42108
42110
|
var isLinearInterpolation = this.useLinearInterpolation();
|
|
42109
42111
|
|
|
42110
42112
|
if (gdata !== null && gdata !== void 0 && gdata.length) {
|
|
42111
42113
|
if (typeof dataIndex === 'number' && this.show) {
|
|
42112
42114
|
item.data = gdata[dataIndex];
|
|
42113
42115
|
item.index = dataIndex;
|
|
42116
|
+
|
|
42117
|
+
if (item.data) {
|
|
42118
|
+
var point = gdata[dataIndex];
|
|
42119
|
+
var yDist = Math.abs(yp - point.yp);
|
|
42120
|
+
var directHitThreshold = 15; // 직접 히트 임계값
|
|
42121
|
+
|
|
42122
|
+
if (yDist <= directHitThreshold) {
|
|
42123
|
+
item.hit = true;
|
|
42124
|
+
}
|
|
42125
|
+
}
|
|
42114
42126
|
} else if (typeof this.beforeFindItemIndex === 'number' && this.show && useSelectLabelOrItem) {
|
|
42115
42127
|
item.data = gdata[this.beforeFindItemIndex];
|
|
42116
42128
|
item.index = this.beforeFindItemIndex;
|
|
42117
42129
|
} else {
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
var
|
|
42121
|
-
|
|
42122
|
-
var
|
|
42123
|
-
|
|
42124
|
-
|
|
42125
|
-
|
|
42126
|
-
|
|
42127
|
-
|
|
42128
|
-
|
|
42129
|
-
|
|
42130
|
-
|
|
42131
|
-
|
|
42132
|
-
|
|
42133
|
-
|
|
42134
|
-
|
|
42135
|
-
|
|
42136
|
-
|
|
42137
|
-
|
|
42138
|
-
|
|
42139
|
-
|
|
42140
|
-
|
|
42141
|
-
|
|
42142
|
-
|
|
42143
|
-
|
|
42144
|
-
|
|
42145
|
-
|
|
42146
|
-
|
|
42147
|
-
|
|
42148
|
-
|
|
42149
|
-
|
|
42150
|
-
|
|
42151
|
-
|
|
42152
|
-
|
|
42153
|
-
|
|
42154
|
-
|
|
42155
|
-
|
|
42156
|
-
|
|
42157
|
-
|
|
42158
|
-
item.index = m + 1;
|
|
42159
|
-
} else {
|
|
42160
|
-
item.data = gdata[m];
|
|
42161
|
-
item.index = m;
|
|
42162
|
-
}
|
|
42130
|
+
// Axis 트리거 방식: X축 위치에서 가장 가까운 데이터 포인트 찾기
|
|
42131
|
+
var closestXDistance = Infinity;
|
|
42132
|
+
var closestIndex = -1; // null이 아닌 유효한 데이터만 필터링
|
|
42133
|
+
|
|
42134
|
+
var validData = [];
|
|
42135
|
+
gdata.forEach(function (point, idx) {
|
|
42136
|
+
if (point.xp !== null && point.yp !== null && point.o !== null) {
|
|
42137
|
+
validData.push(_objectSpread2(_objectSpread2({}, point), {}, {
|
|
42138
|
+
originalIndex: idx
|
|
42139
|
+
}));
|
|
42140
|
+
}
|
|
42141
|
+
});
|
|
42142
|
+
|
|
42143
|
+
if (validData.length === 0) {
|
|
42144
|
+
return item;
|
|
42145
|
+
} // 이진 탐색으로 가장 가까운 포인트 찾기
|
|
42146
|
+
|
|
42147
|
+
|
|
42148
|
+
var left = 0;
|
|
42149
|
+
var right = validData.length - 1;
|
|
42150
|
+
|
|
42151
|
+
while (left <= right) {
|
|
42152
|
+
var mid = Math.floor((left + right) / 2);
|
|
42153
|
+
var _point = validData[mid];
|
|
42154
|
+
var xDistance = Math.abs(xp - _point.xp);
|
|
42155
|
+
|
|
42156
|
+
if (xDistance < closestXDistance) {
|
|
42157
|
+
closestXDistance = xDistance;
|
|
42158
|
+
closestIndex = _point.originalIndex;
|
|
42159
|
+
}
|
|
42160
|
+
|
|
42161
|
+
if (_point.xp < xp) {
|
|
42162
|
+
left = mid + 1; // 다음 포인트도 확인
|
|
42163
|
+
|
|
42164
|
+
if (left < validData.length) {
|
|
42165
|
+
var nextDistance = Math.abs(xp - validData[left].xp);
|
|
42166
|
+
|
|
42167
|
+
if (nextDistance < closestXDistance) {
|
|
42168
|
+
closestXDistance = nextDistance;
|
|
42169
|
+
closestIndex = validData[left].originalIndex;
|
|
42163
42170
|
}
|
|
42164
|
-
} else {
|
|
42165
|
-
item.data = gdata[m];
|
|
42166
|
-
item.index = m;
|
|
42167
42171
|
}
|
|
42172
|
+
} else if (_point.xp > xp) {
|
|
42173
|
+
right = mid - 1; // 이전 포인트도 확인
|
|
42168
42174
|
|
|
42169
|
-
if (
|
|
42170
|
-
|
|
42171
|
-
}
|
|
42175
|
+
if (right >= 0) {
|
|
42176
|
+
var prevDistance = Math.abs(xp - validData[right].xp);
|
|
42172
42177
|
|
|
42178
|
+
if (prevDistance < closestXDistance) {
|
|
42179
|
+
closestXDistance = prevDistance;
|
|
42180
|
+
closestIndex = validData[right].originalIndex;
|
|
42181
|
+
}
|
|
42182
|
+
}
|
|
42183
|
+
} else {
|
|
42184
|
+
// 정확히 일치하는 경우
|
|
42173
42185
|
break;
|
|
42174
|
-
}
|
|
42175
|
-
|
|
42186
|
+
}
|
|
42187
|
+
} // 이진 탐색 후 주변 포인트 추가 확인 (정확도 향상)
|
|
42188
|
+
|
|
42189
|
+
|
|
42190
|
+
var foundIdx = validData.findIndex(function (p) {
|
|
42191
|
+
return p.originalIndex === closestIndex;
|
|
42192
|
+
});
|
|
42193
|
+
|
|
42194
|
+
if (foundIdx !== -1) {
|
|
42195
|
+
// 앞뒤 2개씩 추가 확인
|
|
42196
|
+
for (var i = Math.max(0, foundIdx - 2); i <= Math.min(validData.length - 1, foundIdx + 2); i++) {
|
|
42197
|
+
var _point2 = validData[i];
|
|
42198
|
+
|
|
42199
|
+
var _xDistance = Math.abs(xp - _point2.xp);
|
|
42200
|
+
|
|
42201
|
+
if (_xDistance < closestXDistance) {
|
|
42202
|
+
closestXDistance = _xDistance;
|
|
42203
|
+
closestIndex = _point2.originalIndex;
|
|
42204
|
+
}
|
|
42205
|
+
}
|
|
42206
|
+
} // 가장 가까운 포인트 설정
|
|
42207
|
+
|
|
42208
|
+
|
|
42209
|
+
if (closestIndex !== -1) {
|
|
42210
|
+
// 데이터 간격 계산 - 모든 데이터(null 포함)의 평균 간격 사용
|
|
42211
|
+
var avgInterval = 50;
|
|
42212
|
+
|
|
42213
|
+
if (gdata.length > 1) {
|
|
42214
|
+
var intervals = [];
|
|
42215
|
+
|
|
42216
|
+
for (var _i = 1; _i < gdata.length; _i++) {
|
|
42217
|
+
if (gdata[_i].xp !== null && gdata[_i - 1].xp !== null) {
|
|
42218
|
+
intervals.push(Math.abs(gdata[_i].xp - gdata[_i - 1].xp));
|
|
42219
|
+
}
|
|
42220
|
+
}
|
|
42221
|
+
|
|
42222
|
+
if (intervals.length > 0) {
|
|
42223
|
+
avgInterval = intervals.reduce(function (a, b) {
|
|
42224
|
+
return a + b;
|
|
42225
|
+
}, 0) / intervals.length;
|
|
42226
|
+
}
|
|
42227
|
+
} // 두 가지 임계값 설정
|
|
42228
|
+
|
|
42229
|
+
|
|
42230
|
+
var strictThreshold = avgInterval * 0.3; // 엄격한 임계값: 데이터 간격의 30%
|
|
42231
|
+
|
|
42232
|
+
var relaxedThreshold = avgInterval; // 느슨한 임계값: 데이터 간격 전체
|
|
42233
|
+
// 1. 먼저 엄격한 임계값으로 정확한 매치 확인
|
|
42234
|
+
|
|
42235
|
+
if (closestXDistance <= strictThreshold) {
|
|
42236
|
+
// 정확히 일치하거나 매우 가까운 데이터가 있음
|
|
42237
|
+
item.data = gdata[closestIndex];
|
|
42238
|
+
item.index = closestIndex;
|
|
42176
42239
|
} else {
|
|
42177
|
-
|
|
42240
|
+
// 2. 정확한 매치가 없을 때, 현재 X 위치 근처에 다른 유효 데이터가 있는지 확인
|
|
42241
|
+
var hasNearbyValidData = false;
|
|
42242
|
+
|
|
42243
|
+
for (var _i2 = 0; _i2 < validData.length; _i2++) {
|
|
42244
|
+
var xDist = Math.abs(xp - validData[_i2].xp);
|
|
42245
|
+
|
|
42246
|
+
if (xDist <= strictThreshold) {
|
|
42247
|
+
hasNearbyValidData = true;
|
|
42248
|
+
break;
|
|
42249
|
+
}
|
|
42250
|
+
} // 3. 근처에 다른 유효 데이터가 없을 때만 느슨한 임계값 적용
|
|
42251
|
+
|
|
42252
|
+
|
|
42253
|
+
if (!hasNearbyValidData && closestXDistance <= relaxedThreshold) {
|
|
42254
|
+
item.data = gdata[closestIndex];
|
|
42255
|
+
item.index = closestIndex;
|
|
42256
|
+
}
|
|
42257
|
+
} // Y축 거리를 확인하여 직접 히트 판정
|
|
42258
|
+
|
|
42259
|
+
|
|
42260
|
+
if (item.data) {
|
|
42261
|
+
var _point3 = gdata[closestIndex];
|
|
42262
|
+
|
|
42263
|
+
var _yDist = Math.abs(yp - _point3.yp);
|
|
42264
|
+
|
|
42265
|
+
var _directHitThreshold = 15; // 직접 히트 임계값
|
|
42266
|
+
|
|
42267
|
+
if (_yDist <= _directHitThreshold) {
|
|
42268
|
+
item.hit = true;
|
|
42269
|
+
}
|
|
42178
42270
|
}
|
|
42179
42271
|
}
|
|
42180
42272
|
}
|
|
@@ -42205,6 +42297,8 @@ var element_line_Line = /*#__PURE__*/function () {
|
|
|
42205
42297
|
}, {
|
|
42206
42298
|
key: "findApproximateData",
|
|
42207
42299
|
value: function findApproximateData(offset) {
|
|
42300
|
+
var _gdata$, _gdata$2;
|
|
42301
|
+
|
|
42208
42302
|
var xp = offset[0];
|
|
42209
42303
|
var yp = offset[1];
|
|
42210
42304
|
var item = {
|
|
@@ -42215,41 +42309,87 @@ var element_line_Line = /*#__PURE__*/function () {
|
|
|
42215
42309
|
var gdata = this.data.filter(function (data) {
|
|
42216
42310
|
return !helpers_util.isNullOrUndefined(data.x);
|
|
42217
42311
|
});
|
|
42312
|
+
|
|
42313
|
+
if (!gdata.length) {
|
|
42314
|
+
return item;
|
|
42315
|
+
} // 동적 감지 범위 계산
|
|
42316
|
+
|
|
42317
|
+
|
|
42318
|
+
var gap = gdata.length > 1 ? Math.abs(((_gdata$ = gdata[1]) === null || _gdata$ === void 0 ? void 0 : _gdata$.xp) - ((_gdata$2 = gdata[0]) === null || _gdata$2 === void 0 ? void 0 : _gdata$2.xp)) : 50;
|
|
42319
|
+
var xpInterval = Math.max(gap * 0.4, 10); // 데이터 간격의 40% 또는 최소 10px
|
|
42320
|
+
|
|
42218
42321
|
var s = 0;
|
|
42219
42322
|
var e = gdata.length - 1;
|
|
42323
|
+
var closestIndex = -1;
|
|
42324
|
+
var closestDistance = Infinity; // 이진 탐색으로 근처 데이터 찾기
|
|
42220
42325
|
|
|
42221
42326
|
while (s <= e) {
|
|
42222
42327
|
var m = Math.floor((s + e) / 2);
|
|
42223
|
-
var x = gdata[m].xp;
|
|
42224
|
-
|
|
42328
|
+
var x = gdata[m].xp; // X 좌표가 감지 범위 내에 있는 경우
|
|
42329
|
+
|
|
42330
|
+
if (x - xpInterval <= xp && xp <= x + xpInterval) {
|
|
42331
|
+
// 중간점 주변 데이터들과 거리 비교
|
|
42332
|
+
var checkStart = Math.max(0, m - 2);
|
|
42333
|
+
var checkEnd = Math.min(gdata.length - 1, m + 2);
|
|
42225
42334
|
|
|
42226
|
-
|
|
42227
|
-
|
|
42228
|
-
|
|
42335
|
+
for (var i = checkStart; i <= checkEnd; i++) {
|
|
42336
|
+
if (gdata[i].xp !== null && gdata[i].yp !== null) {
|
|
42337
|
+
var distance = Math.sqrt(Math.pow(xp - gdata[i].xp, 2) + Math.pow(yp - gdata[i].yp, 2));
|
|
42229
42338
|
|
|
42230
|
-
|
|
42231
|
-
|
|
42339
|
+
if (distance < closestDistance) {
|
|
42340
|
+
closestDistance = distance;
|
|
42341
|
+
closestIndex = i;
|
|
42342
|
+
}
|
|
42343
|
+
}
|
|
42344
|
+
}
|
|
42345
|
+
|
|
42346
|
+
if (closestIndex !== -1) {
|
|
42347
|
+
item.data = gdata[closestIndex];
|
|
42348
|
+
item.index = closestIndex; // 매우 가까운 경우 hit으로 표시
|
|
42349
|
+
|
|
42350
|
+
if (closestDistance < 5) {
|
|
42351
|
+
item.hit = true;
|
|
42352
|
+
}
|
|
42232
42353
|
}
|
|
42233
42354
|
|
|
42234
42355
|
return item;
|
|
42235
|
-
} else if (x +
|
|
42356
|
+
} else if (x + xpInterval < xp) {
|
|
42357
|
+
// 마우스가 오른쪽에 있는 경우
|
|
42236
42358
|
if (m < e && xp < gdata[m + 1].xp) {
|
|
42237
42359
|
var curr = Math.abs(gdata[m].xp - xp);
|
|
42238
42360
|
var next = Math.abs(gdata[m + 1].xp - xp);
|
|
42239
42361
|
item.data = curr > next ? gdata[m + 1] : gdata[m];
|
|
42240
|
-
item.index = curr > next ? m + 1 : m;
|
|
42362
|
+
item.index = curr > next ? m + 1 : m; // Y 거리도 확인하여 hit 판정
|
|
42363
|
+
|
|
42364
|
+
var selectedPoint = item.data;
|
|
42365
|
+
var yDist = Math.abs(yp - selectedPoint.yp);
|
|
42366
|
+
|
|
42367
|
+
if (yDist < 10) {
|
|
42368
|
+
item.hit = true;
|
|
42369
|
+
}
|
|
42370
|
+
|
|
42241
42371
|
return item;
|
|
42242
42372
|
}
|
|
42243
42373
|
|
|
42244
42374
|
s = m + 1;
|
|
42245
42375
|
} else {
|
|
42376
|
+
// 마우스가 왼쪽에 있는 경우
|
|
42246
42377
|
if (m > 0 && xp > gdata[m - 1].xp) {
|
|
42247
42378
|
var prev = Math.abs(gdata[m - 1].xp - xp);
|
|
42248
42379
|
|
|
42249
42380
|
var _curr = Math.abs(gdata[m].xp - xp);
|
|
42250
42381
|
|
|
42251
42382
|
item.data = prev > _curr ? gdata[m] : gdata[m - 1];
|
|
42252
|
-
item.index = prev > _curr ? m : m - 1;
|
|
42383
|
+
item.index = prev > _curr ? m : m - 1; // Y 거리도 확인하여 hit 판정
|
|
42384
|
+
|
|
42385
|
+
var _selectedPoint = item.data;
|
|
42386
|
+
|
|
42387
|
+
var _yDist2 = Math.abs(yp - _selectedPoint.yp);
|
|
42388
|
+
|
|
42389
|
+
if (_yDist2 < 10) {
|
|
42390
|
+
item.hit = true;
|
|
42391
|
+
}
|
|
42392
|
+
|
|
42253
42393
|
return item;
|
|
42254
42394
|
}
|
|
42255
42395
|
|
|
@@ -42700,6 +42840,7 @@ var element_scatter_Scatter = /*#__PURE__*/function () {
|
|
|
42700
42840
|
|
|
42701
42841
|
|
|
42702
42842
|
|
|
42843
|
+
|
|
42703
42844
|
var element_bar_Bar = /*#__PURE__*/function () {
|
|
42704
42845
|
function Bar(sId, opt, sIdx, isHorizontal) {
|
|
42705
42846
|
var _this = this;
|
|
@@ -42762,18 +42903,11 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
42762
42903
|
var minmaxX = axesSteps.x[this.xAxisIndex];
|
|
42763
42904
|
var minmaxY = axesSteps.y[this.yAxisIndex];
|
|
42764
42905
|
var totalCount = this.data.length;
|
|
42765
|
-
var minIndex;
|
|
42766
|
-
var maxIndex;
|
|
42767
42906
|
|
|
42768
|
-
|
|
42769
|
-
|
|
42770
|
-
|
|
42771
|
-
|
|
42772
|
-
} else {
|
|
42773
|
-
var _ref2 = [minmaxX.minIndex, minmaxX.maxIndex];
|
|
42774
|
-
minIndex = _ref2[0];
|
|
42775
|
-
maxIndex = _ref2[1];
|
|
42776
|
-
} // minIndex, maxIndex가 유효하면 실제 그릴 데이터 개수로 보정
|
|
42907
|
+
var _ref = isHorizontal ? [minmaxY.minIndex, minmaxY.maxIndex] : [minmaxX.minIndex, minmaxX.maxIndex],
|
|
42908
|
+
_ref2 = _slicedToArray(_ref, 2),
|
|
42909
|
+
minIndex = _ref2[0],
|
|
42910
|
+
maxIndex = _ref2[1]; // minIndex, maxIndex가 유효하면 실제 그릴 데이터 개수로 보정
|
|
42777
42911
|
|
|
42778
42912
|
|
|
42779
42913
|
if (truthyNumber(minIndex) && truthyNumber(maxIndex)) {
|
|
@@ -42804,20 +42938,7 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
42804
42938
|
var h;
|
|
42805
42939
|
bArea = cArea > cPad * 2 ? cArea - cPad * 2 : cArea;
|
|
42806
42940
|
bArea = this.isExistGrp ? bArea : bArea / showSeriesCount;
|
|
42807
|
-
|
|
42808
|
-
var getSize = function getSize() {
|
|
42809
|
-
if (typeof thickness === 'string' && /[0-9]+px/.test(thickness)) {
|
|
42810
|
-
return Math.min(bArea, Number(thickness.replace('px', '')));
|
|
42811
|
-
}
|
|
42812
|
-
|
|
42813
|
-
if (typeof thickness === 'number' && thickness <= 1 && thickness >= 0) {
|
|
42814
|
-
return Math.ceil(bArea * thickness);
|
|
42815
|
-
}
|
|
42816
|
-
|
|
42817
|
-
return bArea;
|
|
42818
|
-
};
|
|
42819
|
-
|
|
42820
|
-
var size = getSize();
|
|
42941
|
+
var size = this.calculateBarSize(thickness, bArea);
|
|
42821
42942
|
w = isHorizontal ? null : size;
|
|
42822
42943
|
h = isHorizontal ? size : null;
|
|
42823
42944
|
var bPad = isHorizontal ? (bArea - h) / 2 : (bArea - w) / 2;
|
|
@@ -42845,14 +42966,7 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
42845
42966
|
var _param$selectLabel, _param$selectItem, _param$selectLabel$se, _param$selectLabel2, _param$selectLabel2$s, _param$selectItem$sel, _param$selectItem2;
|
|
42846
42967
|
|
|
42847
42968
|
// 스크롤 offset(minIndex)만큼 보정해서 그리기
|
|
42848
|
-
var categoryPoint =
|
|
42849
|
-
|
|
42850
|
-
if (isHorizontal) {
|
|
42851
|
-
categoryPoint = ysp - cArea * screenIndex - cPad;
|
|
42852
|
-
} else {
|
|
42853
|
-
categoryPoint = xsp + cArea * screenIndex + cPad;
|
|
42854
|
-
} // 기본 위치 설정
|
|
42855
|
-
|
|
42969
|
+
var categoryPoint = isHorizontal ? ysp - cArea * screenIndex - cPad : xsp + cArea * screenIndex + cPad; // 기본 위치 설정
|
|
42856
42970
|
|
|
42857
42971
|
if (isHorizontal) {
|
|
42858
42972
|
x = xsp;
|
|
@@ -43038,13 +43152,32 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43038
43152
|
* Find graph item
|
|
43039
43153
|
* @param {array} offset mouse position
|
|
43040
43154
|
* @param {boolean} isHorizontal determines if a horizontal option's value
|
|
43155
|
+
* @param {number} dataIndex selected label data index
|
|
43156
|
+
* @param {boolean} useIndicatorOnLabel
|
|
43041
43157
|
*
|
|
43042
43158
|
* @returns {object} graph item
|
|
43043
43159
|
*/
|
|
43044
43160
|
|
|
43045
43161
|
}, {
|
|
43046
43162
|
key: "findGraphData",
|
|
43047
|
-
value: function findGraphData(offset, isHorizontal) {
|
|
43163
|
+
value: function findGraphData(offset, isHorizontal, dataIndex, useIndicatorOnLabel) {
|
|
43164
|
+
if (typeof dataIndex === 'number' && this.show && useIndicatorOnLabel) {
|
|
43165
|
+
var gdata = this.data;
|
|
43166
|
+
var item = {
|
|
43167
|
+
data: null,
|
|
43168
|
+
hit: false,
|
|
43169
|
+
color: this.color
|
|
43170
|
+
};
|
|
43171
|
+
|
|
43172
|
+
if (gdata[dataIndex]) {
|
|
43173
|
+
item.data = gdata[dataIndex];
|
|
43174
|
+
item.index = dataIndex;
|
|
43175
|
+
item.hit = this.isPointInBar(offset, gdata[dataIndex]);
|
|
43176
|
+
}
|
|
43177
|
+
|
|
43178
|
+
return item;
|
|
43179
|
+
}
|
|
43180
|
+
|
|
43048
43181
|
return isHorizontal ? this.findGraphRangeCount(offset) : this.findGraphRange(offset);
|
|
43049
43182
|
}
|
|
43050
43183
|
/**
|
|
@@ -43054,13 +43187,23 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43054
43187
|
* @returns {object} graph item
|
|
43055
43188
|
*/
|
|
43056
43189
|
|
|
43190
|
+
/**
|
|
43191
|
+
* Binary search for finding graph item
|
|
43192
|
+
* @private
|
|
43193
|
+
* @param {array} offset - mouse position
|
|
43194
|
+
* @param {boolean} isHorizontal - search orientation
|
|
43195
|
+
* @returns {object} graph item
|
|
43196
|
+
*/
|
|
43197
|
+
|
|
43057
43198
|
}, {
|
|
43058
|
-
key: "
|
|
43059
|
-
value: function
|
|
43199
|
+
key: "binarySearchBar",
|
|
43200
|
+
value: function binarySearchBar(offset, isHorizontal) {
|
|
43060
43201
|
var _this$filteredCount;
|
|
43061
43202
|
|
|
43062
|
-
var
|
|
43063
|
-
|
|
43203
|
+
var _offset = _slicedToArray(offset, 2),
|
|
43204
|
+
xp = _offset[0],
|
|
43205
|
+
yp = _offset[1];
|
|
43206
|
+
|
|
43064
43207
|
var item = {
|
|
43065
43208
|
data: null,
|
|
43066
43209
|
hit: false,
|
|
@@ -43073,21 +43216,25 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43073
43216
|
|
|
43074
43217
|
while (s <= e) {
|
|
43075
43218
|
var m = Math.floor((s + e) / 2);
|
|
43076
|
-
var
|
|
43077
|
-
var
|
|
43078
|
-
|
|
43079
|
-
|
|
43080
|
-
|
|
43081
|
-
|
|
43082
|
-
|
|
43083
|
-
|
|
43219
|
+
var barData = gdata[m];
|
|
43220
|
+
var sx = barData.xp,
|
|
43221
|
+
sy = barData.yp,
|
|
43222
|
+
w = barData.w,
|
|
43223
|
+
h = barData.h;
|
|
43224
|
+
var ex = sx + w;
|
|
43225
|
+
var ey = sy + h;
|
|
43226
|
+
var inRange = isHorizontal ? ey <= yp && yp <= sy : sx <= xp && xp <= ex;
|
|
43227
|
+
|
|
43228
|
+
if (inRange) {
|
|
43229
|
+
item.data = barData;
|
|
43230
|
+
item.index = barData.index;
|
|
43231
|
+
item.hit = this.isPointInBar(offset, barData);
|
|
43232
|
+
return item;
|
|
43233
|
+
}
|
|
43084
43234
|
|
|
43085
|
-
|
|
43086
|
-
item.hit = true;
|
|
43087
|
-
}
|
|
43235
|
+
var shouldGoRight = isHorizontal ? !(ey < yp) : sx + 4 < xp;
|
|
43088
43236
|
|
|
43089
|
-
|
|
43090
|
-
} else if (sx + 4 < xp) {
|
|
43237
|
+
if (shouldGoRight) {
|
|
43091
43238
|
s = m + 1;
|
|
43092
43239
|
} else {
|
|
43093
43240
|
e = m - 1;
|
|
@@ -43096,6 +43243,11 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43096
43243
|
|
|
43097
43244
|
return item;
|
|
43098
43245
|
}
|
|
43246
|
+
}, {
|
|
43247
|
+
key: "findGraphRange",
|
|
43248
|
+
value: function findGraphRange(offset) {
|
|
43249
|
+
return this.binarySearchBar(offset, false);
|
|
43250
|
+
}
|
|
43099
43251
|
/**
|
|
43100
43252
|
* Find graph item (horizontal)
|
|
43101
43253
|
* @param {array} offset mouse position
|
|
@@ -43106,44 +43258,7 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43106
43258
|
}, {
|
|
43107
43259
|
key: "findGraphRangeCount",
|
|
43108
43260
|
value: function findGraphRangeCount(offset) {
|
|
43109
|
-
|
|
43110
|
-
|
|
43111
|
-
var xp = offset[0];
|
|
43112
|
-
var yp = offset[1];
|
|
43113
|
-
var item = {
|
|
43114
|
-
data: null,
|
|
43115
|
-
hit: false,
|
|
43116
|
-
color: this.color
|
|
43117
|
-
};
|
|
43118
|
-
var gdata = this.data;
|
|
43119
|
-
var totalCount = (_this$filteredCount2 = this.filteredCount) !== null && _this$filteredCount2 !== void 0 ? _this$filteredCount2 : gdata.length;
|
|
43120
|
-
var s = 0;
|
|
43121
|
-
var e = totalCount - 1;
|
|
43122
|
-
|
|
43123
|
-
while (s <= e) {
|
|
43124
|
-
var m = Math.floor((s + e) / 2);
|
|
43125
|
-
var sx = gdata[m].xp;
|
|
43126
|
-
var sy = gdata[m].yp;
|
|
43127
|
-
var ex = sx + gdata[m].w;
|
|
43128
|
-
var ey = sy + gdata[m].h;
|
|
43129
|
-
|
|
43130
|
-
if (ey <= yp && yp <= sy) {
|
|
43131
|
-
item.data = gdata[m];
|
|
43132
|
-
item.index = gdata[m].index; // 원본 데이터 인덱스 사용
|
|
43133
|
-
|
|
43134
|
-
if (sx <= xp && xp <= ex) {
|
|
43135
|
-
item.hit = true;
|
|
43136
|
-
}
|
|
43137
|
-
|
|
43138
|
-
return item;
|
|
43139
|
-
} else if (ey < yp) {
|
|
43140
|
-
e = m - 1;
|
|
43141
|
-
} else {
|
|
43142
|
-
s = m + 1;
|
|
43143
|
-
}
|
|
43144
|
-
}
|
|
43145
|
-
|
|
43146
|
-
return item;
|
|
43261
|
+
return this.binarySearchBar(offset, true);
|
|
43147
43262
|
}
|
|
43148
43263
|
/**
|
|
43149
43264
|
* Draw value label if series 'use' of showValue option is true
|
|
@@ -43307,14 +43422,36 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43307
43422
|
|
|
43308
43423
|
ctx.restore();
|
|
43309
43424
|
}
|
|
43425
|
+
/**
|
|
43426
|
+
* Calculate bar size based on thickness
|
|
43427
|
+
* @private
|
|
43428
|
+
* @param {string|number} thickness - thickness value
|
|
43429
|
+
* @param {number} bArea - available bar area
|
|
43430
|
+
* @returns {number} calculated size
|
|
43431
|
+
*/
|
|
43432
|
+
|
|
43433
|
+
}, {
|
|
43434
|
+
key: "calculateBarSize",
|
|
43435
|
+
value: function calculateBarSize(thickness, bArea) {
|
|
43436
|
+
if (typeof thickness === 'string' && /[0-9]+px/.test(thickness)) {
|
|
43437
|
+
return Math.min(bArea, Number(thickness.replace('px', '')));
|
|
43438
|
+
}
|
|
43439
|
+
|
|
43440
|
+
if (typeof thickness === 'number' && thickness <= 1 && thickness >= 0) {
|
|
43441
|
+
return Math.ceil(bArea * thickness);
|
|
43442
|
+
}
|
|
43443
|
+
|
|
43444
|
+
return bArea;
|
|
43445
|
+
}
|
|
43310
43446
|
}, {
|
|
43311
43447
|
key: "drawBar",
|
|
43312
43448
|
value: function drawBar(_ref6) {
|
|
43313
43449
|
var ctx = _ref6.ctx,
|
|
43314
43450
|
positions = _ref6.positions;
|
|
43315
|
-
var isHorizontal = this.isHorizontal
|
|
43451
|
+
var isHorizontal = this.isHorizontal,
|
|
43452
|
+
borderRadius = this.borderRadius;
|
|
43316
43453
|
var isStackBar = ('stackIndex' in this);
|
|
43317
|
-
var isBorderRadius =
|
|
43454
|
+
var isBorderRadius = borderRadius && borderRadius > 0;
|
|
43318
43455
|
var x = positions.x,
|
|
43319
43456
|
y = positions.y,
|
|
43320
43457
|
w = positions.w;
|
|
@@ -43338,17 +43475,40 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43338
43475
|
|
|
43339
43476
|
ctx.restore();
|
|
43340
43477
|
}
|
|
43478
|
+
/**
|
|
43479
|
+
* Check if point is within bar boundaries
|
|
43480
|
+
* @param {array} offset - [x, y] mouse position
|
|
43481
|
+
* @param {object} barData - bar data object with xp, yp, w, h properties
|
|
43482
|
+
* @returns {boolean} true if point is within bar
|
|
43483
|
+
*/
|
|
43484
|
+
|
|
43485
|
+
}, {
|
|
43486
|
+
key: "isPointInBar",
|
|
43487
|
+
value: function isPointInBar(offset, barData) {
|
|
43488
|
+
var _offset2 = _slicedToArray(offset, 2),
|
|
43489
|
+
xp = _offset2[0],
|
|
43490
|
+
yp = _offset2[1];
|
|
43491
|
+
|
|
43492
|
+
var sx = barData.xp,
|
|
43493
|
+
sy = barData.yp,
|
|
43494
|
+
w = barData.w,
|
|
43495
|
+
h = barData.h;
|
|
43496
|
+
var ex = sx + w;
|
|
43497
|
+
var ey = sy + h;
|
|
43498
|
+
return sx <= xp && xp <= ex && ey <= yp && yp <= sy;
|
|
43499
|
+
}
|
|
43341
43500
|
}, {
|
|
43342
43501
|
key: "drawRoundedRect",
|
|
43343
43502
|
value: function drawRoundedRect(ctx, positions) {
|
|
43344
|
-
var chartRect = this.chartRect
|
|
43345
|
-
|
|
43346
|
-
|
|
43503
|
+
var chartRect = this.chartRect,
|
|
43504
|
+
labelOffset = this.labelOffset,
|
|
43505
|
+
isHorizontal = this.isHorizontal,
|
|
43506
|
+
borderRadius = this.borderRadius;
|
|
43347
43507
|
var x = positions.x,
|
|
43348
43508
|
y = positions.y;
|
|
43349
43509
|
var w = positions.w,
|
|
43350
43510
|
h = positions.h;
|
|
43351
|
-
var r =
|
|
43511
|
+
var r = borderRadius;
|
|
43352
43512
|
var squarePath = new Path2D();
|
|
43353
43513
|
squarePath.rect(chartRect.x1 + labelOffset.left, chartRect.y1, chartRect.chartWidth - labelOffset.right, chartRect.chartHeight - labelOffset.bottom);
|
|
43354
43514
|
ctx.clip(squarePath);
|
|
@@ -50695,7 +50855,7 @@ function toFinite(value) {
|
|
|
50695
50855
|
* _.inRange(-3, -2, -6);
|
|
50696
50856
|
* // => true
|
|
50697
50857
|
*/
|
|
50698
|
-
function
|
|
50858
|
+
function inRange_inRange(number, start, end) {
|
|
50699
50859
|
start = lodash_es_toFinite(start);
|
|
50700
50860
|
if (end === undefined) {
|
|
50701
50861
|
end = start;
|
|
@@ -50707,7 +50867,7 @@ function inRange(number, start, end) {
|
|
|
50707
50867
|
return _baseInRange(number, start, end);
|
|
50708
50868
|
}
|
|
50709
50869
|
|
|
50710
|
-
/* harmony default export */ var lodash_es_inRange = (
|
|
50870
|
+
/* harmony default export */ var lodash_es_inRange = (inRange_inRange);
|
|
50711
50871
|
|
|
50712
50872
|
// CONCATENATED MODULE: ./src/components/chart/plugins/plugins.interaction.js
|
|
50713
50873
|
|
|
@@ -50729,6 +50889,8 @@ function inRange(number, start, end) {
|
|
|
50729
50889
|
|
|
50730
50890
|
|
|
50731
50891
|
|
|
50892
|
+
|
|
50893
|
+
|
|
50732
50894
|
|
|
50733
50895
|
|
|
50734
50896
|
|
|
@@ -50814,6 +50976,29 @@ var plugins_interaction_modules = {
|
|
|
50814
50976
|
_this.drawTooltip(hitInfo, _this.tooltipCtx);
|
|
50815
50977
|
}
|
|
50816
50978
|
}
|
|
50979
|
+
} // tooltip이 표시될 때 indicator를 해당 라벨 위치로 이동 (line 차트이거나 line series가 포함된 경우)
|
|
50980
|
+
|
|
50981
|
+
|
|
50982
|
+
var hasLineSeries = Object.values(_this.seriesList || {}).some(function (series) {
|
|
50983
|
+
return series.type === 'line';
|
|
50984
|
+
});
|
|
50985
|
+
|
|
50986
|
+
if (tooltip.use && (type === 'line' || hasLineSeries)) {
|
|
50987
|
+
// indicator를 그리고 실제 위치한 라벨 정보를 받음
|
|
50988
|
+
var indicatorInfo = _this.drawIndicatorForTooltip(hitInfo, indicator.color); // 실제 indicator가 위치한 라벨 값을 동기화에 사용
|
|
50989
|
+
|
|
50990
|
+
|
|
50991
|
+
var actualLabelValue = indicatorInfo === null || indicatorInfo === void 0 ? void 0 : indicatorInfo.labelValue;
|
|
50992
|
+
|
|
50993
|
+
var label = _this.getTimeLabel(offset);
|
|
50994
|
+
|
|
50995
|
+
args.hoveredLabel = {
|
|
50996
|
+
horizontal: _this.options.horizontal,
|
|
50997
|
+
label: label,
|
|
50998
|
+
mousePosition: [e.clientX, e.clientY],
|
|
50999
|
+
dataLabel: actualLabelValue,
|
|
51000
|
+
isTooltipBased: true
|
|
51001
|
+
};
|
|
50817
51002
|
}
|
|
50818
51003
|
} else if (tooltip.use && _this.isInitTooltip) {
|
|
50819
51004
|
if (typeof (tooltip === null || tooltip === void 0 ? void 0 : tooltip.returnValue) === 'function') {
|
|
@@ -50825,19 +51010,28 @@ var plugins_interaction_modules = {
|
|
|
50825
51010
|
|
|
50826
51011
|
if (_this.dragInfoBackup) {
|
|
50827
51012
|
_this.drawSelectionArea(_this.dragInfoBackup);
|
|
50828
|
-
}
|
|
51013
|
+
} // tooltip 기반 indicator가 아직 설정되지 않은 경우에만 일반 indicator 처리
|
|
51014
|
+
|
|
50829
51015
|
|
|
50830
|
-
if (
|
|
50831
|
-
|
|
51016
|
+
if (!args.hoveredLabel && type !== 'pie' && type !== 'scatter' && type !== 'heatMap') {
|
|
51017
|
+
// line 차트가 아니고 line series가 없거나, tooltip이 없을 때는 일반 indicator 표시
|
|
51018
|
+
var _hasLineSeries = Object.values(_this.seriesList || {}).some(function (series) {
|
|
51019
|
+
return series.type === 'line';
|
|
51020
|
+
});
|
|
51021
|
+
|
|
51022
|
+
if (type !== 'line' && !_hasLineSeries || !tooltip.use || !Object.keys(hitInfo.items).length) {
|
|
51023
|
+
_this.drawIndicator(offset, indicator.color);
|
|
51024
|
+
}
|
|
50832
51025
|
|
|
50833
|
-
var
|
|
51026
|
+
var _label = _this.getTimeLabel(offset);
|
|
50834
51027
|
|
|
50835
51028
|
args.hoveredLabel = {
|
|
50836
51029
|
horizontal: _this.options.horizontal,
|
|
50837
|
-
label:
|
|
50838
|
-
mousePosition: [e.clientX, e.clientY]
|
|
51030
|
+
label: _label,
|
|
51031
|
+
mousePosition: [e.clientX, e.clientY],
|
|
51032
|
+
isTooltipBased: false
|
|
50839
51033
|
};
|
|
50840
|
-
} else {
|
|
51034
|
+
} else if (!args.hoveredLabel) {
|
|
50841
51035
|
args.hoveredLabel = {
|
|
50842
51036
|
label: ''
|
|
50843
51037
|
};
|
|
@@ -51702,6 +51896,8 @@ var plugins_interaction_modules = {
|
|
|
51702
51896
|
* @returns {object} hit item information
|
|
51703
51897
|
*/
|
|
51704
51898
|
findHitItem: function findHitItem(offset) {
|
|
51899
|
+
var _this4 = this;
|
|
51900
|
+
|
|
51705
51901
|
var sIds = Object.keys(this.seriesList);
|
|
51706
51902
|
var items = {};
|
|
51707
51903
|
var isHorizontal = !!this.options.horizontal;
|
|
@@ -51711,66 +51907,153 @@ var plugins_interaction_modules = {
|
|
|
51711
51907
|
var maxsw = 0;
|
|
51712
51908
|
var maxv = '';
|
|
51713
51909
|
var maxg = null;
|
|
51714
|
-
var maxSID = null;
|
|
51910
|
+
var maxSID = null; // 파이 차트는 특별한 처리가 필요
|
|
51715
51911
|
|
|
51716
|
-
|
|
51717
|
-
var
|
|
51718
|
-
|
|
51912
|
+
if (this.options.type === 'pie') {
|
|
51913
|
+
for (var ix = 0; ix < sIds.length; ix++) {
|
|
51914
|
+
var sId = sIds[ix];
|
|
51915
|
+
var series = this.seriesList[sId];
|
|
51916
|
+
|
|
51917
|
+
if (series.findGraphData && series.show) {
|
|
51918
|
+
var item = series.findGraphData(offset);
|
|
51919
|
+
|
|
51920
|
+
if (item !== null && item !== void 0 && item.data && item.hit) {
|
|
51921
|
+
var gdata = item.data.o;
|
|
51922
|
+
|
|
51923
|
+
if (gdata !== null && gdata !== undefined) {
|
|
51924
|
+
var formattedSeriesName = this.getFormattedTooltipLabel({
|
|
51925
|
+
dataId: series.id,
|
|
51926
|
+
seriesId: sId,
|
|
51927
|
+
seriesName: series.name,
|
|
51928
|
+
itemData: item.data
|
|
51929
|
+
});
|
|
51930
|
+
var sw = ctx ? ctx.measureText(formattedSeriesName).width : 1;
|
|
51931
|
+
item.id = series.id;
|
|
51932
|
+
item.name = formattedSeriesName;
|
|
51933
|
+
item.axis = {
|
|
51934
|
+
x: 0,
|
|
51935
|
+
y: 0
|
|
51936
|
+
};
|
|
51937
|
+
items[sId] = item;
|
|
51938
|
+
var formattedTxt = this.getFormattedTooltipValue({
|
|
51939
|
+
dataId: series.id,
|
|
51940
|
+
seriesId: sId,
|
|
51941
|
+
seriesName: formattedSeriesName,
|
|
51942
|
+
value: gdata,
|
|
51943
|
+
itemData: item.data
|
|
51944
|
+
});
|
|
51945
|
+
item.data.formatted = formattedTxt;
|
|
51946
|
+
|
|
51947
|
+
if (maxsw < sw) {
|
|
51948
|
+
maxs = formattedSeriesName;
|
|
51949
|
+
maxsw = sw;
|
|
51950
|
+
}
|
|
51951
|
+
|
|
51952
|
+
if (maxv.length <= "".concat(formattedTxt).length) {
|
|
51953
|
+
maxv = "".concat(formattedTxt);
|
|
51954
|
+
}
|
|
51955
|
+
|
|
51956
|
+
if (maxg === null || maxg <= gdata) {
|
|
51957
|
+
maxg = gdata;
|
|
51958
|
+
maxSID = sId;
|
|
51959
|
+
}
|
|
51960
|
+
|
|
51961
|
+
hitId = sId;
|
|
51962
|
+
}
|
|
51963
|
+
}
|
|
51964
|
+
}
|
|
51965
|
+
}
|
|
51966
|
+
|
|
51967
|
+
var _maxHighlight2 = maxg !== null ? [maxSID, maxg] : null;
|
|
51968
|
+
|
|
51969
|
+
return {
|
|
51970
|
+
items: items,
|
|
51971
|
+
hitId: hitId,
|
|
51972
|
+
maxTip: [maxs, maxv],
|
|
51973
|
+
maxHighlight: _maxHighlight2
|
|
51974
|
+
};
|
|
51975
|
+
} // 1. 먼저 공통으로 사용할 데이터 인덱스 결정
|
|
51976
|
+
|
|
51977
|
+
|
|
51978
|
+
var targetDataIndex = this.findClosestDataIndex(offset, sIds);
|
|
51979
|
+
|
|
51980
|
+
if (targetDataIndex === -1) {
|
|
51981
|
+
return {
|
|
51982
|
+
items: items,
|
|
51983
|
+
hitId: hitId,
|
|
51984
|
+
maxTip: [maxs, maxv],
|
|
51985
|
+
maxHighlight: null
|
|
51986
|
+
};
|
|
51987
|
+
} // 2. 모든 시리즈가 동일한 데이터 인덱스 사용
|
|
51988
|
+
|
|
51989
|
+
|
|
51990
|
+
var allSeriesIsBar = sIds.every(function (sId) {
|
|
51991
|
+
return _this4.seriesList[sId].type === 'bar';
|
|
51992
|
+
});
|
|
51993
|
+
|
|
51994
|
+
for (var _ix = 0; _ix < sIds.length; _ix++) {
|
|
51995
|
+
var _sId = sIds[_ix];
|
|
51996
|
+
var _series = this.seriesList[_sId];
|
|
51719
51997
|
|
|
51720
|
-
if (
|
|
51721
|
-
|
|
51998
|
+
if (_series.findGraphData && _series.show) {
|
|
51999
|
+
// 특정 데이터 인덱스로 데이터 요청
|
|
52000
|
+
var _item = _series.findGraphData(offset, isHorizontal, targetDataIndex, !allSeriesIsBar);
|
|
51722
52001
|
|
|
51723
|
-
if (
|
|
51724
|
-
var
|
|
52002
|
+
if (_item !== null && _item !== void 0 && _item.data) {
|
|
52003
|
+
var _gdata = void 0;
|
|
51725
52004
|
|
|
51726
|
-
if (
|
|
51727
|
-
if (!
|
|
51728
|
-
|
|
52005
|
+
if (_item.data.o === null && _series.interpolation !== 'zero') {
|
|
52006
|
+
if (!_series.isExistGrp) {
|
|
52007
|
+
_gdata = isHorizontal ? _item.data.x : _item.data.y;
|
|
51729
52008
|
}
|
|
51730
|
-
} else if (!isNaN(
|
|
51731
|
-
|
|
52009
|
+
} else if (!isNaN(_item.data.o)) {
|
|
52010
|
+
_gdata = _item.data.o;
|
|
51732
52011
|
}
|
|
51733
52012
|
|
|
51734
|
-
if (
|
|
51735
|
-
var
|
|
51736
|
-
dataId:
|
|
51737
|
-
seriesId:
|
|
51738
|
-
seriesName:
|
|
51739
|
-
itemData:
|
|
52013
|
+
if (_gdata !== null && _gdata !== undefined) {
|
|
52014
|
+
var _formattedSeriesName = this.getFormattedTooltipLabel({
|
|
52015
|
+
dataId: _series.id,
|
|
52016
|
+
seriesId: _sId,
|
|
52017
|
+
seriesName: _series.name,
|
|
52018
|
+
itemData: _item.data
|
|
51740
52019
|
});
|
|
51741
|
-
|
|
51742
|
-
|
|
51743
|
-
|
|
51744
|
-
|
|
51745
|
-
|
|
51746
|
-
|
|
52020
|
+
|
|
52021
|
+
var _sw = ctx ? ctx.measureText(_formattedSeriesName).width : 1;
|
|
52022
|
+
|
|
52023
|
+
_item.id = _series.id;
|
|
52024
|
+
_item.name = _formattedSeriesName;
|
|
52025
|
+
_item.axis = {
|
|
52026
|
+
x: _series.xAxisIndex,
|
|
52027
|
+
y: _series.yAxisIndex
|
|
51747
52028
|
};
|
|
51748
|
-
items[
|
|
51749
|
-
|
|
51750
|
-
|
|
51751
|
-
|
|
51752
|
-
|
|
51753
|
-
|
|
51754
|
-
|
|
52029
|
+
items[_sId] = _item;
|
|
52030
|
+
|
|
52031
|
+
var _formattedTxt = this.getFormattedTooltipValue({
|
|
52032
|
+
dataId: _series.id,
|
|
52033
|
+
seriesId: _sId,
|
|
52034
|
+
seriesName: _formattedSeriesName,
|
|
52035
|
+
value: _gdata,
|
|
52036
|
+
itemData: _item.data
|
|
51755
52037
|
});
|
|
51756
|
-
item.data.formatted = formattedTxt;
|
|
51757
52038
|
|
|
51758
|
-
|
|
51759
|
-
|
|
51760
|
-
|
|
52039
|
+
_item.data.formatted = _formattedTxt;
|
|
52040
|
+
|
|
52041
|
+
if (maxsw < _sw) {
|
|
52042
|
+
maxs = _formattedSeriesName;
|
|
52043
|
+
maxsw = _sw;
|
|
51761
52044
|
}
|
|
51762
52045
|
|
|
51763
|
-
if (maxv.length <= "".concat(
|
|
51764
|
-
maxv = "".concat(
|
|
52046
|
+
if (maxv.length <= "".concat(_formattedTxt).length) {
|
|
52047
|
+
maxv = "".concat(_formattedTxt);
|
|
51765
52048
|
}
|
|
51766
52049
|
|
|
51767
|
-
if (maxg === null || maxg <=
|
|
51768
|
-
maxg =
|
|
51769
|
-
maxSID =
|
|
52050
|
+
if (maxg === null || maxg <= _gdata) {
|
|
52051
|
+
maxg = _gdata;
|
|
52052
|
+
maxSID = _sId;
|
|
51770
52053
|
}
|
|
51771
52054
|
|
|
51772
|
-
if (
|
|
51773
|
-
hitId =
|
|
52055
|
+
if (_item.hit) {
|
|
52056
|
+
hitId = _sId;
|
|
51774
52057
|
}
|
|
51775
52058
|
}
|
|
51776
52059
|
}
|
|
@@ -51787,6 +52070,78 @@ var plugins_interaction_modules = {
|
|
|
51787
52070
|
};
|
|
51788
52071
|
},
|
|
51789
52072
|
|
|
52073
|
+
/**
|
|
52074
|
+
* Find the closest data index (label) based on mouse position
|
|
52075
|
+
* @param {array} offset mouse position
|
|
52076
|
+
* @param {array} sIds series IDs
|
|
52077
|
+
* @returns {number} closest data index
|
|
52078
|
+
*/
|
|
52079
|
+
findClosestDataIndex: function findClosestDataIndex(offset, sIds) {
|
|
52080
|
+
var _this5 = this,
|
|
52081
|
+
_this$seriesList$refe;
|
|
52082
|
+
|
|
52083
|
+
var _offset = _slicedToArray(offset, 2),
|
|
52084
|
+
xp = _offset[0],
|
|
52085
|
+
yp = _offset[1];
|
|
52086
|
+
|
|
52087
|
+
var isHorizontal = !!this.options.horizontal;
|
|
52088
|
+
var mousePos = isHorizontal ? yp : xp;
|
|
52089
|
+
var closestDistance = Infinity;
|
|
52090
|
+
var closestIndex = -1; // 첫 번째 표시 중인 시리즈를 기준으로 라벨 위치 확인
|
|
52091
|
+
|
|
52092
|
+
var referenceSeries = sIds.find(function (sId) {
|
|
52093
|
+
var _this5$seriesList$sId;
|
|
52094
|
+
|
|
52095
|
+
return (_this5$seriesList$sId = _this5.seriesList[sId]) === null || _this5$seriesList$sId === void 0 ? void 0 : _this5$seriesList$sId.show;
|
|
52096
|
+
});
|
|
52097
|
+
|
|
52098
|
+
if (!referenceSeries || !((_this$seriesList$refe = this.seriesList[referenceSeries]) !== null && _this$seriesList$refe !== void 0 && _this$seriesList$refe.data)) {
|
|
52099
|
+
return -1;
|
|
52100
|
+
}
|
|
52101
|
+
|
|
52102
|
+
var referenceData = this.seriesList[referenceSeries].data; // 각 라벨에서 가장 가까운 것 찾기
|
|
52103
|
+
|
|
52104
|
+
var _loop = function _loop(i) {
|
|
52105
|
+
// 이 라벨에 유효한 데이터가 있는 시리즈가 하나 이상 있는지 확인
|
|
52106
|
+
var hasValidData = sIds.some(function (sId) {
|
|
52107
|
+
var _series$data, _series$data$i, _series$data2, _series$data2$i;
|
|
52108
|
+
|
|
52109
|
+
var series = _this5.seriesList[sId];
|
|
52110
|
+
return (series === null || series === void 0 ? void 0 : series.show) && ((_series$data = series.data) === null || _series$data === void 0 ? void 0 : (_series$data$i = _series$data[i]) === null || _series$data$i === void 0 ? void 0 : _series$data$i.o) !== null && ((_series$data2 = series.data) === null || _series$data2 === void 0 ? void 0 : (_series$data2$i = _series$data2[i]) === null || _series$data2$i === void 0 ? void 0 : _series$data2$i.o) !== undefined;
|
|
52111
|
+
});
|
|
52112
|
+
|
|
52113
|
+
if (hasValidData) {
|
|
52114
|
+
var point = referenceData[i];
|
|
52115
|
+
|
|
52116
|
+
if (point) {
|
|
52117
|
+
// 라벨 위치 계산
|
|
52118
|
+
var labelPos;
|
|
52119
|
+
|
|
52120
|
+
if (isHorizontal) {
|
|
52121
|
+
labelPos = point.h ? point.yp + point.h / 2 : point.yp;
|
|
52122
|
+
} else {
|
|
52123
|
+
labelPos = point.w ? point.xp + point.w / 2 : point.xp;
|
|
52124
|
+
}
|
|
52125
|
+
|
|
52126
|
+
if (labelPos !== null) {
|
|
52127
|
+
var distance = Math.abs(mousePos - labelPos);
|
|
52128
|
+
|
|
52129
|
+
if (distance < closestDistance) {
|
|
52130
|
+
closestDistance = distance;
|
|
52131
|
+
closestIndex = i;
|
|
52132
|
+
}
|
|
52133
|
+
}
|
|
52134
|
+
}
|
|
52135
|
+
}
|
|
52136
|
+
};
|
|
52137
|
+
|
|
52138
|
+
for (var i = 0; i < referenceData.length; i++) {
|
|
52139
|
+
_loop(i);
|
|
52140
|
+
}
|
|
52141
|
+
|
|
52142
|
+
return closestIndex;
|
|
52143
|
+
},
|
|
52144
|
+
|
|
51790
52145
|
/**
|
|
51791
52146
|
* get formatted label for tooltip
|
|
51792
52147
|
* @param dataId
|
|
@@ -51916,9 +52271,9 @@ var plugins_interaction_modules = {
|
|
|
51916
52271
|
seriesName: formattedSeriesName,
|
|
51917
52272
|
value: hasData === null || hasData === void 0 ? void 0 : hasData.o,
|
|
51918
52273
|
itemData: hasData
|
|
51919
|
-
});
|
|
52274
|
+
}); // Only add data if there's a valid value for this exact label
|
|
51920
52275
|
|
|
51921
|
-
if (hasData && !hitInfo.items[sId]) {
|
|
52276
|
+
if (hasData && hasData.o !== null && hasData.o !== undefined && !hitInfo.items[sId]) {
|
|
51922
52277
|
var item = {};
|
|
51923
52278
|
item.color = series.color;
|
|
51924
52279
|
item.hit = false;
|
|
@@ -52008,7 +52363,7 @@ var plugins_interaction_modules = {
|
|
|
52008
52363
|
* @returns {object[]}
|
|
52009
52364
|
*/
|
|
52010
52365
|
getSelectedLabelInfoWithLabelData: function getSelectedLabelInfoWithLabelData(labelIndexList, targetAxis) {
|
|
52011
|
-
var
|
|
52366
|
+
var _this6 = this;
|
|
52012
52367
|
|
|
52013
52368
|
var _this$options9 = this.options,
|
|
52014
52369
|
selectLabelOpt = _this$options9.selectLabel,
|
|
@@ -52024,7 +52379,7 @@ var plugins_interaction_modules = {
|
|
|
52024
52379
|
{
|
|
52025
52380
|
result.dataIndex.splice(selectLabelOpt.limit);
|
|
52026
52381
|
result.label = result.dataIndex.map(function (i) {
|
|
52027
|
-
return
|
|
52382
|
+
return _this6.data.labels[i];
|
|
52028
52383
|
});
|
|
52029
52384
|
var dataEntries = Object.entries(this.data.data);
|
|
52030
52385
|
result.data = result.dataIndex.map(function (labelIdx) {
|
|
@@ -52054,7 +52409,7 @@ var plugins_interaction_modules = {
|
|
|
52054
52409
|
}
|
|
52055
52410
|
|
|
52056
52411
|
result.label = result.dataIndex.map(function (i) {
|
|
52057
|
-
return
|
|
52412
|
+
return _this6.data.labels[targetAxisDirection][i];
|
|
52058
52413
|
});
|
|
52059
52414
|
var dataValues = Object.values(this.data.data)[0];
|
|
52060
52415
|
result.data = dataValues.filter(function (_ref6) {
|
|
@@ -52145,6 +52500,76 @@ var plugins_interaction_modules = {
|
|
|
52145
52500
|
return after;
|
|
52146
52501
|
},
|
|
52147
52502
|
|
|
52503
|
+
/**
|
|
52504
|
+
* Draw indicator at the label position when tooltip is displayed
|
|
52505
|
+
* @param {object} hitInfo hit item information from findHitItem
|
|
52506
|
+
* @param {string} color indicator color
|
|
52507
|
+
* @returns {object|null} indicator position info with actual label value
|
|
52508
|
+
*/
|
|
52509
|
+
drawIndicatorForTooltip: function drawIndicatorForTooltip(hitInfo, color) {
|
|
52510
|
+
var _this$options$indicat;
|
|
52511
|
+
|
|
52512
|
+
if (!(hitInfo !== null && hitInfo !== void 0 && hitInfo.items) || !Object.keys(hitInfo.items).length) {
|
|
52513
|
+
return null;
|
|
52514
|
+
}
|
|
52515
|
+
|
|
52516
|
+
var ctx = this.overlayCtx;
|
|
52517
|
+
var horizontal = this.options.horizontal;
|
|
52518
|
+
var graphPos = {
|
|
52519
|
+
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
52520
|
+
x2: this.chartRect.x2 - this.labelOffset.right,
|
|
52521
|
+
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
52522
|
+
y2: this.chartRect.y2 - this.labelOffset.bottom
|
|
52523
|
+
}; // 첫 번째 시리즈의 데이터를 기준으로 라벨 위치 계산
|
|
52524
|
+
|
|
52525
|
+
var firstSeriesId = Object.keys(hitInfo.items)[0];
|
|
52526
|
+
var firstItem = hitInfo.items[firstSeriesId];
|
|
52527
|
+
|
|
52528
|
+
if (!(firstItem !== null && firstItem !== void 0 && firstItem.data)) {
|
|
52529
|
+
return null;
|
|
52530
|
+
} // 실제 indicator가 위치하는 라벨 값 추출
|
|
52531
|
+
|
|
52532
|
+
|
|
52533
|
+
var actualLabelValue = horizontal ? firstItem.data.y : firstItem.data.x;
|
|
52534
|
+
var indicatorPosition;
|
|
52535
|
+
|
|
52536
|
+
if (horizontal) {
|
|
52537
|
+
// 수평 차트에서는 Y축 라벨 위치에 수평선
|
|
52538
|
+
var yPosition = firstItem.data.yp + (firstItem.data.h ? firstItem.data.h / 2 : 0);
|
|
52539
|
+
indicatorPosition = [graphPos.x1, yPosition];
|
|
52540
|
+
} else {
|
|
52541
|
+
// 수직 차트에서는 X축 라벨 위치에 수직선
|
|
52542
|
+
var xPosition = firstItem.data.xp + (firstItem.data.w ? firstItem.data.w / 2 : 0);
|
|
52543
|
+
indicatorPosition = [xPosition, graphPos.y1];
|
|
52544
|
+
}
|
|
52545
|
+
|
|
52546
|
+
ctx.beginPath();
|
|
52547
|
+
ctx.save();
|
|
52548
|
+
ctx.strokeStyle = color;
|
|
52549
|
+
ctx.lineWidth = 1;
|
|
52550
|
+
|
|
52551
|
+
if ((_this$options$indicat = this.options.indicator) !== null && _this$options$indicat !== void 0 && _this$options$indicat.segments) {
|
|
52552
|
+
ctx.setLineDash(this.options.indicator.segments);
|
|
52553
|
+
}
|
|
52554
|
+
|
|
52555
|
+
if (horizontal) {
|
|
52556
|
+
ctx.moveTo(graphPos.x1, indicatorPosition[1] + 0.5);
|
|
52557
|
+
ctx.lineTo(graphPos.x2, indicatorPosition[1] + 0.5);
|
|
52558
|
+
} else {
|
|
52559
|
+
ctx.moveTo(indicatorPosition[0] + 0.5, graphPos.y1);
|
|
52560
|
+
ctx.lineTo(indicatorPosition[0] + 0.5, graphPos.y2);
|
|
52561
|
+
}
|
|
52562
|
+
|
|
52563
|
+
ctx.stroke();
|
|
52564
|
+
ctx.restore();
|
|
52565
|
+
ctx.closePath(); // 실제 indicator가 위치한 라벨 정보 반환
|
|
52566
|
+
|
|
52567
|
+
return {
|
|
52568
|
+
labelValue: actualLabelValue,
|
|
52569
|
+
position: indicatorPosition
|
|
52570
|
+
};
|
|
52571
|
+
},
|
|
52572
|
+
|
|
52148
52573
|
/**
|
|
52149
52574
|
* Find items by series within a range
|
|
52150
52575
|
* @param {object} range object for find series items
|
|
@@ -52277,9 +52702,9 @@ var plugins_interaction_modules = {
|
|
|
52277
52702
|
* @returns {string}
|
|
52278
52703
|
*/
|
|
52279
52704
|
getCurMouseLocation: function getCurMouseLocation(offset) {
|
|
52280
|
-
var
|
|
52281
|
-
offsetX =
|
|
52282
|
-
offsetY =
|
|
52705
|
+
var _offset2 = _slicedToArray(offset, 2),
|
|
52706
|
+
offsetX = _offset2[0],
|
|
52707
|
+
offsetY = _offset2[1];
|
|
52283
52708
|
|
|
52284
52709
|
var aPos = {
|
|
52285
52710
|
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
@@ -52339,6 +52764,8 @@ var plugins_interaction_modules = {
|
|
|
52339
52764
|
|
|
52340
52765
|
|
|
52341
52766
|
|
|
52767
|
+
|
|
52768
|
+
|
|
52342
52769
|
|
|
52343
52770
|
var LINE_SPACING = 8;
|
|
52344
52771
|
var VALUE_MARGIN = 50;
|
|
@@ -53130,9 +53557,10 @@ var plugins_tooltip_modules = {
|
|
|
53130
53557
|
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
53131
53558
|
y2: this.chartRect.y2 - this.labelOffset.bottom
|
|
53132
53559
|
};
|
|
53133
|
-
var mouseXIp =
|
|
53560
|
+
var mouseXIp = 15; // mouseInterpolation - 더 넓은 범위에서 감지
|
|
53561
|
+
|
|
53562
|
+
var mouseYIp = 15; // Y축도 동일하게 증가
|
|
53134
53563
|
|
|
53135
|
-
var mouseYIp = 10;
|
|
53136
53564
|
var options = this.options;
|
|
53137
53565
|
|
|
53138
53566
|
if (offsetX >= graphPos.x1 - mouseXIp && offsetX <= graphPos.x2 + mouseXIp && offsetY >= graphPos.y1 - mouseYIp && offsetY <= graphPos.y2 + mouseYIp) {
|
|
@@ -53226,11 +53654,23 @@ var plugins_tooltip_modules = {
|
|
|
53226
53654
|
|
|
53227
53655
|
var horizontal = _ref5.horizontal,
|
|
53228
53656
|
label = _ref5.label,
|
|
53229
|
-
mousePosition = _ref5.mousePosition
|
|
53657
|
+
mousePosition = _ref5.mousePosition,
|
|
53658
|
+
dataLabel = _ref5.dataLabel,
|
|
53659
|
+
isTooltipBased = _ref5.isTooltipBased;
|
|
53230
53660
|
|
|
53231
53661
|
if (!mousePosition || !!horizontal !== !!this.options.horizontal) {
|
|
53232
53662
|
return;
|
|
53233
|
-
}
|
|
53663
|
+
} // tooltip 기반 동기화인 경우
|
|
53664
|
+
|
|
53665
|
+
|
|
53666
|
+
if (isTooltipBased) {
|
|
53667
|
+
this.drawSyncedIndicatorForTooltip({
|
|
53668
|
+
dataLabel: dataLabel,
|
|
53669
|
+
mousePosition: mousePosition
|
|
53670
|
+
});
|
|
53671
|
+
return;
|
|
53672
|
+
} // 기존 시간 기반 동기화
|
|
53673
|
+
|
|
53234
53674
|
|
|
53235
53675
|
if (this.options.syncHover === false || !horizontal && !this.options.axesX.every(function (_ref6) {
|
|
53236
53676
|
var type = _ref6.type;
|
|
@@ -53284,6 +53724,82 @@ var plugins_tooltip_modules = {
|
|
|
53284
53724
|
}
|
|
53285
53725
|
},
|
|
53286
53726
|
|
|
53727
|
+
/**
|
|
53728
|
+
* 제공된 dataLabel과 일치하는 Label이 있다면 indicator를 그림
|
|
53729
|
+
* @param {object} dataLabel data label
|
|
53730
|
+
* @param {object} mousePosition mouse position
|
|
53731
|
+
*
|
|
53732
|
+
* @returns {undefined}
|
|
53733
|
+
*/
|
|
53734
|
+
drawSyncedIndicatorForTooltip: function drawSyncedIndicatorForTooltip(_ref8) {
|
|
53735
|
+
var _this$data;
|
|
53736
|
+
|
|
53737
|
+
var dataLabel = _ref8.dataLabel,
|
|
53738
|
+
mousePosition = _ref8.mousePosition;
|
|
53739
|
+
|
|
53740
|
+
if (!((_this$data = this.data) !== null && _this$data !== void 0 && _this$data.labels) || !dataLabel) {
|
|
53741
|
+
return;
|
|
53742
|
+
}
|
|
53743
|
+
|
|
53744
|
+
var matchingLabelIndex = this.data.labels.findIndex(function (label) {
|
|
53745
|
+
return (label === null || label === void 0 ? void 0 : label.valueOf()) === (dataLabel === null || dataLabel === void 0 ? void 0 : dataLabel.valueOf());
|
|
53746
|
+
});
|
|
53747
|
+
|
|
53748
|
+
if (matchingLabelIndex === -1) {
|
|
53749
|
+
this.overlayClear();
|
|
53750
|
+
return;
|
|
53751
|
+
}
|
|
53752
|
+
|
|
53753
|
+
var horizontal = this.options.horizontal;
|
|
53754
|
+
|
|
53755
|
+
var _this$chartDOM$getBou2 = this.chartDOM.getBoundingClientRect(),
|
|
53756
|
+
top = _this$chartDOM$getBou2.top,
|
|
53757
|
+
bottom = _this$chartDOM$getBou2.bottom,
|
|
53758
|
+
left = _this$chartDOM$getBou2.left,
|
|
53759
|
+
right = _this$chartDOM$getBou2.right;
|
|
53760
|
+
|
|
53761
|
+
var isHoveredChart = lodash_es_inRange(mousePosition[0], left, right) && lodash_es_inRange(mousePosition[1], bottom, top);
|
|
53762
|
+
|
|
53763
|
+
if (isHoveredChart) {
|
|
53764
|
+
return;
|
|
53765
|
+
}
|
|
53766
|
+
|
|
53767
|
+
this.overlayClear();
|
|
53768
|
+
var graphPos = {
|
|
53769
|
+
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
53770
|
+
x2: this.chartRect.x2 - this.labelOffset.right,
|
|
53771
|
+
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
53772
|
+
y2: this.chartRect.y2 - this.labelOffset.bottom
|
|
53773
|
+
};
|
|
53774
|
+
var labelsCount = this.data.labels.length;
|
|
53775
|
+
var indicatorPosition;
|
|
53776
|
+
|
|
53777
|
+
if (horizontal) {
|
|
53778
|
+
var _this$options$axesY;
|
|
53779
|
+
|
|
53780
|
+
var chartHeight = graphPos.y2 - graphPos.y1; // CategoryMode인 경우 라벨들이 균등 간격으로 배치됨
|
|
53781
|
+
|
|
53782
|
+
var isCategoryMode = (_this$options$axesY = this.options.axesY) === null || _this$options$axesY === void 0 ? void 0 : _this$options$axesY.some(function (axis) {
|
|
53783
|
+
return axis.categoryMode;
|
|
53784
|
+
});
|
|
53785
|
+
var positionY = isCategoryMode ? graphPos.y1 + chartHeight * (matchingLabelIndex + 0.5) / labelsCount : graphPos.y1 + chartHeight * matchingLabelIndex / (labelsCount - 1);
|
|
53786
|
+
indicatorPosition = [graphPos.x2, positionY];
|
|
53787
|
+
} else {
|
|
53788
|
+
var _this$options$axesX;
|
|
53789
|
+
|
|
53790
|
+
var chartWidth = graphPos.x2 - graphPos.x1; // CategoryMode인 경우 라벨들이 균등 간격으로 배치됨
|
|
53791
|
+
|
|
53792
|
+
var _isCategoryMode = (_this$options$axesX = this.options.axesX) === null || _this$options$axesX === void 0 ? void 0 : _this$options$axesX.some(function (axis) {
|
|
53793
|
+
return axis.categoryMode;
|
|
53794
|
+
});
|
|
53795
|
+
|
|
53796
|
+
var positionX = _isCategoryMode ? graphPos.x1 + chartWidth * (matchingLabelIndex + 0.5) / labelsCount : graphPos.x1 + chartWidth * matchingLabelIndex / (labelsCount - 1);
|
|
53797
|
+
indicatorPosition = [positionX, graphPos.y2];
|
|
53798
|
+
}
|
|
53799
|
+
|
|
53800
|
+
this.drawIndicator(indicatorPosition, this.options.indicator.color);
|
|
53801
|
+
},
|
|
53802
|
+
|
|
53287
53803
|
/**
|
|
53288
53804
|
* Clear tooltip canvas
|
|
53289
53805
|
*
|