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.
- package/LICENSE +21 -21
- package/README.md +40 -40
- package/dist/evui.common.js +1907 -1832
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +1907 -1832
- 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/dist/img/{EVUI.7f3588fb.svg → EVUI.b82ee81a.svg} +292 -292
- package/dist/img/{icon_mysql.7ea26d5d.svg → icon_mysql.1085fdc9.svg} +78 -78
- package/dist/img/{icon_oracle.9009b108.svg → icon_oracle.0572d3ee.svg} +13 -13
- package/dist/img/{icon_postgresql.f8fffba9.svg → icon_postgresql.ee12bde8.svg} +58 -58
- package/package.json +61 -61
- package/src/common/emitter.js +20 -20
- package/src/common/utils.debounce.js +223 -223
- package/src/common/utils.js +134 -134
- package/src/common/utils.table.js +78 -78
- package/src/common/utils.throttle.js +83 -83
- package/src/common/utils.tree.js +18 -18
- package/src/components/button/Button.vue +198 -198
- package/src/components/button/index.js +7 -7
- package/src/components/buttonGroup/ButtonGroup.vue +11 -11
- package/src/components/buttonGroup/index.js +7 -7
- package/src/components/calendar/Calendar.vue +661 -661
- package/src/components/calendar/index.js +7 -7
- package/src/components/calendar/uses.js +1272 -1272
- package/src/components/chart/Chart.vue +189 -192
- package/src/components/chart/chart.core.js +870 -870
- package/src/components/chart/element/element.bar.js +524 -524
- package/src/components/chart/element/element.bar.time.js +156 -156
- package/src/components/chart/element/element.heatmap.js +533 -533
- package/src/components/chart/element/element.line.js +339 -339
- package/src/components/chart/element/element.pie.js +197 -197
- package/src/components/chart/element/element.scatter.js +184 -184
- package/src/components/chart/element/element.tip.js +550 -542
- package/src/components/chart/helpers/helpers.canvas.js +265 -265
- package/src/components/chart/helpers/helpers.constant.js +206 -206
- package/src/components/chart/helpers/helpers.util.js +346 -338
- package/src/components/chart/index.js +9 -9
- package/src/components/chart/model/index.js +4 -4
- package/src/components/chart/model/model.series.js +93 -93
- package/src/components/chart/model/model.store.js +977 -967
- package/src/components/chart/plugins/plugins.interaction.js +769 -769
- package/src/components/chart/plugins/plugins.legend.gradient.js +602 -602
- package/src/components/chart/plugins/plugins.legend.js +1155 -1151
- package/src/components/chart/plugins/plugins.pie.js +254 -254
- package/src/components/chart/plugins/plugins.title.js +56 -56
- package/src/components/chart/plugins/plugins.tooltip.js +692 -692
- package/src/components/chart/scale/scale.js +848 -848
- package/src/components/chart/scale/scale.linear.js +38 -38
- package/src/components/chart/scale/scale.logarithmic.js +128 -128
- package/src/components/chart/scale/scale.step.js +336 -336
- package/src/components/chart/scale/scale.time.category.js +277 -277
- package/src/components/chart/scale/scale.time.js +48 -48
- package/src/components/chart/style/chart.scss +312 -312
- package/src/components/chart/uses.js +264 -252
- package/src/components/checkbox/Checkbox.vue +200 -200
- package/src/components/checkbox/index.js +7 -7
- package/src/components/checkboxGroup/CheckboxGroup.vue +44 -44
- package/src/components/checkboxGroup/index.js +7 -7
- package/src/components/contextMenu/ContextMenu.vue +80 -80
- package/src/components/contextMenu/MenuList.vue +149 -149
- package/src/components/contextMenu/index.js +7 -7
- package/src/components/contextMenu/uses.js +203 -203
- package/src/components/datePicker/DatePicker.vue +437 -437
- package/src/components/datePicker/index.js +7 -7
- package/src/components/datePicker/uses.js +419 -419
- package/src/components/grid/Grid.vue +827 -827
- package/src/components/grid/grid.filter.window.vue +493 -493
- package/src/components/grid/grid.pagination.vue +75 -75
- package/src/components/grid/grid.summary.vue +265 -265
- package/src/components/grid/grid.toolbar.vue +26 -26
- package/src/components/grid/index.js +11 -11
- package/src/components/grid/style/grid.scss +263 -263
- package/src/components/grid/uses.js +1002 -1007
- package/src/components/icon/Icon.vue +49 -49
- package/src/components/icon/index.js +8 -8
- package/src/components/inputNumber/InputNumber.vue +212 -212
- package/src/components/inputNumber/index.js +7 -7
- package/src/components/inputNumber/uses.js +217 -217
- package/src/components/loading/Loading.vue +125 -125
- package/src/components/loading/index.js +7 -7
- package/src/components/menu/Menu.vue +68 -68
- package/src/components/menu/MenuItem.vue +187 -187
- package/src/components/menu/index.js +7 -7
- package/src/components/message/Message.vue +223 -223
- package/src/components/message/index.js +31 -31
- package/src/components/messageBox/MessageBox.vue +358 -358
- package/src/components/messageBox/index.js +22 -22
- package/src/components/notification/Notification.vue +316 -316
- package/src/components/notification/index.js +49 -49
- package/src/components/pagination/Pagination.vue +271 -271
- package/src/components/pagination/index.js +7 -7
- package/src/components/pagination/pageButton.vue +30 -30
- package/src/components/progress/Progress.vue +139 -139
- package/src/components/progress/index.js +7 -7
- package/src/components/radio/Radio.vue +159 -159
- package/src/components/radio/index.js +7 -7
- package/src/components/radioGroup/RadioGroup.vue +41 -41
- package/src/components/radioGroup/index.js +7 -7
- package/src/components/scheduler/Scheduler.vue +149 -149
- package/src/components/scheduler/index.js +7 -7
- package/src/components/scheduler/uses.js +183 -183
- package/src/components/select/Select.vue +440 -440
- package/src/components/select/index.js +7 -7
- package/src/components/select/uses.js +270 -270
- package/src/components/slider/Slider.vue +505 -505
- package/src/components/slider/index.js +7 -7
- package/src/components/slider/uses.js +390 -390
- package/src/components/tabPanel/TabPanel.vue +74 -74
- package/src/components/tabPanel/index.js +7 -7
- package/src/components/tabs/Tabs.vue +517 -517
- package/src/components/tabs/index.js +7 -7
- package/src/components/textField/TextField.vue +375 -375
- package/src/components/textField/index.js +7 -7
- package/src/components/timePicker/TimePicker.vue +352 -352
- package/src/components/timePicker/index.js +7 -7
- package/src/components/toggle/Toggle.vue +115 -115
- package/src/components/toggle/index.js +7 -7
- package/src/components/tree/Tree.vue +313 -313
- package/src/components/tree/TreeNode.vue +293 -293
- package/src/components/tree/index.js +7 -7
- package/src/components/treeGrid/TreeGrid.vue +758 -758
- package/src/components/treeGrid/TreeGridNode.vue +275 -275
- package/src/components/treeGrid/index.js +9 -9
- package/src/components/treeGrid/style/treeGrid.scss +261 -261
- package/src/components/treeGrid/treeGrid.toolbar.vue +26 -26
- package/src/components/treeGrid/uses.js +867 -867
- package/src/components/window/Window.vue +329 -329
- package/src/components/window/index.js +7 -7
- package/src/components/window/uses.js +899 -899
- package/src/directives/clickoutside.js +90 -90
- package/src/main.js +116 -116
- package/src/style/components/input.scss +108 -108
- package/src/style/functions.scss +3 -3
- package/src/style/index.scss +6 -6
- package/src/style/lib/fonts/EVUI.svg +292 -292
- package/src/style/lib/icon.css +888 -888
- package/src/style/mixins.scss +94 -94
- package/src/style/themes.scss +67 -67
- package/src/style/variables.scss +22 -22
|
@@ -1,338 +1,346 @@
|
|
|
1
|
-
import {
|
|
2
|
-
billions,
|
|
3
|
-
millions,
|
|
4
|
-
quadrillion,
|
|
5
|
-
trillion,
|
|
6
|
-
truthy,
|
|
7
|
-
} from '@/common/utils';
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
/**
|
|
11
|
-
* Transforming hex to rgb code
|
|
12
|
-
* @param {string} hex hex color code
|
|
13
|
-
*
|
|
14
|
-
* @returns {string} rgb code
|
|
15
|
-
*/
|
|
16
|
-
hexToRgb(hex) {
|
|
17
|
-
if (!hex) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
22
|
-
|
|
23
|
-
const r = parseInt(result[1], 16);
|
|
24
|
-
const g = parseInt(result[2], 16);
|
|
25
|
-
const b = parseInt(result[3], 16);
|
|
26
|
-
|
|
27
|
-
return `${r},${g},${b}`;
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Check color string and return what type it is. ('HEX', 'RGB', 'RGBA' or 'NONE')
|
|
32
|
-
* @param colorStr
|
|
33
|
-
* @returns {string} color type
|
|
34
|
-
*/
|
|
35
|
-
getColorStringType(colorStr) {
|
|
36
|
-
const noneWhiteSpaceColorStr = colorStr.replace(/ /g, '');
|
|
37
|
-
const isHEX = /^#(?:[A-Fa-f0-9]{3}){1,2}$/.exec(noneWhiteSpaceColorStr);
|
|
38
|
-
const isRGB = /^rgb[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*(?:,(?![)])|(?=[)]))){3}[)]$/.exec(noneWhiteSpaceColorStr);
|
|
39
|
-
const isRGBA = /^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1?)\s*[)]$/.exec(noneWhiteSpaceColorStr);
|
|
40
|
-
let result = '';
|
|
41
|
-
|
|
42
|
-
if (isHEX) {
|
|
43
|
-
result = 'HEX';
|
|
44
|
-
} else if (isRGB) {
|
|
45
|
-
result = 'RGB';
|
|
46
|
-
} else if (isRGBA) {
|
|
47
|
-
result = 'RGBA';
|
|
48
|
-
} else {
|
|
49
|
-
result = 'NONE';
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return result;
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Transforming color string to rgba code
|
|
57
|
-
* Return BLACK ('rgba(0, 0, 0, ${opacity})') if fail transforming
|
|
58
|
-
* @param colorStr hex color code, rgb, rgba .. etc
|
|
59
|
-
* @param opacity color opacity. (default 1)translate
|
|
60
|
-
* @returns {string} transformed rgba
|
|
61
|
-
*/
|
|
62
|
-
colorStringToRgba(colorStr, opacity = 1) {
|
|
63
|
-
const noneWhiteSpaceColorStr = colorStr.replace(/ /g, '');
|
|
64
|
-
const colorType = this.getColorStringType(noneWhiteSpaceColorStr);
|
|
65
|
-
let resultRGBA = '';
|
|
66
|
-
|
|
67
|
-
switch (colorType) {
|
|
68
|
-
case 'HEX':
|
|
69
|
-
resultRGBA = `rgba(${this.hexToRgb(noneWhiteSpaceColorStr)},${opacity})`;
|
|
70
|
-
break;
|
|
71
|
-
case 'RGB':
|
|
72
|
-
resultRGBA = noneWhiteSpaceColorStr.replace(')', `, ${opacity})`).replace('rgb', 'rgba');
|
|
73
|
-
break;
|
|
74
|
-
case 'RGBA':
|
|
75
|
-
resultRGBA = noneWhiteSpaceColorStr.replace(`${this.getOpacity(colorStr)})`, `${opacity})`);
|
|
76
|
-
break;
|
|
77
|
-
default:
|
|
78
|
-
resultRGBA = `rgba(0, 0, 0, ${opacity})`;
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return resultRGBA;
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* get opacity value on rgba color string
|
|
87
|
-
* ex) input : rgba(255, 255, 255, 0.1)
|
|
88
|
-
* return : 0.1
|
|
89
|
-
* @param rgbaColorString
|
|
90
|
-
* @returns {string} opacity
|
|
91
|
-
*/
|
|
92
|
-
getOpacity(rgbaColorString) {
|
|
93
|
-
const noneWhiteSpaceColorStr = rgbaColorString.replace(/ /g, '');
|
|
94
|
-
const colorType = this.getColorStringType(noneWhiteSpaceColorStr);
|
|
95
|
-
|
|
96
|
-
if (colorType === 'RGBA') {
|
|
97
|
-
return noneWhiteSpaceColorStr.replace(/^.*,(.+)\)/, '$1');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return '1';
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* To logarithmic scale, compute log value
|
|
105
|
-
* @param {number} value graph value
|
|
106
|
-
*
|
|
107
|
-
* @returns {number} computed value
|
|
108
|
-
*/
|
|
109
|
-
calculateMagnitude(value) {
|
|
110
|
-
return Math.floor(Math.log(value) / Math.LN10);
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Set alias pixel to deal with anti-aliasing
|
|
115
|
-
* @param {number} width line width
|
|
116
|
-
*
|
|
117
|
-
* @returns {number} computed value
|
|
118
|
-
*/
|
|
119
|
-
aliasPixel(width) {
|
|
120
|
-
return width % 2 === 0 ? 0 : 0.5;
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Create string for canvas font style
|
|
125
|
-
* @param {object} style style object by user
|
|
126
|
-
*
|
|
127
|
-
* @returns {string} computed value
|
|
128
|
-
*/
|
|
129
|
-
getLabelStyle(style) {
|
|
130
|
-
const {
|
|
131
|
-
fontStyle = 'normal',
|
|
132
|
-
fontWeight = 'norma',
|
|
133
|
-
fontSize = '12',
|
|
134
|
-
fontFamily = 'Roboto',
|
|
135
|
-
} = style;
|
|
136
|
-
|
|
137
|
-
return `${fontStyle} normal ${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Create sign format with number
|
|
142
|
-
* @param {number} value graph value
|
|
143
|
-
* @param {number} decimalPoint decimal point
|
|
144
|
-
*
|
|
145
|
-
* @returns {string} signed value
|
|
146
|
-
*/
|
|
147
|
-
labelSignFormat(value, decimalPoint = 0) {
|
|
148
|
-
const quad = quadrillion(1);
|
|
149
|
-
const trill = trillion(1);
|
|
150
|
-
const billi = billions(1);
|
|
151
|
-
const milli = millions(1);
|
|
152
|
-
const killo = 1000;
|
|
153
|
-
|
|
154
|
-
let label;
|
|
155
|
-
if (!truthy(value)) {
|
|
156
|
-
return value;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const assignLabelWith = (v, target, lb) => {
|
|
160
|
-
if (v % target === 0) {
|
|
161
|
-
return `${(v / target).toFixed(decimalPoint)}${lb}`;
|
|
162
|
-
}
|
|
163
|
-
return `${(v / target).toFixed(1)}${lb}`;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
if (value >= quad) {
|
|
167
|
-
label = assignLabelWith(value, quad, 'P');
|
|
168
|
-
} else if (value >= trill) {
|
|
169
|
-
label = assignLabelWith(value, trill, 'T');
|
|
170
|
-
} else if (value >= billi) {
|
|
171
|
-
label = assignLabelWith(value, billi, 'G');
|
|
172
|
-
} else if (value >= milli) {
|
|
173
|
-
label = assignLabelWith(value, milli, 'M');
|
|
174
|
-
} else if (value >= killo) {
|
|
175
|
-
label = assignLabelWith(value, 1000, 'K');
|
|
176
|
-
} else {
|
|
177
|
-
label = value.toFixed(decimalPoint);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return label;
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Calculate text size with html
|
|
185
|
-
* @param {string} text text is needed to check size
|
|
186
|
-
* @param {string} fontStyle text font style
|
|
187
|
-
*
|
|
188
|
-
* @returns {object} text size information
|
|
189
|
-
*/
|
|
190
|
-
calcTextSize(text, fontStyle) {
|
|
191
|
-
const calc = document.createElement('span');
|
|
192
|
-
const style = `visibility:hidden; position:absolute; top:-10000px; font: ${fontStyle};`;
|
|
193
|
-
|
|
194
|
-
calc.setAttribute('style', style);
|
|
195
|
-
calc.style.font = fontStyle;
|
|
196
|
-
calc.textContent = text;
|
|
197
|
-
document.body.appendChild(calc);
|
|
198
|
-
|
|
199
|
-
const rect = calc.getBoundingClientRect();
|
|
200
|
-
const width = rect.width || 2;
|
|
201
|
-
const height = rect.height || 2;
|
|
202
|
-
|
|
203
|
-
calc.remove();
|
|
204
|
-
|
|
205
|
-
return { width, height };
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Comparing strings
|
|
210
|
-
* @param {array} array compared array
|
|
211
|
-
*
|
|
212
|
-
* @returns {object} min/max information
|
|
213
|
-
*/
|
|
214
|
-
getStringMinMax(array) {
|
|
215
|
-
const minMax = {
|
|
216
|
-
min: array[0],
|
|
217
|
-
max: array[0],
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
array.forEach((item) => {
|
|
221
|
-
if (minMax?.max?.length < item?.length) {
|
|
222
|
-
minMax.max = item;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (minMax?.min?.length > item?.length) {
|
|
226
|
-
minMax.min = item;
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
return minMax;
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Truncate the long string to short string with ellipsis until fitting maxWidth
|
|
235
|
-
* @param {string} str target string
|
|
236
|
-
* @param {number} maxWidth maximum string width on canvas
|
|
237
|
-
* @param {Object} ctx canvas context
|
|
238
|
-
* @param {string} direction left or right (default: right)
|
|
239
|
-
*/
|
|
240
|
-
truncateLabelWithEllipsis(str, maxWidth, ctx, direction = 'right') {
|
|
241
|
-
if (!str) {
|
|
242
|
-
return '';
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (!maxWidth) {
|
|
246
|
-
return str;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const ellipsis = '…';
|
|
250
|
-
const ellipsisWidth = ctx.measureText(ellipsis).width;
|
|
251
|
-
|
|
252
|
-
let temp = str;
|
|
253
|
-
let tempWidth = ctx.measureText(temp).width;
|
|
254
|
-
|
|
255
|
-
if (tempWidth <= maxWidth || tempWidth <= ellipsisWidth) {
|
|
256
|
-
return str;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
let len = temp.length;
|
|
260
|
-
while (tempWidth >= maxWidth - ellipsisWidth && len-- > 0) {
|
|
261
|
-
temp = direction === 'right' ? temp.substring(0, len) : temp.substring(1, temp.length);
|
|
262
|
-
tempWidth = ctx.measureText(temp).width;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return direction === 'right' ? temp + ellipsis : ellipsis + temp;
|
|
266
|
-
},
|
|
267
|
-
/**
|
|
268
|
-
* Draw text tip
|
|
269
|
-
* @param {object} param object for drawing text tip
|
|
270
|
-
*
|
|
271
|
-
* @returns {undefined}
|
|
272
|
-
*/
|
|
273
|
-
showLabelTip(param) {
|
|
274
|
-
const {
|
|
275
|
-
ctx,
|
|
276
|
-
width,
|
|
277
|
-
height,
|
|
278
|
-
x,
|
|
279
|
-
y,
|
|
280
|
-
arrowSize,
|
|
281
|
-
borderRadius,
|
|
282
|
-
text,
|
|
283
|
-
backgroundColor,
|
|
284
|
-
textColor,
|
|
285
|
-
} = param;
|
|
286
|
-
const sx = x - (width / 2);
|
|
287
|
-
const ex = x + (width / 2);
|
|
288
|
-
const sy = y - height;
|
|
289
|
-
const ey = y;
|
|
290
|
-
|
|
291
|
-
ctx.beginPath();
|
|
292
|
-
ctx.save();
|
|
293
|
-
ctx.fillStyle = backgroundColor || '#E96E2C';
|
|
294
|
-
ctx.strokeStyle = backgroundColor || '#E96E2C';
|
|
295
|
-
ctx.shadowBlur = 0;
|
|
296
|
-
ctx.moveTo(sx + borderRadius, sy);
|
|
297
|
-
ctx.quadraticCurveTo(sx, sy, sx, sy + borderRadius);
|
|
298
|
-
ctx.lineTo(sx, ey - borderRadius);
|
|
299
|
-
ctx.quadraticCurveTo(sx, ey, sx + borderRadius, ey);
|
|
300
|
-
ctx.lineTo(ex - borderRadius, ey);
|
|
301
|
-
ctx.quadraticCurveTo(ex, ey, ex, ey - borderRadius);
|
|
302
|
-
ctx.lineTo(ex, sy + borderRadius);
|
|
303
|
-
ctx.quadraticCurveTo(ex, sy, ex - borderRadius, sy);
|
|
304
|
-
ctx.lineTo(x - arrowSize, sy);
|
|
305
|
-
ctx.lineTo(x, sy - arrowSize);
|
|
306
|
-
ctx.lineTo(x + arrowSize, sy);
|
|
307
|
-
ctx.lineTo(sx + borderRadius, sy);
|
|
308
|
-
ctx.closePath();
|
|
309
|
-
ctx.fill();
|
|
310
|
-
ctx.restore();
|
|
311
|
-
ctx.save();
|
|
312
|
-
ctx.font = 'normal normal bold 12px Roboto';
|
|
313
|
-
ctx.fillStyle = textColor || '#FFF';
|
|
314
|
-
ctx.textBaseline = 'middle';
|
|
315
|
-
ctx.textAlign = 'center';
|
|
316
|
-
ctx.fillText(`${text}`, x, sy + (height / 2));
|
|
317
|
-
ctx.restore();
|
|
318
|
-
ctx.beginPath();
|
|
319
|
-
},
|
|
320
|
-
|
|
321
|
-
isPieType(type) {
|
|
322
|
-
return type === 'pie' || type === 'doughnut' || type === 'sunburst';
|
|
323
|
-
},
|
|
324
|
-
|
|
325
|
-
isDoughnutHole(type) {
|
|
326
|
-
return type === 'doughnut' || type === 'sunburst';
|
|
327
|
-
},
|
|
328
|
-
|
|
329
|
-
setDOMStyle(targetDOM, styleObject) {
|
|
330
|
-
if (!targetDOM || !styleObject) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
Object.keys(styleObject)?.forEach((key) => {
|
|
335
|
-
targetDOM.style[key] = styleObject[key];
|
|
336
|
-
});
|
|
337
|
-
},
|
|
338
|
-
|
|
1
|
+
import {
|
|
2
|
+
billions,
|
|
3
|
+
millions,
|
|
4
|
+
quadrillion,
|
|
5
|
+
trillion,
|
|
6
|
+
truthy,
|
|
7
|
+
} from '@/common/utils';
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
/**
|
|
11
|
+
* Transforming hex to rgb code
|
|
12
|
+
* @param {string} hex hex color code
|
|
13
|
+
*
|
|
14
|
+
* @returns {string} rgb code
|
|
15
|
+
*/
|
|
16
|
+
hexToRgb(hex) {
|
|
17
|
+
if (!hex) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
22
|
+
|
|
23
|
+
const r = parseInt(result[1], 16);
|
|
24
|
+
const g = parseInt(result[2], 16);
|
|
25
|
+
const b = parseInt(result[3], 16);
|
|
26
|
+
|
|
27
|
+
return `${r},${g},${b}`;
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check color string and return what type it is. ('HEX', 'RGB', 'RGBA' or 'NONE')
|
|
32
|
+
* @param colorStr
|
|
33
|
+
* @returns {string} color type
|
|
34
|
+
*/
|
|
35
|
+
getColorStringType(colorStr) {
|
|
36
|
+
const noneWhiteSpaceColorStr = colorStr.replace(/ /g, '');
|
|
37
|
+
const isHEX = /^#(?:[A-Fa-f0-9]{3}){1,2}$/.exec(noneWhiteSpaceColorStr);
|
|
38
|
+
const isRGB = /^rgb[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*(?:,(?![)])|(?=[)]))){3}[)]$/.exec(noneWhiteSpaceColorStr);
|
|
39
|
+
const isRGBA = /^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1?)\s*[)]$/.exec(noneWhiteSpaceColorStr);
|
|
40
|
+
let result = '';
|
|
41
|
+
|
|
42
|
+
if (isHEX) {
|
|
43
|
+
result = 'HEX';
|
|
44
|
+
} else if (isRGB) {
|
|
45
|
+
result = 'RGB';
|
|
46
|
+
} else if (isRGBA) {
|
|
47
|
+
result = 'RGBA';
|
|
48
|
+
} else {
|
|
49
|
+
result = 'NONE';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return result;
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Transforming color string to rgba code
|
|
57
|
+
* Return BLACK ('rgba(0, 0, 0, ${opacity})') if fail transforming
|
|
58
|
+
* @param colorStr hex color code, rgb, rgba .. etc
|
|
59
|
+
* @param opacity color opacity. (default 1)translate
|
|
60
|
+
* @returns {string} transformed rgba
|
|
61
|
+
*/
|
|
62
|
+
colorStringToRgba(colorStr, opacity = 1) {
|
|
63
|
+
const noneWhiteSpaceColorStr = colorStr.replace(/ /g, '');
|
|
64
|
+
const colorType = this.getColorStringType(noneWhiteSpaceColorStr);
|
|
65
|
+
let resultRGBA = '';
|
|
66
|
+
|
|
67
|
+
switch (colorType) {
|
|
68
|
+
case 'HEX':
|
|
69
|
+
resultRGBA = `rgba(${this.hexToRgb(noneWhiteSpaceColorStr)},${opacity})`;
|
|
70
|
+
break;
|
|
71
|
+
case 'RGB':
|
|
72
|
+
resultRGBA = noneWhiteSpaceColorStr.replace(')', `, ${opacity})`).replace('rgb', 'rgba');
|
|
73
|
+
break;
|
|
74
|
+
case 'RGBA':
|
|
75
|
+
resultRGBA = noneWhiteSpaceColorStr.replace(`${this.getOpacity(colorStr)})`, `${opacity})`);
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
resultRGBA = `rgba(0, 0, 0, ${opacity})`;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return resultRGBA;
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* get opacity value on rgba color string
|
|
87
|
+
* ex) input : rgba(255, 255, 255, 0.1)
|
|
88
|
+
* return : 0.1
|
|
89
|
+
* @param rgbaColorString
|
|
90
|
+
* @returns {string} opacity
|
|
91
|
+
*/
|
|
92
|
+
getOpacity(rgbaColorString) {
|
|
93
|
+
const noneWhiteSpaceColorStr = rgbaColorString.replace(/ /g, '');
|
|
94
|
+
const colorType = this.getColorStringType(noneWhiteSpaceColorStr);
|
|
95
|
+
|
|
96
|
+
if (colorType === 'RGBA') {
|
|
97
|
+
return noneWhiteSpaceColorStr.replace(/^.*,(.+)\)/, '$1');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return '1';
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* To logarithmic scale, compute log value
|
|
105
|
+
* @param {number} value graph value
|
|
106
|
+
*
|
|
107
|
+
* @returns {number} computed value
|
|
108
|
+
*/
|
|
109
|
+
calculateMagnitude(value) {
|
|
110
|
+
return Math.floor(Math.log(value) / Math.LN10);
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Set alias pixel to deal with anti-aliasing
|
|
115
|
+
* @param {number} width line width
|
|
116
|
+
*
|
|
117
|
+
* @returns {number} computed value
|
|
118
|
+
*/
|
|
119
|
+
aliasPixel(width) {
|
|
120
|
+
return width % 2 === 0 ? 0 : 0.5;
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Create string for canvas font style
|
|
125
|
+
* @param {object} style style object by user
|
|
126
|
+
*
|
|
127
|
+
* @returns {string} computed value
|
|
128
|
+
*/
|
|
129
|
+
getLabelStyle(style) {
|
|
130
|
+
const {
|
|
131
|
+
fontStyle = 'normal',
|
|
132
|
+
fontWeight = 'norma',
|
|
133
|
+
fontSize = '12',
|
|
134
|
+
fontFamily = 'Roboto',
|
|
135
|
+
} = style;
|
|
136
|
+
|
|
137
|
+
return `${fontStyle} normal ${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Create sign format with number
|
|
142
|
+
* @param {number} value graph value
|
|
143
|
+
* @param {number} decimalPoint decimal point
|
|
144
|
+
*
|
|
145
|
+
* @returns {string} signed value
|
|
146
|
+
*/
|
|
147
|
+
labelSignFormat(value, decimalPoint = 0) {
|
|
148
|
+
const quad = quadrillion(1);
|
|
149
|
+
const trill = trillion(1);
|
|
150
|
+
const billi = billions(1);
|
|
151
|
+
const milli = millions(1);
|
|
152
|
+
const killo = 1000;
|
|
153
|
+
|
|
154
|
+
let label;
|
|
155
|
+
if (!truthy(value)) {
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const assignLabelWith = (v, target, lb) => {
|
|
160
|
+
if (v % target === 0) {
|
|
161
|
+
return `${(v / target).toFixed(decimalPoint)}${lb}`;
|
|
162
|
+
}
|
|
163
|
+
return `${(v / target).toFixed(1)}${lb}`;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
if (value >= quad) {
|
|
167
|
+
label = assignLabelWith(value, quad, 'P');
|
|
168
|
+
} else if (value >= trill) {
|
|
169
|
+
label = assignLabelWith(value, trill, 'T');
|
|
170
|
+
} else if (value >= billi) {
|
|
171
|
+
label = assignLabelWith(value, billi, 'G');
|
|
172
|
+
} else if (value >= milli) {
|
|
173
|
+
label = assignLabelWith(value, milli, 'M');
|
|
174
|
+
} else if (value >= killo) {
|
|
175
|
+
label = assignLabelWith(value, 1000, 'K');
|
|
176
|
+
} else {
|
|
177
|
+
label = value.toFixed(decimalPoint);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return label;
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Calculate text size with html
|
|
185
|
+
* @param {string} text text is needed to check size
|
|
186
|
+
* @param {string} fontStyle text font style
|
|
187
|
+
*
|
|
188
|
+
* @returns {object} text size information
|
|
189
|
+
*/
|
|
190
|
+
calcTextSize(text, fontStyle) {
|
|
191
|
+
const calc = document.createElement('span');
|
|
192
|
+
const style = `visibility:hidden; position:absolute; top:-10000px; font: ${fontStyle};`;
|
|
193
|
+
|
|
194
|
+
calc.setAttribute('style', style);
|
|
195
|
+
calc.style.font = fontStyle;
|
|
196
|
+
calc.textContent = text;
|
|
197
|
+
document.body.appendChild(calc);
|
|
198
|
+
|
|
199
|
+
const rect = calc.getBoundingClientRect();
|
|
200
|
+
const width = rect.width || 2;
|
|
201
|
+
const height = rect.height || 2;
|
|
202
|
+
|
|
203
|
+
calc.remove();
|
|
204
|
+
|
|
205
|
+
return { width, height };
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Comparing strings
|
|
210
|
+
* @param {array} array compared array
|
|
211
|
+
*
|
|
212
|
+
* @returns {object} min/max information
|
|
213
|
+
*/
|
|
214
|
+
getStringMinMax(array) {
|
|
215
|
+
const minMax = {
|
|
216
|
+
min: array[0],
|
|
217
|
+
max: array[0],
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
array.forEach((item) => {
|
|
221
|
+
if (minMax?.max?.length < item?.length) {
|
|
222
|
+
minMax.max = item;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (minMax?.min?.length > item?.length) {
|
|
226
|
+
minMax.min = item;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return minMax;
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Truncate the long string to short string with ellipsis until fitting maxWidth
|
|
235
|
+
* @param {string} str target string
|
|
236
|
+
* @param {number} maxWidth maximum string width on canvas
|
|
237
|
+
* @param {Object} ctx canvas context
|
|
238
|
+
* @param {string} direction left or right (default: right)
|
|
239
|
+
*/
|
|
240
|
+
truncateLabelWithEllipsis(str, maxWidth, ctx, direction = 'right') {
|
|
241
|
+
if (!str) {
|
|
242
|
+
return '';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!maxWidth) {
|
|
246
|
+
return str;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const ellipsis = '…';
|
|
250
|
+
const ellipsisWidth = ctx.measureText(ellipsis).width;
|
|
251
|
+
|
|
252
|
+
let temp = str;
|
|
253
|
+
let tempWidth = ctx.measureText(temp).width;
|
|
254
|
+
|
|
255
|
+
if (tempWidth <= maxWidth || tempWidth <= ellipsisWidth) {
|
|
256
|
+
return str;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
let len = temp.length;
|
|
260
|
+
while (tempWidth >= maxWidth - ellipsisWidth && len-- > 0) {
|
|
261
|
+
temp = direction === 'right' ? temp.substring(0, len) : temp.substring(1, temp.length);
|
|
262
|
+
tempWidth = ctx.measureText(temp).width;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return direction === 'right' ? temp + ellipsis : ellipsis + temp;
|
|
266
|
+
},
|
|
267
|
+
/**
|
|
268
|
+
* Draw text tip
|
|
269
|
+
* @param {object} param object for drawing text tip
|
|
270
|
+
*
|
|
271
|
+
* @returns {undefined}
|
|
272
|
+
*/
|
|
273
|
+
showLabelTip(param) {
|
|
274
|
+
const {
|
|
275
|
+
ctx,
|
|
276
|
+
width,
|
|
277
|
+
height,
|
|
278
|
+
x,
|
|
279
|
+
y,
|
|
280
|
+
arrowSize,
|
|
281
|
+
borderRadius,
|
|
282
|
+
text,
|
|
283
|
+
backgroundColor,
|
|
284
|
+
textColor,
|
|
285
|
+
} = param;
|
|
286
|
+
const sx = x - (width / 2);
|
|
287
|
+
const ex = x + (width / 2);
|
|
288
|
+
const sy = y - height;
|
|
289
|
+
const ey = y;
|
|
290
|
+
|
|
291
|
+
ctx.beginPath();
|
|
292
|
+
ctx.save();
|
|
293
|
+
ctx.fillStyle = backgroundColor || '#E96E2C';
|
|
294
|
+
ctx.strokeStyle = backgroundColor || '#E96E2C';
|
|
295
|
+
ctx.shadowBlur = 0;
|
|
296
|
+
ctx.moveTo(sx + borderRadius, sy);
|
|
297
|
+
ctx.quadraticCurveTo(sx, sy, sx, sy + borderRadius);
|
|
298
|
+
ctx.lineTo(sx, ey - borderRadius);
|
|
299
|
+
ctx.quadraticCurveTo(sx, ey, sx + borderRadius, ey);
|
|
300
|
+
ctx.lineTo(ex - borderRadius, ey);
|
|
301
|
+
ctx.quadraticCurveTo(ex, ey, ex, ey - borderRadius);
|
|
302
|
+
ctx.lineTo(ex, sy + borderRadius);
|
|
303
|
+
ctx.quadraticCurveTo(ex, sy, ex - borderRadius, sy);
|
|
304
|
+
ctx.lineTo(x - arrowSize, sy);
|
|
305
|
+
ctx.lineTo(x, sy - arrowSize);
|
|
306
|
+
ctx.lineTo(x + arrowSize, sy);
|
|
307
|
+
ctx.lineTo(sx + borderRadius, sy);
|
|
308
|
+
ctx.closePath();
|
|
309
|
+
ctx.fill();
|
|
310
|
+
ctx.restore();
|
|
311
|
+
ctx.save();
|
|
312
|
+
ctx.font = 'normal normal bold 12px Roboto';
|
|
313
|
+
ctx.fillStyle = textColor || '#FFF';
|
|
314
|
+
ctx.textBaseline = 'middle';
|
|
315
|
+
ctx.textAlign = 'center';
|
|
316
|
+
ctx.fillText(`${text}`, x, sy + (height / 2));
|
|
317
|
+
ctx.restore();
|
|
318
|
+
ctx.beginPath();
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
isPieType(type) {
|
|
322
|
+
return type === 'pie' || type === 'doughnut' || type === 'sunburst';
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
isDoughnutHole(type) {
|
|
326
|
+
return type === 'doughnut' || type === 'sunburst';
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
setDOMStyle(targetDOM, styleObject) {
|
|
330
|
+
if (!targetDOM || !styleObject) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
Object.keys(styleObject)?.forEach((key) => {
|
|
335
|
+
targetDOM.style[key] = styleObject[key];
|
|
336
|
+
});
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
checkSafeInteger(value) {
|
|
340
|
+
if (value === null || value === undefined) {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return value <= Number.MAX_SAFE_INTEGER && value >= Number.MIN_SAFE_INTEGER;
|
|
345
|
+
},
|
|
346
|
+
};
|