evui 3.4.130 → 3.4.131
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 -224
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +741 -224
- 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 +92 -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.131\"}");
|
|
11178
11178
|
|
|
11179
11179
|
/***/ }),
|
|
11180
11180
|
|
|
@@ -41698,6 +41698,9 @@ var TIME_INTERVALS = {
|
|
|
41698
41698
|
|
|
41699
41699
|
|
|
41700
41700
|
|
|
41701
|
+
|
|
41702
|
+
|
|
41703
|
+
|
|
41701
41704
|
|
|
41702
41705
|
var element_line_Line = /*#__PURE__*/function () {
|
|
41703
41706
|
function Line(sId, opt, sIdx) {
|
|
@@ -42082,77 +42085,166 @@ var element_line_Line = /*#__PURE__*/function () {
|
|
|
42082
42085
|
var gdata = this.data.filter(function (data) {
|
|
42083
42086
|
return !helpers_util.isNullOrUndefined(data.x);
|
|
42084
42087
|
});
|
|
42085
|
-
var SPARE_XP = 0.5;
|
|
42086
42088
|
var isLinearInterpolation = this.useLinearInterpolation();
|
|
42087
42089
|
|
|
42088
42090
|
if (gdata !== null && gdata !== void 0 && gdata.length) {
|
|
42089
42091
|
if (typeof dataIndex === 'number' && this.show) {
|
|
42090
42092
|
item.data = gdata[dataIndex];
|
|
42091
42093
|
item.index = dataIndex;
|
|
42094
|
+
|
|
42095
|
+
if (item.data) {
|
|
42096
|
+
var point = gdata[dataIndex];
|
|
42097
|
+
var yDist = Math.abs(yp - point.yp);
|
|
42098
|
+
var directHitThreshold = 15; // 직접 히트 임계값
|
|
42099
|
+
|
|
42100
|
+
if (yDist <= directHitThreshold) {
|
|
42101
|
+
item.hit = true;
|
|
42102
|
+
}
|
|
42103
|
+
}
|
|
42092
42104
|
} else if (typeof this.beforeFindItemIndex === 'number' && this.show && useSelectLabelOrItem) {
|
|
42093
42105
|
item.data = gdata[this.beforeFindItemIndex];
|
|
42094
42106
|
item.index = this.beforeFindItemIndex;
|
|
42095
42107
|
} else {
|
|
42096
|
-
|
|
42097
|
-
|
|
42098
|
-
var
|
|
42099
|
-
|
|
42100
|
-
var
|
|
42101
|
-
|
|
42102
|
-
|
|
42103
|
-
|
|
42104
|
-
|
|
42105
|
-
|
|
42106
|
-
|
|
42107
|
-
|
|
42108
|
-
|
|
42109
|
-
|
|
42110
|
-
|
|
42111
|
-
|
|
42112
|
-
|
|
42113
|
-
|
|
42114
|
-
|
|
42115
|
-
|
|
42116
|
-
|
|
42117
|
-
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
|
|
42121
|
-
|
|
42122
|
-
|
|
42123
|
-
|
|
42124
|
-
|
|
42125
|
-
|
|
42126
|
-
|
|
42127
|
-
|
|
42128
|
-
|
|
42129
|
-
|
|
42130
|
-
|
|
42131
|
-
|
|
42132
|
-
|
|
42133
|
-
|
|
42134
|
-
|
|
42135
|
-
|
|
42136
|
-
item.index = m + 1;
|
|
42137
|
-
} else {
|
|
42138
|
-
item.data = gdata[m];
|
|
42139
|
-
item.index = m;
|
|
42140
|
-
}
|
|
42108
|
+
// Axis 트리거 방식: X축 위치에서 가장 가까운 데이터 포인트 찾기
|
|
42109
|
+
var closestXDistance = Infinity;
|
|
42110
|
+
var closestIndex = -1; // null이 아닌 유효한 데이터만 필터링
|
|
42111
|
+
|
|
42112
|
+
var validData = [];
|
|
42113
|
+
gdata.forEach(function (point, idx) {
|
|
42114
|
+
if (point.xp !== null && point.yp !== null && point.o !== null) {
|
|
42115
|
+
validData.push(_objectSpread2(_objectSpread2({}, point), {}, {
|
|
42116
|
+
originalIndex: idx
|
|
42117
|
+
}));
|
|
42118
|
+
}
|
|
42119
|
+
});
|
|
42120
|
+
|
|
42121
|
+
if (validData.length === 0) {
|
|
42122
|
+
return item;
|
|
42123
|
+
} // 이진 탐색으로 가장 가까운 포인트 찾기
|
|
42124
|
+
|
|
42125
|
+
|
|
42126
|
+
var left = 0;
|
|
42127
|
+
var right = validData.length - 1;
|
|
42128
|
+
|
|
42129
|
+
while (left <= right) {
|
|
42130
|
+
var mid = Math.floor((left + right) / 2);
|
|
42131
|
+
var _point = validData[mid];
|
|
42132
|
+
var xDistance = Math.abs(xp - _point.xp);
|
|
42133
|
+
|
|
42134
|
+
if (xDistance < closestXDistance) {
|
|
42135
|
+
closestXDistance = xDistance;
|
|
42136
|
+
closestIndex = _point.originalIndex;
|
|
42137
|
+
}
|
|
42138
|
+
|
|
42139
|
+
if (_point.xp < xp) {
|
|
42140
|
+
left = mid + 1; // 다음 포인트도 확인
|
|
42141
|
+
|
|
42142
|
+
if (left < validData.length) {
|
|
42143
|
+
var nextDistance = Math.abs(xp - validData[left].xp);
|
|
42144
|
+
|
|
42145
|
+
if (nextDistance < closestXDistance) {
|
|
42146
|
+
closestXDistance = nextDistance;
|
|
42147
|
+
closestIndex = validData[left].originalIndex;
|
|
42141
42148
|
}
|
|
42142
|
-
} else {
|
|
42143
|
-
item.data = gdata[m];
|
|
42144
|
-
item.index = m;
|
|
42145
42149
|
}
|
|
42150
|
+
} else if (_point.xp > xp) {
|
|
42151
|
+
right = mid - 1; // 이전 포인트도 확인
|
|
42146
42152
|
|
|
42147
|
-
if (
|
|
42148
|
-
|
|
42149
|
-
}
|
|
42153
|
+
if (right >= 0) {
|
|
42154
|
+
var prevDistance = Math.abs(xp - validData[right].xp);
|
|
42150
42155
|
|
|
42156
|
+
if (prevDistance < closestXDistance) {
|
|
42157
|
+
closestXDistance = prevDistance;
|
|
42158
|
+
closestIndex = validData[right].originalIndex;
|
|
42159
|
+
}
|
|
42160
|
+
}
|
|
42161
|
+
} else {
|
|
42162
|
+
// 정확히 일치하는 경우
|
|
42151
42163
|
break;
|
|
42152
|
-
}
|
|
42153
|
-
|
|
42164
|
+
}
|
|
42165
|
+
} // 이진 탐색 후 주변 포인트 추가 확인 (정확도 향상)
|
|
42166
|
+
|
|
42167
|
+
|
|
42168
|
+
var foundIdx = validData.findIndex(function (p) {
|
|
42169
|
+
return p.originalIndex === closestIndex;
|
|
42170
|
+
});
|
|
42171
|
+
|
|
42172
|
+
if (foundIdx !== -1) {
|
|
42173
|
+
// 앞뒤 2개씩 추가 확인
|
|
42174
|
+
for (var i = Math.max(0, foundIdx - 2); i <= Math.min(validData.length - 1, foundIdx + 2); i++) {
|
|
42175
|
+
var _point2 = validData[i];
|
|
42176
|
+
|
|
42177
|
+
var _xDistance = Math.abs(xp - _point2.xp);
|
|
42178
|
+
|
|
42179
|
+
if (_xDistance < closestXDistance) {
|
|
42180
|
+
closestXDistance = _xDistance;
|
|
42181
|
+
closestIndex = _point2.originalIndex;
|
|
42182
|
+
}
|
|
42183
|
+
}
|
|
42184
|
+
} // 가장 가까운 포인트 설정
|
|
42185
|
+
|
|
42186
|
+
|
|
42187
|
+
if (closestIndex !== -1) {
|
|
42188
|
+
// 데이터 간격 계산 - 모든 데이터(null 포함)의 평균 간격 사용
|
|
42189
|
+
var avgInterval = 50;
|
|
42190
|
+
|
|
42191
|
+
if (gdata.length > 1) {
|
|
42192
|
+
var intervals = [];
|
|
42193
|
+
|
|
42194
|
+
for (var _i = 1; _i < gdata.length; _i++) {
|
|
42195
|
+
if (gdata[_i].xp !== null && gdata[_i - 1].xp !== null) {
|
|
42196
|
+
intervals.push(Math.abs(gdata[_i].xp - gdata[_i - 1].xp));
|
|
42197
|
+
}
|
|
42198
|
+
}
|
|
42199
|
+
|
|
42200
|
+
if (intervals.length > 0) {
|
|
42201
|
+
avgInterval = intervals.reduce(function (a, b) {
|
|
42202
|
+
return a + b;
|
|
42203
|
+
}, 0) / intervals.length;
|
|
42204
|
+
}
|
|
42205
|
+
} // 두 가지 임계값 설정
|
|
42206
|
+
|
|
42207
|
+
|
|
42208
|
+
var strictThreshold = avgInterval * 0.3; // 엄격한 임계값: 데이터 간격의 30%
|
|
42209
|
+
|
|
42210
|
+
var relaxedThreshold = avgInterval; // 느슨한 임계값: 데이터 간격 전체
|
|
42211
|
+
// 1. 먼저 엄격한 임계값으로 정확한 매치 확인
|
|
42212
|
+
|
|
42213
|
+
if (closestXDistance <= strictThreshold) {
|
|
42214
|
+
// 정확히 일치하거나 매우 가까운 데이터가 있음
|
|
42215
|
+
item.data = gdata[closestIndex];
|
|
42216
|
+
item.index = closestIndex;
|
|
42154
42217
|
} else {
|
|
42155
|
-
|
|
42218
|
+
// 2. 정확한 매치가 없을 때, 현재 X 위치 근처에 다른 유효 데이터가 있는지 확인
|
|
42219
|
+
var hasNearbyValidData = false;
|
|
42220
|
+
|
|
42221
|
+
for (var _i2 = 0; _i2 < validData.length; _i2++) {
|
|
42222
|
+
var xDist = Math.abs(xp - validData[_i2].xp);
|
|
42223
|
+
|
|
42224
|
+
if (xDist <= strictThreshold) {
|
|
42225
|
+
hasNearbyValidData = true;
|
|
42226
|
+
break;
|
|
42227
|
+
}
|
|
42228
|
+
} // 3. 근처에 다른 유효 데이터가 없을 때만 느슨한 임계값 적용
|
|
42229
|
+
|
|
42230
|
+
|
|
42231
|
+
if (!hasNearbyValidData && closestXDistance <= relaxedThreshold) {
|
|
42232
|
+
item.data = gdata[closestIndex];
|
|
42233
|
+
item.index = closestIndex;
|
|
42234
|
+
}
|
|
42235
|
+
} // Y축 거리를 확인하여 직접 히트 판정
|
|
42236
|
+
|
|
42237
|
+
|
|
42238
|
+
if (item.data) {
|
|
42239
|
+
var _point3 = gdata[closestIndex];
|
|
42240
|
+
|
|
42241
|
+
var _yDist = Math.abs(yp - _point3.yp);
|
|
42242
|
+
|
|
42243
|
+
var _directHitThreshold = 15; // 직접 히트 임계값
|
|
42244
|
+
|
|
42245
|
+
if (_yDist <= _directHitThreshold) {
|
|
42246
|
+
item.hit = true;
|
|
42247
|
+
}
|
|
42156
42248
|
}
|
|
42157
42249
|
}
|
|
42158
42250
|
}
|
|
@@ -42183,6 +42275,8 @@ var element_line_Line = /*#__PURE__*/function () {
|
|
|
42183
42275
|
}, {
|
|
42184
42276
|
key: "findApproximateData",
|
|
42185
42277
|
value: function findApproximateData(offset) {
|
|
42278
|
+
var _gdata$, _gdata$2;
|
|
42279
|
+
|
|
42186
42280
|
var xp = offset[0];
|
|
42187
42281
|
var yp = offset[1];
|
|
42188
42282
|
var item = {
|
|
@@ -42193,41 +42287,87 @@ var element_line_Line = /*#__PURE__*/function () {
|
|
|
42193
42287
|
var gdata = this.data.filter(function (data) {
|
|
42194
42288
|
return !helpers_util.isNullOrUndefined(data.x);
|
|
42195
42289
|
});
|
|
42290
|
+
|
|
42291
|
+
if (!gdata.length) {
|
|
42292
|
+
return item;
|
|
42293
|
+
} // 동적 감지 범위 계산
|
|
42294
|
+
|
|
42295
|
+
|
|
42296
|
+
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;
|
|
42297
|
+
var xpInterval = Math.max(gap * 0.4, 10); // 데이터 간격의 40% 또는 최소 10px
|
|
42298
|
+
|
|
42196
42299
|
var s = 0;
|
|
42197
42300
|
var e = gdata.length - 1;
|
|
42301
|
+
var closestIndex = -1;
|
|
42302
|
+
var closestDistance = Infinity; // 이진 탐색으로 근처 데이터 찾기
|
|
42198
42303
|
|
|
42199
42304
|
while (s <= e) {
|
|
42200
42305
|
var m = Math.floor((s + e) / 2);
|
|
42201
|
-
var x = gdata[m].xp;
|
|
42202
|
-
|
|
42306
|
+
var x = gdata[m].xp; // X 좌표가 감지 범위 내에 있는 경우
|
|
42307
|
+
|
|
42308
|
+
if (x - xpInterval <= xp && xp <= x + xpInterval) {
|
|
42309
|
+
// 중간점 주변 데이터들과 거리 비교
|
|
42310
|
+
var checkStart = Math.max(0, m - 2);
|
|
42311
|
+
var checkEnd = Math.min(gdata.length - 1, m + 2);
|
|
42203
42312
|
|
|
42204
|
-
|
|
42205
|
-
|
|
42206
|
-
|
|
42313
|
+
for (var i = checkStart; i <= checkEnd; i++) {
|
|
42314
|
+
if (gdata[i].xp !== null && gdata[i].yp !== null) {
|
|
42315
|
+
var distance = Math.sqrt(Math.pow(xp - gdata[i].xp, 2) + Math.pow(yp - gdata[i].yp, 2));
|
|
42207
42316
|
|
|
42208
|
-
|
|
42209
|
-
|
|
42317
|
+
if (distance < closestDistance) {
|
|
42318
|
+
closestDistance = distance;
|
|
42319
|
+
closestIndex = i;
|
|
42320
|
+
}
|
|
42321
|
+
}
|
|
42322
|
+
}
|
|
42323
|
+
|
|
42324
|
+
if (closestIndex !== -1) {
|
|
42325
|
+
item.data = gdata[closestIndex];
|
|
42326
|
+
item.index = closestIndex; // 매우 가까운 경우 hit으로 표시
|
|
42327
|
+
|
|
42328
|
+
if (closestDistance < 5) {
|
|
42329
|
+
item.hit = true;
|
|
42330
|
+
}
|
|
42210
42331
|
}
|
|
42211
42332
|
|
|
42212
42333
|
return item;
|
|
42213
|
-
} else if (x +
|
|
42334
|
+
} else if (x + xpInterval < xp) {
|
|
42335
|
+
// 마우스가 오른쪽에 있는 경우
|
|
42214
42336
|
if (m < e && xp < gdata[m + 1].xp) {
|
|
42215
42337
|
var curr = Math.abs(gdata[m].xp - xp);
|
|
42216
42338
|
var next = Math.abs(gdata[m + 1].xp - xp);
|
|
42217
42339
|
item.data = curr > next ? gdata[m + 1] : gdata[m];
|
|
42218
|
-
item.index = curr > next ? m + 1 : m;
|
|
42340
|
+
item.index = curr > next ? m + 1 : m; // Y 거리도 확인하여 hit 판정
|
|
42341
|
+
|
|
42342
|
+
var selectedPoint = item.data;
|
|
42343
|
+
var yDist = Math.abs(yp - selectedPoint.yp);
|
|
42344
|
+
|
|
42345
|
+
if (yDist < 10) {
|
|
42346
|
+
item.hit = true;
|
|
42347
|
+
}
|
|
42348
|
+
|
|
42219
42349
|
return item;
|
|
42220
42350
|
}
|
|
42221
42351
|
|
|
42222
42352
|
s = m + 1;
|
|
42223
42353
|
} else {
|
|
42354
|
+
// 마우스가 왼쪽에 있는 경우
|
|
42224
42355
|
if (m > 0 && xp > gdata[m - 1].xp) {
|
|
42225
42356
|
var prev = Math.abs(gdata[m - 1].xp - xp);
|
|
42226
42357
|
|
|
42227
42358
|
var _curr = Math.abs(gdata[m].xp - xp);
|
|
42228
42359
|
|
|
42229
42360
|
item.data = prev > _curr ? gdata[m] : gdata[m - 1];
|
|
42230
|
-
item.index = prev > _curr ? m : m - 1;
|
|
42361
|
+
item.index = prev > _curr ? m : m - 1; // Y 거리도 확인하여 hit 판정
|
|
42362
|
+
|
|
42363
|
+
var _selectedPoint = item.data;
|
|
42364
|
+
|
|
42365
|
+
var _yDist2 = Math.abs(yp - _selectedPoint.yp);
|
|
42366
|
+
|
|
42367
|
+
if (_yDist2 < 10) {
|
|
42368
|
+
item.hit = true;
|
|
42369
|
+
}
|
|
42370
|
+
|
|
42231
42371
|
return item;
|
|
42232
42372
|
}
|
|
42233
42373
|
|
|
@@ -42678,6 +42818,7 @@ var element_scatter_Scatter = /*#__PURE__*/function () {
|
|
|
42678
42818
|
|
|
42679
42819
|
|
|
42680
42820
|
|
|
42821
|
+
|
|
42681
42822
|
var element_bar_Bar = /*#__PURE__*/function () {
|
|
42682
42823
|
function Bar(sId, opt, sIdx, isHorizontal) {
|
|
42683
42824
|
var _this = this;
|
|
@@ -42740,18 +42881,11 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
42740
42881
|
var minmaxX = axesSteps.x[this.xAxisIndex];
|
|
42741
42882
|
var minmaxY = axesSteps.y[this.yAxisIndex];
|
|
42742
42883
|
var totalCount = this.data.length;
|
|
42743
|
-
var minIndex;
|
|
42744
|
-
var maxIndex;
|
|
42745
42884
|
|
|
42746
|
-
|
|
42747
|
-
|
|
42748
|
-
|
|
42749
|
-
|
|
42750
|
-
} else {
|
|
42751
|
-
var _ref2 = [minmaxX.minIndex, minmaxX.maxIndex];
|
|
42752
|
-
minIndex = _ref2[0];
|
|
42753
|
-
maxIndex = _ref2[1];
|
|
42754
|
-
} // minIndex, maxIndex가 유효하면 실제 그릴 데이터 개수로 보정
|
|
42885
|
+
var _ref = isHorizontal ? [minmaxY.minIndex, minmaxY.maxIndex] : [minmaxX.minIndex, minmaxX.maxIndex],
|
|
42886
|
+
_ref2 = _slicedToArray(_ref, 2),
|
|
42887
|
+
minIndex = _ref2[0],
|
|
42888
|
+
maxIndex = _ref2[1]; // minIndex, maxIndex가 유효하면 실제 그릴 데이터 개수로 보정
|
|
42755
42889
|
|
|
42756
42890
|
|
|
42757
42891
|
if (truthyNumber(minIndex) && truthyNumber(maxIndex)) {
|
|
@@ -42778,20 +42912,7 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
42778
42912
|
var h;
|
|
42779
42913
|
bArea = cArea > cPad * 2 ? cArea - cPad * 2 : cArea;
|
|
42780
42914
|
bArea = this.isExistGrp ? bArea : bArea / showSeriesCount;
|
|
42781
|
-
|
|
42782
|
-
var getSize = function getSize() {
|
|
42783
|
-
if (typeof thickness === 'string' && /[0-9]+px/.test(thickness)) {
|
|
42784
|
-
return Math.min(bArea, Number(thickness.replace('px', '')));
|
|
42785
|
-
}
|
|
42786
|
-
|
|
42787
|
-
if (typeof thickness === 'number' && thickness <= 1 && thickness >= 0) {
|
|
42788
|
-
return Math.ceil(bArea * thickness);
|
|
42789
|
-
}
|
|
42790
|
-
|
|
42791
|
-
return bArea;
|
|
42792
|
-
};
|
|
42793
|
-
|
|
42794
|
-
var size = getSize();
|
|
42915
|
+
var size = this.calculateBarSize(thickness, bArea);
|
|
42795
42916
|
w = isHorizontal ? null : size;
|
|
42796
42917
|
h = isHorizontal ? size : null;
|
|
42797
42918
|
var bPad = isHorizontal ? (bArea - h) / 2 : (bArea - w) / 2;
|
|
@@ -42819,13 +42940,7 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
42819
42940
|
var _param$selectLabel, _param$selectItem, _param$selectLabel$se, _param$selectLabel2, _param$selectLabel2$s, _param$selectItem$sel, _param$selectItem2;
|
|
42820
42941
|
|
|
42821
42942
|
// 스크롤 offset(minIndex)만큼 보정해서 그리기
|
|
42822
|
-
var categoryPoint =
|
|
42823
|
-
|
|
42824
|
-
if (isHorizontal) {
|
|
42825
|
-
categoryPoint = ysp - cArea * screenIndex - cPad;
|
|
42826
|
-
} else {
|
|
42827
|
-
categoryPoint = xsp + cArea * screenIndex + cPad;
|
|
42828
|
-
}
|
|
42943
|
+
var categoryPoint = isHorizontal ? ysp - cArea * screenIndex - cPad : xsp + cArea * screenIndex + cPad;
|
|
42829
42944
|
|
|
42830
42945
|
if (isHorizontal) {
|
|
42831
42946
|
x = xsp;
|
|
@@ -43003,13 +43118,32 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43003
43118
|
* Find graph item
|
|
43004
43119
|
* @param {array} offset mouse position
|
|
43005
43120
|
* @param {boolean} isHorizontal determines if a horizontal option's value
|
|
43121
|
+
* @param {number} dataIndex selected label data index
|
|
43122
|
+
* @param {boolean} useIndicatorOnLabel
|
|
43006
43123
|
*
|
|
43007
43124
|
* @returns {object} graph item
|
|
43008
43125
|
*/
|
|
43009
43126
|
|
|
43010
43127
|
}, {
|
|
43011
43128
|
key: "findGraphData",
|
|
43012
|
-
value: function findGraphData(offset, isHorizontal) {
|
|
43129
|
+
value: function findGraphData(offset, isHorizontal, dataIndex, useIndicatorOnLabel) {
|
|
43130
|
+
if (typeof dataIndex === 'number' && this.show && useIndicatorOnLabel) {
|
|
43131
|
+
var gdata = this.data;
|
|
43132
|
+
var item = {
|
|
43133
|
+
data: null,
|
|
43134
|
+
hit: false,
|
|
43135
|
+
color: this.color
|
|
43136
|
+
};
|
|
43137
|
+
|
|
43138
|
+
if (gdata[dataIndex]) {
|
|
43139
|
+
item.data = gdata[dataIndex];
|
|
43140
|
+
item.index = dataIndex;
|
|
43141
|
+
item.hit = this.isPointInBar(offset, gdata[dataIndex]);
|
|
43142
|
+
}
|
|
43143
|
+
|
|
43144
|
+
return item;
|
|
43145
|
+
}
|
|
43146
|
+
|
|
43013
43147
|
return isHorizontal ? this.findGraphRangeCount(offset) : this.findGraphRange(offset);
|
|
43014
43148
|
}
|
|
43015
43149
|
/**
|
|
@@ -43019,13 +43153,23 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43019
43153
|
* @returns {object} graph item
|
|
43020
43154
|
*/
|
|
43021
43155
|
|
|
43156
|
+
/**
|
|
43157
|
+
* Binary search for finding graph item
|
|
43158
|
+
* @private
|
|
43159
|
+
* @param {array} offset - mouse position
|
|
43160
|
+
* @param {boolean} isHorizontal - search orientation
|
|
43161
|
+
* @returns {object} graph item
|
|
43162
|
+
*/
|
|
43163
|
+
|
|
43022
43164
|
}, {
|
|
43023
|
-
key: "
|
|
43024
|
-
value: function
|
|
43165
|
+
key: "binarySearchBar",
|
|
43166
|
+
value: function binarySearchBar(offset, isHorizontal) {
|
|
43025
43167
|
var _this$filteredCount;
|
|
43026
43168
|
|
|
43027
|
-
var
|
|
43028
|
-
|
|
43169
|
+
var _offset = _slicedToArray(offset, 2),
|
|
43170
|
+
xp = _offset[0],
|
|
43171
|
+
yp = _offset[1];
|
|
43172
|
+
|
|
43029
43173
|
var item = {
|
|
43030
43174
|
data: null,
|
|
43031
43175
|
hit: false,
|
|
@@ -43038,21 +43182,25 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43038
43182
|
|
|
43039
43183
|
while (s <= e) {
|
|
43040
43184
|
var m = Math.floor((s + e) / 2);
|
|
43041
|
-
var
|
|
43042
|
-
var
|
|
43043
|
-
|
|
43044
|
-
|
|
43045
|
-
|
|
43046
|
-
|
|
43047
|
-
|
|
43048
|
-
|
|
43185
|
+
var barData = gdata[m];
|
|
43186
|
+
var sx = barData.xp,
|
|
43187
|
+
sy = barData.yp,
|
|
43188
|
+
w = barData.w,
|
|
43189
|
+
h = barData.h;
|
|
43190
|
+
var ex = sx + w;
|
|
43191
|
+
var ey = sy + h;
|
|
43192
|
+
var inRange = isHorizontal ? ey <= yp && yp <= sy : sx <= xp && xp <= ex;
|
|
43193
|
+
|
|
43194
|
+
if (inRange) {
|
|
43195
|
+
item.data = barData;
|
|
43196
|
+
item.index = barData.index;
|
|
43197
|
+
item.hit = this.isPointInBar(offset, barData);
|
|
43198
|
+
return item;
|
|
43199
|
+
}
|
|
43049
43200
|
|
|
43050
|
-
|
|
43051
|
-
item.hit = true;
|
|
43052
|
-
}
|
|
43201
|
+
var shouldGoRight = isHorizontal ? !(ey < yp) : sx + 4 < xp;
|
|
43053
43202
|
|
|
43054
|
-
|
|
43055
|
-
} else if (sx + 4 < xp) {
|
|
43203
|
+
if (shouldGoRight) {
|
|
43056
43204
|
s = m + 1;
|
|
43057
43205
|
} else {
|
|
43058
43206
|
e = m - 1;
|
|
@@ -43061,6 +43209,11 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43061
43209
|
|
|
43062
43210
|
return item;
|
|
43063
43211
|
}
|
|
43212
|
+
}, {
|
|
43213
|
+
key: "findGraphRange",
|
|
43214
|
+
value: function findGraphRange(offset) {
|
|
43215
|
+
return this.binarySearchBar(offset, false);
|
|
43216
|
+
}
|
|
43064
43217
|
/**
|
|
43065
43218
|
* Find graph item (horizontal)
|
|
43066
43219
|
* @param {array} offset mouse position
|
|
@@ -43071,44 +43224,7 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43071
43224
|
}, {
|
|
43072
43225
|
key: "findGraphRangeCount",
|
|
43073
43226
|
value: function findGraphRangeCount(offset) {
|
|
43074
|
-
|
|
43075
|
-
|
|
43076
|
-
var xp = offset[0];
|
|
43077
|
-
var yp = offset[1];
|
|
43078
|
-
var item = {
|
|
43079
|
-
data: null,
|
|
43080
|
-
hit: false,
|
|
43081
|
-
color: this.color
|
|
43082
|
-
};
|
|
43083
|
-
var gdata = this.data;
|
|
43084
|
-
var totalCount = (_this$filteredCount2 = this.filteredCount) !== null && _this$filteredCount2 !== void 0 ? _this$filteredCount2 : gdata.length;
|
|
43085
|
-
var s = 0;
|
|
43086
|
-
var e = totalCount - 1;
|
|
43087
|
-
|
|
43088
|
-
while (s <= e) {
|
|
43089
|
-
var m = Math.floor((s + e) / 2);
|
|
43090
|
-
var sx = gdata[m].xp;
|
|
43091
|
-
var sy = gdata[m].yp;
|
|
43092
|
-
var ex = sx + gdata[m].w;
|
|
43093
|
-
var ey = sy + gdata[m].h;
|
|
43094
|
-
|
|
43095
|
-
if (ey <= yp && yp <= sy) {
|
|
43096
|
-
item.data = gdata[m];
|
|
43097
|
-
item.index = gdata[m].index; // 원본 데이터 인덱스 사용
|
|
43098
|
-
|
|
43099
|
-
if (sx <= xp && xp <= ex) {
|
|
43100
|
-
item.hit = true;
|
|
43101
|
-
}
|
|
43102
|
-
|
|
43103
|
-
return item;
|
|
43104
|
-
} else if (ey < yp) {
|
|
43105
|
-
e = m - 1;
|
|
43106
|
-
} else {
|
|
43107
|
-
s = m + 1;
|
|
43108
|
-
}
|
|
43109
|
-
}
|
|
43110
|
-
|
|
43111
|
-
return item;
|
|
43227
|
+
return this.binarySearchBar(offset, true);
|
|
43112
43228
|
}
|
|
43113
43229
|
/**
|
|
43114
43230
|
* Draw value label if series 'use' of showValue option is true
|
|
@@ -43247,14 +43363,36 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43247
43363
|
|
|
43248
43364
|
ctx.restore();
|
|
43249
43365
|
}
|
|
43366
|
+
/**
|
|
43367
|
+
* Calculate bar size based on thickness
|
|
43368
|
+
* @private
|
|
43369
|
+
* @param {string|number} thickness - thickness value
|
|
43370
|
+
* @param {number} bArea - available bar area
|
|
43371
|
+
* @returns {number} calculated size
|
|
43372
|
+
*/
|
|
43373
|
+
|
|
43374
|
+
}, {
|
|
43375
|
+
key: "calculateBarSize",
|
|
43376
|
+
value: function calculateBarSize(thickness, bArea) {
|
|
43377
|
+
if (typeof thickness === 'string' && /[0-9]+px/.test(thickness)) {
|
|
43378
|
+
return Math.min(bArea, Number(thickness.replace('px', '')));
|
|
43379
|
+
}
|
|
43380
|
+
|
|
43381
|
+
if (typeof thickness === 'number' && thickness <= 1 && thickness >= 0) {
|
|
43382
|
+
return Math.ceil(bArea * thickness);
|
|
43383
|
+
}
|
|
43384
|
+
|
|
43385
|
+
return bArea;
|
|
43386
|
+
}
|
|
43250
43387
|
}, {
|
|
43251
43388
|
key: "drawBar",
|
|
43252
43389
|
value: function drawBar(_ref6) {
|
|
43253
43390
|
var ctx = _ref6.ctx,
|
|
43254
43391
|
positions = _ref6.positions;
|
|
43255
|
-
var isHorizontal = this.isHorizontal
|
|
43392
|
+
var isHorizontal = this.isHorizontal,
|
|
43393
|
+
borderRadius = this.borderRadius;
|
|
43256
43394
|
var isStackBar = ('stackIndex' in this);
|
|
43257
|
-
var isBorderRadius =
|
|
43395
|
+
var isBorderRadius = borderRadius && borderRadius > 0;
|
|
43258
43396
|
var x = positions.x,
|
|
43259
43397
|
y = positions.y,
|
|
43260
43398
|
w = positions.w;
|
|
@@ -43278,17 +43416,40 @@ var element_bar_Bar = /*#__PURE__*/function () {
|
|
|
43278
43416
|
|
|
43279
43417
|
ctx.restore();
|
|
43280
43418
|
}
|
|
43419
|
+
/**
|
|
43420
|
+
* Check if point is within bar boundaries
|
|
43421
|
+
* @param {array} offset - [x, y] mouse position
|
|
43422
|
+
* @param {object} barData - bar data object with xp, yp, w, h properties
|
|
43423
|
+
* @returns {boolean} true if point is within bar
|
|
43424
|
+
*/
|
|
43425
|
+
|
|
43426
|
+
}, {
|
|
43427
|
+
key: "isPointInBar",
|
|
43428
|
+
value: function isPointInBar(offset, barData) {
|
|
43429
|
+
var _offset2 = _slicedToArray(offset, 2),
|
|
43430
|
+
xp = _offset2[0],
|
|
43431
|
+
yp = _offset2[1];
|
|
43432
|
+
|
|
43433
|
+
var sx = barData.xp,
|
|
43434
|
+
sy = barData.yp,
|
|
43435
|
+
w = barData.w,
|
|
43436
|
+
h = barData.h;
|
|
43437
|
+
var ex = sx + w;
|
|
43438
|
+
var ey = sy + h;
|
|
43439
|
+
return sx <= xp && xp <= ex && ey <= yp && yp <= sy;
|
|
43440
|
+
}
|
|
43281
43441
|
}, {
|
|
43282
43442
|
key: "drawRoundedRect",
|
|
43283
43443
|
value: function drawRoundedRect(ctx, positions) {
|
|
43284
|
-
var chartRect = this.chartRect
|
|
43285
|
-
|
|
43286
|
-
|
|
43444
|
+
var chartRect = this.chartRect,
|
|
43445
|
+
labelOffset = this.labelOffset,
|
|
43446
|
+
isHorizontal = this.isHorizontal,
|
|
43447
|
+
borderRadius = this.borderRadius;
|
|
43287
43448
|
var x = positions.x,
|
|
43288
43449
|
y = positions.y;
|
|
43289
43450
|
var w = positions.w,
|
|
43290
43451
|
h = positions.h;
|
|
43291
|
-
var r =
|
|
43452
|
+
var r = borderRadius;
|
|
43292
43453
|
var squarePath = new Path2D();
|
|
43293
43454
|
squarePath.rect(chartRect.x1 + labelOffset.left, chartRect.y1, chartRect.chartWidth - labelOffset.right, chartRect.chartHeight - labelOffset.bottom);
|
|
43294
43455
|
ctx.clip(squarePath);
|
|
@@ -50430,7 +50591,7 @@ function toFinite(value) {
|
|
|
50430
50591
|
* _.inRange(-3, -2, -6);
|
|
50431
50592
|
* // => true
|
|
50432
50593
|
*/
|
|
50433
|
-
function
|
|
50594
|
+
function inRange_inRange(number, start, end) {
|
|
50434
50595
|
start = lodash_es_toFinite(start);
|
|
50435
50596
|
if (end === undefined) {
|
|
50436
50597
|
end = start;
|
|
@@ -50442,7 +50603,7 @@ function inRange(number, start, end) {
|
|
|
50442
50603
|
return _baseInRange(number, start, end);
|
|
50443
50604
|
}
|
|
50444
50605
|
|
|
50445
|
-
/* harmony default export */ var lodash_es_inRange = (
|
|
50606
|
+
/* harmony default export */ var lodash_es_inRange = (inRange_inRange);
|
|
50446
50607
|
|
|
50447
50608
|
// CONCATENATED MODULE: ./src/components/chart/plugins/plugins.interaction.js
|
|
50448
50609
|
|
|
@@ -50464,6 +50625,8 @@ function inRange(number, start, end) {
|
|
|
50464
50625
|
|
|
50465
50626
|
|
|
50466
50627
|
|
|
50628
|
+
|
|
50629
|
+
|
|
50467
50630
|
|
|
50468
50631
|
|
|
50469
50632
|
|
|
@@ -50549,6 +50712,29 @@ var plugins_interaction_modules = {
|
|
|
50549
50712
|
_this.drawTooltip(hitInfo, _this.tooltipCtx);
|
|
50550
50713
|
}
|
|
50551
50714
|
}
|
|
50715
|
+
} // tooltip이 표시될 때 indicator를 해당 라벨 위치로 이동 (line 차트이거나 line series가 포함된 경우)
|
|
50716
|
+
|
|
50717
|
+
|
|
50718
|
+
var hasLineSeries = Object.values(_this.seriesList || {}).some(function (series) {
|
|
50719
|
+
return series.type === 'line';
|
|
50720
|
+
});
|
|
50721
|
+
|
|
50722
|
+
if (tooltip.use && (type === 'line' || hasLineSeries)) {
|
|
50723
|
+
// indicator를 그리고 실제 위치한 라벨 정보를 받음
|
|
50724
|
+
var indicatorInfo = _this.drawIndicatorForTooltip(hitInfo, indicator.color); // 실제 indicator가 위치한 라벨 값을 동기화에 사용
|
|
50725
|
+
|
|
50726
|
+
|
|
50727
|
+
var actualLabelValue = indicatorInfo === null || indicatorInfo === void 0 ? void 0 : indicatorInfo.labelValue;
|
|
50728
|
+
|
|
50729
|
+
var label = _this.getTimeLabel(offset);
|
|
50730
|
+
|
|
50731
|
+
args.hoveredLabel = {
|
|
50732
|
+
horizontal: _this.options.horizontal,
|
|
50733
|
+
label: label,
|
|
50734
|
+
mousePosition: [e.clientX, e.clientY],
|
|
50735
|
+
dataLabel: actualLabelValue,
|
|
50736
|
+
isTooltipBased: true
|
|
50737
|
+
};
|
|
50552
50738
|
}
|
|
50553
50739
|
} else if (tooltip.use && _this.isInitTooltip) {
|
|
50554
50740
|
if (typeof (tooltip === null || tooltip === void 0 ? void 0 : tooltip.returnValue) === 'function') {
|
|
@@ -50560,19 +50746,28 @@ var plugins_interaction_modules = {
|
|
|
50560
50746
|
|
|
50561
50747
|
if (_this.dragInfoBackup) {
|
|
50562
50748
|
_this.drawSelectionArea(_this.dragInfoBackup);
|
|
50563
|
-
}
|
|
50749
|
+
} // tooltip 기반 indicator가 아직 설정되지 않은 경우에만 일반 indicator 처리
|
|
50750
|
+
|
|
50564
50751
|
|
|
50565
|
-
if (
|
|
50566
|
-
|
|
50752
|
+
if (!args.hoveredLabel && type !== 'pie' && type !== 'scatter' && type !== 'heatMap') {
|
|
50753
|
+
// line 차트가 아니고 line series가 없거나, tooltip이 없을 때는 일반 indicator 표시
|
|
50754
|
+
var _hasLineSeries = Object.values(_this.seriesList || {}).some(function (series) {
|
|
50755
|
+
return series.type === 'line';
|
|
50756
|
+
});
|
|
50757
|
+
|
|
50758
|
+
if (type !== 'line' && !_hasLineSeries || !tooltip.use || !Object.keys(hitInfo.items).length) {
|
|
50759
|
+
_this.drawIndicator(offset, indicator.color);
|
|
50760
|
+
}
|
|
50567
50761
|
|
|
50568
|
-
var
|
|
50762
|
+
var _label = _this.getTimeLabel(offset);
|
|
50569
50763
|
|
|
50570
50764
|
args.hoveredLabel = {
|
|
50571
50765
|
horizontal: _this.options.horizontal,
|
|
50572
|
-
label:
|
|
50573
|
-
mousePosition: [e.clientX, e.clientY]
|
|
50766
|
+
label: _label,
|
|
50767
|
+
mousePosition: [e.clientX, e.clientY],
|
|
50768
|
+
isTooltipBased: false
|
|
50574
50769
|
};
|
|
50575
|
-
} else {
|
|
50770
|
+
} else if (!args.hoveredLabel) {
|
|
50576
50771
|
args.hoveredLabel = {
|
|
50577
50772
|
label: ''
|
|
50578
50773
|
};
|
|
@@ -51437,6 +51632,8 @@ var plugins_interaction_modules = {
|
|
|
51437
51632
|
* @returns {object} hit item information
|
|
51438
51633
|
*/
|
|
51439
51634
|
findHitItem: function findHitItem(offset) {
|
|
51635
|
+
var _this4 = this;
|
|
51636
|
+
|
|
51440
51637
|
var sIds = Object.keys(this.seriesList);
|
|
51441
51638
|
var items = {};
|
|
51442
51639
|
var isHorizontal = !!this.options.horizontal;
|
|
@@ -51446,66 +51643,153 @@ var plugins_interaction_modules = {
|
|
|
51446
51643
|
var maxsw = 0;
|
|
51447
51644
|
var maxv = '';
|
|
51448
51645
|
var maxg = null;
|
|
51449
|
-
var maxSID = null;
|
|
51646
|
+
var maxSID = null; // 파이 차트는 특별한 처리가 필요
|
|
51450
51647
|
|
|
51451
|
-
|
|
51452
|
-
var
|
|
51453
|
-
|
|
51648
|
+
if (this.options.type === 'pie') {
|
|
51649
|
+
for (var ix = 0; ix < sIds.length; ix++) {
|
|
51650
|
+
var sId = sIds[ix];
|
|
51651
|
+
var series = this.seriesList[sId];
|
|
51652
|
+
|
|
51653
|
+
if (series.findGraphData && series.show) {
|
|
51654
|
+
var item = series.findGraphData(offset);
|
|
51655
|
+
|
|
51656
|
+
if (item !== null && item !== void 0 && item.data && item.hit) {
|
|
51657
|
+
var gdata = item.data.o;
|
|
51658
|
+
|
|
51659
|
+
if (gdata !== null && gdata !== undefined) {
|
|
51660
|
+
var formattedSeriesName = this.getFormattedTooltipLabel({
|
|
51661
|
+
dataId: series.id,
|
|
51662
|
+
seriesId: sId,
|
|
51663
|
+
seriesName: series.name,
|
|
51664
|
+
itemData: item.data
|
|
51665
|
+
});
|
|
51666
|
+
var sw = ctx ? ctx.measureText(formattedSeriesName).width : 1;
|
|
51667
|
+
item.id = series.id;
|
|
51668
|
+
item.name = formattedSeriesName;
|
|
51669
|
+
item.axis = {
|
|
51670
|
+
x: 0,
|
|
51671
|
+
y: 0
|
|
51672
|
+
};
|
|
51673
|
+
items[sId] = item;
|
|
51674
|
+
var formattedTxt = this.getFormattedTooltipValue({
|
|
51675
|
+
dataId: series.id,
|
|
51676
|
+
seriesId: sId,
|
|
51677
|
+
seriesName: formattedSeriesName,
|
|
51678
|
+
value: gdata,
|
|
51679
|
+
itemData: item.data
|
|
51680
|
+
});
|
|
51681
|
+
item.data.formatted = formattedTxt;
|
|
51682
|
+
|
|
51683
|
+
if (maxsw < sw) {
|
|
51684
|
+
maxs = formattedSeriesName;
|
|
51685
|
+
maxsw = sw;
|
|
51686
|
+
}
|
|
51687
|
+
|
|
51688
|
+
if (maxv.length <= "".concat(formattedTxt).length) {
|
|
51689
|
+
maxv = "".concat(formattedTxt);
|
|
51690
|
+
}
|
|
51691
|
+
|
|
51692
|
+
if (maxg === null || maxg <= gdata) {
|
|
51693
|
+
maxg = gdata;
|
|
51694
|
+
maxSID = sId;
|
|
51695
|
+
}
|
|
51696
|
+
|
|
51697
|
+
hitId = sId;
|
|
51698
|
+
}
|
|
51699
|
+
}
|
|
51700
|
+
}
|
|
51701
|
+
}
|
|
51702
|
+
|
|
51703
|
+
var _maxHighlight2 = maxg !== null ? [maxSID, maxg] : null;
|
|
51704
|
+
|
|
51705
|
+
return {
|
|
51706
|
+
items: items,
|
|
51707
|
+
hitId: hitId,
|
|
51708
|
+
maxTip: [maxs, maxv],
|
|
51709
|
+
maxHighlight: _maxHighlight2
|
|
51710
|
+
};
|
|
51711
|
+
} // 1. 먼저 공통으로 사용할 데이터 인덱스 결정
|
|
51712
|
+
|
|
51713
|
+
|
|
51714
|
+
var targetDataIndex = this.findClosestDataIndex(offset, sIds);
|
|
51715
|
+
|
|
51716
|
+
if (targetDataIndex === -1) {
|
|
51717
|
+
return {
|
|
51718
|
+
items: items,
|
|
51719
|
+
hitId: hitId,
|
|
51720
|
+
maxTip: [maxs, maxv],
|
|
51721
|
+
maxHighlight: null
|
|
51722
|
+
};
|
|
51723
|
+
} // 2. 모든 시리즈가 동일한 데이터 인덱스 사용
|
|
51724
|
+
|
|
51725
|
+
|
|
51726
|
+
var allSeriesIsBar = sIds.every(function (sId) {
|
|
51727
|
+
return _this4.seriesList[sId].type === 'bar';
|
|
51728
|
+
});
|
|
51729
|
+
|
|
51730
|
+
for (var _ix = 0; _ix < sIds.length; _ix++) {
|
|
51731
|
+
var _sId = sIds[_ix];
|
|
51732
|
+
var _series = this.seriesList[_sId];
|
|
51454
51733
|
|
|
51455
|
-
if (
|
|
51456
|
-
|
|
51734
|
+
if (_series.findGraphData && _series.show) {
|
|
51735
|
+
// 특정 데이터 인덱스로 데이터 요청
|
|
51736
|
+
var _item = _series.findGraphData(offset, isHorizontal, targetDataIndex, !allSeriesIsBar);
|
|
51457
51737
|
|
|
51458
|
-
if (
|
|
51459
|
-
var
|
|
51738
|
+
if (_item !== null && _item !== void 0 && _item.data) {
|
|
51739
|
+
var _gdata = void 0;
|
|
51460
51740
|
|
|
51461
|
-
if (
|
|
51462
|
-
if (!
|
|
51463
|
-
|
|
51741
|
+
if (_item.data.o === null && _series.interpolation !== 'zero') {
|
|
51742
|
+
if (!_series.isExistGrp) {
|
|
51743
|
+
_gdata = isHorizontal ? _item.data.x : _item.data.y;
|
|
51464
51744
|
}
|
|
51465
|
-
} else if (!isNaN(
|
|
51466
|
-
|
|
51745
|
+
} else if (!isNaN(_item.data.o)) {
|
|
51746
|
+
_gdata = _item.data.o;
|
|
51467
51747
|
}
|
|
51468
51748
|
|
|
51469
|
-
if (
|
|
51470
|
-
var
|
|
51471
|
-
dataId:
|
|
51472
|
-
seriesId:
|
|
51473
|
-
seriesName:
|
|
51474
|
-
itemData:
|
|
51749
|
+
if (_gdata !== null && _gdata !== undefined) {
|
|
51750
|
+
var _formattedSeriesName = this.getFormattedTooltipLabel({
|
|
51751
|
+
dataId: _series.id,
|
|
51752
|
+
seriesId: _sId,
|
|
51753
|
+
seriesName: _series.name,
|
|
51754
|
+
itemData: _item.data
|
|
51475
51755
|
});
|
|
51476
|
-
|
|
51477
|
-
|
|
51478
|
-
|
|
51479
|
-
|
|
51480
|
-
|
|
51481
|
-
|
|
51756
|
+
|
|
51757
|
+
var _sw = ctx ? ctx.measureText(_formattedSeriesName).width : 1;
|
|
51758
|
+
|
|
51759
|
+
_item.id = _series.id;
|
|
51760
|
+
_item.name = _formattedSeriesName;
|
|
51761
|
+
_item.axis = {
|
|
51762
|
+
x: _series.xAxisIndex,
|
|
51763
|
+
y: _series.yAxisIndex
|
|
51482
51764
|
};
|
|
51483
|
-
items[
|
|
51484
|
-
|
|
51485
|
-
|
|
51486
|
-
|
|
51487
|
-
|
|
51488
|
-
|
|
51489
|
-
|
|
51765
|
+
items[_sId] = _item;
|
|
51766
|
+
|
|
51767
|
+
var _formattedTxt = this.getFormattedTooltipValue({
|
|
51768
|
+
dataId: _series.id,
|
|
51769
|
+
seriesId: _sId,
|
|
51770
|
+
seriesName: _formattedSeriesName,
|
|
51771
|
+
value: _gdata,
|
|
51772
|
+
itemData: _item.data
|
|
51490
51773
|
});
|
|
51491
|
-
item.data.formatted = formattedTxt;
|
|
51492
51774
|
|
|
51493
|
-
|
|
51494
|
-
|
|
51495
|
-
|
|
51775
|
+
_item.data.formatted = _formattedTxt;
|
|
51776
|
+
|
|
51777
|
+
if (maxsw < _sw) {
|
|
51778
|
+
maxs = _formattedSeriesName;
|
|
51779
|
+
maxsw = _sw;
|
|
51496
51780
|
}
|
|
51497
51781
|
|
|
51498
|
-
if (maxv.length <= "".concat(
|
|
51499
|
-
maxv = "".concat(
|
|
51782
|
+
if (maxv.length <= "".concat(_formattedTxt).length) {
|
|
51783
|
+
maxv = "".concat(_formattedTxt);
|
|
51500
51784
|
}
|
|
51501
51785
|
|
|
51502
|
-
if (maxg === null || maxg <=
|
|
51503
|
-
maxg =
|
|
51504
|
-
maxSID =
|
|
51786
|
+
if (maxg === null || maxg <= _gdata) {
|
|
51787
|
+
maxg = _gdata;
|
|
51788
|
+
maxSID = _sId;
|
|
51505
51789
|
}
|
|
51506
51790
|
|
|
51507
|
-
if (
|
|
51508
|
-
hitId =
|
|
51791
|
+
if (_item.hit) {
|
|
51792
|
+
hitId = _sId;
|
|
51509
51793
|
}
|
|
51510
51794
|
}
|
|
51511
51795
|
}
|
|
@@ -51522,6 +51806,78 @@ var plugins_interaction_modules = {
|
|
|
51522
51806
|
};
|
|
51523
51807
|
},
|
|
51524
51808
|
|
|
51809
|
+
/**
|
|
51810
|
+
* Find the closest data index (label) based on mouse position
|
|
51811
|
+
* @param {array} offset mouse position
|
|
51812
|
+
* @param {array} sIds series IDs
|
|
51813
|
+
* @returns {number} closest data index
|
|
51814
|
+
*/
|
|
51815
|
+
findClosestDataIndex: function findClosestDataIndex(offset, sIds) {
|
|
51816
|
+
var _this5 = this,
|
|
51817
|
+
_this$seriesList$refe;
|
|
51818
|
+
|
|
51819
|
+
var _offset = _slicedToArray(offset, 2),
|
|
51820
|
+
xp = _offset[0],
|
|
51821
|
+
yp = _offset[1];
|
|
51822
|
+
|
|
51823
|
+
var isHorizontal = !!this.options.horizontal;
|
|
51824
|
+
var mousePos = isHorizontal ? yp : xp;
|
|
51825
|
+
var closestDistance = Infinity;
|
|
51826
|
+
var closestIndex = -1; // 첫 번째 표시 중인 시리즈를 기준으로 라벨 위치 확인
|
|
51827
|
+
|
|
51828
|
+
var referenceSeries = sIds.find(function (sId) {
|
|
51829
|
+
var _this5$seriesList$sId;
|
|
51830
|
+
|
|
51831
|
+
return (_this5$seriesList$sId = _this5.seriesList[sId]) === null || _this5$seriesList$sId === void 0 ? void 0 : _this5$seriesList$sId.show;
|
|
51832
|
+
});
|
|
51833
|
+
|
|
51834
|
+
if (!referenceSeries || !((_this$seriesList$refe = this.seriesList[referenceSeries]) !== null && _this$seriesList$refe !== void 0 && _this$seriesList$refe.data)) {
|
|
51835
|
+
return -1;
|
|
51836
|
+
}
|
|
51837
|
+
|
|
51838
|
+
var referenceData = this.seriesList[referenceSeries].data; // 각 라벨에서 가장 가까운 것 찾기
|
|
51839
|
+
|
|
51840
|
+
var _loop = function _loop(i) {
|
|
51841
|
+
// 이 라벨에 유효한 데이터가 있는 시리즈가 하나 이상 있는지 확인
|
|
51842
|
+
var hasValidData = sIds.some(function (sId) {
|
|
51843
|
+
var _series$data, _series$data$i, _series$data2, _series$data2$i;
|
|
51844
|
+
|
|
51845
|
+
var series = _this5.seriesList[sId];
|
|
51846
|
+
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;
|
|
51847
|
+
});
|
|
51848
|
+
|
|
51849
|
+
if (hasValidData) {
|
|
51850
|
+
var point = referenceData[i];
|
|
51851
|
+
|
|
51852
|
+
if (point) {
|
|
51853
|
+
// 라벨 위치 계산
|
|
51854
|
+
var labelPos;
|
|
51855
|
+
|
|
51856
|
+
if (isHorizontal) {
|
|
51857
|
+
labelPos = point.h ? point.yp + point.h / 2 : point.yp;
|
|
51858
|
+
} else {
|
|
51859
|
+
labelPos = point.w ? point.xp + point.w / 2 : point.xp;
|
|
51860
|
+
}
|
|
51861
|
+
|
|
51862
|
+
if (labelPos !== null) {
|
|
51863
|
+
var distance = Math.abs(mousePos - labelPos);
|
|
51864
|
+
|
|
51865
|
+
if (distance < closestDistance) {
|
|
51866
|
+
closestDistance = distance;
|
|
51867
|
+
closestIndex = i;
|
|
51868
|
+
}
|
|
51869
|
+
}
|
|
51870
|
+
}
|
|
51871
|
+
}
|
|
51872
|
+
};
|
|
51873
|
+
|
|
51874
|
+
for (var i = 0; i < referenceData.length; i++) {
|
|
51875
|
+
_loop(i);
|
|
51876
|
+
}
|
|
51877
|
+
|
|
51878
|
+
return closestIndex;
|
|
51879
|
+
},
|
|
51880
|
+
|
|
51525
51881
|
/**
|
|
51526
51882
|
* get formatted label for tooltip
|
|
51527
51883
|
* @param dataId
|
|
@@ -51651,9 +52007,9 @@ var plugins_interaction_modules = {
|
|
|
51651
52007
|
seriesName: formattedSeriesName,
|
|
51652
52008
|
value: hasData === null || hasData === void 0 ? void 0 : hasData.o,
|
|
51653
52009
|
itemData: hasData
|
|
51654
|
-
});
|
|
52010
|
+
}); // Only add data if there's a valid value for this exact label
|
|
51655
52011
|
|
|
51656
|
-
if (hasData && !hitInfo.items[sId]) {
|
|
52012
|
+
if (hasData && hasData.o !== null && hasData.o !== undefined && !hitInfo.items[sId]) {
|
|
51657
52013
|
var item = {};
|
|
51658
52014
|
item.color = series.color;
|
|
51659
52015
|
item.hit = false;
|
|
@@ -51743,7 +52099,7 @@ var plugins_interaction_modules = {
|
|
|
51743
52099
|
* @returns {object[]}
|
|
51744
52100
|
*/
|
|
51745
52101
|
getSelectedLabelInfoWithLabelData: function getSelectedLabelInfoWithLabelData(labelIndexList, targetAxis) {
|
|
51746
|
-
var
|
|
52102
|
+
var _this6 = this;
|
|
51747
52103
|
|
|
51748
52104
|
var _this$options9 = this.options,
|
|
51749
52105
|
selectLabelOpt = _this$options9.selectLabel,
|
|
@@ -51759,7 +52115,7 @@ var plugins_interaction_modules = {
|
|
|
51759
52115
|
{
|
|
51760
52116
|
result.dataIndex.splice(selectLabelOpt.limit);
|
|
51761
52117
|
result.label = result.dataIndex.map(function (i) {
|
|
51762
|
-
return
|
|
52118
|
+
return _this6.data.labels[i];
|
|
51763
52119
|
});
|
|
51764
52120
|
var dataEntries = Object.entries(this.data.data);
|
|
51765
52121
|
result.data = result.dataIndex.map(function (labelIdx) {
|
|
@@ -51789,7 +52145,7 @@ var plugins_interaction_modules = {
|
|
|
51789
52145
|
}
|
|
51790
52146
|
|
|
51791
52147
|
result.label = result.dataIndex.map(function (i) {
|
|
51792
|
-
return
|
|
52148
|
+
return _this6.data.labels[targetAxisDirection][i];
|
|
51793
52149
|
});
|
|
51794
52150
|
var dataValues = Object.values(this.data.data)[0];
|
|
51795
52151
|
result.data = dataValues.filter(function (_ref6) {
|
|
@@ -51880,6 +52236,76 @@ var plugins_interaction_modules = {
|
|
|
51880
52236
|
return after;
|
|
51881
52237
|
},
|
|
51882
52238
|
|
|
52239
|
+
/**
|
|
52240
|
+
* Draw indicator at the label position when tooltip is displayed
|
|
52241
|
+
* @param {object} hitInfo hit item information from findHitItem
|
|
52242
|
+
* @param {string} color indicator color
|
|
52243
|
+
* @returns {object|null} indicator position info with actual label value
|
|
52244
|
+
*/
|
|
52245
|
+
drawIndicatorForTooltip: function drawIndicatorForTooltip(hitInfo, color) {
|
|
52246
|
+
var _this$options$indicat;
|
|
52247
|
+
|
|
52248
|
+
if (!(hitInfo !== null && hitInfo !== void 0 && hitInfo.items) || !Object.keys(hitInfo.items).length) {
|
|
52249
|
+
return null;
|
|
52250
|
+
}
|
|
52251
|
+
|
|
52252
|
+
var ctx = this.overlayCtx;
|
|
52253
|
+
var horizontal = this.options.horizontal;
|
|
52254
|
+
var graphPos = {
|
|
52255
|
+
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
52256
|
+
x2: this.chartRect.x2 - this.labelOffset.right,
|
|
52257
|
+
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
52258
|
+
y2: this.chartRect.y2 - this.labelOffset.bottom
|
|
52259
|
+
}; // 첫 번째 시리즈의 데이터를 기준으로 라벨 위치 계산
|
|
52260
|
+
|
|
52261
|
+
var firstSeriesId = Object.keys(hitInfo.items)[0];
|
|
52262
|
+
var firstItem = hitInfo.items[firstSeriesId];
|
|
52263
|
+
|
|
52264
|
+
if (!(firstItem !== null && firstItem !== void 0 && firstItem.data)) {
|
|
52265
|
+
return null;
|
|
52266
|
+
} // 실제 indicator가 위치하는 라벨 값 추출
|
|
52267
|
+
|
|
52268
|
+
|
|
52269
|
+
var actualLabelValue = horizontal ? firstItem.data.y : firstItem.data.x;
|
|
52270
|
+
var indicatorPosition;
|
|
52271
|
+
|
|
52272
|
+
if (horizontal) {
|
|
52273
|
+
// 수평 차트에서는 Y축 라벨 위치에 수평선
|
|
52274
|
+
var yPosition = firstItem.data.yp + (firstItem.data.h ? firstItem.data.h / 2 : 0);
|
|
52275
|
+
indicatorPosition = [graphPos.x1, yPosition];
|
|
52276
|
+
} else {
|
|
52277
|
+
// 수직 차트에서는 X축 라벨 위치에 수직선
|
|
52278
|
+
var xPosition = firstItem.data.xp + (firstItem.data.w ? firstItem.data.w / 2 : 0);
|
|
52279
|
+
indicatorPosition = [xPosition, graphPos.y1];
|
|
52280
|
+
}
|
|
52281
|
+
|
|
52282
|
+
ctx.beginPath();
|
|
52283
|
+
ctx.save();
|
|
52284
|
+
ctx.strokeStyle = color;
|
|
52285
|
+
ctx.lineWidth = 1;
|
|
52286
|
+
|
|
52287
|
+
if ((_this$options$indicat = this.options.indicator) !== null && _this$options$indicat !== void 0 && _this$options$indicat.segments) {
|
|
52288
|
+
ctx.setLineDash(this.options.indicator.segments);
|
|
52289
|
+
}
|
|
52290
|
+
|
|
52291
|
+
if (horizontal) {
|
|
52292
|
+
ctx.moveTo(graphPos.x1, indicatorPosition[1] + 0.5);
|
|
52293
|
+
ctx.lineTo(graphPos.x2, indicatorPosition[1] + 0.5);
|
|
52294
|
+
} else {
|
|
52295
|
+
ctx.moveTo(indicatorPosition[0] + 0.5, graphPos.y1);
|
|
52296
|
+
ctx.lineTo(indicatorPosition[0] + 0.5, graphPos.y2);
|
|
52297
|
+
}
|
|
52298
|
+
|
|
52299
|
+
ctx.stroke();
|
|
52300
|
+
ctx.restore();
|
|
52301
|
+
ctx.closePath(); // 실제 indicator가 위치한 라벨 정보 반환
|
|
52302
|
+
|
|
52303
|
+
return {
|
|
52304
|
+
labelValue: actualLabelValue,
|
|
52305
|
+
position: indicatorPosition
|
|
52306
|
+
};
|
|
52307
|
+
},
|
|
52308
|
+
|
|
51883
52309
|
/**
|
|
51884
52310
|
* Find items by series within a range
|
|
51885
52311
|
* @param {object} range object for find series items
|
|
@@ -52012,9 +52438,9 @@ var plugins_interaction_modules = {
|
|
|
52012
52438
|
* @returns {string}
|
|
52013
52439
|
*/
|
|
52014
52440
|
getCurMouseLocation: function getCurMouseLocation(offset) {
|
|
52015
|
-
var
|
|
52016
|
-
offsetX =
|
|
52017
|
-
offsetY =
|
|
52441
|
+
var _offset2 = _slicedToArray(offset, 2),
|
|
52442
|
+
offsetX = _offset2[0],
|
|
52443
|
+
offsetY = _offset2[1];
|
|
52018
52444
|
|
|
52019
52445
|
var aPos = {
|
|
52020
52446
|
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
@@ -52074,6 +52500,8 @@ var plugins_interaction_modules = {
|
|
|
52074
52500
|
|
|
52075
52501
|
|
|
52076
52502
|
|
|
52503
|
+
|
|
52504
|
+
|
|
52077
52505
|
|
|
52078
52506
|
var LINE_SPACING = 8;
|
|
52079
52507
|
var VALUE_MARGIN = 50;
|
|
@@ -52865,9 +53293,10 @@ var plugins_tooltip_modules = {
|
|
|
52865
53293
|
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
52866
53294
|
y2: this.chartRect.y2 - this.labelOffset.bottom
|
|
52867
53295
|
};
|
|
52868
|
-
var mouseXIp =
|
|
53296
|
+
var mouseXIp = 15; // mouseInterpolation - 더 넓은 범위에서 감지
|
|
53297
|
+
|
|
53298
|
+
var mouseYIp = 15; // Y축도 동일하게 증가
|
|
52869
53299
|
|
|
52870
|
-
var mouseYIp = 10;
|
|
52871
53300
|
var options = this.options;
|
|
52872
53301
|
|
|
52873
53302
|
if (offsetX >= graphPos.x1 - mouseXIp && offsetX <= graphPos.x2 + mouseXIp && offsetY >= graphPos.y1 - mouseYIp && offsetY <= graphPos.y2 + mouseYIp) {
|
|
@@ -52961,11 +53390,23 @@ var plugins_tooltip_modules = {
|
|
|
52961
53390
|
|
|
52962
53391
|
var horizontal = _ref5.horizontal,
|
|
52963
53392
|
label = _ref5.label,
|
|
52964
|
-
mousePosition = _ref5.mousePosition
|
|
53393
|
+
mousePosition = _ref5.mousePosition,
|
|
53394
|
+
dataLabel = _ref5.dataLabel,
|
|
53395
|
+
isTooltipBased = _ref5.isTooltipBased;
|
|
52965
53396
|
|
|
52966
53397
|
if (!mousePosition || !!horizontal !== !!this.options.horizontal) {
|
|
52967
53398
|
return;
|
|
52968
|
-
}
|
|
53399
|
+
} // tooltip 기반 동기화인 경우
|
|
53400
|
+
|
|
53401
|
+
|
|
53402
|
+
if (isTooltipBased) {
|
|
53403
|
+
this.drawSyncedIndicatorForTooltip({
|
|
53404
|
+
dataLabel: dataLabel,
|
|
53405
|
+
mousePosition: mousePosition
|
|
53406
|
+
});
|
|
53407
|
+
return;
|
|
53408
|
+
} // 기존 시간 기반 동기화
|
|
53409
|
+
|
|
52969
53410
|
|
|
52970
53411
|
if (this.options.syncHover === false || !horizontal && !this.options.axesX.every(function (_ref6) {
|
|
52971
53412
|
var type = _ref6.type;
|
|
@@ -53019,6 +53460,82 @@ var plugins_tooltip_modules = {
|
|
|
53019
53460
|
}
|
|
53020
53461
|
},
|
|
53021
53462
|
|
|
53463
|
+
/**
|
|
53464
|
+
* 제공된 dataLabel과 일치하는 Label이 있다면 indicator를 그림
|
|
53465
|
+
* @param {object} dataLabel data label
|
|
53466
|
+
* @param {object} mousePosition mouse position
|
|
53467
|
+
*
|
|
53468
|
+
* @returns {undefined}
|
|
53469
|
+
*/
|
|
53470
|
+
drawSyncedIndicatorForTooltip: function drawSyncedIndicatorForTooltip(_ref8) {
|
|
53471
|
+
var _this$data;
|
|
53472
|
+
|
|
53473
|
+
var dataLabel = _ref8.dataLabel,
|
|
53474
|
+
mousePosition = _ref8.mousePosition;
|
|
53475
|
+
|
|
53476
|
+
if (!((_this$data = this.data) !== null && _this$data !== void 0 && _this$data.labels) || !dataLabel) {
|
|
53477
|
+
return;
|
|
53478
|
+
}
|
|
53479
|
+
|
|
53480
|
+
var matchingLabelIndex = this.data.labels.findIndex(function (label) {
|
|
53481
|
+
return (label === null || label === void 0 ? void 0 : label.valueOf()) === (dataLabel === null || dataLabel === void 0 ? void 0 : dataLabel.valueOf());
|
|
53482
|
+
});
|
|
53483
|
+
|
|
53484
|
+
if (matchingLabelIndex === -1) {
|
|
53485
|
+
this.overlayClear();
|
|
53486
|
+
return;
|
|
53487
|
+
}
|
|
53488
|
+
|
|
53489
|
+
var horizontal = this.options.horizontal;
|
|
53490
|
+
|
|
53491
|
+
var _this$chartDOM$getBou2 = this.chartDOM.getBoundingClientRect(),
|
|
53492
|
+
top = _this$chartDOM$getBou2.top,
|
|
53493
|
+
bottom = _this$chartDOM$getBou2.bottom,
|
|
53494
|
+
left = _this$chartDOM$getBou2.left,
|
|
53495
|
+
right = _this$chartDOM$getBou2.right;
|
|
53496
|
+
|
|
53497
|
+
var isHoveredChart = lodash_es_inRange(mousePosition[0], left, right) && lodash_es_inRange(mousePosition[1], bottom, top);
|
|
53498
|
+
|
|
53499
|
+
if (isHoveredChart) {
|
|
53500
|
+
return;
|
|
53501
|
+
}
|
|
53502
|
+
|
|
53503
|
+
this.overlayClear();
|
|
53504
|
+
var graphPos = {
|
|
53505
|
+
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
53506
|
+
x2: this.chartRect.x2 - this.labelOffset.right,
|
|
53507
|
+
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
53508
|
+
y2: this.chartRect.y2 - this.labelOffset.bottom
|
|
53509
|
+
};
|
|
53510
|
+
var labelsCount = this.data.labels.length;
|
|
53511
|
+
var indicatorPosition;
|
|
53512
|
+
|
|
53513
|
+
if (horizontal) {
|
|
53514
|
+
var _this$options$axesY;
|
|
53515
|
+
|
|
53516
|
+
var chartHeight = graphPos.y2 - graphPos.y1; // CategoryMode인 경우 라벨들이 균등 간격으로 배치됨
|
|
53517
|
+
|
|
53518
|
+
var isCategoryMode = (_this$options$axesY = this.options.axesY) === null || _this$options$axesY === void 0 ? void 0 : _this$options$axesY.some(function (axis) {
|
|
53519
|
+
return axis.categoryMode;
|
|
53520
|
+
});
|
|
53521
|
+
var positionY = isCategoryMode ? graphPos.y1 + chartHeight * (matchingLabelIndex + 0.5) / labelsCount : graphPos.y1 + chartHeight * matchingLabelIndex / (labelsCount - 1);
|
|
53522
|
+
indicatorPosition = [graphPos.x2, positionY];
|
|
53523
|
+
} else {
|
|
53524
|
+
var _this$options$axesX;
|
|
53525
|
+
|
|
53526
|
+
var chartWidth = graphPos.x2 - graphPos.x1; // CategoryMode인 경우 라벨들이 균등 간격으로 배치됨
|
|
53527
|
+
|
|
53528
|
+
var _isCategoryMode = (_this$options$axesX = this.options.axesX) === null || _this$options$axesX === void 0 ? void 0 : _this$options$axesX.some(function (axis) {
|
|
53529
|
+
return axis.categoryMode;
|
|
53530
|
+
});
|
|
53531
|
+
|
|
53532
|
+
var positionX = _isCategoryMode ? graphPos.x1 + chartWidth * (matchingLabelIndex + 0.5) / labelsCount : graphPos.x1 + chartWidth * matchingLabelIndex / (labelsCount - 1);
|
|
53533
|
+
indicatorPosition = [positionX, graphPos.y2];
|
|
53534
|
+
}
|
|
53535
|
+
|
|
53536
|
+
this.drawIndicator(indicatorPosition, this.options.indicator.color);
|
|
53537
|
+
},
|
|
53538
|
+
|
|
53022
53539
|
/**
|
|
53023
53540
|
* Clear tooltip canvas
|
|
53024
53541
|
*
|