evui 3.3.36 → 3.3.39

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.
Files changed (141) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +40 -40
  3. package/dist/evui.common.js +1907 -1832
  4. package/dist/evui.common.js.map +1 -1
  5. package/dist/evui.umd.js +1907 -1832
  6. package/dist/evui.umd.js.map +1 -1
  7. package/dist/evui.umd.min.js +1 -1
  8. package/dist/evui.umd.min.js.map +1 -1
  9. package/dist/img/{EVUI.7f3588fb.svg → EVUI.b82ee81a.svg} +292 -292
  10. package/dist/img/{icon_mysql.7ea26d5d.svg → icon_mysql.1085fdc9.svg} +78 -78
  11. package/dist/img/{icon_oracle.9009b108.svg → icon_oracle.0572d3ee.svg} +13 -13
  12. package/dist/img/{icon_postgresql.f8fffba9.svg → icon_postgresql.ee12bde8.svg} +58 -58
  13. package/package.json +61 -61
  14. package/src/common/emitter.js +20 -20
  15. package/src/common/utils.debounce.js +223 -223
  16. package/src/common/utils.js +134 -134
  17. package/src/common/utils.table.js +78 -78
  18. package/src/common/utils.throttle.js +83 -83
  19. package/src/common/utils.tree.js +18 -18
  20. package/src/components/button/Button.vue +198 -198
  21. package/src/components/button/index.js +7 -7
  22. package/src/components/buttonGroup/ButtonGroup.vue +11 -11
  23. package/src/components/buttonGroup/index.js +7 -7
  24. package/src/components/calendar/Calendar.vue +661 -661
  25. package/src/components/calendar/index.js +7 -7
  26. package/src/components/calendar/uses.js +1272 -1272
  27. package/src/components/chart/Chart.vue +189 -192
  28. package/src/components/chart/chart.core.js +870 -870
  29. package/src/components/chart/element/element.bar.js +524 -524
  30. package/src/components/chart/element/element.bar.time.js +156 -156
  31. package/src/components/chart/element/element.heatmap.js +533 -533
  32. package/src/components/chart/element/element.line.js +339 -339
  33. package/src/components/chart/element/element.pie.js +197 -197
  34. package/src/components/chart/element/element.scatter.js +184 -184
  35. package/src/components/chart/element/element.tip.js +550 -542
  36. package/src/components/chart/helpers/helpers.canvas.js +265 -265
  37. package/src/components/chart/helpers/helpers.constant.js +206 -206
  38. package/src/components/chart/helpers/helpers.util.js +346 -338
  39. package/src/components/chart/index.js +9 -9
  40. package/src/components/chart/model/index.js +4 -4
  41. package/src/components/chart/model/model.series.js +93 -93
  42. package/src/components/chart/model/model.store.js +977 -967
  43. package/src/components/chart/plugins/plugins.interaction.js +769 -769
  44. package/src/components/chart/plugins/plugins.legend.gradient.js +602 -602
  45. package/src/components/chart/plugins/plugins.legend.js +1155 -1151
  46. package/src/components/chart/plugins/plugins.pie.js +254 -254
  47. package/src/components/chart/plugins/plugins.title.js +56 -56
  48. package/src/components/chart/plugins/plugins.tooltip.js +692 -692
  49. package/src/components/chart/scale/scale.js +848 -848
  50. package/src/components/chart/scale/scale.linear.js +38 -38
  51. package/src/components/chart/scale/scale.logarithmic.js +128 -128
  52. package/src/components/chart/scale/scale.step.js +336 -336
  53. package/src/components/chart/scale/scale.time.category.js +277 -277
  54. package/src/components/chart/scale/scale.time.js +48 -48
  55. package/src/components/chart/style/chart.scss +312 -312
  56. package/src/components/chart/uses.js +264 -252
  57. package/src/components/checkbox/Checkbox.vue +200 -200
  58. package/src/components/checkbox/index.js +7 -7
  59. package/src/components/checkboxGroup/CheckboxGroup.vue +44 -44
  60. package/src/components/checkboxGroup/index.js +7 -7
  61. package/src/components/contextMenu/ContextMenu.vue +80 -80
  62. package/src/components/contextMenu/MenuList.vue +149 -149
  63. package/src/components/contextMenu/index.js +7 -7
  64. package/src/components/contextMenu/uses.js +203 -203
  65. package/src/components/datePicker/DatePicker.vue +437 -437
  66. package/src/components/datePicker/index.js +7 -7
  67. package/src/components/datePicker/uses.js +419 -419
  68. package/src/components/grid/Grid.vue +827 -827
  69. package/src/components/grid/grid.filter.window.vue +493 -493
  70. package/src/components/grid/grid.pagination.vue +75 -75
  71. package/src/components/grid/grid.summary.vue +265 -265
  72. package/src/components/grid/grid.toolbar.vue +26 -26
  73. package/src/components/grid/index.js +11 -11
  74. package/src/components/grid/style/grid.scss +263 -263
  75. package/src/components/grid/uses.js +1002 -1007
  76. package/src/components/icon/Icon.vue +49 -49
  77. package/src/components/icon/index.js +8 -8
  78. package/src/components/inputNumber/InputNumber.vue +212 -212
  79. package/src/components/inputNumber/index.js +7 -7
  80. package/src/components/inputNumber/uses.js +217 -217
  81. package/src/components/loading/Loading.vue +125 -125
  82. package/src/components/loading/index.js +7 -7
  83. package/src/components/menu/Menu.vue +68 -68
  84. package/src/components/menu/MenuItem.vue +187 -187
  85. package/src/components/menu/index.js +7 -7
  86. package/src/components/message/Message.vue +223 -223
  87. package/src/components/message/index.js +31 -31
  88. package/src/components/messageBox/MessageBox.vue +358 -358
  89. package/src/components/messageBox/index.js +22 -22
  90. package/src/components/notification/Notification.vue +316 -316
  91. package/src/components/notification/index.js +49 -49
  92. package/src/components/pagination/Pagination.vue +271 -271
  93. package/src/components/pagination/index.js +7 -7
  94. package/src/components/pagination/pageButton.vue +30 -30
  95. package/src/components/progress/Progress.vue +139 -139
  96. package/src/components/progress/index.js +7 -7
  97. package/src/components/radio/Radio.vue +159 -159
  98. package/src/components/radio/index.js +7 -7
  99. package/src/components/radioGroup/RadioGroup.vue +41 -41
  100. package/src/components/radioGroup/index.js +7 -7
  101. package/src/components/scheduler/Scheduler.vue +149 -149
  102. package/src/components/scheduler/index.js +7 -7
  103. package/src/components/scheduler/uses.js +183 -183
  104. package/src/components/select/Select.vue +440 -440
  105. package/src/components/select/index.js +7 -7
  106. package/src/components/select/uses.js +270 -270
  107. package/src/components/slider/Slider.vue +505 -505
  108. package/src/components/slider/index.js +7 -7
  109. package/src/components/slider/uses.js +390 -390
  110. package/src/components/tabPanel/TabPanel.vue +74 -74
  111. package/src/components/tabPanel/index.js +7 -7
  112. package/src/components/tabs/Tabs.vue +517 -517
  113. package/src/components/tabs/index.js +7 -7
  114. package/src/components/textField/TextField.vue +375 -375
  115. package/src/components/textField/index.js +7 -7
  116. package/src/components/timePicker/TimePicker.vue +352 -352
  117. package/src/components/timePicker/index.js +7 -7
  118. package/src/components/toggle/Toggle.vue +115 -115
  119. package/src/components/toggle/index.js +7 -7
  120. package/src/components/tree/Tree.vue +313 -313
  121. package/src/components/tree/TreeNode.vue +293 -293
  122. package/src/components/tree/index.js +7 -7
  123. package/src/components/treeGrid/TreeGrid.vue +758 -758
  124. package/src/components/treeGrid/TreeGridNode.vue +275 -275
  125. package/src/components/treeGrid/index.js +9 -9
  126. package/src/components/treeGrid/style/treeGrid.scss +261 -261
  127. package/src/components/treeGrid/treeGrid.toolbar.vue +26 -26
  128. package/src/components/treeGrid/uses.js +867 -867
  129. package/src/components/window/Window.vue +329 -329
  130. package/src/components/window/index.js +7 -7
  131. package/src/components/window/uses.js +899 -899
  132. package/src/directives/clickoutside.js +90 -90
  133. package/src/main.js +116 -116
  134. package/src/style/components/input.scss +108 -108
  135. package/src/style/functions.scss +3 -3
  136. package/src/style/index.scss +6 -6
  137. package/src/style/lib/fonts/EVUI.svg +292 -292
  138. package/src/style/lib/icon.css +888 -888
  139. package/src/style/mixins.scss +94 -94
  140. package/src/style/themes.scss +67 -67
  141. package/src/style/variables.scss +22 -22
@@ -1,336 +1,336 @@
1
- import { defaultsDeep } from 'lodash-es';
2
- import { PLOT_BAND_OPTION, PLOT_LINE_OPTION } from '@/components/chart/helpers/helpers.constant';
3
- import Scale from './scale';
4
- import Util from '../helpers/helpers.util';
5
-
6
- class StepScale extends Scale {
7
- constructor(type, opt, ctx, labels, options) {
8
- super(type, opt, ctx, options);
9
- this.labels = labels;
10
- }
11
-
12
- /**
13
- * Calculate min/max value, label and size information for step scale
14
- * @param {object} minMax min/max information (unused on step scale)
15
- * @param {object} chartRect chart size information
16
- *
17
- * @returns {object} min/max value and label
18
- */
19
- calculateScaleRange(minMax, chartRect) {
20
- const stepMinMax = this.labelStyle.alignToGridLine
21
- ? minMax : Util.getStringMinMax(this.labels);
22
- const maxValue = stepMinMax.max;
23
- const minValue = stepMinMax.min;
24
- const maxWidth = chartRect.chartWidth / (this.labels.length + 2);
25
-
26
- return {
27
- min: minValue,
28
- max: maxValue,
29
- minLabel: this.getLabelFormat(minValue, maxWidth),
30
- maxLabel: this.getLabelFormat(maxValue, maxWidth),
31
- size: Util.calcTextSize(
32
- this.getLabelFormat(maxValue, maxWidth),
33
- Util.getLabelStyle(this.labelStyle),
34
- ),
35
- };
36
- }
37
-
38
- /**
39
- * With range information, calculate how many labels in axis
40
- * @param {object} range min/max information
41
- *
42
- * @returns {object} steps, interval, min/max graph value
43
- */
44
- calculateSteps(range) {
45
- let numberOfSteps = this.labels.length;
46
- let interval = 1;
47
-
48
- const isNumbersArray = this.labels.every(label => !isNaN(label));
49
- if (this.labelStyle.alignToGridLine && isNumbersArray) {
50
- const { maxSteps } = range;
51
-
52
- if (maxSteps > 2) {
53
- while (numberOfSteps > maxSteps * 2) {
54
- interval *= 2;
55
- numberOfSteps = Math.round(numberOfSteps / interval);
56
- }
57
- } else {
58
- interval = this.labels.length;
59
- }
60
- }
61
-
62
- return {
63
- steps: numberOfSteps,
64
- interval,
65
- graphMin: range.minValue,
66
- graphMax: range.maxValue,
67
- };
68
- }
69
-
70
- /**
71
- * Draw axis
72
- * @param {object} chartRect min/max information
73
- * @param {object} labelOffset label offset information
74
- * @param {object} stepInfo label steps information
75
- *
76
- * @returns {undefined}
77
- */
78
- draw(chartRect, labelOffset, stepInfo, hitInfo, selectLabelInfo) {
79
- const ctx = this.ctx;
80
- const labels = this.labels;
81
- const aPos = {
82
- x1: chartRect.x1 + labelOffset.left,
83
- x2: chartRect.x2 - labelOffset.right,
84
- y1: chartRect.y1 + labelOffset.top,
85
- y2: chartRect.y2 - labelOffset.bottom,
86
- };
87
-
88
- const oriSteps = this.labels.length;
89
- const steps = stepInfo.steps;
90
- const count = stepInfo.interval;
91
-
92
- const startPoint = aPos[this.units.rectStart];
93
- const endPoint = aPos[this.units.rectEnd];
94
- const offsetPoint = aPos[this.units.rectOffset(this.position)];
95
- const offsetCounterPoint = aPos[this.units.rectOffsetCounter(this.position)];
96
- const maxWidth = chartRect.chartWidth / (this.labels.length + 2);
97
-
98
- this.drawAxisTitle(chartRect, labelOffset);
99
-
100
- if (this.labelStyle?.show) {
101
- // label font 설정
102
- ctx.font = Util.getLabelStyle(this.labelStyle);
103
-
104
- if (this.type === 'x') {
105
- ctx.textAlign = 'center';
106
- ctx.textBaseline = this.position === 'top' ? 'bottom' : 'top';
107
- } else {
108
- ctx.textAlign = this.position === 'left' ? 'right' : 'left';
109
- ctx.textBaseline = 'middle';
110
- }
111
-
112
- ctx.fillStyle = this.labelStyle.color;
113
- ctx.lineWidth = 1;
114
- const aliasPixel = Util.aliasPixel(ctx.lineWidth);
115
-
116
- ctx.beginPath();
117
- ctx.strokeStyle = this.axisLineColor;
118
- if (this.type === 'x') {
119
- ctx.moveTo(startPoint, offsetPoint + aliasPixel);
120
- ctx.lineTo(endPoint, offsetPoint + aliasPixel);
121
- } else {
122
- ctx.moveTo(offsetPoint + aliasPixel, startPoint);
123
- ctx.lineTo(offsetPoint + aliasPixel, endPoint);
124
- }
125
- ctx.stroke();
126
-
127
- if (steps === 0) {
128
- return;
129
- }
130
-
131
- const labelGap = (endPoint - startPoint) / labels.length;
132
- const alignToGridLine = this.labelStyle.alignToGridLine;
133
- let labelCenter = null;
134
- let linePosition = null;
135
-
136
- ctx.beginPath();
137
- ctx.strokeStyle = this.gridLineColor;
138
-
139
- let labelText;
140
- let labelPoint;
141
- let index;
142
-
143
- for (index = 0; index < oriSteps; index += count) {
144
- const item = this.labels[index];
145
- labelCenter = Math.round(startPoint + (labelGap * index));
146
- linePosition = labelCenter + aliasPixel;
147
- labelText = this.getLabelFormat(item, maxWidth);
148
-
149
- const isBlurredLabel = this.options?.selectLabel?.use
150
- && this.options?.selectLabel?.useLabelOpacity
151
- && (this.options.horizontal === (this.type === 'y'))
152
- && selectLabelInfo?.dataIndex?.length
153
- && !selectLabelInfo?.dataIndex?.includes(index);
154
-
155
- const labelColor = this.labelStyle.color;
156
- let defaultOpacity = 1;
157
-
158
- if (Util.getColorStringType(labelColor) === 'RGBA') {
159
- defaultOpacity = Util.getOpacity(labelColor);
160
- }
161
-
162
- ctx.fillStyle = Util.colorStringToRgba(labelColor, isBlurredLabel ? 0.1 : defaultOpacity);
163
-
164
- if (this.type === 'x') {
165
- labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
166
- const xPoint = alignToGridLine ? labelCenter : labelCenter + (labelGap / 2);
167
- ctx.fillText(labelText, xPoint, labelPoint);
168
-
169
- if (!isBlurredLabel
170
- && this.options?.selectItem?.showLabelTip
171
- && hitInfo?.label
172
- && !this.options?.horizontal) {
173
- const selectedLabel = hitInfo.label;
174
- if (selectedLabel === labelText) {
175
- const height = Math.round(ctx.measureText(this.labelStyle?.fontSize).width);
176
- Util.showLabelTip({
177
- ctx: this.ctx,
178
- width: Math.round(ctx.measureText(selectedLabel).width) + 10,
179
- height,
180
- x: labelCenter + (labelGap / 2),
181
- y: labelPoint + (height - 2),
182
- borderRadius: 2,
183
- arrowSize: 3,
184
- text: labelText,
185
- backgroundColor: this.options?.selectItem?.labelTipStyle?.backgroundColor,
186
- textColor: this.options?.selectItem?.labelTipStyle?.textColor,
187
- });
188
- }
189
- }
190
-
191
- if (index > 0 && this.showGrid) {
192
- ctx.moveTo(linePosition, offsetPoint);
193
- ctx.lineTo(linePosition, offsetCounterPoint);
194
- }
195
- } else {
196
- labelPoint = this.position === 'left' ? offsetPoint - 10 : offsetPoint + 10;
197
- const yPoint = alignToGridLine ? labelCenter : labelCenter + (labelGap / 2);
198
- ctx.fillText(labelText, labelPoint, yPoint);
199
-
200
- if (index > 0 && this.showGrid) {
201
- ctx.moveTo(offsetPoint, linePosition);
202
- ctx.lineTo(offsetCounterPoint, linePosition);
203
- }
204
- }
205
- ctx.stroke();
206
- }
207
-
208
- if (alignToGridLine && (index === this.labels.length)) {
209
- let labelLastText = +labels[labels.length - 1] + (+labels[1] - +labels[0]);
210
- if (isNaN(labelLastText)) {
211
- labelLastText = 'Max';
212
- }
213
- labelCenter = Math.round(startPoint + (labelGap * labels.length));
214
- linePosition = labelCenter + aliasPixel;
215
-
216
- if (this.type === 'x') {
217
- ctx.fillText(labelLastText, labelCenter, labelPoint);
218
- if (this.showGrid) {
219
- ctx.moveTo(linePosition, offsetPoint);
220
- ctx.lineTo(linePosition, offsetCounterPoint);
221
- }
222
- } else {
223
- ctx.fillText(labelLastText, labelPoint, labelCenter);
224
- if (this.showGrid) {
225
- ctx.moveTo(offsetPoint, linePosition);
226
- ctx.lineTo(offsetCounterPoint, linePosition);
227
- }
228
- }
229
- ctx.stroke();
230
- }
231
-
232
- ctx.closePath();
233
- }
234
-
235
- // draw plot lines and plot bands
236
- if (this.plotBands?.length || this.plotLines?.length) {
237
- const padding = Util.aliasPixel(ctx.lineWidth) + 1;
238
- const minX = aPos.x1 + padding;
239
- const maxX = aPos.x2;
240
- const minY = aPos.y1 + padding;
241
- const maxY = aPos.y2;
242
- const labelGap = (endPoint - startPoint) / (this.labelStyle.show ? labels.length : 1);
243
-
244
- this.plotBands?.forEach((plotBand) => {
245
- if (!plotBand.from && !plotBand.to) {
246
- return;
247
- }
248
-
249
- const mergedPlotBandOpt = defaultsDeep({}, plotBand, PLOT_BAND_OPTION);
250
- const { from = 0, to = labels.length, label: labelOpt } = mergedPlotBandOpt;
251
- const fromPos = Math.round(startPoint + (labelGap * from));
252
- const toPos = Math.round(startPoint + (labelGap * to));
253
-
254
- this.setPlotBandStyle(mergedPlotBandOpt);
255
-
256
- if (this.type === 'x') {
257
- this.drawXPlotBand(fromPos, toPos, minX, maxX, minY, maxY);
258
- } else {
259
- this.drawYPlotBand(fromPos, toPos, minX, maxX, minY, maxY);
260
- }
261
-
262
- if (labelOpt.show) {
263
- const labelOptions = this.getNormalizedLabelOptions(chartRect, labelOpt);
264
- const textXY = this.getPlotBandLabelPosition(fromPos, toPos, labelOptions, maxX, minY);
265
- this.drawPlotLabel(labelOptions, textXY);
266
- }
267
-
268
- ctx.restore();
269
- });
270
-
271
- this.plotLines?.forEach((plotLine) => {
272
- if (!plotLine.value) {
273
- return;
274
- }
275
-
276
- const mergedPlotLineOpt = defaultsDeep({}, plotLine, PLOT_LINE_OPTION);
277
- const { value, label: labelOpt } = mergedPlotLineOpt;
278
- const dataPos = Math.round(startPoint + (labelGap * value)) + (labelGap / 2);
279
-
280
- this.setPlotLineStyle(mergedPlotLineOpt);
281
-
282
- if (this.type === 'x') {
283
- this.drawXPlotLine(dataPos, minX, maxX, minY, maxY);
284
- } else {
285
- this.drawYPlotLine(dataPos, minX, maxX, minY, maxY);
286
- }
287
-
288
- if (labelOpt.show) {
289
- const labelOptions = this.getNormalizedLabelOptions(chartRect, labelOpt);
290
- const textXY = this.getPlotLineLabelPosition(dataPos, labelOptions, maxX, minY);
291
- this.drawPlotLabel(labelOptions, textXY);
292
- }
293
-
294
- ctx.restore();
295
- });
296
- }
297
- }
298
-
299
- /**
300
- * Transforming label by designated format
301
- * @param {string} value label value
302
- * @param {number} maxWidth max width for each label
303
- *
304
- * @returns {string} formatted label
305
- */
306
- getLabelFormat(value, maxWidth) {
307
- if (this.formatter) {
308
- const formattedLabel = this.formatter(value);
309
-
310
- if (typeof formattedLabel === 'string') {
311
- return formattedLabel;
312
- }
313
- }
314
-
315
- return this.labelStyle.fitWidth ? this.fittingString(value, maxWidth) : value;
316
- }
317
-
318
- /**
319
- * Transforming ellipsis label by designated format and specific width
320
- * @param {string} value label value
321
- * @param {number} maxWidth max width for each label
322
- *
323
- * @returns {string} formatted label
324
- */
325
- fittingString(value, maxWidth) {
326
- const ctx = this.ctx;
327
-
328
- ctx.save();
329
- ctx.font = Util.getLabelStyle(this.labelStyle);
330
- const dir = this.labelStyle.fitDir;
331
-
332
- return Util.truncateLabelWithEllipsis(value, maxWidth, ctx, dir);
333
- }
334
- }
335
-
336
- export default StepScale;
1
+ import { defaultsDeep } from 'lodash-es';
2
+ import { PLOT_BAND_OPTION, PLOT_LINE_OPTION } from '@/components/chart/helpers/helpers.constant';
3
+ import Scale from './scale';
4
+ import Util from '../helpers/helpers.util';
5
+
6
+ class StepScale extends Scale {
7
+ constructor(type, opt, ctx, labels, options) {
8
+ super(type, opt, ctx, options);
9
+ this.labels = labels;
10
+ }
11
+
12
+ /**
13
+ * Calculate min/max value, label and size information for step scale
14
+ * @param {object} minMax min/max information (unused on step scale)
15
+ * @param {object} chartRect chart size information
16
+ *
17
+ * @returns {object} min/max value and label
18
+ */
19
+ calculateScaleRange(minMax, chartRect) {
20
+ const stepMinMax = this.labelStyle.alignToGridLine
21
+ ? minMax : Util.getStringMinMax(this.labels);
22
+ const maxValue = stepMinMax.max;
23
+ const minValue = stepMinMax.min;
24
+ const maxWidth = chartRect.chartWidth / (this.labels.length + 2);
25
+
26
+ return {
27
+ min: minValue,
28
+ max: maxValue,
29
+ minLabel: this.getLabelFormat(minValue, maxWidth),
30
+ maxLabel: this.getLabelFormat(maxValue, maxWidth),
31
+ size: Util.calcTextSize(
32
+ this.getLabelFormat(maxValue, maxWidth),
33
+ Util.getLabelStyle(this.labelStyle),
34
+ ),
35
+ };
36
+ }
37
+
38
+ /**
39
+ * With range information, calculate how many labels in axis
40
+ * @param {object} range min/max information
41
+ *
42
+ * @returns {object} steps, interval, min/max graph value
43
+ */
44
+ calculateSteps(range) {
45
+ let numberOfSteps = this.labels.length;
46
+ let interval = 1;
47
+
48
+ const isNumbersArray = this.labels.every(label => !isNaN(label));
49
+ if (this.labelStyle.alignToGridLine && isNumbersArray) {
50
+ const { maxSteps } = range;
51
+
52
+ if (maxSteps > 2) {
53
+ while (numberOfSteps > maxSteps * 2) {
54
+ interval *= 2;
55
+ numberOfSteps = Math.round(numberOfSteps / interval);
56
+ }
57
+ } else {
58
+ interval = this.labels.length;
59
+ }
60
+ }
61
+
62
+ return {
63
+ steps: numberOfSteps,
64
+ interval,
65
+ graphMin: range.minValue,
66
+ graphMax: range.maxValue,
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Draw axis
72
+ * @param {object} chartRect min/max information
73
+ * @param {object} labelOffset label offset information
74
+ * @param {object} stepInfo label steps information
75
+ *
76
+ * @returns {undefined}
77
+ */
78
+ draw(chartRect, labelOffset, stepInfo, hitInfo, selectLabelInfo) {
79
+ const ctx = this.ctx;
80
+ const labels = this.labels;
81
+ const aPos = {
82
+ x1: chartRect.x1 + labelOffset.left,
83
+ x2: chartRect.x2 - labelOffset.right,
84
+ y1: chartRect.y1 + labelOffset.top,
85
+ y2: chartRect.y2 - labelOffset.bottom,
86
+ };
87
+
88
+ const oriSteps = this.labels.length;
89
+ const steps = stepInfo.steps;
90
+ const count = stepInfo.interval;
91
+
92
+ const startPoint = aPos[this.units.rectStart];
93
+ const endPoint = aPos[this.units.rectEnd];
94
+ const offsetPoint = aPos[this.units.rectOffset(this.position)];
95
+ const offsetCounterPoint = aPos[this.units.rectOffsetCounter(this.position)];
96
+ const maxWidth = chartRect.chartWidth / (this.labels.length + 2);
97
+
98
+ this.drawAxisTitle(chartRect, labelOffset);
99
+
100
+ if (this.labelStyle?.show) {
101
+ // label font 설정
102
+ ctx.font = Util.getLabelStyle(this.labelStyle);
103
+
104
+ if (this.type === 'x') {
105
+ ctx.textAlign = 'center';
106
+ ctx.textBaseline = this.position === 'top' ? 'bottom' : 'top';
107
+ } else {
108
+ ctx.textAlign = this.position === 'left' ? 'right' : 'left';
109
+ ctx.textBaseline = 'middle';
110
+ }
111
+
112
+ ctx.fillStyle = this.labelStyle.color;
113
+ ctx.lineWidth = 1;
114
+ const aliasPixel = Util.aliasPixel(ctx.lineWidth);
115
+
116
+ ctx.beginPath();
117
+ ctx.strokeStyle = this.axisLineColor;
118
+ if (this.type === 'x') {
119
+ ctx.moveTo(startPoint, offsetPoint + aliasPixel);
120
+ ctx.lineTo(endPoint, offsetPoint + aliasPixel);
121
+ } else {
122
+ ctx.moveTo(offsetPoint + aliasPixel, startPoint);
123
+ ctx.lineTo(offsetPoint + aliasPixel, endPoint);
124
+ }
125
+ ctx.stroke();
126
+
127
+ if (steps === 0) {
128
+ return;
129
+ }
130
+
131
+ const labelGap = (endPoint - startPoint) / labels.length;
132
+ const alignToGridLine = this.labelStyle.alignToGridLine;
133
+ let labelCenter = null;
134
+ let linePosition = null;
135
+
136
+ ctx.beginPath();
137
+ ctx.strokeStyle = this.gridLineColor;
138
+
139
+ let labelText;
140
+ let labelPoint;
141
+ let index;
142
+
143
+ for (index = 0; index < oriSteps; index += count) {
144
+ const item = this.labels[index];
145
+ labelCenter = Math.round(startPoint + (labelGap * index));
146
+ linePosition = labelCenter + aliasPixel;
147
+ labelText = this.getLabelFormat(item, maxWidth);
148
+
149
+ const isBlurredLabel = this.options?.selectLabel?.use
150
+ && this.options?.selectLabel?.useLabelOpacity
151
+ && (this.options.horizontal === (this.type === 'y'))
152
+ && selectLabelInfo?.dataIndex?.length
153
+ && !selectLabelInfo?.dataIndex?.includes(index);
154
+
155
+ const labelColor = this.labelStyle.color;
156
+ let defaultOpacity = 1;
157
+
158
+ if (Util.getColorStringType(labelColor) === 'RGBA') {
159
+ defaultOpacity = Util.getOpacity(labelColor);
160
+ }
161
+
162
+ ctx.fillStyle = Util.colorStringToRgba(labelColor, isBlurredLabel ? 0.1 : defaultOpacity);
163
+
164
+ if (this.type === 'x') {
165
+ labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
166
+ const xPoint = alignToGridLine ? labelCenter : labelCenter + (labelGap / 2);
167
+ ctx.fillText(labelText, xPoint, labelPoint);
168
+
169
+ if (!isBlurredLabel
170
+ && this.options?.selectItem?.showLabelTip
171
+ && hitInfo?.label
172
+ && !this.options?.horizontal) {
173
+ const selectedLabel = hitInfo.label;
174
+ if (selectedLabel === labelText) {
175
+ const height = Math.round(ctx.measureText(this.labelStyle?.fontSize).width);
176
+ Util.showLabelTip({
177
+ ctx: this.ctx,
178
+ width: Math.round(ctx.measureText(selectedLabel).width) + 10,
179
+ height,
180
+ x: labelCenter + (labelGap / 2),
181
+ y: labelPoint + (height - 2),
182
+ borderRadius: 2,
183
+ arrowSize: 3,
184
+ text: labelText,
185
+ backgroundColor: this.options?.selectItem?.labelTipStyle?.backgroundColor,
186
+ textColor: this.options?.selectItem?.labelTipStyle?.textColor,
187
+ });
188
+ }
189
+ }
190
+
191
+ if (index > 0 && this.showGrid) {
192
+ ctx.moveTo(linePosition, offsetPoint);
193
+ ctx.lineTo(linePosition, offsetCounterPoint);
194
+ }
195
+ } else {
196
+ labelPoint = this.position === 'left' ? offsetPoint - 10 : offsetPoint + 10;
197
+ const yPoint = alignToGridLine ? labelCenter : labelCenter + (labelGap / 2);
198
+ ctx.fillText(labelText, labelPoint, yPoint);
199
+
200
+ if (index > 0 && this.showGrid) {
201
+ ctx.moveTo(offsetPoint, linePosition);
202
+ ctx.lineTo(offsetCounterPoint, linePosition);
203
+ }
204
+ }
205
+ ctx.stroke();
206
+ }
207
+
208
+ if (alignToGridLine && (index === this.labels.length)) {
209
+ let labelLastText = +labels[labels.length - 1] + (+labels[1] - +labels[0]);
210
+ if (isNaN(labelLastText)) {
211
+ labelLastText = 'Max';
212
+ }
213
+ labelCenter = Math.round(startPoint + (labelGap * labels.length));
214
+ linePosition = labelCenter + aliasPixel;
215
+
216
+ if (this.type === 'x') {
217
+ ctx.fillText(labelLastText, labelCenter, labelPoint);
218
+ if (this.showGrid) {
219
+ ctx.moveTo(linePosition, offsetPoint);
220
+ ctx.lineTo(linePosition, offsetCounterPoint);
221
+ }
222
+ } else {
223
+ ctx.fillText(labelLastText, labelPoint, labelCenter);
224
+ if (this.showGrid) {
225
+ ctx.moveTo(offsetPoint, linePosition);
226
+ ctx.lineTo(offsetCounterPoint, linePosition);
227
+ }
228
+ }
229
+ ctx.stroke();
230
+ }
231
+
232
+ ctx.closePath();
233
+ }
234
+
235
+ // draw plot lines and plot bands
236
+ if (this.plotBands?.length || this.plotLines?.length) {
237
+ const padding = Util.aliasPixel(ctx.lineWidth) + 1;
238
+ const minX = aPos.x1 + padding;
239
+ const maxX = aPos.x2;
240
+ const minY = aPos.y1 + padding;
241
+ const maxY = aPos.y2;
242
+ const labelGap = (endPoint - startPoint) / (this.labelStyle.show ? labels.length : 1);
243
+
244
+ this.plotBands?.forEach((plotBand) => {
245
+ if (!plotBand.from && !plotBand.to) {
246
+ return;
247
+ }
248
+
249
+ const mergedPlotBandOpt = defaultsDeep({}, plotBand, PLOT_BAND_OPTION);
250
+ const { from = 0, to = labels.length, label: labelOpt } = mergedPlotBandOpt;
251
+ const fromPos = Math.round(startPoint + (labelGap * from));
252
+ const toPos = Math.round(startPoint + (labelGap * to));
253
+
254
+ this.setPlotBandStyle(mergedPlotBandOpt);
255
+
256
+ if (this.type === 'x') {
257
+ this.drawXPlotBand(fromPos, toPos, minX, maxX, minY, maxY);
258
+ } else {
259
+ this.drawYPlotBand(fromPos, toPos, minX, maxX, minY, maxY);
260
+ }
261
+
262
+ if (labelOpt.show) {
263
+ const labelOptions = this.getNormalizedLabelOptions(chartRect, labelOpt);
264
+ const textXY = this.getPlotBandLabelPosition(fromPos, toPos, labelOptions, maxX, minY);
265
+ this.drawPlotLabel(labelOptions, textXY);
266
+ }
267
+
268
+ ctx.restore();
269
+ });
270
+
271
+ this.plotLines?.forEach((plotLine) => {
272
+ if (!plotLine.value) {
273
+ return;
274
+ }
275
+
276
+ const mergedPlotLineOpt = defaultsDeep({}, plotLine, PLOT_LINE_OPTION);
277
+ const { value, label: labelOpt } = mergedPlotLineOpt;
278
+ const dataPos = Math.round(startPoint + (labelGap * value)) + (labelGap / 2);
279
+
280
+ this.setPlotLineStyle(mergedPlotLineOpt);
281
+
282
+ if (this.type === 'x') {
283
+ this.drawXPlotLine(dataPos, minX, maxX, minY, maxY);
284
+ } else {
285
+ this.drawYPlotLine(dataPos, minX, maxX, minY, maxY);
286
+ }
287
+
288
+ if (labelOpt.show) {
289
+ const labelOptions = this.getNormalizedLabelOptions(chartRect, labelOpt);
290
+ const textXY = this.getPlotLineLabelPosition(dataPos, labelOptions, maxX, minY);
291
+ this.drawPlotLabel(labelOptions, textXY);
292
+ }
293
+
294
+ ctx.restore();
295
+ });
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Transforming label by designated format
301
+ * @param {string} value label value
302
+ * @param {number} maxWidth max width for each label
303
+ *
304
+ * @returns {string} formatted label
305
+ */
306
+ getLabelFormat(value, maxWidth) {
307
+ if (this.formatter) {
308
+ const formattedLabel = this.formatter(value);
309
+
310
+ if (typeof formattedLabel === 'string') {
311
+ return formattedLabel;
312
+ }
313
+ }
314
+
315
+ return this.labelStyle.fitWidth ? this.fittingString(value, maxWidth) : value;
316
+ }
317
+
318
+ /**
319
+ * Transforming ellipsis label by designated format and specific width
320
+ * @param {string} value label value
321
+ * @param {number} maxWidth max width for each label
322
+ *
323
+ * @returns {string} formatted label
324
+ */
325
+ fittingString(value, maxWidth) {
326
+ const ctx = this.ctx;
327
+
328
+ ctx.save();
329
+ ctx.font = Util.getLabelStyle(this.labelStyle);
330
+ const dir = this.labelStyle.fitDir;
331
+
332
+ return Util.truncateLabelWithEllipsis(value, maxWidth, ctx, dir);
333
+ }
334
+ }
335
+
336
+ export default StepScale;