evui 3.4.207 → 3.4.209
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/README.md +18 -33
- package/dist/404.html +44 -0
- package/dist/favicon.ico +0 -0
- package/dist/index.js +22738 -0
- package/dist/index.umd.cjs +28 -0
- package/dist/style.css +1 -0
- package/package.json +46 -43
- package/dist/evui.common.js +0 -63681
- package/dist/evui.common.js.map +0 -1
- package/dist/evui.umd.js +0 -63691
- package/dist/evui.umd.js.map +0 -1
- package/dist/evui.umd.min.js +0 -2
- package/dist/evui.umd.min.js.map +0 -1
- package/dist/img/EVUI.b82ee81a.svg +0 -293
- package/src/assets/logo.png +0 -0
- package/src/common/emitter.js +0 -20
- package/src/common/utils.bignumber.js +0 -67
- package/src/common/utils.debounce.js +0 -223
- package/src/common/utils.js +0 -151
- package/src/common/utils.table.js +0 -78
- package/src/common/utils.throttle.js +0 -83
- package/src/common/utils.tree.js +0 -18
- package/src/components/button/Button.vue +0 -195
- package/src/components/button/index.js +0 -7
- package/src/components/buttonGroup/ButtonGroup.vue +0 -11
- package/src/components/buttonGroup/index.js +0 -7
- package/src/components/calendar/Calendar.vue +0 -725
- package/src/components/calendar/index.js +0 -7
- package/src/components/calendar/uses.js +0 -1410
- package/src/components/chart/Chart.vue +0 -363
- package/src/components/chart/ChartToolbar.vue +0 -52
- package/src/components/chart/chart.core.js +0 -1170
- package/src/components/chart/chartZoom.core.js +0 -540
- package/src/components/chart/element/element.bar.js +0 -672
- package/src/components/chart/element/element.bar.time.js +0 -166
- package/src/components/chart/element/element.heatmap.js +0 -743
- package/src/components/chart/element/element.line.js +0 -611
- package/src/components/chart/element/element.pie.js +0 -197
- package/src/components/chart/element/element.scatter.js +0 -320
- package/src/components/chart/element/element.tip.js +0 -717
- package/src/components/chart/helpers/helpers.canvas.js +0 -265
- package/src/components/chart/helpers/helpers.constant.js +0 -235
- package/src/components/chart/helpers/helpers.util.js +0 -400
- package/src/components/chart/index.js +0 -9
- package/src/components/chart/model/index.js +0 -50
- package/src/components/chart/model/model.series.js +0 -125
- package/src/components/chart/model/model.store.js +0 -1427
- package/src/components/chart/plugins/plugins.interaction.js +0 -1659
- package/src/components/chart/plugins/plugins.legend.gradient.js +0 -606
- package/src/components/chart/plugins/plugins.legend.js +0 -1543
- package/src/components/chart/plugins/plugins.pie.js +0 -254
- package/src/components/chart/plugins/plugins.scrollbar.js +0 -732
- package/src/components/chart/plugins/plugins.title.js +0 -61
- package/src/components/chart/plugins/plugins.tooltip.js +0 -1041
- package/src/components/chart/scale/scale.js +0 -951
- package/src/components/chart/scale/scale.linear.js +0 -268
- package/src/components/chart/scale/scale.logarithmic.js +0 -135
- package/src/components/chart/scale/scale.step.js +0 -430
- package/src/components/chart/scale/scale.time.category.js +0 -338
- package/src/components/chart/scale/scale.time.js +0 -49
- package/src/components/chart/style/chart.scss +0 -405
- package/src/components/chart/uses.js +0 -721
- package/src/components/chartBrush/ChartBrush.vue +0 -323
- package/src/components/chartBrush/chartBrush.core.js +0 -691
- package/src/components/chartBrush/index.js +0 -9
- package/src/components/chartBrush/uses.js +0 -23
- package/src/components/chartGroup/ChartGroup.vue +0 -144
- package/src/components/chartGroup/index.js +0 -9
- package/src/components/chartGroup/style/chartGroup.scss +0 -5
- package/src/components/chartGroup/uses.js +0 -53
- package/src/components/checkbox/Checkbox.vue +0 -229
- package/src/components/checkbox/index.js +0 -7
- package/src/components/checkboxGroup/CheckboxGroup.vue +0 -44
- package/src/components/checkboxGroup/index.js +0 -7
- package/src/components/contextMenu/ContextMenu.vue +0 -95
- package/src/components/contextMenu/MenuList.vue +0 -182
- package/src/components/contextMenu/index.js +0 -7
- package/src/components/contextMenu/uses.js +0 -223
- package/src/components/datePicker/DatePicker.vue +0 -504
- package/src/components/datePicker/index.js +0 -7
- package/src/components/datePicker/uses.js +0 -460
- package/src/components/grid/Grid.vue +0 -1535
- package/src/components/grid/GridColumnSetting.vue +0 -358
- package/src/components/grid/GridFilterSetting.vue +0 -323
- package/src/components/grid/GridPagination.vue +0 -75
- package/src/components/grid/GridSummary.vue +0 -314
- package/src/components/grid/GridToolbar.vue +0 -35
- package/src/components/grid/icon/icon-option-button.vue +0 -17
- package/src/components/grid/icon/icon-sort-button.vue +0 -67
- package/src/components/grid/index.js +0 -11
- package/src/components/grid/style/grid.scss +0 -417
- package/src/components/grid/uses.js +0 -1629
- package/src/components/icon/Icon.vue +0 -53
- package/src/components/icon/index.js +0 -8
- package/src/components/inputNumber/InputNumber.vue +0 -212
- package/src/components/inputNumber/index.js +0 -7
- package/src/components/inputNumber/uses.js +0 -217
- package/src/components/loading/Loading.vue +0 -125
- package/src/components/loading/index.js +0 -7
- package/src/components/menu/Menu.vue +0 -79
- package/src/components/menu/MenuItem.vue +0 -201
- package/src/components/menu/index.js +0 -7
- package/src/components/message/Message.vue +0 -229
- package/src/components/message/index.js +0 -34
- package/src/components/messageBox/MessageBox.vue +0 -358
- package/src/components/messageBox/index.js +0 -22
- package/src/components/notification/Notification.vue +0 -316
- package/src/components/notification/index.js +0 -49
- package/src/components/pagination/Pagination.vue +0 -317
- package/src/components/pagination/index.js +0 -7
- package/src/components/pagination/pageButton.vue +0 -31
- package/src/components/progress/Progress.vue +0 -139
- package/src/components/progress/index.js +0 -7
- package/src/components/radio/Radio.vue +0 -159
- package/src/components/radio/index.js +0 -7
- package/src/components/radioGroup/RadioGroup.vue +0 -41
- package/src/components/radioGroup/index.js +0 -7
- package/src/components/scheduler/Scheduler.vue +0 -149
- package/src/components/scheduler/index.js +0 -7
- package/src/components/scheduler/uses.js +0 -183
- package/src/components/select/Select.vue +0 -556
- package/src/components/select/index.js +0 -7
- package/src/components/select/uses.js +0 -379
- package/src/components/slider/Slider.vue +0 -505
- package/src/components/slider/index.js +0 -7
- package/src/components/slider/uses.js +0 -391
- package/src/components/tabPanel/TabPanel.vue +0 -74
- package/src/components/tabPanel/index.js +0 -7
- package/src/components/tabs/Tabs.vue +0 -517
- package/src/components/tabs/index.js +0 -7
- package/src/components/textField/TextField.vue +0 -399
- package/src/components/textField/index.js +0 -7
- package/src/components/timePicker/TimePicker.vue +0 -364
- package/src/components/timePicker/index.js +0 -7
- package/src/components/toggle/Toggle.vue +0 -115
- package/src/components/toggle/index.js +0 -7
- package/src/components/tree/Tree.vue +0 -338
- package/src/components/tree/TreeNode.vue +0 -293
- package/src/components/tree/index.js +0 -7
- package/src/components/treeGrid/TreeGrid.vue +0 -1074
- package/src/components/treeGrid/TreeGridNode.vue +0 -349
- package/src/components/treeGrid/TreeGridToolbar.vue +0 -35
- package/src/components/treeGrid/icon/icon-tree.png +0 -0
- package/src/components/treeGrid/index.js +0 -9
- package/src/components/treeGrid/style/treeGrid.scss +0 -277
- package/src/components/treeGrid/uses.js +0 -1178
- package/src/components/window/Window.vue +0 -329
- package/src/components/window/index.js +0 -7
- package/src/components/window/uses.js +0 -908
- package/src/directives/clickoutside.js +0 -90
- package/src/main.js +0 -120
- package/src/style/components/input.scss +0 -108
- package/src/style/functions.scss +0 -3
- package/src/style/index.scss +0 -6
- package/src/style/lib/fonts/EVUI.eot +0 -0
- package/src/style/lib/fonts/EVUI.svg +0 -293
- package/src/style/lib/fonts/EVUI.ttf +0 -0
- package/src/style/lib/fonts/EVUI.woff +0 -0
- package/src/style/lib/icon.css +0 -888
- package/src/style/mixins.scss +0 -94
- package/src/style/themes.scss +0 -69
- package/src/style/variables.scss +0 -22
|
@@ -1,672 +0,0 @@
|
|
|
1
|
-
import { defaultsDeep } from 'lodash-es';
|
|
2
|
-
import { truthy, truthyNumber } from '@/common/utils';
|
|
3
|
-
import { COLOR, BAR_OPTION } from '../helpers/helpers.constant';
|
|
4
|
-
import Canvas from '../helpers/helpers.canvas';
|
|
5
|
-
import Util from '../helpers/helpers.util';
|
|
6
|
-
|
|
7
|
-
class Bar {
|
|
8
|
-
constructor(sId, opt, sIdx, isHorizontal) {
|
|
9
|
-
const merged = defaultsDeep({}, opt, BAR_OPTION);
|
|
10
|
-
Object.keys(merged).forEach((key) => {
|
|
11
|
-
this[key] = merged[key];
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
if (this.name === undefined) {
|
|
15
|
-
this.name = `series-${sIdx}`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (this.color === undefined) {
|
|
19
|
-
this.color = COLOR[sIdx];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
this.type = 'bar';
|
|
23
|
-
this.sId = sId;
|
|
24
|
-
this.data = [];
|
|
25
|
-
this.isHorizontal = isHorizontal;
|
|
26
|
-
this.size = {
|
|
27
|
-
cat: 0,
|
|
28
|
-
bar: 0,
|
|
29
|
-
cPad: 0,
|
|
30
|
-
bPad: 0,
|
|
31
|
-
w: 0,
|
|
32
|
-
h: 0,
|
|
33
|
-
ix: 0,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Draw series data
|
|
39
|
-
* @param {object} param object for drawing series data
|
|
40
|
-
*
|
|
41
|
-
* @returns {undefined}
|
|
42
|
-
*/
|
|
43
|
-
draw(param) {
|
|
44
|
-
if (!this.show) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const { isHorizontal, showValue } = this;
|
|
49
|
-
const ctx = param.ctx;
|
|
50
|
-
const chartRect = param.chartRect;
|
|
51
|
-
const labelOffset = param.labelOffset;
|
|
52
|
-
const axesSteps = param.axesSteps;
|
|
53
|
-
const showIndex = param.showIndex;
|
|
54
|
-
const thickness = param.thickness;
|
|
55
|
-
const showSeriesCount = param.showSeriesCount;
|
|
56
|
-
|
|
57
|
-
let x;
|
|
58
|
-
let y;
|
|
59
|
-
|
|
60
|
-
const minmaxX = axesSteps.x[this.xAxisIndex];
|
|
61
|
-
const minmaxY = axesSteps.y[this.yAxisIndex];
|
|
62
|
-
|
|
63
|
-
let totalCount = this.data.length;
|
|
64
|
-
const [minIndex, maxIndex] = isHorizontal
|
|
65
|
-
? [minmaxY.minIndex, minmaxY.maxIndex]
|
|
66
|
-
: [minmaxX.minIndex, minmaxX.maxIndex];
|
|
67
|
-
|
|
68
|
-
// minIndex, maxIndex가 유효하면 실제 그릴 데이터 개수로 보정
|
|
69
|
-
if (truthyNumber(minIndex) && truthyNumber(maxIndex)) {
|
|
70
|
-
totalCount = (maxIndex - minIndex) + 1;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const xArea = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
|
|
74
|
-
const yArea = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
|
|
75
|
-
|
|
76
|
-
const xAxisPosition = chartRect.x1 + labelOffset.left;
|
|
77
|
-
const yAxisPosition = chartRect.y2 - labelOffset.bottom;
|
|
78
|
-
const xZeroPosition = Canvas.calculateX(0, minmaxX.graphMin, minmaxX.graphMax, xArea);
|
|
79
|
-
const yZeroPosition = Canvas.calculateY(0, minmaxY.graphMin, minmaxY.graphMax, yArea);
|
|
80
|
-
|
|
81
|
-
const xsp = isHorizontal ? xAxisPosition + xZeroPosition : xAxisPosition;
|
|
82
|
-
const ysp = isHorizontal ? yAxisPosition : yAxisPosition + yZeroPosition;
|
|
83
|
-
|
|
84
|
-
const dArea = isHorizontal ? yArea : xArea;
|
|
85
|
-
const cArea = dArea / (totalCount || 1);
|
|
86
|
-
|
|
87
|
-
let cPad;
|
|
88
|
-
const isUnableToDrawCategoryPadding = param.cPadRatio >= 1 || param.cPadRatio <= 0;
|
|
89
|
-
if (isUnableToDrawCategoryPadding) {
|
|
90
|
-
cPad = 2;
|
|
91
|
-
} else {
|
|
92
|
-
cPad = Math.max((dArea * (param.cPadRatio / 2)) / totalCount, 2);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let bArea;
|
|
96
|
-
let w;
|
|
97
|
-
let h;
|
|
98
|
-
|
|
99
|
-
bArea = cArea > (cPad * 2) ? (cArea - (cPad * 2)) : cArea;
|
|
100
|
-
bArea = this.isExistGrp ? bArea : bArea / showSeriesCount;
|
|
101
|
-
|
|
102
|
-
const size = this.calculateBarSize(thickness, bArea);
|
|
103
|
-
w = isHorizontal ? null : size;
|
|
104
|
-
h = isHorizontal ? size : null;
|
|
105
|
-
|
|
106
|
-
const bPad = isHorizontal ? (bArea - h) / 2 : (bArea - w) / 2;
|
|
107
|
-
const barSeriesX = this.isExistGrp ? 1 : showIndex + 1;
|
|
108
|
-
|
|
109
|
-
this.size.cat = cArea;
|
|
110
|
-
this.size.bar = bArea;
|
|
111
|
-
this.size.cPad = cPad;
|
|
112
|
-
this.size.bPad = bPad;
|
|
113
|
-
this.size.w = w;
|
|
114
|
-
this.size.h = h;
|
|
115
|
-
this.size.ix = barSeriesX;
|
|
116
|
-
this.chartRect = chartRect;
|
|
117
|
-
this.labelOffset = labelOffset;
|
|
118
|
-
this.borderRadius = param.borderRadius;
|
|
119
|
-
this.filteredCount = totalCount;
|
|
120
|
-
|
|
121
|
-
const startIndex = truthyNumber(minIndex) ? minIndex : 0;
|
|
122
|
-
const endIndex = truthyNumber(maxIndex) ? maxIndex : this.data.length - 1;
|
|
123
|
-
|
|
124
|
-
// 스크롤 범위 내에서만 루프 돌림
|
|
125
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
126
|
-
const screenIndex = i - startIndex; // 현재 화면상의 위치 인덱스
|
|
127
|
-
const item = this.data[i]; // 실제 데이터 인덱스에 해당하는 항목
|
|
128
|
-
if (item) {
|
|
129
|
-
// 스크롤 offset(minIndex)만큼 보정해서 그리기
|
|
130
|
-
|
|
131
|
-
const categoryPoint = isHorizontal
|
|
132
|
-
? ysp - (cArea * screenIndex) - cPad
|
|
133
|
-
: xsp + (cArea * screenIndex) + cPad;
|
|
134
|
-
|
|
135
|
-
// 기본 위치 설정
|
|
136
|
-
if (isHorizontal) {
|
|
137
|
-
x = xsp;
|
|
138
|
-
y = Math.round(categoryPoint - ((bArea * barSeriesX) - (h + bPad)));
|
|
139
|
-
} else {
|
|
140
|
-
x = Math.round(categoryPoint + ((bArea * barSeriesX) - (w + bPad)));
|
|
141
|
-
y = ysp;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// 너비 / 높이 계산, 스택의 경우 위치 값 재계산
|
|
145
|
-
if (isHorizontal) {
|
|
146
|
-
const barValue = item.b ? item.o : item.x;
|
|
147
|
-
|
|
148
|
-
w = Canvas.calculateX(
|
|
149
|
-
barValue, minmaxX.graphMin, minmaxX.graphMax, xArea, -xZeroPosition,
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
if (item.b) {
|
|
153
|
-
x = Canvas.calculateX(
|
|
154
|
-
item.b, minmaxX.graphMin, minmaxX.graphMax, xArea, xsp - xZeroPosition,
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const minimumBarWidth = barValue > 0 ? -1 : 1;
|
|
159
|
-
w = barValue && Math.abs(w) === 0 ? minimumBarWidth : w;
|
|
160
|
-
} else {
|
|
161
|
-
const barValue = item.b ? item.o : item.y;
|
|
162
|
-
|
|
163
|
-
h = Canvas.calculateY(
|
|
164
|
-
barValue, minmaxY.graphMin, minmaxY.graphMax, yArea, -yZeroPosition,
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
if (item.b) {
|
|
168
|
-
y = Canvas.calculateY(
|
|
169
|
-
item.b, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp - yZeroPosition,
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const minimumBarHeight = barValue > 0 ? -1 : 1;
|
|
174
|
-
h = barValue && Math.abs(h) === 0 ? minimumBarHeight : h;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const barColor = item.dataColor || this.color;
|
|
178
|
-
const legendHitInfo = param?.legendHitInfo;
|
|
179
|
-
const selectLabelOption = param?.selectLabel?.option;
|
|
180
|
-
const selectItemOption = param?.selectItem?.option;
|
|
181
|
-
const selectedLabelList = param?.selectLabel?.selected?.dataIndex ?? [];
|
|
182
|
-
const {
|
|
183
|
-
dataIndex: selectedItemDataIndex,
|
|
184
|
-
seriesID: selectedItemSeriesId,
|
|
185
|
-
} = param?.selectItem?.selected ?? {};
|
|
186
|
-
|
|
187
|
-
let isDownplay = false;
|
|
188
|
-
|
|
189
|
-
if (legendHitInfo) {
|
|
190
|
-
isDownplay = legendHitInfo?.sId !== this.sId;
|
|
191
|
-
} else if (selectLabelOption?.use && selectLabelOption?.useSeriesOpacity) {
|
|
192
|
-
isDownplay = selectedLabelList.length && !selectedLabelList.includes(i);
|
|
193
|
-
} else if (truthy(selectedItemDataIndex) && selectItemOption?.useSeriesOpacity) {
|
|
194
|
-
if (this.isExistGrp) {
|
|
195
|
-
isDownplay = selectedItemDataIndex !== i;
|
|
196
|
-
} else {
|
|
197
|
-
isDownplay = selectedItemDataIndex !== i || selectedItemSeriesId !== this.sId;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (typeof barColor !== 'string') {
|
|
202
|
-
ctx.fillStyle = Canvas.createGradient(
|
|
203
|
-
ctx,
|
|
204
|
-
isHorizontal,
|
|
205
|
-
{ x, y, w, h },
|
|
206
|
-
barColor,
|
|
207
|
-
isDownplay,
|
|
208
|
-
);
|
|
209
|
-
} else {
|
|
210
|
-
const noneDownplayOpacity = barColor.includes('rgba') ? Util.getOpacity(barColor) : 1;
|
|
211
|
-
const opacity = isDownplay ? 0.1 : noneDownplayOpacity;
|
|
212
|
-
|
|
213
|
-
ctx.fillStyle = Util.colorStringToRgba(barColor, opacity);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
this.drawBar({
|
|
217
|
-
ctx,
|
|
218
|
-
positions: { x, y, w, h },
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
if (showValue.use) {
|
|
222
|
-
this.drawValueLabels({
|
|
223
|
-
context: ctx,
|
|
224
|
-
data: item,
|
|
225
|
-
positions: {
|
|
226
|
-
x,
|
|
227
|
-
y,
|
|
228
|
-
h,
|
|
229
|
-
w,
|
|
230
|
-
},
|
|
231
|
-
isHighlight: false,
|
|
232
|
-
textColor: item.dataTextColor,
|
|
233
|
-
index: i,
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// 좌표 및 인덱스 정보 세팅 (툴팁/hover용)
|
|
238
|
-
item.xp = x; // eslint-disable-line
|
|
239
|
-
item.yp = y; // eslint-disable-line
|
|
240
|
-
item.w = w; // eslint-disable-line
|
|
241
|
-
item.h = isHorizontal ? -h : h; // eslint-disable-line
|
|
242
|
-
item.index = i; // 실제 데이터 인덱스 (스크롤 offset 포함)
|
|
243
|
-
|
|
244
|
-
// 검색(hitInfo) 로직은 this.data[0..filteredCount-1] 범위만 검사하므로,
|
|
245
|
-
// 현재 화면에 그린 항목을 배열 앞쪽으로 매핑해준다.
|
|
246
|
-
this.data[screenIndex] = item;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Draw item highlight
|
|
253
|
-
* @param {object} item object for drawing series data
|
|
254
|
-
* @param {CanvasRenderingContext2D} context canvas context
|
|
255
|
-
* @param {number} index label index
|
|
256
|
-
*
|
|
257
|
-
* @returns {undefined}
|
|
258
|
-
*/
|
|
259
|
-
itemHighlight(item, context, index) {
|
|
260
|
-
const showValue = this.showValue;
|
|
261
|
-
|
|
262
|
-
const gdata = item.data;
|
|
263
|
-
const ctx = context;
|
|
264
|
-
|
|
265
|
-
const x = gdata.xp;
|
|
266
|
-
const y = gdata.yp;
|
|
267
|
-
const w = gdata.w;
|
|
268
|
-
const h = gdata.h;
|
|
269
|
-
|
|
270
|
-
ctx.save();
|
|
271
|
-
ctx.shadowOffsetX = 0;
|
|
272
|
-
ctx.shadowOffsetY = 0;
|
|
273
|
-
ctx.shadowBlur = 4;
|
|
274
|
-
|
|
275
|
-
const color = item.data.dataColor || this.color;
|
|
276
|
-
if (typeof color !== 'string') {
|
|
277
|
-
const grd = Canvas.createGradient(ctx, this.isHorizontal, { x, y, w, h }, color);
|
|
278
|
-
ctx.fillStyle = grd;
|
|
279
|
-
ctx.shadowColor = color[color.length - 1][1];
|
|
280
|
-
} else {
|
|
281
|
-
ctx.fillStyle = color;
|
|
282
|
-
ctx.shadowColor = color;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
ctx.beginPath();
|
|
286
|
-
|
|
287
|
-
this.drawBar({
|
|
288
|
-
ctx,
|
|
289
|
-
positions: { x, y, w, h: this.isHorizontal ? -h : h },
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
if (showValue.use) {
|
|
293
|
-
this.drawValueLabels({
|
|
294
|
-
context: ctx,
|
|
295
|
-
data: gdata,
|
|
296
|
-
positions: {
|
|
297
|
-
x,
|
|
298
|
-
y,
|
|
299
|
-
h,
|
|
300
|
-
w,
|
|
301
|
-
},
|
|
302
|
-
isHighlight: true,
|
|
303
|
-
textColor: item.data.dataTextColor || item.dataTextColor,
|
|
304
|
-
index,
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
ctx.restore();
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Find graph item
|
|
313
|
-
* @param {array} offset mouse position
|
|
314
|
-
* @param {boolean} isHorizontal determines if a horizontal option's value
|
|
315
|
-
* @param {number} dataIndex selected label data index
|
|
316
|
-
* @param {boolean} useIndicatorOnLabel
|
|
317
|
-
*
|
|
318
|
-
* @returns {object} graph item
|
|
319
|
-
*/
|
|
320
|
-
findGraphData(offset, isHorizontal, dataIndex, useIndicatorOnLabel) {
|
|
321
|
-
if (typeof dataIndex === 'number' && this.show && useIndicatorOnLabel) {
|
|
322
|
-
const gdata = this.data;
|
|
323
|
-
const item = { data: null, hit: false, color: this.color };
|
|
324
|
-
|
|
325
|
-
if (gdata[dataIndex]) {
|
|
326
|
-
item.data = gdata[dataIndex];
|
|
327
|
-
item.index = dataIndex;
|
|
328
|
-
item.hit = this.isPointInBar(offset, gdata[dataIndex]);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return item;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
return isHorizontal ? this.findGraphRangeCount(offset) : this.findGraphRange(offset);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Find graph item
|
|
339
|
-
* @param {array} offset mouse position
|
|
340
|
-
*
|
|
341
|
-
* @returns {object} graph item
|
|
342
|
-
*/
|
|
343
|
-
/**
|
|
344
|
-
* Binary search for finding graph item
|
|
345
|
-
* @private
|
|
346
|
-
* @param {array} offset - mouse position
|
|
347
|
-
* @param {boolean} isHorizontal - search orientation
|
|
348
|
-
* @returns {object} graph item
|
|
349
|
-
*/
|
|
350
|
-
binarySearchBar(offset, isHorizontal) {
|
|
351
|
-
const [xp, yp] = offset;
|
|
352
|
-
const item = { data: null, hit: false, color: this.color };
|
|
353
|
-
const gdata = this.data;
|
|
354
|
-
const totalCount = this.filteredCount ?? gdata.length;
|
|
355
|
-
|
|
356
|
-
let s = 0;
|
|
357
|
-
let e = totalCount - 1;
|
|
358
|
-
|
|
359
|
-
while (s <= e) {
|
|
360
|
-
const m = Math.floor((s + e) / 2);
|
|
361
|
-
const barData = gdata[m];
|
|
362
|
-
const { xp: sx, yp: sy, w, h } = barData;
|
|
363
|
-
const ex = sx + w;
|
|
364
|
-
const ey = sy + h;
|
|
365
|
-
|
|
366
|
-
const inRange = isHorizontal
|
|
367
|
-
? ((ey <= yp) && (yp <= sy))
|
|
368
|
-
: ((sx <= xp) && (xp <= ex));
|
|
369
|
-
|
|
370
|
-
if (inRange) {
|
|
371
|
-
item.data = barData;
|
|
372
|
-
item.index = barData.index;
|
|
373
|
-
item.hit = this.isPointInBar(offset, barData);
|
|
374
|
-
return item;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const shouldGoRight = isHorizontal
|
|
378
|
-
? (!(ey < yp))
|
|
379
|
-
: (sx + 4 < xp);
|
|
380
|
-
|
|
381
|
-
if (shouldGoRight) {
|
|
382
|
-
s = m + 1;
|
|
383
|
-
} else {
|
|
384
|
-
e = m - 1;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
return item;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
findGraphRange(offset) {
|
|
392
|
-
return this.binarySearchBar(offset, false);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Find graph item (horizontal)
|
|
397
|
-
* @param {array} offset mouse position
|
|
398
|
-
*
|
|
399
|
-
* @returns {object} graph item
|
|
400
|
-
*/
|
|
401
|
-
findGraphRangeCount(offset) {
|
|
402
|
-
return this.binarySearchBar(offset, true);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Draw value label if series 'use' of showValue option is true
|
|
407
|
-
*
|
|
408
|
-
* @param context canvas context
|
|
409
|
-
* @param data series value data (model.store.js addData return value)
|
|
410
|
-
* @param positions series value positions
|
|
411
|
-
* @param isHighlight draw label with highlight effect
|
|
412
|
-
* @param textColor data text color
|
|
413
|
-
* @param index label index
|
|
414
|
-
*/
|
|
415
|
-
drawValueLabels({ context, data, positions, isHighlight, textColor, index }) {
|
|
416
|
-
const isHorizontal = this.isHorizontal;
|
|
417
|
-
const { fontSize, textColor: seriesTextColor, align, formatter, decimalPoint } = this.showValue;
|
|
418
|
-
const { x: barX, y: barY, w: barWidth, h: barHeight } = positions;
|
|
419
|
-
const ctx = context;
|
|
420
|
-
|
|
421
|
-
ctx.save();
|
|
422
|
-
ctx.beginPath();
|
|
423
|
-
|
|
424
|
-
ctx.font = `normal normal normal ${fontSize}px Roboto`;
|
|
425
|
-
ctx.fillStyle = textColor || seriesTextColor;
|
|
426
|
-
ctx.lineWidth = 1;
|
|
427
|
-
ctx.textBaseline = 'middle';
|
|
428
|
-
ctx.textAlign = isHorizontal && align !== 'center' ? 'left' : 'center';
|
|
429
|
-
|
|
430
|
-
let value;
|
|
431
|
-
const isStacked = truthy(this.stackIndex);
|
|
432
|
-
if (isStacked) {
|
|
433
|
-
value = data.o;
|
|
434
|
-
} else {
|
|
435
|
-
value = (isHorizontal ? data.x : data.y) ?? '';
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
let formattedTxt;
|
|
439
|
-
if (formatter) {
|
|
440
|
-
formattedTxt = formatter(value, {
|
|
441
|
-
label: isHorizontal ? data.y : data.x,
|
|
442
|
-
index,
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
if (!formatter || typeof formattedTxt !== 'string') {
|
|
447
|
-
formattedTxt = Util.labelSignFormat(value, decimalPoint) ?? '';
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
const isNegativeValue = value < 0;
|
|
451
|
-
const textWidth = Math.round(ctx.measureText(formattedTxt).width);
|
|
452
|
-
const textHeight = fontSize; // fontSize와 textHeight는 같을 수 없지만, 정확히 구할 필요 없음
|
|
453
|
-
|
|
454
|
-
const GAP = 10;
|
|
455
|
-
const minXPos = isNegativeValue ? barX - GAP : barX + GAP;
|
|
456
|
-
const minYPos = isNegativeValue ? barY + GAP : barY - GAP;
|
|
457
|
-
|
|
458
|
-
const centerXOnBar = barX + (barWidth / 2);
|
|
459
|
-
const centerYOnBar = isHighlight ? barY + (barHeight / 2) : barY - (barHeight / 2);
|
|
460
|
-
|
|
461
|
-
const drawableBarWidth = Math.abs(barWidth) - GAP;
|
|
462
|
-
const drawableBarHeight = Math.abs(barHeight) - GAP;
|
|
463
|
-
|
|
464
|
-
switch (align) {
|
|
465
|
-
case 'start': {
|
|
466
|
-
if (isHorizontal && textWidth < drawableBarWidth) {
|
|
467
|
-
const xPos = isNegativeValue ? minXPos - textWidth : minXPos;
|
|
468
|
-
ctx.fillText(formattedTxt, xPos, centerYOnBar);
|
|
469
|
-
} else if (!isHorizontal && textHeight < drawableBarHeight) {
|
|
470
|
-
const yPos = isNegativeValue
|
|
471
|
-
? barY + GAP
|
|
472
|
-
: barY - GAP;
|
|
473
|
-
ctx.fillText(formattedTxt, centerXOnBar, yPos);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
break;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
case 'center': {
|
|
480
|
-
if (isHorizontal && textWidth < drawableBarWidth) {
|
|
481
|
-
ctx.fillText(formattedTxt, centerXOnBar, centerYOnBar);
|
|
482
|
-
} else if (!isHorizontal && textHeight < drawableBarHeight) {
|
|
483
|
-
ctx.fillText(formattedTxt, centerXOnBar, barY + (barHeight / 2));
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
break;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
case 'out': {
|
|
490
|
-
if (isStacked) {
|
|
491
|
-
console.warn('[EVUI][Bar Chart] In case of Stack Bar Chart, \'out\' of \'showValue\'\'s align is not supported.');
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
if (isHorizontal) {
|
|
496
|
-
const minXOnChart = this.chartRect.x1 + this.labelOffset.left;
|
|
497
|
-
const maxXOnChart = this.chartRect.x2 - this.labelOffset.right;
|
|
498
|
-
|
|
499
|
-
if (isNegativeValue) {
|
|
500
|
-
const xPos = barX - GAP + barWidth - textWidth;
|
|
501
|
-
if (xPos > minXOnChart) {
|
|
502
|
-
ctx.fillText(formattedTxt, xPos, centerYOnBar);
|
|
503
|
-
}
|
|
504
|
-
} else {
|
|
505
|
-
const xPos = barX + GAP + barWidth;
|
|
506
|
-
if (xPos + textWidth < maxXOnChart) {
|
|
507
|
-
ctx.fillText(formattedTxt, xPos, centerYOnBar);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
} else {
|
|
511
|
-
const yPos = isNegativeValue
|
|
512
|
-
? barY + barHeight + GAP
|
|
513
|
-
: barY + barHeight - GAP;
|
|
514
|
-
ctx.fillText(formattedTxt, centerXOnBar, yPos);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
break;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
default:
|
|
521
|
-
case 'end': {
|
|
522
|
-
if (isHorizontal && textWidth < drawableBarWidth) {
|
|
523
|
-
const xPos = isNegativeValue
|
|
524
|
-
? barX + barWidth + GAP
|
|
525
|
-
: barX + barWidth - textWidth - GAP;
|
|
526
|
-
ctx.fillText(formattedTxt, xPos, centerYOnBar);
|
|
527
|
-
} else if (!isHorizontal) {
|
|
528
|
-
if (isNegativeValue) {
|
|
529
|
-
const yPos = barY + barHeight - GAP;
|
|
530
|
-
if (yPos > minYPos) {
|
|
531
|
-
ctx.fillText(formattedTxt, centerXOnBar, yPos);
|
|
532
|
-
}
|
|
533
|
-
} else if (textHeight < drawableBarHeight) {
|
|
534
|
-
const yPos = barY + barHeight + GAP;
|
|
535
|
-
ctx.fillText(formattedTxt, centerXOnBar, yPos);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
break;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
ctx.restore();
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Calculate bar size based on thickness
|
|
548
|
-
* @private
|
|
549
|
-
* @param {string|number} thickness - thickness value
|
|
550
|
-
* @param {number} bArea - available bar area
|
|
551
|
-
* @returns {number} calculated size
|
|
552
|
-
*/
|
|
553
|
-
calculateBarSize(thickness, bArea) {
|
|
554
|
-
if (typeof thickness === 'string' && /[0-9]+px/.test(thickness)) {
|
|
555
|
-
return Math.min(bArea, Number(thickness.replace('px', '')));
|
|
556
|
-
}
|
|
557
|
-
if (typeof thickness === 'number' && thickness <= 1 && thickness >= 0) {
|
|
558
|
-
return Math.ceil(bArea * thickness);
|
|
559
|
-
}
|
|
560
|
-
return bArea;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
drawBar({ ctx, positions }) {
|
|
564
|
-
const { isHorizontal, borderRadius } = this;
|
|
565
|
-
const isStackBar = 'stackIndex' in this;
|
|
566
|
-
const isBorderRadius = borderRadius && borderRadius > 0;
|
|
567
|
-
const { x, y, w } = positions;
|
|
568
|
-
const h = isHorizontal ? -positions.h : positions.h;
|
|
569
|
-
|
|
570
|
-
// Dont's draw bar that has value 0
|
|
571
|
-
if (w === 0 || h === 0) {
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
ctx.save();
|
|
576
|
-
|
|
577
|
-
if (isBorderRadius && !isStackBar) {
|
|
578
|
-
try {
|
|
579
|
-
this.drawRoundedRect(ctx, positions);
|
|
580
|
-
} catch (e) {
|
|
581
|
-
ctx.fillRect(x, y, w, h);
|
|
582
|
-
}
|
|
583
|
-
} else {
|
|
584
|
-
ctx.fillRect(x, y, w, h);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
ctx.restore();
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/**
|
|
591
|
-
* Check if point is within bar boundaries
|
|
592
|
-
* @param {array} offset - [x, y] mouse position
|
|
593
|
-
* @param {object} barData - bar data object with xp, yp, w, h properties
|
|
594
|
-
* @returns {boolean} true if point is within bar
|
|
595
|
-
*/
|
|
596
|
-
isPointInBar(offset, barData) {
|
|
597
|
-
const [xp, yp] = offset;
|
|
598
|
-
const { xp: sx, yp: sy, w, h } = barData;
|
|
599
|
-
const ex = sx + w;
|
|
600
|
-
const ey = sy + h;
|
|
601
|
-
|
|
602
|
-
return (sx <= xp) && (xp <= ex) && (ey <= yp) && (yp <= sy);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
drawRoundedRect(ctx, positions) {
|
|
606
|
-
const { chartRect, labelOffset, isHorizontal, borderRadius } = this;
|
|
607
|
-
const { x, y } = positions;
|
|
608
|
-
let { w, h } = positions;
|
|
609
|
-
let r = borderRadius;
|
|
610
|
-
|
|
611
|
-
const squarePath = new Path2D();
|
|
612
|
-
squarePath.rect(
|
|
613
|
-
chartRect.x1 + labelOffset.left,
|
|
614
|
-
chartRect.y1,
|
|
615
|
-
chartRect.chartWidth - labelOffset.right,
|
|
616
|
-
chartRect.chartHeight - labelOffset.bottom,
|
|
617
|
-
);
|
|
618
|
-
|
|
619
|
-
ctx.clip(squarePath);
|
|
620
|
-
|
|
621
|
-
ctx.beginPath();
|
|
622
|
-
ctx.moveTo(x, y);
|
|
623
|
-
if (Math.abs(w) < r * 2) {
|
|
624
|
-
r = Math.abs(w) / 2;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
if (Math.abs(h) < r * 2) {
|
|
628
|
-
r = Math.abs(h) / 2;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
if (isHorizontal) {
|
|
632
|
-
const isNegativeValue = w < 0;
|
|
633
|
-
if (isNegativeValue) {
|
|
634
|
-
w += r;
|
|
635
|
-
ctx.lineTo(x + w, y);
|
|
636
|
-
ctx.arcTo(x + w - r, y, x + w - r, y - r, r);
|
|
637
|
-
ctx.arcTo(x + w - r, y - h, x + w, y - h, r);
|
|
638
|
-
ctx.lineTo(x, y - h);
|
|
639
|
-
ctx.lineTo(x, y);
|
|
640
|
-
} else {
|
|
641
|
-
w -= r;
|
|
642
|
-
ctx.lineTo(x + w, y);
|
|
643
|
-
ctx.arcTo(x + w + r, y, x + w + r, y - r, r);
|
|
644
|
-
ctx.arcTo(x + w + r, y - h, x + w, y - h, r);
|
|
645
|
-
ctx.lineTo(x, y - h);
|
|
646
|
-
ctx.lineTo(x, y);
|
|
647
|
-
}
|
|
648
|
-
} else {
|
|
649
|
-
const isNegativeValue = h > 0;
|
|
650
|
-
if (isNegativeValue) {
|
|
651
|
-
h -= r;
|
|
652
|
-
ctx.lineTo(x + w, y);
|
|
653
|
-
ctx.lineTo(x + w, y + h);
|
|
654
|
-
ctx.arcTo(x + w, y + h + r, x - w + r, y + h + r, r);
|
|
655
|
-
ctx.arcTo(x, y + h + r, x, y + h, r);
|
|
656
|
-
ctx.lineTo(x, y);
|
|
657
|
-
} else {
|
|
658
|
-
h += r;
|
|
659
|
-
ctx.lineTo(x + w, y);
|
|
660
|
-
ctx.lineTo(x + w, y + h);
|
|
661
|
-
ctx.arcTo(x + w, y + h - r, x + w - r, y + h - r, r);
|
|
662
|
-
ctx.arcTo(x, y + h - r, x, y + h, r);
|
|
663
|
-
ctx.lineTo(x, y);
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
ctx.fill();
|
|
668
|
-
ctx.closePath();
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
export default Bar;
|