evui 3.1.52 → 3.1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evui",
3
- "version": "3.1.52",
3
+ "version": "3.1.56",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -2,19 +2,17 @@
2
2
  <div class="ev-calendar-wrapper">
3
3
  <div class="ev-calendar-date-area">
4
4
  <div class="ev-calendar-header">
5
- <div>
6
- <i
7
- class="ev-icon-s-arrow-left move-month-arrow"
8
- @click="clickPrevNextBtn('main', 'prev')"
9
- />
5
+ <div @click="clickPrevNextBtn('main', 'prev')">
6
+ <i class="ev-icon-s-arrow-left move-month-arrow" />
10
7
  </div>
11
8
  <span class="ev-calendar-year">{{ mainCalendarPageInfo.year }}</span>
12
9
  <span class="ev-calendar-month">{{ mainCalendarMonth }}</span>
13
- <div>
10
+ <div @click="clickPrevNextBtn('main', 'next')">
14
11
  <i
15
- class="ev-icon-s-arrow-right move-month-arrow"
16
- :class="{ disabled: isContinuousMonths }"
17
- @click="clickPrevNextBtn('main', 'next')"
12
+ :class="[
13
+ 'ev-icon-s-arrow-right move-month-arrow',
14
+ { disabled: isContinuousMonths },
15
+ ]"
18
16
  />
19
17
  </div>
20
18
  </div>
@@ -133,20 +131,18 @@
133
131
  class="ev-calendar-date-area"
134
132
  >
135
133
  <div class="ev-calendar-header">
136
- <div>
134
+ <div @click="clickPrevNextBtn('expanded', 'prev')">
137
135
  <i
138
- class="ev-icon-s-arrow-left move-month-arrow"
139
- :class="{ disabled: isContinuousMonths }"
140
- @click="clickPrevNextBtn('expanded', 'prev')"
136
+ :class="[
137
+ 'ev-icon-s-arrow-left move-month-arrow',
138
+ { disabled: isContinuousMonths },
139
+ ]"
141
140
  />
142
141
  </div>
143
142
  <span class="ev-calendar-year">{{ expandedCalendarPageInfo.year }}</span>
144
143
  <span class="ev-calendar-month">{{ expandedCalendarMonth }}</span>
145
- <div>
146
- <i
147
- class="ev-icon-s-arrow-right move-month-arrow"
148
- @click="clickPrevNextBtn('expanded', 'next')"
149
- />
144
+ <div @click="clickPrevNextBtn('expanded', 'next')">
145
+ <i class="ev-icon-s-arrow-right move-month-arrow" />
150
146
  </div>
151
147
  </div>
152
148
  <div class="ev-calendar-body">
@@ -429,6 +425,7 @@ export default {
429
425
  width: 20px;
430
426
  flex: 1;
431
427
  text-align: center;
428
+ cursor: pointer;
432
429
  }
433
430
 
434
431
  .move-month-arrow {
@@ -437,7 +434,6 @@ export default {
437
434
  line-height: 20px;
438
435
  color: #606266;
439
436
  text-align: center;
440
- cursor: pointer;
441
437
  &:hover {
442
438
  color: #3C81F6;
443
439
  }
@@ -213,14 +213,30 @@ export const getChangedValueByTimeFormat = (timeFormat, modelValue) => {
213
213
  return `${modelValue.split(' ')[0]} ${hourByTimeFormat}:${minByTimeFormat}:${secByTimeFormat}`;
214
214
  };
215
215
 
216
- const compareFromAndToDate = (calendarType, targetDate, modelValue) => {
216
+ const compareFromAndToDateTime = (mode, calendarType, targetDate, modelValue) => {
217
217
  if (!modelValue.length) {
218
218
  return false;
219
219
  }
220
- const fromDate = calendarType === 'main' ? targetDate : modelValue[0];
221
- const toDate = calendarType === 'expanded' ? targetDate : modelValue[1];
220
+ let fromDate = calendarType === 'main' ? targetDate : modelValue[0];
221
+ let toDate = calendarType === 'expanded' ? targetDate : modelValue[1];
222
+
223
+ let fromDateTime = fromDate;
224
+ let toDateTime = toDate;
225
+ if (!targetDate.split(' ')[1]) {
226
+ if (mode === 'dateTimeRange') {
227
+ fromDate = fromDateTime.split(' ')[0];
228
+ toDate = toDateTime.split(' ')[0];
229
+ const fromTime = modelValue[0].split(' ')[1];
230
+ const toTime = modelValue[1].split(' ')[1];
231
+ fromDateTime = `${fromDate} ${fromTime}`;
232
+ toDateTime = `${toDate} ${toTime}`;
233
+ } else {
234
+ fromDateTime = `${fromDate} 00:00:00`;
235
+ toDateTime = `${toDate} 23:59:59`;
236
+ }
237
+ }
222
238
 
223
- return +new Date(fromDate) > +new Date(toDate);
239
+ return new Date(fromDateTime).getTime() > +new Date(toDateTime).getTime();
224
240
  };
225
241
 
226
242
  /**
@@ -328,24 +344,11 @@ export const useModel = () => {
328
344
  && selectedValue.value[1]
329
345
  ) {
330
346
  const expandedValue = selectedValue.value[1];
331
- const fromDate = {
332
- year: getDateTimeInfoByType(selectedValue.value[0], 'year'),
333
- month: getDateTimeInfoByType(selectedValue.value[0], 'month'),
334
- };
335
347
  const toDate = {
336
348
  year: getDateTimeInfoByType(expandedValue, 'year'),
337
349
  month: getDateTimeInfoByType(expandedValue, 'month'),
338
350
  };
339
- // fromDate, toDate의 연, 월이 같은 경우의 확장된 달력 페이징 정보는 다음달로 세팅
340
- if (props.mode === 'dateRange' && (fromDate.year === toDate.year && fromDate.month === toDate.month)) {
341
- expandedCalendarPageInfo = reactive(getSideMonthCalendarInfo(
342
- 'next',
343
- mainCalendarPageInfo.year,
344
- mainCalendarPageInfo.month,
345
- ));
346
- } else {
347
- expandedCalendarPageInfo = reactive(toDate);
348
- }
351
+ expandedCalendarPageInfo = reactive(toDate);
349
352
 
350
353
  if (props.mode === 'dateTimeRange') {
351
354
  expandedCalendarPageInfo.hour = Math.floor(getDateTimeInfoByType(expandedValue, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1 || 1;
@@ -377,11 +380,9 @@ export const useModel = () => {
377
380
  DAY_OF_THE_WEEK_NAME_LIST[props.dayOfTheWeekNotation]);
378
381
  // mode: dateRange에 두 달력이 연속적인 경우
379
382
  const isContinuousMonths = computed(
380
- () => (props.mode === 'dateRange'
381
- && (getSideMonthCalendarInfo('next', mainCalendarPageInfo.year, mainCalendarPageInfo.month).year === expandedCalendarPageInfo.year
382
- && getSideMonthCalendarInfo('next', mainCalendarPageInfo.year, mainCalendarPageInfo.month).month === expandedCalendarPageInfo.month))
383
- || (props.mode === 'dateTimeRange' && (mainCalendarPageInfo.year === expandedCalendarPageInfo.year
384
- && mainCalendarPageInfo.month === expandedCalendarPageInfo.month)),
383
+ () => ['dateRange', 'dateTimeRange'].includes(props.mode)
384
+ && (mainCalendarPageInfo.year === expandedCalendarPageInfo.year
385
+ && mainCalendarPageInfo.month === expandedCalendarPageInfo.month),
385
386
  );
386
387
 
387
388
  onBeforeMount(() => {
@@ -469,42 +470,22 @@ export const useCalendarDate = (param) => {
469
470
  // date 숫자 및 속성 세팅
470
471
  const setDateInfo = (monthType, i, j) => {
471
472
  currDate = formatDateTime({ year, month, date });
473
+ const isRangeMode = ['dateRange', 'dateTimeRange'].includes(props.mode);
472
474
  const isDisabled = disabledDate ? disabledDate(new Date(currDate)) : false;
473
- const isInvalidDate = props.mode === 'dateTimeRange'
474
- && compareFromAndToDate(calendarType, `${currDate} 00:00:00`, selectedValue.value);
475
- const inRangeCls = () => {
476
- if (['dateRange'].includes(props.mode) && selectedValue.value.length === 2) {
477
- if (getDateMs(selectedValue.value[0].split(' ')[0]) <= getDateMs(currDate)
478
- && getDateMs(currDate) <= getDateMs(selectedValue.value[1].split(' ')[0])
479
- ) {
480
- if (getDateMs(selectedValue.value[0]) === getDateMs(selectedValue.value[1])) {
481
- return ' in-range start-end-date';
482
- } else if (getDateMs(selectedValue.value[0]) === getDateMs(currDate)) {
483
- return ' in-range start-date';
484
- } else if (getDateMs(currDate) === getDateMs(selectedValue.value[1])) {
485
- return ' in-range end-date';
486
- }
487
- return ' in-range';
488
- }
489
- return '';
490
- }
491
- return '';
492
- };
475
+ const isInvalidDate = isRangeMode
476
+ && compareFromAndToDateTime(props.mode, calendarType, currDate, selectedValue.value);
493
477
 
494
- const isDateRangeSelected = props.mode === 'dateRange'
495
- && selectedValue.value?.map(v => v.split(' ')[0]).includes(currDate);
496
- // mode:dateTimeRange인 경우는 한 달력에 from, to 선택 못함
497
478
  const index = calendarType !== 'main' | 0;
498
- const isDateTimeRangeSelected = props.mode === 'dateTimeRange'
499
- && selectedValue.value.length > index && selectedValue.value[index].split(' ')[0].includes(currDate);
479
+ const isRangeSelected = isRangeMode && selectedValue.value.length > index
480
+ && selectedValue.value[index].split(' ')[0].includes(currDate);
500
481
 
501
482
  // mode가 dateRange일 때는 이전, 다음달에 selected 를 하지 않는다.
502
483
  calendarTableInfo[i][j] = {
503
- monthType: `${monthType}${isDisabled || isInvalidDate ? ' disabled' : ''}${inRangeCls()}`,
484
+ monthType: `${monthType}${isDisabled || isInvalidDate ? ' disabled' : ''}`,
504
485
  isToday: TODAY_YMD === currDate,
505
- isSelected: !['dateRange', 'dateTimeRange'].includes(props.mode)
506
- ? selectedValue.value?.includes(currDate)
507
- : monthType === '' && (isDateRangeSelected || isDateTimeRangeSelected),
486
+ isSelected: isRangeMode
487
+ ? monthType === '' && isRangeSelected
488
+ : selectedValue.value?.includes(currDate),
508
489
  year,
509
490
  month,
510
491
  date,
@@ -583,7 +564,12 @@ export const useCalendarDate = (param) => {
583
564
  }
584
565
 
585
566
  const targetDateTimeValue = `${date} ${lpadToTwoDigits(hour)}:${lpadToTwoDigits(min)}:${lpadToTwoDigits(sec)}`;
586
- return compareFromAndToDate(calendarType, targetDateTimeValue, selectedValue.value);
567
+ return compareFromAndToDateTime(
568
+ props.mode,
569
+ calendarType,
570
+ targetDateTimeValue,
571
+ selectedValue.value,
572
+ );
587
573
  };
588
574
 
589
575
  ['hour', 'min', 'sec'].forEach((v) => {
@@ -705,11 +691,11 @@ export const useEvent = (param) => {
705
691
  };
706
692
 
707
693
  /**
708
- * page를 Array로 담아 페이지 세팅
709
- * @param pageList
694
+ * value를 Array로 담아 페이지 세팅
695
+ * @param valueList
710
696
  */
711
- const updatePageList = (pageList) => {
712
- pageList?.forEach((currValue, index) => {
697
+ const updateCalendarPage = (valueList) => {
698
+ valueList?.forEach((currValue, index) => {
713
699
  const changeCalendarType = index === 0 ? 'main' : 'expanded';
714
700
  setCalendarPageInfo(changeCalendarType, {
715
701
  year: getDateTimeInfoByType(currValue, 'year'),
@@ -750,18 +736,11 @@ export const useEvent = (param) => {
750
736
  } else {
751
737
  calendarPageInfo = calendarType === 'expanded'
752
738
  ? expandedCalendarPageInfo : mainCalendarPageInfo;
753
- // 메인 달력 날짜 + 1Month
754
- const nextYearMonth = getSideMonthCalendarInfo(
755
- 'next',
756
- mainCalendarPageInfo.year,
757
- mainCalendarPageInfo.month,
758
- );
759
- const targetYearMonth = props.mode === 'dateRange' ? nextYearMonth : mainCalendarPageInfo;
739
+
760
740
  // 두 달력간의 연속 여부 (메인 달력 + 1Month === 확장된 달력)
761
- // 연속된 경우 mainCalendar와 expandedCalendar는 서로 같은 달로 이동 불가
762
741
  // mainCalendar Month < expandedCalendar Month
763
- const isContinuousMonths = expandedCalendarPageInfo.year === targetYearMonth.year
764
- && expandedCalendarPageInfo.month === targetYearMonth.month;
742
+ const isContinuousMonths = expandedCalendarPageInfo.year === mainCalendarPageInfo.year
743
+ && expandedCalendarPageInfo.month === mainCalendarPageInfo.month;
765
744
  if (type === 'prev') {
766
745
  if (isContinuousMonths && calendarType === 'expanded') {
767
746
  return;
@@ -831,6 +810,17 @@ export const useEvent = (param) => {
831
810
  }
832
811
  };
833
812
 
813
+ const setRangeModeDateByIndex = (currIndex, currDate) => {
814
+ if (compareFromAndToDateTime(props.mode, calendarType, currDate, selectedValue.value)) {
815
+ return false;
816
+ }
817
+
818
+ selectedValue.value[currIndex] = currDate;
819
+ moveDispCalendarMonth();
820
+ updateCalendarPage(selectedValue.value);
821
+ return true;
822
+ };
823
+
834
824
  switch (props.mode) {
835
825
  case 'date':
836
826
  selectedValue.value = CURR_DATE_STR;
@@ -905,28 +895,17 @@ export const useEvent = (param) => {
905
895
  break;
906
896
  }
907
897
  case 'dateRange': {
908
- const isMouseover = calendarEventName.value === 'mousemove';
909
- if (isMouseover) {
910
- calendarEventName.value = null;
911
- // throttle delay 보다 더 빠르게 날짜 클릭하는 경우
912
- if (selectedValue.value.length === 1) {
913
- selectedValue.value.push(CURR_DATE_STR);
914
- }
915
- emit('update:modelValue', [...selectedValue.value]);
916
- dateRangeClickedDate.value = '';
917
- setCalendarDate(calendarType);
898
+ if (!selectedValue.value.length) {
899
+ selectedValue.value.push(CURR_DATE_STR);
900
+ selectedValue.value.push(CURR_DATE_STR);
901
+ updateCalendarPage(selectedValue.value);
918
902
  } else {
919
- selectedValue.value.splice(0);
920
- calendarEventName.value = 'mousemove';
921
- dateRangeClickedDate.value = CURR_DATE_STR;
922
- selectedValue.value.push(dateRangeClickedDate.value);
923
- setCalendarDate('main');
924
- setCalendarDate('expanded');
903
+ setRangeModeDateByIndex(calendarType !== 'main' | 0, CURR_DATE_STR);
925
904
  }
905
+ emit('update:modelValue', [...selectedValue.value]);
926
906
  break;
927
907
  }
928
908
  case 'dateTimeRange': {
929
- const currIndex = calendarType !== 'main' | 0;
930
909
  if (!selectedValue.value.length) {
931
910
  let fromDate = `${CURR_DATE_STR} 00:00:00`;
932
911
  let toDate = `${CURR_DATE_STR} 00:00:00`;
@@ -943,19 +922,10 @@ export const useEvent = (param) => {
943
922
  selectedValue.value.push(fromDate);
944
923
  selectedValue.value.push(toDate);
945
924
 
946
- selectedValue.value?.forEach((currValue, index) => {
947
- setCalendarPageInfo(index === 0 ? 'main' : 'expanded', {
948
- year: getDateTimeInfoByType(currValue, 'year'),
949
- month: getDateTimeInfoByType(currValue, 'month'),
950
- hour: Math.floor(getDateTimeInfoByType(currValue, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1,
951
- min: Math.floor(getDateTimeInfoByType(currValue, 'min') / CELL_CNT_IN_ONE_PAGE) + 1,
952
- sec: Math.floor(getDateTimeInfoByType(currValue, 'sec') / CELL_CNT_IN_ONE_PAGE) + 1,
953
- });
954
- });
955
- setCalendarDate('main');
956
- setCalendarDate('expanded');
925
+ updateCalendarPage(selectedValue.value);
957
926
  setHmsTime();
958
927
  } else {
928
+ const currIndex = calendarType !== 'main' | 0;
959
929
  const CURR_TIME_HMS = selectedValue.value[currIndex]?.split(' ')[1] || '00:00:00';
960
930
 
961
931
  let currDate = `${CURR_DATE_STR} ${CURR_TIME_HMS}`;
@@ -965,17 +935,7 @@ export const useEvent = (param) => {
965
935
  currDate,
966
936
  );
967
937
  }
968
-
969
- const fromDate = currIndex ? selectedValue.value[0] : currDate;
970
- const toDate = currIndex ? currDate : selectedValue.value[1];
971
-
972
- if (new Date(fromDate).getTime() > new Date(toDate).getTime()) {
973
- break;
974
- }
975
-
976
- selectedValue.value[currIndex] = currDate;
977
- moveDispCalendarMonth();
978
- setCalendarDate(calendarType);
938
+ setRangeModeDateByIndex(currIndex, currDate);
979
939
  }
980
940
  emit('update:modelValue', [...selectedValue.value]);
981
941
  break;
@@ -1049,7 +1009,7 @@ export const useEvent = (param) => {
1049
1009
  date: TODAY.getDate(),
1050
1010
  };
1051
1011
  let EXIST_MODEL = true;
1052
- let pageUpdateList = [];
1012
+ let valueListByUpdatePage = [];
1053
1013
 
1054
1014
  const getTimeValueByType = () => {
1055
1015
  let targetTimeValue;
@@ -1074,7 +1034,8 @@ export const useEvent = (param) => {
1074
1034
  } else if (timeType === 'sec') {
1075
1035
  START_IDX = SEC_START_IDX;
1076
1036
  }
1077
- return `${targetValue?.substr(0, START_IDX)}${lpadToTwoDigits(clickedNum)}${targetValue?.substr(START_IDX + REPLACE_TEXT_SIZE)}`;
1037
+ return `${targetValue?.substr(0, START_IDX)}`
1038
+ + `${lpadToTwoDigits(clickedNum)}${targetValue?.substr(START_IDX + REPLACE_TEXT_SIZE)}`;
1078
1039
  };
1079
1040
 
1080
1041
  if (props.mode === 'dateTime') {
@@ -1092,7 +1053,7 @@ export const useEvent = (param) => {
1092
1053
  );
1093
1054
  emit('update:modelValue', selectedValue.value);
1094
1055
  }
1095
- pageUpdateList.push(selectedValue.value);
1056
+ valueListByUpdatePage.push(selectedValue.value);
1096
1057
  } else {
1097
1058
  const index = calendarType !== 'main' | 0;
1098
1059
  if (!props.modelValue.length) {
@@ -1105,7 +1066,7 @@ export const useEvent = (param) => {
1105
1066
  }
1106
1067
 
1107
1068
  EXIST_MODEL = false;
1108
- pageUpdateList = selectedValue.value;
1069
+ valueListByUpdatePage = selectedValue.value;
1109
1070
  } else {
1110
1071
  let currDateTime = getChangedValue(props.modelValue[index]);
1111
1072
  if (timeFormat && timeFormat.length) {
@@ -1129,7 +1090,7 @@ export const useEvent = (param) => {
1129
1090
  setHmsTime();
1130
1091
  // dateTime의 v-model값이 없는 경우 time area를 클릭하였을 때 date의 값은 today로 세팅
1131
1092
  if (!EXIST_MODEL) {
1132
- updatePageList(pageUpdateList);
1093
+ updateCalendarPage(valueListByUpdatePage);
1133
1094
  }
1134
1095
  };
1135
1096
 
@@ -1207,16 +1168,16 @@ export const useEvent = (param) => {
1207
1168
  * Calendar Info 전체 업데이트
1208
1169
  */
1209
1170
  const resetCalendarInfo = () => {
1210
- let pageUpdateList = [];
1171
+ let valueListByUpdatePage = [];
1211
1172
 
1212
1173
  if (['date', 'dateTime'].includes(props.mode)) {
1213
- pageUpdateList.push(selectedValue.value);
1174
+ valueListByUpdatePage.push(selectedValue.value);
1214
1175
  } else {
1215
- pageUpdateList = selectedValue.value;
1176
+ valueListByUpdatePage = selectedValue.value;
1216
1177
  }
1217
1178
 
1218
1179
  if (['dateTime', 'dateTimeRange'].includes(props.mode)) {
1219
- updatePageList(pageUpdateList);
1180
+ updateCalendarPage(valueListByUpdatePage);
1220
1181
  setHmsTime();
1221
1182
  }
1222
1183
  };
@@ -85,7 +85,8 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
85
85
 
86
86
  await watch(() => props.data, (chartData) => {
87
87
  const newData = getNormalizedData(chartData);
88
- const isUpdateSeries = !isEqual(newData, evChart.data);
88
+ const isUpdateSeries = !isEqual(newData.series, evChart.data.series)
89
+ || !isEqual(newData.groups, evChart.data.groups);
89
90
  evChart.data = cloneDeep(newData);
90
91
  evChart.update({
91
92
  updateSeries: isUpdateSeries,
@@ -105,14 +106,8 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
105
106
  });
106
107
 
107
108
  const redrawChart = () => {
108
- if (isInit) {
109
- evChart.update({
110
- updateSeries: false,
111
- updateSelTip: {
112
- update: false,
113
- keepDomain: false,
114
- },
115
- });
109
+ if (evChart && 'resize' in evChart && isInit) {
110
+ evChart.resize();
116
111
  }
117
112
  };
118
113
 
@@ -90,7 +90,6 @@ class EvChart {
90
90
  this.axesRange = this.getAxesRange();
91
91
  this.labelOffset = this.getLabelOffset();
92
92
 
93
- this.initScale();
94
93
  this.drawChart();
95
94
 
96
95
  if (tooltip.use) {
@@ -131,6 +130,7 @@ class EvChart {
131
130
  * @returns {undefined}
132
131
  */
133
132
  drawChart(hitInfo) {
133
+ this.initScale();
134
134
  this.labelRange = this.getAxesLabelRange();
135
135
  this.axesSteps = this.calculateSteps();
136
136
  this.drawAxis(hitInfo);
@@ -523,7 +523,7 @@ class EvChart {
523
523
  this.createSeriesSet(series, options.type, options.horizontal);
524
524
 
525
525
  if (this.legendDOM) {
526
- this.resetLegend();
526
+ this.updateLegend();
527
527
  }
528
528
  }
529
529
 
@@ -532,6 +532,7 @@ class EvChart {
532
532
 
533
533
  if (!updateSelTip.keepDomain) {
534
534
  this.lastTip.pos = null;
535
+ this.lastHitInfo = null;
535
536
  }
536
537
  }
537
538
 
@@ -643,8 +644,8 @@ class EvChart {
643
644
  this.bufferCtx.restore();
644
645
  this.bufferCtx.save();
645
646
 
646
- this.getChartDOMRect();
647
647
  this.initScale();
648
+ this.chartRect = this.getChartRect();
648
649
  this.drawChart();
649
650
  }
650
651
 
@@ -657,7 +658,6 @@ class EvChart {
657
658
  render(hitInfo) {
658
659
  this.clear();
659
660
  this.chartRect = this.getChartRect();
660
- this.initScale();
661
661
  this.drawChart(hitInfo);
662
662
  }
663
663
 
@@ -151,7 +151,6 @@ class Bar {
151
151
  this.drawBar({
152
152
  ctx,
153
153
  positions: { x, y, w, h },
154
- isTop: item.isTop,
155
154
  });
156
155
 
157
156
  if (showValue.use) {
@@ -213,7 +212,6 @@ class Bar {
213
212
  this.drawBar({
214
213
  ctx,
215
214
  positions: { x, y, w, h: this.isHorizontal ? -h : h },
216
- isTop: item.data.isTop,
217
215
  });
218
216
 
219
217
  if (showValue.use) {
@@ -411,7 +409,7 @@ class Bar {
411
409
  ctx.restore();
412
410
  }
413
411
 
414
- drawBar({ ctx, positions, isTop }) {
412
+ drawBar({ ctx, positions }) {
415
413
  const isHorizontal = this.isHorizontal;
416
414
  const isStackBar = 'stackIndex' in this;
417
415
  const isBorderRadius = this.borderRadius && this.borderRadius > 0;
@@ -423,7 +421,7 @@ class Bar {
423
421
  return;
424
422
  }
425
423
 
426
- if ((!isStackBar && isBorderRadius) || (isStackBar && isBorderRadius && isTop)) {
424
+ if (isBorderRadius && !isStackBar) {
427
425
  try {
428
426
  this.drawRoundedRect(ctx, positions);
429
427
  } catch (e) {
@@ -26,7 +26,7 @@ const modules = {
26
26
 
27
27
  if (series && sData) {
28
28
  if (series.isExistGrp && series.stackIndex) {
29
- series.data = this.addSeriesStackDS(sData, label, series);
29
+ series.data = this.addSeriesStackDS(sData, label, series.bsIds, series.stackIndex);
30
30
  } else {
31
31
  series.data = this.addSeriesDS(sData, label);
32
32
  }
@@ -173,12 +173,12 @@ const modules = {
173
173
  * Take data and label to create stack data for each series
174
174
  * @param {object} data chart series info
175
175
  * @param {object} label chart label
176
- * @param {object} series series Information
176
+ * @param {array} bsIds stacked base data ID List
177
+ * @param {number} sIdx series ordered index
177
178
  *
178
179
  * @returns {array} data for each series
179
180
  */
180
- addSeriesStackDS(data, label, series) {
181
- const bsIds = series.bsIds; // stacked base data ID List
181
+ addSeriesStackDS(data, label, bsIds, sIdx = 0) {
182
182
  const isHorizontal = this.options.horizontal;
183
183
  const sdata = [];
184
184
 
@@ -201,8 +201,6 @@ const modules = {
201
201
  };
202
202
 
203
203
  data.forEach((curr, index) => {
204
- const { stackIndex, show: isShowSeries } = series;
205
- const isTop = true; // is top position on stack (Stacked or not, default is true)
206
204
  const baseIndex = bsIds.length - 1 < 0 ? 0 : bsIds.length - 1;
207
205
  let bdata = getBaseDataPosition(baseIndex, index); // base(previous) series data
208
206
  let odata = curr; // current series original data
@@ -216,7 +214,7 @@ const modules = {
216
214
  }
217
215
 
218
216
  const oData = odata?.value ?? odata;
219
- if (stackIndex > 0) {
217
+ if (sIdx > 0) {
220
218
  if (oData != null) {
221
219
  gdata = bdata + oData;
222
220
  } else {
@@ -228,14 +226,7 @@ const modules = {
228
226
  gdata = oData;
229
227
  }
230
228
 
231
- if (gdata && isShowSeries) {
232
- for (let idx = baseIndex; idx > -1; idx--) {
233
- const prevSeriesData = this.seriesList[bsIds[idx]];
234
- prevSeriesData.data[index].isTop = false;
235
- }
236
- }
237
-
238
- sdata.push(this.addData(gdata, ldata, odata, bdata, isTop));
229
+ sdata.push(this.addData(gdata, ldata, odata, bdata));
239
230
  }
240
231
  });
241
232
 
@@ -276,11 +267,10 @@ const modules = {
276
267
  * @param {object} ldata label data (x-axis value for vertical chart)
277
268
  * @param {object} odata original data (without stacked value)
278
269
  * @param {object} bdata base data (stacked value)
279
- * @param {boolean} isTop is top position on stack (Stacked or not, default is true)
280
270
 
281
271
  * @returns {object} data for each graph point
282
272
  */
283
- addData(gdata, ldata, odata = null, bdata = null, isTop = true) {
273
+ addData(gdata, ldata, odata = null, bdata = null) {
284
274
  let data;
285
275
  let gdataValue = null;
286
276
  let odataValue = null;
@@ -312,7 +302,6 @@ const modules = {
312
302
  data.w = null;
313
303
  data.h = null;
314
304
  data.dataColor = gdataColor ?? odataColor;
315
- data.isTop = isTop;
316
305
 
317
306
  return data;
318
307
  },
@@ -175,7 +175,7 @@ const modules = {
175
175
  * @returns {undefined}
176
176
  */
177
177
  dragStart(evt, type) {
178
- const [offsetX, offsetY] = this.getMousePosition(evt);
178
+ let [offsetX, offsetY] = this.getMousePosition(evt);
179
179
  const chartRect = this.chartRect;
180
180
  const labelOffset = this.labelOffset;
181
181
  const range = {
@@ -185,11 +185,20 @@ const modules = {
185
185
  y2: chartRect.y2 - labelOffset.bottom,
186
186
  };
187
187
 
188
- // check graph range
189
- if (offsetX < range.x1 || offsetX > range.x2
190
- || offsetY < range.y1 || offsetY > range.y2
191
- ) {
192
- return;
188
+ if (offsetX < range.x1) {
189
+ offsetX = range.x1;
190
+ }
191
+
192
+ if (offsetX > range.x2) {
193
+ offsetX = range.x2;
194
+ }
195
+
196
+ if (offsetY < range.y1) {
197
+ offsetY = range.y1;
198
+ }
199
+
200
+ if (offsetY > range.y2) {
201
+ offsetY = range.y2;
193
202
  }
194
203
 
195
204
  this.dragInfo = {
@@ -219,11 +219,11 @@ const modules = {
219
219
  let prev = a.data.o;
220
220
  let next = b.data.o;
221
221
 
222
- if (!prev) {
222
+ if (prev === null || prev === undefined) {
223
223
  prev = isHorizontal ? a.data.x : a.data.y;
224
224
  }
225
225
 
226
- if (!next) {
226
+ if (next === null || next === undefined) {
227
227
  next = isHorizontal ? b.data.x : b.data.y;
228
228
  }
229
229
  return next - prev;