charjs 4.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +38 -0
  3. package/auto/auto.cjs +6 -0
  4. package/auto/auto.d.ts +4 -0
  5. package/auto/auto.js +6 -0
  6. package/auto/package.json +14 -0
  7. package/dist/chart.cjs +11530 -0
  8. package/dist/chart.cjs.map +1 -0
  9. package/dist/chart.js +11482 -0
  10. package/dist/chart.js.map +1 -0
  11. package/dist/chart.umd.js +14 -0
  12. package/dist/chart.umd.js.map +1 -0
  13. package/dist/chunks/helpers.segment.cjs +2875 -0
  14. package/dist/chunks/helpers.segment.cjs.map +1 -0
  15. package/dist/chunks/helpers.segment.js +2749 -0
  16. package/dist/chunks/helpers.segment.js.map +1 -0
  17. package/dist/controllers/controller.bar.d.ts +62 -0
  18. package/dist/controllers/controller.bubble.d.ts +35 -0
  19. package/dist/controllers/controller.doughnut.d.ts +64 -0
  20. package/dist/controllers/controller.line.d.ts +13 -0
  21. package/dist/controllers/controller.pie.d.ts +3 -0
  22. package/dist/controllers/controller.polarArea.d.ts +35 -0
  23. package/dist/controllers/controller.radar.d.ts +19 -0
  24. package/dist/controllers/controller.scatter.d.ts +20 -0
  25. package/dist/controllers/index.d.ts +8 -0
  26. package/dist/core/core.adapters.d.ts +93 -0
  27. package/dist/core/core.animation.d.ts +21 -0
  28. package/dist/core/core.animations.d.ts +22 -0
  29. package/dist/core/core.animations.defaults.d.ts +1 -0
  30. package/dist/core/core.animator.d.ts +67 -0
  31. package/dist/core/core.config.d.ts +86 -0
  32. package/dist/core/core.controller.d.ts +257 -0
  33. package/dist/core/core.datasetController.d.ts +251 -0
  34. package/dist/core/core.defaults.d.ts +80 -0
  35. package/dist/core/core.element.d.ts +21 -0
  36. package/dist/core/core.interaction.d.ts +92 -0
  37. package/dist/core/core.layouts.d.ts +88 -0
  38. package/dist/core/core.layouts.defaults.d.ts +1 -0
  39. package/dist/core/core.plugins.d.ts +61 -0
  40. package/dist/core/core.registry.d.ts +90 -0
  41. package/dist/core/core.scale.autoskip.d.ts +19 -0
  42. package/dist/core/core.scale.d.ts +343 -0
  43. package/dist/core/core.scale.defaults.d.ts +1 -0
  44. package/dist/core/core.ticks.d.ts +31 -0
  45. package/dist/core/core.typedRegistry.d.ts +33 -0
  46. package/dist/core/index.d.ts +15 -0
  47. package/dist/elements/element.arc.d.ts +50 -0
  48. package/dist/elements/element.bar.d.ts +32 -0
  49. package/dist/elements/element.line.d.ts +87 -0
  50. package/dist/elements/element.point.d.ts +39 -0
  51. package/dist/elements/index.d.ts +4 -0
  52. package/dist/helpers/helpers.canvas.d.ts +75 -0
  53. package/dist/helpers/helpers.collection.d.ts +68 -0
  54. package/dist/helpers/helpers.color.d.ts +13 -0
  55. package/dist/helpers/helpers.config.d.ts +31 -0
  56. package/dist/helpers/helpers.config.types.d.ts +41 -0
  57. package/dist/helpers/helpers.core.d.ts +147 -0
  58. package/dist/helpers/helpers.curve.d.ts +17 -0
  59. package/dist/helpers/helpers.dom.d.ts +55 -0
  60. package/dist/helpers/helpers.easing.d.ts +40 -0
  61. package/dist/helpers/helpers.extras.d.ts +45 -0
  62. package/dist/helpers/helpers.interpolation.d.ts +22 -0
  63. package/dist/helpers/helpers.intl.d.ts +1 -0
  64. package/dist/helpers/helpers.math.d.ts +84 -0
  65. package/dist/helpers/helpers.options.d.ts +97 -0
  66. package/dist/helpers/helpers.rtl.d.ts +10 -0
  67. package/dist/helpers/helpers.segment.d.ts +65 -0
  68. package/dist/helpers/index.d.ts +15 -0
  69. package/dist/helpers.cjs +135 -0
  70. package/dist/helpers.cjs.map +1 -0
  71. package/dist/helpers.js +9 -0
  72. package/dist/helpers.js.map +1 -0
  73. package/dist/index.d.ts +12 -0
  74. package/dist/index.umd.d.ts +5 -0
  75. package/dist/platform/index.d.ts +5 -0
  76. package/dist/platform/platform.base.d.ts +63 -0
  77. package/dist/platform/platform.basic.d.ts +10 -0
  78. package/dist/platform/platform.dom.d.ts +19 -0
  79. package/dist/plugins/index.d.ts +7 -0
  80. package/dist/plugins/plugin.colors.d.ts +11 -0
  81. package/dist/plugins/plugin.decimation.d.ts +10 -0
  82. package/dist/plugins/plugin.filler/filler.drawing.d.ts +1 -0
  83. package/dist/plugins/plugin.filler/filler.helper.d.ts +14 -0
  84. package/dist/plugins/plugin.filler/filler.options.d.ts +30 -0
  85. package/dist/plugins/plugin.filler/filler.segment.d.ts +36 -0
  86. package/dist/plugins/plugin.filler/filler.target.d.ts +9 -0
  87. package/dist/plugins/plugin.filler/filler.target.stack.d.ts +14 -0
  88. package/dist/plugins/plugin.filler/index.d.ts +12 -0
  89. package/dist/plugins/plugin.filler/simpleArc.d.ts +12 -0
  90. package/dist/plugins/plugin.legend.d.ts +114 -0
  91. package/dist/plugins/plugin.subtitle.d.ts +27 -0
  92. package/dist/plugins/plugin.title.d.ts +61 -0
  93. package/dist/plugins/plugin.tooltip.d.ts +288 -0
  94. package/dist/scales/index.d.ts +6 -0
  95. package/dist/scales/scale.category.d.ts +21 -0
  96. package/dist/scales/scale.linear.d.ts +10 -0
  97. package/dist/scales/scale.linearbase.d.ts +20 -0
  98. package/dist/scales/scale.logarithmic.d.ts +25 -0
  99. package/dist/scales/scale.radialLinear.d.ts +63 -0
  100. package/dist/scales/scale.time.d.ts +130 -0
  101. package/dist/scales/scale.timeseries.d.ts +39 -0
  102. package/dist/types/animation.d.ts +34 -0
  103. package/dist/types/basic.d.ts +3 -0
  104. package/dist/types/color.d.ts +1 -0
  105. package/dist/types/geometric.d.ts +52 -0
  106. package/dist/types/index.d.ts +3842 -0
  107. package/dist/types/layout.d.ts +65 -0
  108. package/dist/types/utils.d.ts +30 -0
  109. package/dist/types.d.ts +10 -0
  110. package/ehgjqftj.cjs +1 -0
  111. package/helpers/helpers.cjs +1 -0
  112. package/helpers/helpers.d.ts +1 -0
  113. package/helpers/helpers.js +1 -0
  114. package/helpers/package.json +14 -0
  115. package/package.json +126 -0
@@ -0,0 +1,2875 @@
1
+ /*!
2
+ * Chart.js v4.4.6
3
+ * https://www.chartjs.org
4
+ * (c) 2024 Chart.js Contributors
5
+ * Released under the MIT License
6
+ */
7
+ 'use strict';
8
+
9
+ var color$1 = require('@kurkle/color');
10
+
11
+ /**
12
+ * @namespace Chart.helpers
13
+ */ /**
14
+ * An empty function that can be used, for example, for optional callback.
15
+ */ function noop() {
16
+ /* noop */ }
17
+ /**
18
+ * Returns a unique id, sequentially generated from a global variable.
19
+ */ const uid = (()=>{
20
+ let id = 0;
21
+ return ()=>id++;
22
+ })();
23
+ /**
24
+ * Returns true if `value` is neither null nor undefined, else returns false.
25
+ * @param value - The value to test.
26
+ * @since 2.7.0
27
+ */ function isNullOrUndef(value) {
28
+ return value === null || typeof value === 'undefined';
29
+ }
30
+ /**
31
+ * Returns true if `value` is an array (including typed arrays), else returns false.
32
+ * @param value - The value to test.
33
+ * @function
34
+ */ function isArray(value) {
35
+ if (Array.isArray && Array.isArray(value)) {
36
+ return true;
37
+ }
38
+ const type = Object.prototype.toString.call(value);
39
+ if (type.slice(0, 7) === '[object' && type.slice(-6) === 'Array]') {
40
+ return true;
41
+ }
42
+ return false;
43
+ }
44
+ /**
45
+ * Returns true if `value` is an object (excluding null), else returns false.
46
+ * @param value - The value to test.
47
+ * @since 2.7.0
48
+ */ function isObject(value) {
49
+ return value !== null && Object.prototype.toString.call(value) === '[object Object]';
50
+ }
51
+ /**
52
+ * Returns true if `value` is a finite number, else returns false
53
+ * @param value - The value to test.
54
+ */ function isNumberFinite(value) {
55
+ return (typeof value === 'number' || value instanceof Number) && isFinite(+value);
56
+ }
57
+ /**
58
+ * Returns `value` if finite, else returns `defaultValue`.
59
+ * @param value - The value to return if defined.
60
+ * @param defaultValue - The value to return if `value` is not finite.
61
+ */ function finiteOrDefault(value, defaultValue) {
62
+ return isNumberFinite(value) ? value : defaultValue;
63
+ }
64
+ /**
65
+ * Returns `value` if defined, else returns `defaultValue`.
66
+ * @param value - The value to return if defined.
67
+ * @param defaultValue - The value to return if `value` is undefined.
68
+ */ function valueOrDefault(value, defaultValue) {
69
+ return typeof value === 'undefined' ? defaultValue : value;
70
+ }
71
+ const toPercentage = (value, dimension)=>typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 : +value / dimension;
72
+ const toDimension = (value, dimension)=>typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 * dimension : +value;
73
+ /**
74
+ * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
75
+ * value returned by `fn`. If `fn` is not a function, this method returns undefined.
76
+ * @param fn - The function to call.
77
+ * @param args - The arguments with which `fn` should be called.
78
+ * @param [thisArg] - The value of `this` provided for the call to `fn`.
79
+ */ function callback(fn, args, thisArg) {
80
+ if (fn && typeof fn.call === 'function') {
81
+ return fn.apply(thisArg, args);
82
+ }
83
+ }
84
+ function each(loopable, fn, thisArg, reverse) {
85
+ let i, len, keys;
86
+ if (isArray(loopable)) {
87
+ len = loopable.length;
88
+ if (reverse) {
89
+ for(i = len - 1; i >= 0; i--){
90
+ fn.call(thisArg, loopable[i], i);
91
+ }
92
+ } else {
93
+ for(i = 0; i < len; i++){
94
+ fn.call(thisArg, loopable[i], i);
95
+ }
96
+ }
97
+ } else if (isObject(loopable)) {
98
+ keys = Object.keys(loopable);
99
+ len = keys.length;
100
+ for(i = 0; i < len; i++){
101
+ fn.call(thisArg, loopable[keys[i]], keys[i]);
102
+ }
103
+ }
104
+ }
105
+ /**
106
+ * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
107
+ * @param a0 - The array to compare
108
+ * @param a1 - The array to compare
109
+ * @private
110
+ */ function _elementsEqual(a0, a1) {
111
+ let i, ilen, v0, v1;
112
+ if (!a0 || !a1 || a0.length !== a1.length) {
113
+ return false;
114
+ }
115
+ for(i = 0, ilen = a0.length; i < ilen; ++i){
116
+ v0 = a0[i];
117
+ v1 = a1[i];
118
+ if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {
119
+ return false;
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ /**
125
+ * Returns a deep copy of `source` without keeping references on objects and arrays.
126
+ * @param source - The value to clone.
127
+ */ function clone(source) {
128
+ if (isArray(source)) {
129
+ return source.map(clone);
130
+ }
131
+ if (isObject(source)) {
132
+ const target = Object.create(null);
133
+ const keys = Object.keys(source);
134
+ const klen = keys.length;
135
+ let k = 0;
136
+ for(; k < klen; ++k){
137
+ target[keys[k]] = clone(source[keys[k]]);
138
+ }
139
+ return target;
140
+ }
141
+ return source;
142
+ }
143
+ function isValidKey(key) {
144
+ return [
145
+ '__proto__',
146
+ 'prototype',
147
+ 'constructor'
148
+ ].indexOf(key) === -1;
149
+ }
150
+ /**
151
+ * The default merger when Chart.helpers.merge is called without merger option.
152
+ * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback.
153
+ * @private
154
+ */ function _merger(key, target, source, options) {
155
+ if (!isValidKey(key)) {
156
+ return;
157
+ }
158
+ const tval = target[key];
159
+ const sval = source[key];
160
+ if (isObject(tval) && isObject(sval)) {
161
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
162
+ merge(tval, sval, options);
163
+ } else {
164
+ target[key] = clone(sval);
165
+ }
166
+ }
167
+ function merge(target, source, options) {
168
+ const sources = isArray(source) ? source : [
169
+ source
170
+ ];
171
+ const ilen = sources.length;
172
+ if (!isObject(target)) {
173
+ return target;
174
+ }
175
+ options = options || {};
176
+ const merger = options.merger || _merger;
177
+ let current;
178
+ for(let i = 0; i < ilen; ++i){
179
+ current = sources[i];
180
+ if (!isObject(current)) {
181
+ continue;
182
+ }
183
+ const keys = Object.keys(current);
184
+ for(let k = 0, klen = keys.length; k < klen; ++k){
185
+ merger(keys[k], target, current, options);
186
+ }
187
+ }
188
+ return target;
189
+ }
190
+ function mergeIf(target, source) {
191
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
192
+ return merge(target, source, {
193
+ merger: _mergerIf
194
+ });
195
+ }
196
+ /**
197
+ * Merges source[key] in target[key] only if target[key] is undefined.
198
+ * @private
199
+ */ function _mergerIf(key, target, source) {
200
+ if (!isValidKey(key)) {
201
+ return;
202
+ }
203
+ const tval = target[key];
204
+ const sval = source[key];
205
+ if (isObject(tval) && isObject(sval)) {
206
+ mergeIf(tval, sval);
207
+ } else if (!Object.prototype.hasOwnProperty.call(target, key)) {
208
+ target[key] = clone(sval);
209
+ }
210
+ }
211
+ /**
212
+ * @private
213
+ */ function _deprecated(scope, value, previous, current) {
214
+ if (value !== undefined) {
215
+ console.warn(scope + ': "' + previous + '" is deprecated. Please use "' + current + '" instead');
216
+ }
217
+ }
218
+ // resolveObjectKey resolver cache
219
+ const keyResolvers = {
220
+ // Chart.helpers.core resolveObjectKey should resolve empty key to root object
221
+ '': (v)=>v,
222
+ // default resolvers
223
+ x: (o)=>o.x,
224
+ y: (o)=>o.y
225
+ };
226
+ /**
227
+ * @private
228
+ */ function _splitKey(key) {
229
+ const parts = key.split('.');
230
+ const keys = [];
231
+ let tmp = '';
232
+ for (const part of parts){
233
+ tmp += part;
234
+ if (tmp.endsWith('\\')) {
235
+ tmp = tmp.slice(0, -1) + '.';
236
+ } else {
237
+ keys.push(tmp);
238
+ tmp = '';
239
+ }
240
+ }
241
+ return keys;
242
+ }
243
+ function _getKeyResolver(key) {
244
+ const keys = _splitKey(key);
245
+ return (obj)=>{
246
+ for (const k of keys){
247
+ if (k === '') {
248
+ break;
249
+ }
250
+ obj = obj && obj[k];
251
+ }
252
+ return obj;
253
+ };
254
+ }
255
+ function resolveObjectKey(obj, key) {
256
+ const resolver = keyResolvers[key] || (keyResolvers[key] = _getKeyResolver(key));
257
+ return resolver(obj);
258
+ }
259
+ /**
260
+ * @private
261
+ */ function _capitalize(str) {
262
+ return str.charAt(0).toUpperCase() + str.slice(1);
263
+ }
264
+ const defined = (value)=>typeof value !== 'undefined';
265
+ const isFunction = (value)=>typeof value === 'function';
266
+ // Adapted from https://stackoverflow.com/questions/31128855/comparing-ecma6-sets-for-equality#31129384
267
+ const setsEqual = (a, b)=>{
268
+ if (a.size !== b.size) {
269
+ return false;
270
+ }
271
+ for (const item of a){
272
+ if (!b.has(item)) {
273
+ return false;
274
+ }
275
+ }
276
+ return true;
277
+ };
278
+ /**
279
+ * @param e - The event
280
+ * @private
281
+ */ function _isClickEvent(e) {
282
+ return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';
283
+ }
284
+
285
+ /**
286
+ * @alias Chart.helpers.math
287
+ * @namespace
288
+ */ const PI = Math.PI;
289
+ const TAU = 2 * PI;
290
+ const PITAU = TAU + PI;
291
+ const INFINITY = Number.POSITIVE_INFINITY;
292
+ const RAD_PER_DEG = PI / 180;
293
+ const HALF_PI = PI / 2;
294
+ const QUARTER_PI = PI / 4;
295
+ const TWO_THIRDS_PI = PI * 2 / 3;
296
+ const log10 = Math.log10;
297
+ const sign = Math.sign;
298
+ function almostEquals(x, y, epsilon) {
299
+ return Math.abs(x - y) < epsilon;
300
+ }
301
+ /**
302
+ * Implementation of the nice number algorithm used in determining where axis labels will go
303
+ */ function niceNum(range) {
304
+ const roundedRange = Math.round(range);
305
+ range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;
306
+ const niceRange = Math.pow(10, Math.floor(log10(range)));
307
+ const fraction = range / niceRange;
308
+ const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
309
+ return niceFraction * niceRange;
310
+ }
311
+ /**
312
+ * Returns an array of factors sorted from 1 to sqrt(value)
313
+ * @private
314
+ */ function _factorize(value) {
315
+ const result = [];
316
+ const sqrt = Math.sqrt(value);
317
+ let i;
318
+ for(i = 1; i < sqrt; i++){
319
+ if (value % i === 0) {
320
+ result.push(i);
321
+ result.push(value / i);
322
+ }
323
+ }
324
+ if (sqrt === (sqrt | 0)) {
325
+ result.push(sqrt);
326
+ }
327
+ result.sort((a, b)=>a - b).pop();
328
+ return result;
329
+ }
330
+ function isNumber(n) {
331
+ return !isNaN(parseFloat(n)) && isFinite(n);
332
+ }
333
+ function almostWhole(x, epsilon) {
334
+ const rounded = Math.round(x);
335
+ return rounded - epsilon <= x && rounded + epsilon >= x;
336
+ }
337
+ /**
338
+ * @private
339
+ */ function _setMinAndMaxByKey(array, target, property) {
340
+ let i, ilen, value;
341
+ for(i = 0, ilen = array.length; i < ilen; i++){
342
+ value = array[i][property];
343
+ if (!isNaN(value)) {
344
+ target.min = Math.min(target.min, value);
345
+ target.max = Math.max(target.max, value);
346
+ }
347
+ }
348
+ }
349
+ function toRadians(degrees) {
350
+ return degrees * (PI / 180);
351
+ }
352
+ function toDegrees(radians) {
353
+ return radians * (180 / PI);
354
+ }
355
+ /**
356
+ * Returns the number of decimal places
357
+ * i.e. the number of digits after the decimal point, of the value of this Number.
358
+ * @param x - A number.
359
+ * @returns The number of decimal places.
360
+ * @private
361
+ */ function _decimalPlaces(x) {
362
+ if (!isNumberFinite(x)) {
363
+ return;
364
+ }
365
+ let e = 1;
366
+ let p = 0;
367
+ while(Math.round(x * e) / e !== x){
368
+ e *= 10;
369
+ p++;
370
+ }
371
+ return p;
372
+ }
373
+ // Gets the angle from vertical upright to the point about a centre.
374
+ function getAngleFromPoint(centrePoint, anglePoint) {
375
+ const distanceFromXCenter = anglePoint.x - centrePoint.x;
376
+ const distanceFromYCenter = anglePoint.y - centrePoint.y;
377
+ const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
378
+ let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
379
+ if (angle < -0.5 * PI) {
380
+ angle += TAU; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
381
+ }
382
+ return {
383
+ angle,
384
+ distance: radialDistanceFromCenter
385
+ };
386
+ }
387
+ function distanceBetweenPoints(pt1, pt2) {
388
+ return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
389
+ }
390
+ /**
391
+ * Shortest distance between angles, in either direction.
392
+ * @private
393
+ */ function _angleDiff(a, b) {
394
+ return (a - b + PITAU) % TAU - PI;
395
+ }
396
+ /**
397
+ * Normalize angle to be between 0 and 2*PI
398
+ * @private
399
+ */ function _normalizeAngle(a) {
400
+ return (a % TAU + TAU) % TAU;
401
+ }
402
+ /**
403
+ * @private
404
+ */ function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
405
+ const a = _normalizeAngle(angle);
406
+ const s = _normalizeAngle(start);
407
+ const e = _normalizeAngle(end);
408
+ const angleToStart = _normalizeAngle(s - a);
409
+ const angleToEnd = _normalizeAngle(e - a);
410
+ const startToAngle = _normalizeAngle(a - s);
411
+ const endToAngle = _normalizeAngle(a - e);
412
+ return a === s || a === e || sameAngleIsFullCircle && s === e || angleToStart > angleToEnd && startToAngle < endToAngle;
413
+ }
414
+ /**
415
+ * Limit `value` between `min` and `max`
416
+ * @param value
417
+ * @param min
418
+ * @param max
419
+ * @private
420
+ */ function _limitValue(value, min, max) {
421
+ return Math.max(min, Math.min(max, value));
422
+ }
423
+ /**
424
+ * @param {number} value
425
+ * @private
426
+ */ function _int16Range(value) {
427
+ return _limitValue(value, -32768, 32767);
428
+ }
429
+ /**
430
+ * @param value
431
+ * @param start
432
+ * @param end
433
+ * @param [epsilon]
434
+ * @private
435
+ */ function _isBetween(value, start, end, epsilon = 1e-6) {
436
+ return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
437
+ }
438
+
439
+ function _lookup(table, value, cmp) {
440
+ cmp = cmp || ((index)=>table[index] < value);
441
+ let hi = table.length - 1;
442
+ let lo = 0;
443
+ let mid;
444
+ while(hi - lo > 1){
445
+ mid = lo + hi >> 1;
446
+ if (cmp(mid)) {
447
+ lo = mid;
448
+ } else {
449
+ hi = mid;
450
+ }
451
+ }
452
+ return {
453
+ lo,
454
+ hi
455
+ };
456
+ }
457
+ /**
458
+ * Binary search
459
+ * @param table - the table search. must be sorted!
460
+ * @param key - property name for the value in each entry
461
+ * @param value - value to find
462
+ * @param last - lookup last index
463
+ * @private
464
+ */ const _lookupByKey = (table, key, value, last)=>_lookup(table, value, last ? (index)=>{
465
+ const ti = table[index][key];
466
+ return ti < value || ti === value && table[index + 1][key] === value;
467
+ } : (index)=>table[index][key] < value);
468
+ /**
469
+ * Reverse binary search
470
+ * @param table - the table search. must be sorted!
471
+ * @param key - property name for the value in each entry
472
+ * @param value - value to find
473
+ * @private
474
+ */ const _rlookupByKey = (table, key, value)=>_lookup(table, value, (index)=>table[index][key] >= value);
475
+ /**
476
+ * Return subset of `values` between `min` and `max` inclusive.
477
+ * Values are assumed to be in sorted order.
478
+ * @param values - sorted array of values
479
+ * @param min - min value
480
+ * @param max - max value
481
+ */ function _filterBetween(values, min, max) {
482
+ let start = 0;
483
+ let end = values.length;
484
+ while(start < end && values[start] < min){
485
+ start++;
486
+ }
487
+ while(end > start && values[end - 1] > max){
488
+ end--;
489
+ }
490
+ return start > 0 || end < values.length ? values.slice(start, end) : values;
491
+ }
492
+ const arrayEvents = [
493
+ 'push',
494
+ 'pop',
495
+ 'shift',
496
+ 'splice',
497
+ 'unshift'
498
+ ];
499
+ function listenArrayEvents(array, listener) {
500
+ if (array._chartjs) {
501
+ array._chartjs.listeners.push(listener);
502
+ return;
503
+ }
504
+ Object.defineProperty(array, '_chartjs', {
505
+ configurable: true,
506
+ enumerable: false,
507
+ value: {
508
+ listeners: [
509
+ listener
510
+ ]
511
+ }
512
+ });
513
+ arrayEvents.forEach((key)=>{
514
+ const method = '_onData' + _capitalize(key);
515
+ const base = array[key];
516
+ Object.defineProperty(array, key, {
517
+ configurable: true,
518
+ enumerable: false,
519
+ value (...args) {
520
+ const res = base.apply(this, args);
521
+ array._chartjs.listeners.forEach((object)=>{
522
+ if (typeof object[method] === 'function') {
523
+ object[method](...args);
524
+ }
525
+ });
526
+ return res;
527
+ }
528
+ });
529
+ });
530
+ }
531
+ function unlistenArrayEvents(array, listener) {
532
+ const stub = array._chartjs;
533
+ if (!stub) {
534
+ return;
535
+ }
536
+ const listeners = stub.listeners;
537
+ const index = listeners.indexOf(listener);
538
+ if (index !== -1) {
539
+ listeners.splice(index, 1);
540
+ }
541
+ if (listeners.length > 0) {
542
+ return;
543
+ }
544
+ arrayEvents.forEach((key)=>{
545
+ delete array[key];
546
+ });
547
+ delete array._chartjs;
548
+ }
549
+ /**
550
+ * @param items
551
+ */ function _arrayUnique(items) {
552
+ const set = new Set(items);
553
+ if (set.size === items.length) {
554
+ return items;
555
+ }
556
+ return Array.from(set);
557
+ }
558
+
559
+ function fontString(pixelSize, fontStyle, fontFamily) {
560
+ return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
561
+ }
562
+ /**
563
+ * Request animation polyfill
564
+ */ const requestAnimFrame = function() {
565
+ if (typeof window === 'undefined') {
566
+ return function(callback) {
567
+ return callback();
568
+ };
569
+ }
570
+ return window.requestAnimationFrame;
571
+ }();
572
+ /**
573
+ * Throttles calling `fn` once per animation frame
574
+ * Latest arguments are used on the actual call
575
+ */ function throttled(fn, thisArg) {
576
+ let argsToUse = [];
577
+ let ticking = false;
578
+ return function(...args) {
579
+ // Save the args for use later
580
+ argsToUse = args;
581
+ if (!ticking) {
582
+ ticking = true;
583
+ requestAnimFrame.call(window, ()=>{
584
+ ticking = false;
585
+ fn.apply(thisArg, argsToUse);
586
+ });
587
+ }
588
+ };
589
+ }
590
+ /**
591
+ * Debounces calling `fn` for `delay` ms
592
+ */ function debounce(fn, delay) {
593
+ let timeout;
594
+ return function(...args) {
595
+ if (delay) {
596
+ clearTimeout(timeout);
597
+ timeout = setTimeout(fn, delay, args);
598
+ } else {
599
+ fn.apply(this, args);
600
+ }
601
+ return delay;
602
+ };
603
+ }
604
+ /**
605
+ * Converts 'start' to 'left', 'end' to 'right' and others to 'center'
606
+ * @private
607
+ */ const _toLeftRightCenter = (align)=>align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';
608
+ /**
609
+ * Returns `start`, `end` or `(start + end) / 2` depending on `align`. Defaults to `center`
610
+ * @private
611
+ */ const _alignStartEnd = (align, start, end)=>align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
612
+ /**
613
+ * Returns `left`, `right` or `(left + right) / 2` depending on `align`. Defaults to `left`
614
+ * @private
615
+ */ const _textX = (align, left, right, rtl)=>{
616
+ const check = rtl ? 'left' : 'right';
617
+ return align === check ? right : align === 'center' ? (left + right) / 2 : left;
618
+ };
619
+ /**
620
+ * Return start and count of visible points.
621
+ * @private
622
+ */ function _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {
623
+ const pointCount = points.length;
624
+ let start = 0;
625
+ let count = pointCount;
626
+ if (meta._sorted) {
627
+ const { iScale , _parsed } = meta;
628
+ const axis = iScale.axis;
629
+ const { min , max , minDefined , maxDefined } = iScale.getUserBounds();
630
+ if (minDefined) {
631
+ start = _limitValue(Math.min(// @ts-expect-error Need to type _parsed
632
+ _lookupByKey(_parsed, axis, min).lo, // @ts-expect-error Need to fix types on _lookupByKey
633
+ animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo), 0, pointCount - 1);
634
+ }
635
+ if (maxDefined) {
636
+ count = _limitValue(Math.max(// @ts-expect-error Need to type _parsed
637
+ _lookupByKey(_parsed, iScale.axis, max, true).hi + 1, // @ts-expect-error Need to fix types on _lookupByKey
638
+ animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1), start, pointCount) - start;
639
+ } else {
640
+ count = pointCount - start;
641
+ }
642
+ }
643
+ return {
644
+ start,
645
+ count
646
+ };
647
+ }
648
+ /**
649
+ * Checks if the scale ranges have changed.
650
+ * @param {object} meta - dataset meta.
651
+ * @returns {boolean}
652
+ * @private
653
+ */ function _scaleRangesChanged(meta) {
654
+ const { xScale , yScale , _scaleRanges } = meta;
655
+ const newRanges = {
656
+ xmin: xScale.min,
657
+ xmax: xScale.max,
658
+ ymin: yScale.min,
659
+ ymax: yScale.max
660
+ };
661
+ if (!_scaleRanges) {
662
+ meta._scaleRanges = newRanges;
663
+ return true;
664
+ }
665
+ const changed = _scaleRanges.xmin !== xScale.min || _scaleRanges.xmax !== xScale.max || _scaleRanges.ymin !== yScale.min || _scaleRanges.ymax !== yScale.max;
666
+ Object.assign(_scaleRanges, newRanges);
667
+ return changed;
668
+ }
669
+
670
+ const atEdge = (t)=>t === 0 || t === 1;
671
+ const elasticIn = (t, s, p)=>-(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));
672
+ const elasticOut = (t, s, p)=>Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1;
673
+ /**
674
+ * Easing functions adapted from Robert Penner's easing equations.
675
+ * @namespace Chart.helpers.easing.effects
676
+ * @see http://www.robertpenner.com/easing/
677
+ */ const effects = {
678
+ linear: (t)=>t,
679
+ easeInQuad: (t)=>t * t,
680
+ easeOutQuad: (t)=>-t * (t - 2),
681
+ easeInOutQuad: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t : -0.5 * (--t * (t - 2) - 1),
682
+ easeInCubic: (t)=>t * t * t,
683
+ easeOutCubic: (t)=>(t -= 1) * t * t + 1,
684
+ easeInOutCubic: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t * t : 0.5 * ((t -= 2) * t * t + 2),
685
+ easeInQuart: (t)=>t * t * t * t,
686
+ easeOutQuart: (t)=>-((t -= 1) * t * t * t - 1),
687
+ easeInOutQuart: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t * t * t : -0.5 * ((t -= 2) * t * t * t - 2),
688
+ easeInQuint: (t)=>t * t * t * t * t,
689
+ easeOutQuint: (t)=>(t -= 1) * t * t * t * t + 1,
690
+ easeInOutQuint: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t * t * t * t : 0.5 * ((t -= 2) * t * t * t * t + 2),
691
+ easeInSine: (t)=>-Math.cos(t * HALF_PI) + 1,
692
+ easeOutSine: (t)=>Math.sin(t * HALF_PI),
693
+ easeInOutSine: (t)=>-0.5 * (Math.cos(PI * t) - 1),
694
+ easeInExpo: (t)=>t === 0 ? 0 : Math.pow(2, 10 * (t - 1)),
695
+ easeOutExpo: (t)=>t === 1 ? 1 : -Math.pow(2, -10 * t) + 1,
696
+ easeInOutExpo: (t)=>atEdge(t) ? t : t < 0.5 ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2),
697
+ easeInCirc: (t)=>t >= 1 ? t : -(Math.sqrt(1 - t * t) - 1),
698
+ easeOutCirc: (t)=>Math.sqrt(1 - (t -= 1) * t),
699
+ easeInOutCirc: (t)=>(t /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),
700
+ easeInElastic: (t)=>atEdge(t) ? t : elasticIn(t, 0.075, 0.3),
701
+ easeOutElastic: (t)=>atEdge(t) ? t : elasticOut(t, 0.075, 0.3),
702
+ easeInOutElastic (t) {
703
+ const s = 0.1125;
704
+ const p = 0.45;
705
+ return atEdge(t) ? t : t < 0.5 ? 0.5 * elasticIn(t * 2, s, p) : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p);
706
+ },
707
+ easeInBack (t) {
708
+ const s = 1.70158;
709
+ return t * t * ((s + 1) * t - s);
710
+ },
711
+ easeOutBack (t) {
712
+ const s = 1.70158;
713
+ return (t -= 1) * t * ((s + 1) * t + s) + 1;
714
+ },
715
+ easeInOutBack (t) {
716
+ let s = 1.70158;
717
+ if ((t /= 0.5) < 1) {
718
+ return 0.5 * (t * t * (((s *= 1.525) + 1) * t - s));
719
+ }
720
+ return 0.5 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);
721
+ },
722
+ easeInBounce: (t)=>1 - effects.easeOutBounce(1 - t),
723
+ easeOutBounce (t) {
724
+ const m = 7.5625;
725
+ const d = 2.75;
726
+ if (t < 1 / d) {
727
+ return m * t * t;
728
+ }
729
+ if (t < 2 / d) {
730
+ return m * (t -= 1.5 / d) * t + 0.75;
731
+ }
732
+ if (t < 2.5 / d) {
733
+ return m * (t -= 2.25 / d) * t + 0.9375;
734
+ }
735
+ return m * (t -= 2.625 / d) * t + 0.984375;
736
+ },
737
+ easeInOutBounce: (t)=>t < 0.5 ? effects.easeInBounce(t * 2) * 0.5 : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5
738
+ };
739
+
740
+ function isPatternOrGradient(value) {
741
+ if (value && typeof value === 'object') {
742
+ const type = value.toString();
743
+ return type === '[object CanvasPattern]' || type === '[object CanvasGradient]';
744
+ }
745
+ return false;
746
+ }
747
+ function color(value) {
748
+ return isPatternOrGradient(value) ? value : new color$1.Color(value);
749
+ }
750
+ function getHoverColor(value) {
751
+ return isPatternOrGradient(value) ? value : new color$1.Color(value).saturate(0.5).darken(0.1).hexString();
752
+ }
753
+
754
+ const numbers = [
755
+ 'x',
756
+ 'y',
757
+ 'borderWidth',
758
+ 'radius',
759
+ 'tension'
760
+ ];
761
+ const colors = [
762
+ 'color',
763
+ 'borderColor',
764
+ 'backgroundColor'
765
+ ];
766
+ function applyAnimationsDefaults(defaults) {
767
+ defaults.set('animation', {
768
+ delay: undefined,
769
+ duration: 1000,
770
+ easing: 'easeOutQuart',
771
+ fn: undefined,
772
+ from: undefined,
773
+ loop: undefined,
774
+ to: undefined,
775
+ type: undefined
776
+ });
777
+ defaults.describe('animation', {
778
+ _fallback: false,
779
+ _indexable: false,
780
+ _scriptable: (name)=>name !== 'onProgress' && name !== 'onComplete' && name !== 'fn'
781
+ });
782
+ defaults.set('animations', {
783
+ colors: {
784
+ type: 'color',
785
+ properties: colors
786
+ },
787
+ numbers: {
788
+ type: 'number',
789
+ properties: numbers
790
+ }
791
+ });
792
+ defaults.describe('animations', {
793
+ _fallback: 'animation'
794
+ });
795
+ defaults.set('transitions', {
796
+ active: {
797
+ animation: {
798
+ duration: 400
799
+ }
800
+ },
801
+ resize: {
802
+ animation: {
803
+ duration: 0
804
+ }
805
+ },
806
+ show: {
807
+ animations: {
808
+ colors: {
809
+ from: 'transparent'
810
+ },
811
+ visible: {
812
+ type: 'boolean',
813
+ duration: 0
814
+ }
815
+ }
816
+ },
817
+ hide: {
818
+ animations: {
819
+ colors: {
820
+ to: 'transparent'
821
+ },
822
+ visible: {
823
+ type: 'boolean',
824
+ easing: 'linear',
825
+ fn: (v)=>v | 0
826
+ }
827
+ }
828
+ }
829
+ });
830
+ }
831
+
832
+ function applyLayoutsDefaults(defaults) {
833
+ defaults.set('layout', {
834
+ autoPadding: true,
835
+ padding: {
836
+ top: 0,
837
+ right: 0,
838
+ bottom: 0,
839
+ left: 0
840
+ }
841
+ });
842
+ }
843
+
844
+ const intlCache = new Map();
845
+ function getNumberFormat(locale, options) {
846
+ options = options || {};
847
+ const cacheKey = locale + JSON.stringify(options);
848
+ let formatter = intlCache.get(cacheKey);
849
+ if (!formatter) {
850
+ formatter = new Intl.NumberFormat(locale, options);
851
+ intlCache.set(cacheKey, formatter);
852
+ }
853
+ return formatter;
854
+ }
855
+ function formatNumber(num, locale, options) {
856
+ return getNumberFormat(locale, options).format(num);
857
+ }
858
+
859
+ const formatters = {
860
+ values (value) {
861
+ return isArray(value) ? value : '' + value;
862
+ },
863
+ numeric (tickValue, index, ticks) {
864
+ if (tickValue === 0) {
865
+ return '0';
866
+ }
867
+ const locale = this.chart.options.locale;
868
+ let notation;
869
+ let delta = tickValue;
870
+ if (ticks.length > 1) {
871
+ const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
872
+ if (maxTick < 1e-4 || maxTick > 1e+15) {
873
+ notation = 'scientific';
874
+ }
875
+ delta = calculateDelta(tickValue, ticks);
876
+ }
877
+ const logDelta = log10(Math.abs(delta));
878
+ const numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0);
879
+ const options = {
880
+ notation,
881
+ minimumFractionDigits: numDecimal,
882
+ maximumFractionDigits: numDecimal
883
+ };
884
+ Object.assign(options, this.options.ticks.format);
885
+ return formatNumber(tickValue, locale, options);
886
+ },
887
+ logarithmic (tickValue, index, ticks) {
888
+ if (tickValue === 0) {
889
+ return '0';
890
+ }
891
+ const remain = ticks[index].significand || tickValue / Math.pow(10, Math.floor(log10(tickValue)));
892
+ if ([
893
+ 1,
894
+ 2,
895
+ 3,
896
+ 5,
897
+ 10,
898
+ 15
899
+ ].includes(remain) || index > 0.8 * ticks.length) {
900
+ return formatters.numeric.call(this, tickValue, index, ticks);
901
+ }
902
+ return '';
903
+ }
904
+ };
905
+ function calculateDelta(tickValue, ticks) {
906
+ let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
907
+ if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {
908
+ delta = tickValue - Math.floor(tickValue);
909
+ }
910
+ return delta;
911
+ }
912
+ var Ticks = {
913
+ formatters
914
+ };
915
+
916
+ function applyScaleDefaults(defaults) {
917
+ defaults.set('scale', {
918
+ display: true,
919
+ offset: false,
920
+ reverse: false,
921
+ beginAtZero: false,
922
+ bounds: 'ticks',
923
+ clip: true,
924
+ grace: 0,
925
+ grid: {
926
+ display: true,
927
+ lineWidth: 1,
928
+ drawOnChartArea: true,
929
+ drawTicks: true,
930
+ tickLength: 8,
931
+ tickWidth: (_ctx, options)=>options.lineWidth,
932
+ tickColor: (_ctx, options)=>options.color,
933
+ offset: false
934
+ },
935
+ border: {
936
+ display: true,
937
+ dash: [],
938
+ dashOffset: 0.0,
939
+ width: 1
940
+ },
941
+ title: {
942
+ display: false,
943
+ text: '',
944
+ padding: {
945
+ top: 4,
946
+ bottom: 4
947
+ }
948
+ },
949
+ ticks: {
950
+ minRotation: 0,
951
+ maxRotation: 50,
952
+ mirror: false,
953
+ textStrokeWidth: 0,
954
+ textStrokeColor: '',
955
+ padding: 3,
956
+ display: true,
957
+ autoSkip: true,
958
+ autoSkipPadding: 3,
959
+ labelOffset: 0,
960
+ callback: Ticks.formatters.values,
961
+ minor: {},
962
+ major: {},
963
+ align: 'center',
964
+ crossAlign: 'near',
965
+ showLabelBackdrop: false,
966
+ backdropColor: 'rgba(255, 255, 255, 0.75)',
967
+ backdropPadding: 2
968
+ }
969
+ });
970
+ defaults.route('scale.ticks', 'color', '', 'color');
971
+ defaults.route('scale.grid', 'color', '', 'borderColor');
972
+ defaults.route('scale.border', 'color', '', 'borderColor');
973
+ defaults.route('scale.title', 'color', '', 'color');
974
+ defaults.describe('scale', {
975
+ _fallback: false,
976
+ _scriptable: (name)=>!name.startsWith('before') && !name.startsWith('after') && name !== 'callback' && name !== 'parser',
977
+ _indexable: (name)=>name !== 'borderDash' && name !== 'tickBorderDash' && name !== 'dash'
978
+ });
979
+ defaults.describe('scales', {
980
+ _fallback: 'scale'
981
+ });
982
+ defaults.describe('scale.ticks', {
983
+ _scriptable: (name)=>name !== 'backdropPadding' && name !== 'callback',
984
+ _indexable: (name)=>name !== 'backdropPadding'
985
+ });
986
+ }
987
+
988
+ const overrides = Object.create(null);
989
+ const descriptors = Object.create(null);
990
+ function getScope$1(node, key) {
991
+ if (!key) {
992
+ return node;
993
+ }
994
+ const keys = key.split('.');
995
+ for(let i = 0, n = keys.length; i < n; ++i){
996
+ const k = keys[i];
997
+ node = node[k] || (node[k] = Object.create(null));
998
+ }
999
+ return node;
1000
+ }
1001
+ function set(root, scope, values) {
1002
+ if (typeof scope === 'string') {
1003
+ return merge(getScope$1(root, scope), values);
1004
+ }
1005
+ return merge(getScope$1(root, ''), scope);
1006
+ }
1007
+ class Defaults {
1008
+ constructor(_descriptors, _appliers){
1009
+ this.animation = undefined;
1010
+ this.backgroundColor = 'rgba(0,0,0,0.1)';
1011
+ this.borderColor = 'rgba(0,0,0,0.1)';
1012
+ this.color = '#666';
1013
+ this.datasets = {};
1014
+ this.devicePixelRatio = (context)=>context.chart.platform.getDevicePixelRatio();
1015
+ this.elements = {};
1016
+ this.events = [
1017
+ 'mousemove',
1018
+ 'mouseout',
1019
+ 'click',
1020
+ 'touchstart',
1021
+ 'touchmove'
1022
+ ];
1023
+ this.font = {
1024
+ family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
1025
+ size: 12,
1026
+ style: 'normal',
1027
+ lineHeight: 1.2,
1028
+ weight: null
1029
+ };
1030
+ this.hover = {};
1031
+ this.hoverBackgroundColor = (ctx, options)=>getHoverColor(options.backgroundColor);
1032
+ this.hoverBorderColor = (ctx, options)=>getHoverColor(options.borderColor);
1033
+ this.hoverColor = (ctx, options)=>getHoverColor(options.color);
1034
+ this.indexAxis = 'x';
1035
+ this.interaction = {
1036
+ mode: 'nearest',
1037
+ intersect: true,
1038
+ includeInvisible: false
1039
+ };
1040
+ this.maintainAspectRatio = true;
1041
+ this.onHover = null;
1042
+ this.onClick = null;
1043
+ this.parsing = true;
1044
+ this.plugins = {};
1045
+ this.responsive = true;
1046
+ this.scale = undefined;
1047
+ this.scales = {};
1048
+ this.showLine = true;
1049
+ this.drawActiveElementsOnTop = true;
1050
+ this.describe(_descriptors);
1051
+ this.apply(_appliers);
1052
+ }
1053
+ set(scope, values) {
1054
+ return set(this, scope, values);
1055
+ }
1056
+ get(scope) {
1057
+ return getScope$1(this, scope);
1058
+ }
1059
+ describe(scope, values) {
1060
+ return set(descriptors, scope, values);
1061
+ }
1062
+ override(scope, values) {
1063
+ return set(overrides, scope, values);
1064
+ }
1065
+ route(scope, name, targetScope, targetName) {
1066
+ const scopeObject = getScope$1(this, scope);
1067
+ const targetScopeObject = getScope$1(this, targetScope);
1068
+ const privateName = '_' + name;
1069
+ Object.defineProperties(scopeObject, {
1070
+ [privateName]: {
1071
+ value: scopeObject[name],
1072
+ writable: true
1073
+ },
1074
+ [name]: {
1075
+ enumerable: true,
1076
+ get () {
1077
+ const local = this[privateName];
1078
+ const target = targetScopeObject[targetName];
1079
+ if (isObject(local)) {
1080
+ return Object.assign({}, target, local);
1081
+ }
1082
+ return valueOrDefault(local, target);
1083
+ },
1084
+ set (value) {
1085
+ this[privateName] = value;
1086
+ }
1087
+ }
1088
+ });
1089
+ }
1090
+ apply(appliers) {
1091
+ appliers.forEach((apply)=>apply(this));
1092
+ }
1093
+ }
1094
+ var defaults = /* #__PURE__ */ new Defaults({
1095
+ _scriptable: (name)=>!name.startsWith('on'),
1096
+ _indexable: (name)=>name !== 'events',
1097
+ hover: {
1098
+ _fallback: 'interaction'
1099
+ },
1100
+ interaction: {
1101
+ _scriptable: false,
1102
+ _indexable: false
1103
+ }
1104
+ }, [
1105
+ applyAnimationsDefaults,
1106
+ applyLayoutsDefaults,
1107
+ applyScaleDefaults
1108
+ ]);
1109
+
1110
+ /**
1111
+ * Converts the given font object into a CSS font string.
1112
+ * @param font - A font object.
1113
+ * @return The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font
1114
+ * @private
1115
+ */ function toFontString(font) {
1116
+ if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {
1117
+ return null;
1118
+ }
1119
+ return (font.style ? font.style + ' ' : '') + (font.weight ? font.weight + ' ' : '') + font.size + 'px ' + font.family;
1120
+ }
1121
+ /**
1122
+ * @private
1123
+ */ function _measureText(ctx, data, gc, longest, string) {
1124
+ let textWidth = data[string];
1125
+ if (!textWidth) {
1126
+ textWidth = data[string] = ctx.measureText(string).width;
1127
+ gc.push(string);
1128
+ }
1129
+ if (textWidth > longest) {
1130
+ longest = textWidth;
1131
+ }
1132
+ return longest;
1133
+ }
1134
+ /**
1135
+ * @private
1136
+ */ // eslint-disable-next-line complexity
1137
+ function _longestText(ctx, font, arrayOfThings, cache) {
1138
+ cache = cache || {};
1139
+ let data = cache.data = cache.data || {};
1140
+ let gc = cache.garbageCollect = cache.garbageCollect || [];
1141
+ if (cache.font !== font) {
1142
+ data = cache.data = {};
1143
+ gc = cache.garbageCollect = [];
1144
+ cache.font = font;
1145
+ }
1146
+ ctx.save();
1147
+ ctx.font = font;
1148
+ let longest = 0;
1149
+ const ilen = arrayOfThings.length;
1150
+ let i, j, jlen, thing, nestedThing;
1151
+ for(i = 0; i < ilen; i++){
1152
+ thing = arrayOfThings[i];
1153
+ // Undefined strings and arrays should not be measured
1154
+ if (thing !== undefined && thing !== null && !isArray(thing)) {
1155
+ longest = _measureText(ctx, data, gc, longest, thing);
1156
+ } else if (isArray(thing)) {
1157
+ // if it is an array lets measure each element
1158
+ // to do maybe simplify this function a bit so we can do this more recursively?
1159
+ for(j = 0, jlen = thing.length; j < jlen; j++){
1160
+ nestedThing = thing[j];
1161
+ // Undefined strings and arrays should not be measured
1162
+ if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) {
1163
+ longest = _measureText(ctx, data, gc, longest, nestedThing);
1164
+ }
1165
+ }
1166
+ }
1167
+ }
1168
+ ctx.restore();
1169
+ const gcLen = gc.length / 2;
1170
+ if (gcLen > arrayOfThings.length) {
1171
+ for(i = 0; i < gcLen; i++){
1172
+ delete data[gc[i]];
1173
+ }
1174
+ gc.splice(0, gcLen);
1175
+ }
1176
+ return longest;
1177
+ }
1178
+ /**
1179
+ * Returns the aligned pixel value to avoid anti-aliasing blur
1180
+ * @param chart - The chart instance.
1181
+ * @param pixel - A pixel value.
1182
+ * @param width - The width of the element.
1183
+ * @returns The aligned pixel value.
1184
+ * @private
1185
+ */ function _alignPixel(chart, pixel, width) {
1186
+ const devicePixelRatio = chart.currentDevicePixelRatio;
1187
+ const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;
1188
+ return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;
1189
+ }
1190
+ /**
1191
+ * Clears the entire canvas.
1192
+ */ function clearCanvas(canvas, ctx) {
1193
+ if (!ctx && !canvas) {
1194
+ return;
1195
+ }
1196
+ ctx = ctx || canvas.getContext('2d');
1197
+ ctx.save();
1198
+ // canvas.width and canvas.height do not consider the canvas transform,
1199
+ // while clearRect does
1200
+ ctx.resetTransform();
1201
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1202
+ ctx.restore();
1203
+ }
1204
+ function drawPoint(ctx, options, x, y) {
1205
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
1206
+ drawPointLegend(ctx, options, x, y, null);
1207
+ }
1208
+ // eslint-disable-next-line complexity
1209
+ function drawPointLegend(ctx, options, x, y, w) {
1210
+ let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW;
1211
+ const style = options.pointStyle;
1212
+ const rotation = options.rotation;
1213
+ const radius = options.radius;
1214
+ let rad = (rotation || 0) * RAD_PER_DEG;
1215
+ if (style && typeof style === 'object') {
1216
+ type = style.toString();
1217
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
1218
+ ctx.save();
1219
+ ctx.translate(x, y);
1220
+ ctx.rotate(rad);
1221
+ ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
1222
+ ctx.restore();
1223
+ return;
1224
+ }
1225
+ }
1226
+ if (isNaN(radius) || radius <= 0) {
1227
+ return;
1228
+ }
1229
+ ctx.beginPath();
1230
+ switch(style){
1231
+ // Default includes circle
1232
+ default:
1233
+ if (w) {
1234
+ ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU);
1235
+ } else {
1236
+ ctx.arc(x, y, radius, 0, TAU);
1237
+ }
1238
+ ctx.closePath();
1239
+ break;
1240
+ case 'triangle':
1241
+ width = w ? w / 2 : radius;
1242
+ ctx.moveTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);
1243
+ rad += TWO_THIRDS_PI;
1244
+ ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);
1245
+ rad += TWO_THIRDS_PI;
1246
+ ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);
1247
+ ctx.closePath();
1248
+ break;
1249
+ case 'rectRounded':
1250
+ // NOTE: the rounded rect implementation changed to use `arc` instead of
1251
+ // `quadraticCurveTo` since it generates better results when rect is
1252
+ // almost a circle. 0.516 (instead of 0.5) produces results with visually
1253
+ // closer proportion to the previous impl and it is inscribed in the
1254
+ // circle with `radius`. For more details, see the following PRs:
1255
+ // https://github.com/chartjs/Chart.js/issues/5597
1256
+ // https://github.com/chartjs/Chart.js/issues/5858
1257
+ cornerRadius = radius * 0.516;
1258
+ size = radius - cornerRadius;
1259
+ xOffset = Math.cos(rad + QUARTER_PI) * size;
1260
+ xOffsetW = Math.cos(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size);
1261
+ yOffset = Math.sin(rad + QUARTER_PI) * size;
1262
+ yOffsetW = Math.sin(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size);
1263
+ ctx.arc(x - xOffsetW, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
1264
+ ctx.arc(x + yOffsetW, y - xOffset, cornerRadius, rad - HALF_PI, rad);
1265
+ ctx.arc(x + xOffsetW, y + yOffset, cornerRadius, rad, rad + HALF_PI);
1266
+ ctx.arc(x - yOffsetW, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
1267
+ ctx.closePath();
1268
+ break;
1269
+ case 'rect':
1270
+ if (!rotation) {
1271
+ size = Math.SQRT1_2 * radius;
1272
+ width = w ? w / 2 : size;
1273
+ ctx.rect(x - width, y - size, 2 * width, 2 * size);
1274
+ break;
1275
+ }
1276
+ rad += QUARTER_PI;
1277
+ /* falls through */ case 'rectRot':
1278
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
1279
+ xOffset = Math.cos(rad) * radius;
1280
+ yOffset = Math.sin(rad) * radius;
1281
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
1282
+ ctx.moveTo(x - xOffsetW, y - yOffset);
1283
+ ctx.lineTo(x + yOffsetW, y - xOffset);
1284
+ ctx.lineTo(x + xOffsetW, y + yOffset);
1285
+ ctx.lineTo(x - yOffsetW, y + xOffset);
1286
+ ctx.closePath();
1287
+ break;
1288
+ case 'crossRot':
1289
+ rad += QUARTER_PI;
1290
+ /* falls through */ case 'cross':
1291
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
1292
+ xOffset = Math.cos(rad) * radius;
1293
+ yOffset = Math.sin(rad) * radius;
1294
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
1295
+ ctx.moveTo(x - xOffsetW, y - yOffset);
1296
+ ctx.lineTo(x + xOffsetW, y + yOffset);
1297
+ ctx.moveTo(x + yOffsetW, y - xOffset);
1298
+ ctx.lineTo(x - yOffsetW, y + xOffset);
1299
+ break;
1300
+ case 'star':
1301
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
1302
+ xOffset = Math.cos(rad) * radius;
1303
+ yOffset = Math.sin(rad) * radius;
1304
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
1305
+ ctx.moveTo(x - xOffsetW, y - yOffset);
1306
+ ctx.lineTo(x + xOffsetW, y + yOffset);
1307
+ ctx.moveTo(x + yOffsetW, y - xOffset);
1308
+ ctx.lineTo(x - yOffsetW, y + xOffset);
1309
+ rad += QUARTER_PI;
1310
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
1311
+ xOffset = Math.cos(rad) * radius;
1312
+ yOffset = Math.sin(rad) * radius;
1313
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
1314
+ ctx.moveTo(x - xOffsetW, y - yOffset);
1315
+ ctx.lineTo(x + xOffsetW, y + yOffset);
1316
+ ctx.moveTo(x + yOffsetW, y - xOffset);
1317
+ ctx.lineTo(x - yOffsetW, y + xOffset);
1318
+ break;
1319
+ case 'line':
1320
+ xOffset = w ? w / 2 : Math.cos(rad) * radius;
1321
+ yOffset = Math.sin(rad) * radius;
1322
+ ctx.moveTo(x - xOffset, y - yOffset);
1323
+ ctx.lineTo(x + xOffset, y + yOffset);
1324
+ break;
1325
+ case 'dash':
1326
+ ctx.moveTo(x, y);
1327
+ ctx.lineTo(x + Math.cos(rad) * (w ? w / 2 : radius), y + Math.sin(rad) * radius);
1328
+ break;
1329
+ case false:
1330
+ ctx.closePath();
1331
+ break;
1332
+ }
1333
+ ctx.fill();
1334
+ if (options.borderWidth > 0) {
1335
+ ctx.stroke();
1336
+ }
1337
+ }
1338
+ /**
1339
+ * Returns true if the point is inside the rectangle
1340
+ * @param point - The point to test
1341
+ * @param area - The rectangle
1342
+ * @param margin - allowed margin
1343
+ * @private
1344
+ */ function _isPointInArea(point, area, margin) {
1345
+ margin = margin || 0.5; // margin - default is to match rounded decimals
1346
+ return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin;
1347
+ }
1348
+ function clipArea(ctx, area) {
1349
+ ctx.save();
1350
+ ctx.beginPath();
1351
+ ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
1352
+ ctx.clip();
1353
+ }
1354
+ function unclipArea(ctx) {
1355
+ ctx.restore();
1356
+ }
1357
+ /**
1358
+ * @private
1359
+ */ function _steppedLineTo(ctx, previous, target, flip, mode) {
1360
+ if (!previous) {
1361
+ return ctx.lineTo(target.x, target.y);
1362
+ }
1363
+ if (mode === 'middle') {
1364
+ const midpoint = (previous.x + target.x) / 2.0;
1365
+ ctx.lineTo(midpoint, previous.y);
1366
+ ctx.lineTo(midpoint, target.y);
1367
+ } else if (mode === 'after' !== !!flip) {
1368
+ ctx.lineTo(previous.x, target.y);
1369
+ } else {
1370
+ ctx.lineTo(target.x, previous.y);
1371
+ }
1372
+ ctx.lineTo(target.x, target.y);
1373
+ }
1374
+ /**
1375
+ * @private
1376
+ */ function _bezierCurveTo(ctx, previous, target, flip) {
1377
+ if (!previous) {
1378
+ return ctx.lineTo(target.x, target.y);
1379
+ }
1380
+ ctx.bezierCurveTo(flip ? previous.cp1x : previous.cp2x, flip ? previous.cp1y : previous.cp2y, flip ? target.cp2x : target.cp1x, flip ? target.cp2y : target.cp1y, target.x, target.y);
1381
+ }
1382
+ function setRenderOpts(ctx, opts) {
1383
+ if (opts.translation) {
1384
+ ctx.translate(opts.translation[0], opts.translation[1]);
1385
+ }
1386
+ if (!isNullOrUndef(opts.rotation)) {
1387
+ ctx.rotate(opts.rotation);
1388
+ }
1389
+ if (opts.color) {
1390
+ ctx.fillStyle = opts.color;
1391
+ }
1392
+ if (opts.textAlign) {
1393
+ ctx.textAlign = opts.textAlign;
1394
+ }
1395
+ if (opts.textBaseline) {
1396
+ ctx.textBaseline = opts.textBaseline;
1397
+ }
1398
+ }
1399
+ function decorateText(ctx, x, y, line, opts) {
1400
+ if (opts.strikethrough || opts.underline) {
1401
+ /**
1402
+ * Now that IE11 support has been dropped, we can use more
1403
+ * of the TextMetrics object. The actual bounding boxes
1404
+ * are unflagged in Chrome, Firefox, Edge, and Safari so they
1405
+ * can be safely used.
1406
+ * See https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics#Browser_compatibility
1407
+ */ const metrics = ctx.measureText(line);
1408
+ const left = x - metrics.actualBoundingBoxLeft;
1409
+ const right = x + metrics.actualBoundingBoxRight;
1410
+ const top = y - metrics.actualBoundingBoxAscent;
1411
+ const bottom = y + metrics.actualBoundingBoxDescent;
1412
+ const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
1413
+ ctx.strokeStyle = ctx.fillStyle;
1414
+ ctx.beginPath();
1415
+ ctx.lineWidth = opts.decorationWidth || 2;
1416
+ ctx.moveTo(left, yDecoration);
1417
+ ctx.lineTo(right, yDecoration);
1418
+ ctx.stroke();
1419
+ }
1420
+ }
1421
+ function drawBackdrop(ctx, opts) {
1422
+ const oldColor = ctx.fillStyle;
1423
+ ctx.fillStyle = opts.color;
1424
+ ctx.fillRect(opts.left, opts.top, opts.width, opts.height);
1425
+ ctx.fillStyle = oldColor;
1426
+ }
1427
+ /**
1428
+ * Render text onto the canvas
1429
+ */ function renderText(ctx, text, x, y, font, opts = {}) {
1430
+ const lines = isArray(text) ? text : [
1431
+ text
1432
+ ];
1433
+ const stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';
1434
+ let i, line;
1435
+ ctx.save();
1436
+ ctx.font = font.string;
1437
+ setRenderOpts(ctx, opts);
1438
+ for(i = 0; i < lines.length; ++i){
1439
+ line = lines[i];
1440
+ if (opts.backdrop) {
1441
+ drawBackdrop(ctx, opts.backdrop);
1442
+ }
1443
+ if (stroke) {
1444
+ if (opts.strokeColor) {
1445
+ ctx.strokeStyle = opts.strokeColor;
1446
+ }
1447
+ if (!isNullOrUndef(opts.strokeWidth)) {
1448
+ ctx.lineWidth = opts.strokeWidth;
1449
+ }
1450
+ ctx.strokeText(line, x, y, opts.maxWidth);
1451
+ }
1452
+ ctx.fillText(line, x, y, opts.maxWidth);
1453
+ decorateText(ctx, x, y, line, opts);
1454
+ y += Number(font.lineHeight);
1455
+ }
1456
+ ctx.restore();
1457
+ }
1458
+ /**
1459
+ * Add a path of a rectangle with rounded corners to the current sub-path
1460
+ * @param ctx - Context
1461
+ * @param rect - Bounding rect
1462
+ */ function addRoundedRectPath(ctx, rect) {
1463
+ const { x , y , w , h , radius } = rect;
1464
+ // top left arc
1465
+ ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, 1.5 * PI, PI, true);
1466
+ // line from top left to bottom left
1467
+ ctx.lineTo(x, y + h - radius.bottomLeft);
1468
+ // bottom left arc
1469
+ ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);
1470
+ // line from bottom left to bottom right
1471
+ ctx.lineTo(x + w - radius.bottomRight, y + h);
1472
+ // bottom right arc
1473
+ ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);
1474
+ // line from bottom right to top right
1475
+ ctx.lineTo(x + w, y + radius.topRight);
1476
+ // top right arc
1477
+ ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true);
1478
+ // line from top right to top left
1479
+ ctx.lineTo(x + radius.topLeft, y);
1480
+ }
1481
+
1482
+ const LINE_HEIGHT = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/;
1483
+ const FONT_STYLE = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;
1484
+ /**
1485
+ * @alias Chart.helpers.options
1486
+ * @namespace
1487
+ */ /**
1488
+ * Converts the given line height `value` in pixels for a specific font `size`.
1489
+ * @param value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').
1490
+ * @param size - The font size (in pixels) used to resolve relative `value`.
1491
+ * @returns The effective line height in pixels (size * 1.2 if value is invalid).
1492
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
1493
+ * @since 2.7.0
1494
+ */ function toLineHeight(value, size) {
1495
+ const matches = ('' + value).match(LINE_HEIGHT);
1496
+ if (!matches || matches[1] === 'normal') {
1497
+ return size * 1.2;
1498
+ }
1499
+ value = +matches[2];
1500
+ switch(matches[3]){
1501
+ case 'px':
1502
+ return value;
1503
+ case '%':
1504
+ value /= 100;
1505
+ break;
1506
+ }
1507
+ return size * value;
1508
+ }
1509
+ const numberOrZero = (v)=>+v || 0;
1510
+ function _readValueToProps(value, props) {
1511
+ const ret = {};
1512
+ const objProps = isObject(props);
1513
+ const keys = objProps ? Object.keys(props) : props;
1514
+ const read = isObject(value) ? objProps ? (prop)=>valueOrDefault(value[prop], value[props[prop]]) : (prop)=>value[prop] : ()=>value;
1515
+ for (const prop of keys){
1516
+ ret[prop] = numberOrZero(read(prop));
1517
+ }
1518
+ return ret;
1519
+ }
1520
+ /**
1521
+ * Converts the given value into a TRBL object.
1522
+ * @param value - If a number, set the value to all TRBL component,
1523
+ * else, if an object, use defined properties and sets undefined ones to 0.
1524
+ * x / y are shorthands for same value for left/right and top/bottom.
1525
+ * @returns The padding values (top, right, bottom, left)
1526
+ * @since 3.0.0
1527
+ */ function toTRBL(value) {
1528
+ return _readValueToProps(value, {
1529
+ top: 'y',
1530
+ right: 'x',
1531
+ bottom: 'y',
1532
+ left: 'x'
1533
+ });
1534
+ }
1535
+ /**
1536
+ * Converts the given value into a TRBL corners object (similar with css border-radius).
1537
+ * @param value - If a number, set the value to all TRBL corner components,
1538
+ * else, if an object, use defined properties and sets undefined ones to 0.
1539
+ * @returns The TRBL corner values (topLeft, topRight, bottomLeft, bottomRight)
1540
+ * @since 3.0.0
1541
+ */ function toTRBLCorners(value) {
1542
+ return _readValueToProps(value, [
1543
+ 'topLeft',
1544
+ 'topRight',
1545
+ 'bottomLeft',
1546
+ 'bottomRight'
1547
+ ]);
1548
+ }
1549
+ /**
1550
+ * Converts the given value into a padding object with pre-computed width/height.
1551
+ * @param value - If a number, set the value to all TRBL component,
1552
+ * else, if an object, use defined properties and sets undefined ones to 0.
1553
+ * x / y are shorthands for same value for left/right and top/bottom.
1554
+ * @returns The padding values (top, right, bottom, left, width, height)
1555
+ * @since 2.7.0
1556
+ */ function toPadding(value) {
1557
+ const obj = toTRBL(value);
1558
+ obj.width = obj.left + obj.right;
1559
+ obj.height = obj.top + obj.bottom;
1560
+ return obj;
1561
+ }
1562
+ /**
1563
+ * Parses font options and returns the font object.
1564
+ * @param options - A object that contains font options to be parsed.
1565
+ * @param fallback - A object that contains fallback font options.
1566
+ * @return The font object.
1567
+ * @private
1568
+ */ function toFont(options, fallback) {
1569
+ options = options || {};
1570
+ fallback = fallback || defaults.font;
1571
+ let size = valueOrDefault(options.size, fallback.size);
1572
+ if (typeof size === 'string') {
1573
+ size = parseInt(size, 10);
1574
+ }
1575
+ let style = valueOrDefault(options.style, fallback.style);
1576
+ if (style && !('' + style).match(FONT_STYLE)) {
1577
+ console.warn('Invalid font style specified: "' + style + '"');
1578
+ style = undefined;
1579
+ }
1580
+ const font = {
1581
+ family: valueOrDefault(options.family, fallback.family),
1582
+ lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),
1583
+ size,
1584
+ style,
1585
+ weight: valueOrDefault(options.weight, fallback.weight),
1586
+ string: ''
1587
+ };
1588
+ font.string = toFontString(font);
1589
+ return font;
1590
+ }
1591
+ /**
1592
+ * Evaluates the given `inputs` sequentially and returns the first defined value.
1593
+ * @param inputs - An array of values, falling back to the last value.
1594
+ * @param context - If defined and the current value is a function, the value
1595
+ * is called with `context` as first argument and the result becomes the new input.
1596
+ * @param index - If defined and the current value is an array, the value
1597
+ * at `index` become the new input.
1598
+ * @param info - object to return information about resolution in
1599
+ * @param info.cacheable - Will be set to `false` if option is not cacheable.
1600
+ * @since 2.7.0
1601
+ */ function resolve(inputs, context, index, info) {
1602
+ let cacheable = true;
1603
+ let i, ilen, value;
1604
+ for(i = 0, ilen = inputs.length; i < ilen; ++i){
1605
+ value = inputs[i];
1606
+ if (value === undefined) {
1607
+ continue;
1608
+ }
1609
+ if (context !== undefined && typeof value === 'function') {
1610
+ value = value(context);
1611
+ cacheable = false;
1612
+ }
1613
+ if (index !== undefined && isArray(value)) {
1614
+ value = value[index % value.length];
1615
+ cacheable = false;
1616
+ }
1617
+ if (value !== undefined) {
1618
+ if (info && !cacheable) {
1619
+ info.cacheable = false;
1620
+ }
1621
+ return value;
1622
+ }
1623
+ }
1624
+ }
1625
+ /**
1626
+ * @param minmax
1627
+ * @param grace
1628
+ * @param beginAtZero
1629
+ * @private
1630
+ */ function _addGrace(minmax, grace, beginAtZero) {
1631
+ const { min , max } = minmax;
1632
+ const change = toDimension(grace, (max - min) / 2);
1633
+ const keepZero = (value, add)=>beginAtZero && value === 0 ? 0 : value + add;
1634
+ return {
1635
+ min: keepZero(min, -Math.abs(change)),
1636
+ max: keepZero(max, change)
1637
+ };
1638
+ }
1639
+ function createContext(parentContext, context) {
1640
+ return Object.assign(Object.create(parentContext), context);
1641
+ }
1642
+
1643
+ /**
1644
+ * Creates a Proxy for resolving raw values for options.
1645
+ * @param scopes - The option scopes to look for values, in resolution order
1646
+ * @param prefixes - The prefixes for values, in resolution order.
1647
+ * @param rootScopes - The root option scopes
1648
+ * @param fallback - Parent scopes fallback
1649
+ * @param getTarget - callback for getting the target for changed values
1650
+ * @returns Proxy
1651
+ * @private
1652
+ */ function _createResolver(scopes, prefixes = [
1653
+ ''
1654
+ ], rootScopes, fallback, getTarget = ()=>scopes[0]) {
1655
+ const finalRootScopes = rootScopes || scopes;
1656
+ if (typeof fallback === 'undefined') {
1657
+ fallback = _resolve('_fallback', scopes);
1658
+ }
1659
+ const cache = {
1660
+ [Symbol.toStringTag]: 'Object',
1661
+ _cacheable: true,
1662
+ _scopes: scopes,
1663
+ _rootScopes: finalRootScopes,
1664
+ _fallback: fallback,
1665
+ _getTarget: getTarget,
1666
+ override: (scope)=>_createResolver([
1667
+ scope,
1668
+ ...scopes
1669
+ ], prefixes, finalRootScopes, fallback)
1670
+ };
1671
+ return new Proxy(cache, {
1672
+ /**
1673
+ * A trap for the delete operator.
1674
+ */ deleteProperty (target, prop) {
1675
+ delete target[prop]; // remove from cache
1676
+ delete target._keys; // remove cached keys
1677
+ delete scopes[0][prop]; // remove from top level scope
1678
+ return true;
1679
+ },
1680
+ /**
1681
+ * A trap for getting property values.
1682
+ */ get (target, prop) {
1683
+ return _cached(target, prop, ()=>_resolveWithPrefixes(prop, prefixes, scopes, target));
1684
+ },
1685
+ /**
1686
+ * A trap for Object.getOwnPropertyDescriptor.
1687
+ * Also used by Object.hasOwnProperty.
1688
+ */ getOwnPropertyDescriptor (target, prop) {
1689
+ return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop);
1690
+ },
1691
+ /**
1692
+ * A trap for Object.getPrototypeOf.
1693
+ */ getPrototypeOf () {
1694
+ return Reflect.getPrototypeOf(scopes[0]);
1695
+ },
1696
+ /**
1697
+ * A trap for the in operator.
1698
+ */ has (target, prop) {
1699
+ return getKeysFromAllScopes(target).includes(prop);
1700
+ },
1701
+ /**
1702
+ * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.
1703
+ */ ownKeys (target) {
1704
+ return getKeysFromAllScopes(target);
1705
+ },
1706
+ /**
1707
+ * A trap for setting property values.
1708
+ */ set (target, prop, value) {
1709
+ const storage = target._storage || (target._storage = getTarget());
1710
+ target[prop] = storage[prop] = value; // set to top level scope + cache
1711
+ delete target._keys; // remove cached keys
1712
+ return true;
1713
+ }
1714
+ });
1715
+ }
1716
+ /**
1717
+ * Returns an Proxy for resolving option values with context.
1718
+ * @param proxy - The Proxy returned by `_createResolver`
1719
+ * @param context - Context object for scriptable/indexable options
1720
+ * @param subProxy - The proxy provided for scriptable options
1721
+ * @param descriptorDefaults - Defaults for descriptors
1722
+ * @private
1723
+ */ function _attachContext(proxy, context, subProxy, descriptorDefaults) {
1724
+ const cache = {
1725
+ _cacheable: false,
1726
+ _proxy: proxy,
1727
+ _context: context,
1728
+ _subProxy: subProxy,
1729
+ _stack: new Set(),
1730
+ _descriptors: _descriptors(proxy, descriptorDefaults),
1731
+ setContext: (ctx)=>_attachContext(proxy, ctx, subProxy, descriptorDefaults),
1732
+ override: (scope)=>_attachContext(proxy.override(scope), context, subProxy, descriptorDefaults)
1733
+ };
1734
+ return new Proxy(cache, {
1735
+ /**
1736
+ * A trap for the delete operator.
1737
+ */ deleteProperty (target, prop) {
1738
+ delete target[prop]; // remove from cache
1739
+ delete proxy[prop]; // remove from proxy
1740
+ return true;
1741
+ },
1742
+ /**
1743
+ * A trap for getting property values.
1744
+ */ get (target, prop, receiver) {
1745
+ return _cached(target, prop, ()=>_resolveWithContext(target, prop, receiver));
1746
+ },
1747
+ /**
1748
+ * A trap for Object.getOwnPropertyDescriptor.
1749
+ * Also used by Object.hasOwnProperty.
1750
+ */ getOwnPropertyDescriptor (target, prop) {
1751
+ return target._descriptors.allKeys ? Reflect.has(proxy, prop) ? {
1752
+ enumerable: true,
1753
+ configurable: true
1754
+ } : undefined : Reflect.getOwnPropertyDescriptor(proxy, prop);
1755
+ },
1756
+ /**
1757
+ * A trap for Object.getPrototypeOf.
1758
+ */ getPrototypeOf () {
1759
+ return Reflect.getPrototypeOf(proxy);
1760
+ },
1761
+ /**
1762
+ * A trap for the in operator.
1763
+ */ has (target, prop) {
1764
+ return Reflect.has(proxy, prop);
1765
+ },
1766
+ /**
1767
+ * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.
1768
+ */ ownKeys () {
1769
+ return Reflect.ownKeys(proxy);
1770
+ },
1771
+ /**
1772
+ * A trap for setting property values.
1773
+ */ set (target, prop, value) {
1774
+ proxy[prop] = value; // set to proxy
1775
+ delete target[prop]; // remove from cache
1776
+ return true;
1777
+ }
1778
+ });
1779
+ }
1780
+ /**
1781
+ * @private
1782
+ */ function _descriptors(proxy, defaults = {
1783
+ scriptable: true,
1784
+ indexable: true
1785
+ }) {
1786
+ const { _scriptable =defaults.scriptable , _indexable =defaults.indexable , _allKeys =defaults.allKeys } = proxy;
1787
+ return {
1788
+ allKeys: _allKeys,
1789
+ scriptable: _scriptable,
1790
+ indexable: _indexable,
1791
+ isScriptable: isFunction(_scriptable) ? _scriptable : ()=>_scriptable,
1792
+ isIndexable: isFunction(_indexable) ? _indexable : ()=>_indexable
1793
+ };
1794
+ }
1795
+ const readKey = (prefix, name)=>prefix ? prefix + _capitalize(name) : name;
1796
+ const needsSubResolver = (prop, value)=>isObject(value) && prop !== 'adapters' && (Object.getPrototypeOf(value) === null || value.constructor === Object);
1797
+ function _cached(target, prop, resolve) {
1798
+ if (Object.prototype.hasOwnProperty.call(target, prop) || prop === 'constructor') {
1799
+ return target[prop];
1800
+ }
1801
+ const value = resolve();
1802
+ // cache the resolved value
1803
+ target[prop] = value;
1804
+ return value;
1805
+ }
1806
+ function _resolveWithContext(target, prop, receiver) {
1807
+ const { _proxy , _context , _subProxy , _descriptors: descriptors } = target;
1808
+ let value = _proxy[prop]; // resolve from proxy
1809
+ // resolve with context
1810
+ if (isFunction(value) && descriptors.isScriptable(prop)) {
1811
+ value = _resolveScriptable(prop, value, target, receiver);
1812
+ }
1813
+ if (isArray(value) && value.length) {
1814
+ value = _resolveArray(prop, value, target, descriptors.isIndexable);
1815
+ }
1816
+ if (needsSubResolver(prop, value)) {
1817
+ // if the resolved value is an object, create a sub resolver for it
1818
+ value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors);
1819
+ }
1820
+ return value;
1821
+ }
1822
+ function _resolveScriptable(prop, getValue, target, receiver) {
1823
+ const { _proxy , _context , _subProxy , _stack } = target;
1824
+ if (_stack.has(prop)) {
1825
+ throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop);
1826
+ }
1827
+ _stack.add(prop);
1828
+ let value = getValue(_context, _subProxy || receiver);
1829
+ _stack.delete(prop);
1830
+ if (needsSubResolver(prop, value)) {
1831
+ // When scriptable option returns an object, create a resolver on that.
1832
+ value = createSubResolver(_proxy._scopes, _proxy, prop, value);
1833
+ }
1834
+ return value;
1835
+ }
1836
+ function _resolveArray(prop, value, target, isIndexable) {
1837
+ const { _proxy , _context , _subProxy , _descriptors: descriptors } = target;
1838
+ if (typeof _context.index !== 'undefined' && isIndexable(prop)) {
1839
+ return value[_context.index % value.length];
1840
+ } else if (isObject(value[0])) {
1841
+ // Array of objects, return array or resolvers
1842
+ const arr = value;
1843
+ const scopes = _proxy._scopes.filter((s)=>s !== arr);
1844
+ value = [];
1845
+ for (const item of arr){
1846
+ const resolver = createSubResolver(scopes, _proxy, prop, item);
1847
+ value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors));
1848
+ }
1849
+ }
1850
+ return value;
1851
+ }
1852
+ function resolveFallback(fallback, prop, value) {
1853
+ return isFunction(fallback) ? fallback(prop, value) : fallback;
1854
+ }
1855
+ const getScope = (key, parent)=>key === true ? parent : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
1856
+ function addScopes(set, parentScopes, key, parentFallback, value) {
1857
+ for (const parent of parentScopes){
1858
+ const scope = getScope(key, parent);
1859
+ if (scope) {
1860
+ set.add(scope);
1861
+ const fallback = resolveFallback(scope._fallback, key, value);
1862
+ if (typeof fallback !== 'undefined' && fallback !== key && fallback !== parentFallback) {
1863
+ // When we reach the descriptor that defines a new _fallback, return that.
1864
+ // The fallback will resume to that new scope.
1865
+ return fallback;
1866
+ }
1867
+ } else if (scope === false && typeof parentFallback !== 'undefined' && key !== parentFallback) {
1868
+ // Fallback to `false` results to `false`, when falling back to different key.
1869
+ // For example `interaction` from `hover` or `plugins.tooltip` and `animation` from `animations`
1870
+ return null;
1871
+ }
1872
+ }
1873
+ return false;
1874
+ }
1875
+ function createSubResolver(parentScopes, resolver, prop, value) {
1876
+ const rootScopes = resolver._rootScopes;
1877
+ const fallback = resolveFallback(resolver._fallback, prop, value);
1878
+ const allScopes = [
1879
+ ...parentScopes,
1880
+ ...rootScopes
1881
+ ];
1882
+ const set = new Set();
1883
+ set.add(value);
1884
+ let key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);
1885
+ if (key === null) {
1886
+ return false;
1887
+ }
1888
+ if (typeof fallback !== 'undefined' && fallback !== prop) {
1889
+ key = addScopesFromKey(set, allScopes, fallback, key, value);
1890
+ if (key === null) {
1891
+ return false;
1892
+ }
1893
+ }
1894
+ return _createResolver(Array.from(set), [
1895
+ ''
1896
+ ], rootScopes, fallback, ()=>subGetTarget(resolver, prop, value));
1897
+ }
1898
+ function addScopesFromKey(set, allScopes, key, fallback, item) {
1899
+ while(key){
1900
+ key = addScopes(set, allScopes, key, fallback, item);
1901
+ }
1902
+ return key;
1903
+ }
1904
+ function subGetTarget(resolver, prop, value) {
1905
+ const parent = resolver._getTarget();
1906
+ if (!(prop in parent)) {
1907
+ parent[prop] = {};
1908
+ }
1909
+ const target = parent[prop];
1910
+ if (isArray(target) && isObject(value)) {
1911
+ // For array of objects, the object is used to store updated values
1912
+ return value;
1913
+ }
1914
+ return target || {};
1915
+ }
1916
+ function _resolveWithPrefixes(prop, prefixes, scopes, proxy) {
1917
+ let value;
1918
+ for (const prefix of prefixes){
1919
+ value = _resolve(readKey(prefix, prop), scopes);
1920
+ if (typeof value !== 'undefined') {
1921
+ return needsSubResolver(prop, value) ? createSubResolver(scopes, proxy, prop, value) : value;
1922
+ }
1923
+ }
1924
+ }
1925
+ function _resolve(key, scopes) {
1926
+ for (const scope of scopes){
1927
+ if (!scope) {
1928
+ continue;
1929
+ }
1930
+ const value = scope[key];
1931
+ if (typeof value !== 'undefined') {
1932
+ return value;
1933
+ }
1934
+ }
1935
+ }
1936
+ function getKeysFromAllScopes(target) {
1937
+ let keys = target._keys;
1938
+ if (!keys) {
1939
+ keys = target._keys = resolveKeysFromAllScopes(target._scopes);
1940
+ }
1941
+ return keys;
1942
+ }
1943
+ function resolveKeysFromAllScopes(scopes) {
1944
+ const set = new Set();
1945
+ for (const scope of scopes){
1946
+ for (const key of Object.keys(scope).filter((k)=>!k.startsWith('_'))){
1947
+ set.add(key);
1948
+ }
1949
+ }
1950
+ return Array.from(set);
1951
+ }
1952
+ function _parseObjectDataRadialScale(meta, data, start, count) {
1953
+ const { iScale } = meta;
1954
+ const { key ='r' } = this._parsing;
1955
+ const parsed = new Array(count);
1956
+ let i, ilen, index, item;
1957
+ for(i = 0, ilen = count; i < ilen; ++i){
1958
+ index = i + start;
1959
+ item = data[index];
1960
+ parsed[i] = {
1961
+ r: iScale.parse(resolveObjectKey(item, key), index)
1962
+ };
1963
+ }
1964
+ return parsed;
1965
+ }
1966
+
1967
+ const EPSILON = Number.EPSILON || 1e-14;
1968
+ const getPoint = (points, i)=>i < points.length && !points[i].skip && points[i];
1969
+ const getValueAxis = (indexAxis)=>indexAxis === 'x' ? 'y' : 'x';
1970
+ function splineCurve(firstPoint, middlePoint, afterPoint, t) {
1971
+ // Props to Rob Spencer at scaled innovation for his post on splining between points
1972
+ // http://scaledinnovation.com/analytics/splines/aboutSplines.html
1973
+ // This function must also respect "skipped" points
1974
+ const previous = firstPoint.skip ? middlePoint : firstPoint;
1975
+ const current = middlePoint;
1976
+ const next = afterPoint.skip ? middlePoint : afterPoint;
1977
+ const d01 = distanceBetweenPoints(current, previous);
1978
+ const d12 = distanceBetweenPoints(next, current);
1979
+ let s01 = d01 / (d01 + d12);
1980
+ let s12 = d12 / (d01 + d12);
1981
+ // If all points are the same, s01 & s02 will be inf
1982
+ s01 = isNaN(s01) ? 0 : s01;
1983
+ s12 = isNaN(s12) ? 0 : s12;
1984
+ const fa = t * s01; // scaling factor for triangle Ta
1985
+ const fb = t * s12;
1986
+ return {
1987
+ previous: {
1988
+ x: current.x - fa * (next.x - previous.x),
1989
+ y: current.y - fa * (next.y - previous.y)
1990
+ },
1991
+ next: {
1992
+ x: current.x + fb * (next.x - previous.x),
1993
+ y: current.y + fb * (next.y - previous.y)
1994
+ }
1995
+ };
1996
+ }
1997
+ /**
1998
+ * Adjust tangents to ensure monotonic properties
1999
+ */ function monotoneAdjust(points, deltaK, mK) {
2000
+ const pointsLen = points.length;
2001
+ let alphaK, betaK, tauK, squaredMagnitude, pointCurrent;
2002
+ let pointAfter = getPoint(points, 0);
2003
+ for(let i = 0; i < pointsLen - 1; ++i){
2004
+ pointCurrent = pointAfter;
2005
+ pointAfter = getPoint(points, i + 1);
2006
+ if (!pointCurrent || !pointAfter) {
2007
+ continue;
2008
+ }
2009
+ if (almostEquals(deltaK[i], 0, EPSILON)) {
2010
+ mK[i] = mK[i + 1] = 0;
2011
+ continue;
2012
+ }
2013
+ alphaK = mK[i] / deltaK[i];
2014
+ betaK = mK[i + 1] / deltaK[i];
2015
+ squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
2016
+ if (squaredMagnitude <= 9) {
2017
+ continue;
2018
+ }
2019
+ tauK = 3 / Math.sqrt(squaredMagnitude);
2020
+ mK[i] = alphaK * tauK * deltaK[i];
2021
+ mK[i + 1] = betaK * tauK * deltaK[i];
2022
+ }
2023
+ }
2024
+ function monotoneCompute(points, mK, indexAxis = 'x') {
2025
+ const valueAxis = getValueAxis(indexAxis);
2026
+ const pointsLen = points.length;
2027
+ let delta, pointBefore, pointCurrent;
2028
+ let pointAfter = getPoint(points, 0);
2029
+ for(let i = 0; i < pointsLen; ++i){
2030
+ pointBefore = pointCurrent;
2031
+ pointCurrent = pointAfter;
2032
+ pointAfter = getPoint(points, i + 1);
2033
+ if (!pointCurrent) {
2034
+ continue;
2035
+ }
2036
+ const iPixel = pointCurrent[indexAxis];
2037
+ const vPixel = pointCurrent[valueAxis];
2038
+ if (pointBefore) {
2039
+ delta = (iPixel - pointBefore[indexAxis]) / 3;
2040
+ pointCurrent[`cp1${indexAxis}`] = iPixel - delta;
2041
+ pointCurrent[`cp1${valueAxis}`] = vPixel - delta * mK[i];
2042
+ }
2043
+ if (pointAfter) {
2044
+ delta = (pointAfter[indexAxis] - iPixel) / 3;
2045
+ pointCurrent[`cp2${indexAxis}`] = iPixel + delta;
2046
+ pointCurrent[`cp2${valueAxis}`] = vPixel + delta * mK[i];
2047
+ }
2048
+ }
2049
+ }
2050
+ /**
2051
+ * This function calculates Bézier control points in a similar way than |splineCurve|,
2052
+ * but preserves monotonicity of the provided data and ensures no local extremums are added
2053
+ * between the dataset discrete points due to the interpolation.
2054
+ * See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
2055
+ */ function splineCurveMonotone(points, indexAxis = 'x') {
2056
+ const valueAxis = getValueAxis(indexAxis);
2057
+ const pointsLen = points.length;
2058
+ const deltaK = Array(pointsLen).fill(0);
2059
+ const mK = Array(pointsLen);
2060
+ // Calculate slopes (deltaK) and initialize tangents (mK)
2061
+ let i, pointBefore, pointCurrent;
2062
+ let pointAfter = getPoint(points, 0);
2063
+ for(i = 0; i < pointsLen; ++i){
2064
+ pointBefore = pointCurrent;
2065
+ pointCurrent = pointAfter;
2066
+ pointAfter = getPoint(points, i + 1);
2067
+ if (!pointCurrent) {
2068
+ continue;
2069
+ }
2070
+ if (pointAfter) {
2071
+ const slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis];
2072
+ // In the case of two points that appear at the same x pixel, slopeDeltaX is 0
2073
+ deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0;
2074
+ }
2075
+ mK[i] = !pointBefore ? deltaK[i] : !pointAfter ? deltaK[i - 1] : sign(deltaK[i - 1]) !== sign(deltaK[i]) ? 0 : (deltaK[i - 1] + deltaK[i]) / 2;
2076
+ }
2077
+ monotoneAdjust(points, deltaK, mK);
2078
+ monotoneCompute(points, mK, indexAxis);
2079
+ }
2080
+ function capControlPoint(pt, min, max) {
2081
+ return Math.max(Math.min(pt, max), min);
2082
+ }
2083
+ function capBezierPoints(points, area) {
2084
+ let i, ilen, point, inArea, inAreaPrev;
2085
+ let inAreaNext = _isPointInArea(points[0], area);
2086
+ for(i = 0, ilen = points.length; i < ilen; ++i){
2087
+ inAreaPrev = inArea;
2088
+ inArea = inAreaNext;
2089
+ inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area);
2090
+ if (!inArea) {
2091
+ continue;
2092
+ }
2093
+ point = points[i];
2094
+ if (inAreaPrev) {
2095
+ point.cp1x = capControlPoint(point.cp1x, area.left, area.right);
2096
+ point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom);
2097
+ }
2098
+ if (inAreaNext) {
2099
+ point.cp2x = capControlPoint(point.cp2x, area.left, area.right);
2100
+ point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom);
2101
+ }
2102
+ }
2103
+ }
2104
+ /**
2105
+ * @private
2106
+ */ function _updateBezierControlPoints(points, options, area, loop, indexAxis) {
2107
+ let i, ilen, point, controlPoints;
2108
+ // Only consider points that are drawn in case the spanGaps option is used
2109
+ if (options.spanGaps) {
2110
+ points = points.filter((pt)=>!pt.skip);
2111
+ }
2112
+ if (options.cubicInterpolationMode === 'monotone') {
2113
+ splineCurveMonotone(points, indexAxis);
2114
+ } else {
2115
+ let prev = loop ? points[points.length - 1] : points[0];
2116
+ for(i = 0, ilen = points.length; i < ilen; ++i){
2117
+ point = points[i];
2118
+ controlPoints = splineCurve(prev, point, points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen], options.tension);
2119
+ point.cp1x = controlPoints.previous.x;
2120
+ point.cp1y = controlPoints.previous.y;
2121
+ point.cp2x = controlPoints.next.x;
2122
+ point.cp2y = controlPoints.next.y;
2123
+ prev = point;
2124
+ }
2125
+ }
2126
+ if (options.capBezierPoints) {
2127
+ capBezierPoints(points, area);
2128
+ }
2129
+ }
2130
+
2131
+ /**
2132
+ * Note: typedefs are auto-exported, so use a made-up `dom` namespace where
2133
+ * necessary to avoid duplicates with `export * from './helpers`; see
2134
+ * https://github.com/microsoft/TypeScript/issues/46011
2135
+ * @typedef { import('../core/core.controller.js').default } dom.Chart
2136
+ * @typedef { import('../../types').ChartEvent } ChartEvent
2137
+ */ /**
2138
+ * @private
2139
+ */ function _isDomSupported() {
2140
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
2141
+ }
2142
+ /**
2143
+ * @private
2144
+ */ function _getParentNode(domNode) {
2145
+ let parent = domNode.parentNode;
2146
+ if (parent && parent.toString() === '[object ShadowRoot]') {
2147
+ parent = parent.host;
2148
+ }
2149
+ return parent;
2150
+ }
2151
+ /**
2152
+ * convert max-width/max-height values that may be percentages into a number
2153
+ * @private
2154
+ */ function parseMaxStyle(styleValue, node, parentProperty) {
2155
+ let valueInPixels;
2156
+ if (typeof styleValue === 'string') {
2157
+ valueInPixels = parseInt(styleValue, 10);
2158
+ if (styleValue.indexOf('%') !== -1) {
2159
+ // percentage * size in dimension
2160
+ valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
2161
+ }
2162
+ } else {
2163
+ valueInPixels = styleValue;
2164
+ }
2165
+ return valueInPixels;
2166
+ }
2167
+ const getComputedStyle = (element)=>element.ownerDocument.defaultView.getComputedStyle(element, null);
2168
+ function getStyle(el, property) {
2169
+ return getComputedStyle(el).getPropertyValue(property);
2170
+ }
2171
+ const positions = [
2172
+ 'top',
2173
+ 'right',
2174
+ 'bottom',
2175
+ 'left'
2176
+ ];
2177
+ function getPositionedStyle(styles, style, suffix) {
2178
+ const result = {};
2179
+ suffix = suffix ? '-' + suffix : '';
2180
+ for(let i = 0; i < 4; i++){
2181
+ const pos = positions[i];
2182
+ result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0;
2183
+ }
2184
+ result.width = result.left + result.right;
2185
+ result.height = result.top + result.bottom;
2186
+ return result;
2187
+ }
2188
+ const useOffsetPos = (x, y, target)=>(x > 0 || y > 0) && (!target || !target.shadowRoot);
2189
+ /**
2190
+ * @param e
2191
+ * @param canvas
2192
+ * @returns Canvas position
2193
+ */ function getCanvasPosition(e, canvas) {
2194
+ const touches = e.touches;
2195
+ const source = touches && touches.length ? touches[0] : e;
2196
+ const { offsetX , offsetY } = source;
2197
+ let box = false;
2198
+ let x, y;
2199
+ if (useOffsetPos(offsetX, offsetY, e.target)) {
2200
+ x = offsetX;
2201
+ y = offsetY;
2202
+ } else {
2203
+ const rect = canvas.getBoundingClientRect();
2204
+ x = source.clientX - rect.left;
2205
+ y = source.clientY - rect.top;
2206
+ box = true;
2207
+ }
2208
+ return {
2209
+ x,
2210
+ y,
2211
+ box
2212
+ };
2213
+ }
2214
+ /**
2215
+ * Gets an event's x, y coordinates, relative to the chart area
2216
+ * @param event
2217
+ * @param chart
2218
+ * @returns x and y coordinates of the event
2219
+ */ function getRelativePosition(event, chart) {
2220
+ if ('native' in event) {
2221
+ return event;
2222
+ }
2223
+ const { canvas , currentDevicePixelRatio } = chart;
2224
+ const style = getComputedStyle(canvas);
2225
+ const borderBox = style.boxSizing === 'border-box';
2226
+ const paddings = getPositionedStyle(style, 'padding');
2227
+ const borders = getPositionedStyle(style, 'border', 'width');
2228
+ const { x , y , box } = getCanvasPosition(event, canvas);
2229
+ const xOffset = paddings.left + (box && borders.left);
2230
+ const yOffset = paddings.top + (box && borders.top);
2231
+ let { width , height } = chart;
2232
+ if (borderBox) {
2233
+ width -= paddings.width + borders.width;
2234
+ height -= paddings.height + borders.height;
2235
+ }
2236
+ return {
2237
+ x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio),
2238
+ y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio)
2239
+ };
2240
+ }
2241
+ function getContainerSize(canvas, width, height) {
2242
+ let maxWidth, maxHeight;
2243
+ if (width === undefined || height === undefined) {
2244
+ const container = canvas && _getParentNode(canvas);
2245
+ if (!container) {
2246
+ width = canvas.clientWidth;
2247
+ height = canvas.clientHeight;
2248
+ } else {
2249
+ const rect = container.getBoundingClientRect(); // this is the border box of the container
2250
+ const containerStyle = getComputedStyle(container);
2251
+ const containerBorder = getPositionedStyle(containerStyle, 'border', 'width');
2252
+ const containerPadding = getPositionedStyle(containerStyle, 'padding');
2253
+ width = rect.width - containerPadding.width - containerBorder.width;
2254
+ height = rect.height - containerPadding.height - containerBorder.height;
2255
+ maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth');
2256
+ maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight');
2257
+ }
2258
+ }
2259
+ return {
2260
+ width,
2261
+ height,
2262
+ maxWidth: maxWidth || INFINITY,
2263
+ maxHeight: maxHeight || INFINITY
2264
+ };
2265
+ }
2266
+ const round1 = (v)=>Math.round(v * 10) / 10;
2267
+ // eslint-disable-next-line complexity
2268
+ function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {
2269
+ const style = getComputedStyle(canvas);
2270
+ const margins = getPositionedStyle(style, 'margin');
2271
+ const maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY;
2272
+ const maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY;
2273
+ const containerSize = getContainerSize(canvas, bbWidth, bbHeight);
2274
+ let { width , height } = containerSize;
2275
+ if (style.boxSizing === 'content-box') {
2276
+ const borders = getPositionedStyle(style, 'border', 'width');
2277
+ const paddings = getPositionedStyle(style, 'padding');
2278
+ width -= paddings.width + borders.width;
2279
+ height -= paddings.height + borders.height;
2280
+ }
2281
+ width = Math.max(0, width - margins.width);
2282
+ height = Math.max(0, aspectRatio ? width / aspectRatio : height - margins.height);
2283
+ width = round1(Math.min(width, maxWidth, containerSize.maxWidth));
2284
+ height = round1(Math.min(height, maxHeight, containerSize.maxHeight));
2285
+ if (width && !height) {
2286
+ // https://github.com/chartjs/Chart.js/issues/4659
2287
+ // If the canvas has width, but no height, default to aspectRatio of 2 (canvas default)
2288
+ height = round1(width / 2);
2289
+ }
2290
+ const maintainHeight = bbWidth !== undefined || bbHeight !== undefined;
2291
+ if (maintainHeight && aspectRatio && containerSize.height && height > containerSize.height) {
2292
+ height = containerSize.height;
2293
+ width = round1(Math.floor(height * aspectRatio));
2294
+ }
2295
+ return {
2296
+ width,
2297
+ height
2298
+ };
2299
+ }
2300
+ /**
2301
+ * @param chart
2302
+ * @param forceRatio
2303
+ * @param forceStyle
2304
+ * @returns True if the canvas context size or transformation has changed.
2305
+ */ function retinaScale(chart, forceRatio, forceStyle) {
2306
+ const pixelRatio = forceRatio || 1;
2307
+ const deviceHeight = Math.floor(chart.height * pixelRatio);
2308
+ const deviceWidth = Math.floor(chart.width * pixelRatio);
2309
+ chart.height = Math.floor(chart.height);
2310
+ chart.width = Math.floor(chart.width);
2311
+ const canvas = chart.canvas;
2312
+ // If no style has been set on the canvas, the render size is used as display size,
2313
+ // making the chart visually bigger, so let's enforce it to the "correct" values.
2314
+ // See https://github.com/chartjs/Chart.js/issues/3575
2315
+ if (canvas.style && (forceStyle || !canvas.style.height && !canvas.style.width)) {
2316
+ canvas.style.height = `${chart.height}px`;
2317
+ canvas.style.width = `${chart.width}px`;
2318
+ }
2319
+ if (chart.currentDevicePixelRatio !== pixelRatio || canvas.height !== deviceHeight || canvas.width !== deviceWidth) {
2320
+ chart.currentDevicePixelRatio = pixelRatio;
2321
+ canvas.height = deviceHeight;
2322
+ canvas.width = deviceWidth;
2323
+ chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
2324
+ return true;
2325
+ }
2326
+ return false;
2327
+ }
2328
+ /**
2329
+ * Detects support for options object argument in addEventListener.
2330
+ * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
2331
+ * @private
2332
+ */ const supportsEventListenerOptions = function() {
2333
+ let passiveSupported = false;
2334
+ try {
2335
+ const options = {
2336
+ get passive () {
2337
+ passiveSupported = true;
2338
+ return false;
2339
+ }
2340
+ };
2341
+ if (_isDomSupported()) {
2342
+ window.addEventListener('test', null, options);
2343
+ window.removeEventListener('test', null, options);
2344
+ }
2345
+ } catch (e) {
2346
+ // continue regardless of error
2347
+ }
2348
+ return passiveSupported;
2349
+ }();
2350
+ /**
2351
+ * The "used" size is the final value of a dimension property after all calculations have
2352
+ * been performed. This method uses the computed style of `element` but returns undefined
2353
+ * if the computed style is not expressed in pixels. That can happen in some cases where
2354
+ * `element` has a size relative to its parent and this last one is not yet displayed,
2355
+ * for example because of `display: none` on a parent node.
2356
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
2357
+ * @returns Size in pixels or undefined if unknown.
2358
+ */ function readUsedSize(element, property) {
2359
+ const value = getStyle(element, property);
2360
+ const matches = value && value.match(/^(\d+)(\.\d+)?px$/);
2361
+ return matches ? +matches[1] : undefined;
2362
+ }
2363
+
2364
+ /**
2365
+ * @private
2366
+ */ function _pointInLine(p1, p2, t, mode) {
2367
+ return {
2368
+ x: p1.x + t * (p2.x - p1.x),
2369
+ y: p1.y + t * (p2.y - p1.y)
2370
+ };
2371
+ }
2372
+ /**
2373
+ * @private
2374
+ */ function _steppedInterpolation(p1, p2, t, mode) {
2375
+ return {
2376
+ x: p1.x + t * (p2.x - p1.x),
2377
+ y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y : mode === 'after' ? t < 1 ? p1.y : p2.y : t > 0 ? p2.y : p1.y
2378
+ };
2379
+ }
2380
+ /**
2381
+ * @private
2382
+ */ function _bezierInterpolation(p1, p2, t, mode) {
2383
+ const cp1 = {
2384
+ x: p1.cp2x,
2385
+ y: p1.cp2y
2386
+ };
2387
+ const cp2 = {
2388
+ x: p2.cp1x,
2389
+ y: p2.cp1y
2390
+ };
2391
+ const a = _pointInLine(p1, cp1, t);
2392
+ const b = _pointInLine(cp1, cp2, t);
2393
+ const c = _pointInLine(cp2, p2, t);
2394
+ const d = _pointInLine(a, b, t);
2395
+ const e = _pointInLine(b, c, t);
2396
+ return _pointInLine(d, e, t);
2397
+ }
2398
+
2399
+ const getRightToLeftAdapter = function(rectX, width) {
2400
+ return {
2401
+ x (x) {
2402
+ return rectX + rectX + width - x;
2403
+ },
2404
+ setWidth (w) {
2405
+ width = w;
2406
+ },
2407
+ textAlign (align) {
2408
+ if (align === 'center') {
2409
+ return align;
2410
+ }
2411
+ return align === 'right' ? 'left' : 'right';
2412
+ },
2413
+ xPlus (x, value) {
2414
+ return x - value;
2415
+ },
2416
+ leftForLtr (x, itemWidth) {
2417
+ return x - itemWidth;
2418
+ }
2419
+ };
2420
+ };
2421
+ const getLeftToRightAdapter = function() {
2422
+ return {
2423
+ x (x) {
2424
+ return x;
2425
+ },
2426
+ setWidth (w) {},
2427
+ textAlign (align) {
2428
+ return align;
2429
+ },
2430
+ xPlus (x, value) {
2431
+ return x + value;
2432
+ },
2433
+ leftForLtr (x, _itemWidth) {
2434
+ return x;
2435
+ }
2436
+ };
2437
+ };
2438
+ function getRtlAdapter(rtl, rectX, width) {
2439
+ return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();
2440
+ }
2441
+ function overrideTextDirection(ctx, direction) {
2442
+ let style, original;
2443
+ if (direction === 'ltr' || direction === 'rtl') {
2444
+ style = ctx.canvas.style;
2445
+ original = [
2446
+ style.getPropertyValue('direction'),
2447
+ style.getPropertyPriority('direction')
2448
+ ];
2449
+ style.setProperty('direction', direction, 'important');
2450
+ ctx.prevTextDirection = original;
2451
+ }
2452
+ }
2453
+ function restoreTextDirection(ctx, original) {
2454
+ if (original !== undefined) {
2455
+ delete ctx.prevTextDirection;
2456
+ ctx.canvas.style.setProperty('direction', original[0], original[1]);
2457
+ }
2458
+ }
2459
+
2460
+ function propertyFn(property) {
2461
+ if (property === 'angle') {
2462
+ return {
2463
+ between: _angleBetween,
2464
+ compare: _angleDiff,
2465
+ normalize: _normalizeAngle
2466
+ };
2467
+ }
2468
+ return {
2469
+ between: _isBetween,
2470
+ compare: (a, b)=>a - b,
2471
+ normalize: (x)=>x
2472
+ };
2473
+ }
2474
+ function normalizeSegment({ start , end , count , loop , style }) {
2475
+ return {
2476
+ start: start % count,
2477
+ end: end % count,
2478
+ loop: loop && (end - start + 1) % count === 0,
2479
+ style
2480
+ };
2481
+ }
2482
+ function getSegment(segment, points, bounds) {
2483
+ const { property , start: startBound , end: endBound } = bounds;
2484
+ const { between , normalize } = propertyFn(property);
2485
+ const count = points.length;
2486
+ let { start , end , loop } = segment;
2487
+ let i, ilen;
2488
+ if (loop) {
2489
+ start += count;
2490
+ end += count;
2491
+ for(i = 0, ilen = count; i < ilen; ++i){
2492
+ if (!between(normalize(points[start % count][property]), startBound, endBound)) {
2493
+ break;
2494
+ }
2495
+ start--;
2496
+ end--;
2497
+ }
2498
+ start %= count;
2499
+ end %= count;
2500
+ }
2501
+ if (end < start) {
2502
+ end += count;
2503
+ }
2504
+ return {
2505
+ start,
2506
+ end,
2507
+ loop,
2508
+ style: segment.style
2509
+ };
2510
+ }
2511
+ function _boundSegment(segment, points, bounds) {
2512
+ if (!bounds) {
2513
+ return [
2514
+ segment
2515
+ ];
2516
+ }
2517
+ const { property , start: startBound , end: endBound } = bounds;
2518
+ const count = points.length;
2519
+ const { compare , between , normalize } = propertyFn(property);
2520
+ const { start , end , loop , style } = getSegment(segment, points, bounds);
2521
+ const result = [];
2522
+ let inside = false;
2523
+ let subStart = null;
2524
+ let value, point, prevValue;
2525
+ const startIsBefore = ()=>between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0;
2526
+ const endIsBefore = ()=>compare(endBound, value) === 0 || between(endBound, prevValue, value);
2527
+ const shouldStart = ()=>inside || startIsBefore();
2528
+ const shouldStop = ()=>!inside || endIsBefore();
2529
+ for(let i = start, prev = start; i <= end; ++i){
2530
+ point = points[i % count];
2531
+ if (point.skip) {
2532
+ continue;
2533
+ }
2534
+ value = normalize(point[property]);
2535
+ if (value === prevValue) {
2536
+ continue;
2537
+ }
2538
+ inside = between(value, startBound, endBound);
2539
+ if (subStart === null && shouldStart()) {
2540
+ subStart = compare(value, startBound) === 0 ? i : prev;
2541
+ }
2542
+ if (subStart !== null && shouldStop()) {
2543
+ result.push(normalizeSegment({
2544
+ start: subStart,
2545
+ end: i,
2546
+ loop,
2547
+ count,
2548
+ style
2549
+ }));
2550
+ subStart = null;
2551
+ }
2552
+ prev = i;
2553
+ prevValue = value;
2554
+ }
2555
+ if (subStart !== null) {
2556
+ result.push(normalizeSegment({
2557
+ start: subStart,
2558
+ end,
2559
+ loop,
2560
+ count,
2561
+ style
2562
+ }));
2563
+ }
2564
+ return result;
2565
+ }
2566
+ function _boundSegments(line, bounds) {
2567
+ const result = [];
2568
+ const segments = line.segments;
2569
+ for(let i = 0; i < segments.length; i++){
2570
+ const sub = _boundSegment(segments[i], line.points, bounds);
2571
+ if (sub.length) {
2572
+ result.push(...sub);
2573
+ }
2574
+ }
2575
+ return result;
2576
+ }
2577
+ function findStartAndEnd(points, count, loop, spanGaps) {
2578
+ let start = 0;
2579
+ let end = count - 1;
2580
+ if (loop && !spanGaps) {
2581
+ while(start < count && !points[start].skip){
2582
+ start++;
2583
+ }
2584
+ }
2585
+ while(start < count && points[start].skip){
2586
+ start++;
2587
+ }
2588
+ start %= count;
2589
+ if (loop) {
2590
+ end += start;
2591
+ }
2592
+ while(end > start && points[end % count].skip){
2593
+ end--;
2594
+ }
2595
+ end %= count;
2596
+ return {
2597
+ start,
2598
+ end
2599
+ };
2600
+ }
2601
+ function solidSegments(points, start, max, loop) {
2602
+ const count = points.length;
2603
+ const result = [];
2604
+ let last = start;
2605
+ let prev = points[start];
2606
+ let end;
2607
+ for(end = start + 1; end <= max; ++end){
2608
+ const cur = points[end % count];
2609
+ if (cur.skip || cur.stop) {
2610
+ if (!prev.skip) {
2611
+ loop = false;
2612
+ result.push({
2613
+ start: start % count,
2614
+ end: (end - 1) % count,
2615
+ loop
2616
+ });
2617
+ start = last = cur.stop ? end : null;
2618
+ }
2619
+ } else {
2620
+ last = end;
2621
+ if (prev.skip) {
2622
+ start = end;
2623
+ }
2624
+ }
2625
+ prev = cur;
2626
+ }
2627
+ if (last !== null) {
2628
+ result.push({
2629
+ start: start % count,
2630
+ end: last % count,
2631
+ loop
2632
+ });
2633
+ }
2634
+ return result;
2635
+ }
2636
+ function _computeSegments(line, segmentOptions) {
2637
+ const points = line.points;
2638
+ const spanGaps = line.options.spanGaps;
2639
+ const count = points.length;
2640
+ if (!count) {
2641
+ return [];
2642
+ }
2643
+ const loop = !!line._loop;
2644
+ const { start , end } = findStartAndEnd(points, count, loop, spanGaps);
2645
+ if (spanGaps === true) {
2646
+ return splitByStyles(line, [
2647
+ {
2648
+ start,
2649
+ end,
2650
+ loop
2651
+ }
2652
+ ], points, segmentOptions);
2653
+ }
2654
+ const max = end < start ? end + count : end;
2655
+ const completeLoop = !!line._fullLoop && start === 0 && end === count - 1;
2656
+ return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions);
2657
+ }
2658
+ function splitByStyles(line, segments, points, segmentOptions) {
2659
+ if (!segmentOptions || !segmentOptions.setContext || !points) {
2660
+ return segments;
2661
+ }
2662
+ return doSplitByStyles(line, segments, points, segmentOptions);
2663
+ }
2664
+ function doSplitByStyles(line, segments, points, segmentOptions) {
2665
+ const chartContext = line._chart.getContext();
2666
+ const baseStyle = readStyle(line.options);
2667
+ const { _datasetIndex: datasetIndex , options: { spanGaps } } = line;
2668
+ const count = points.length;
2669
+ const result = [];
2670
+ let prevStyle = baseStyle;
2671
+ let start = segments[0].start;
2672
+ let i = start;
2673
+ function addStyle(s, e, l, st) {
2674
+ const dir = spanGaps ? -1 : 1;
2675
+ if (s === e) {
2676
+ return;
2677
+ }
2678
+ s += count;
2679
+ while(points[s % count].skip){
2680
+ s -= dir;
2681
+ }
2682
+ while(points[e % count].skip){
2683
+ e += dir;
2684
+ }
2685
+ if (s % count !== e % count) {
2686
+ result.push({
2687
+ start: s % count,
2688
+ end: e % count,
2689
+ loop: l,
2690
+ style: st
2691
+ });
2692
+ prevStyle = st;
2693
+ start = e % count;
2694
+ }
2695
+ }
2696
+ for (const segment of segments){
2697
+ start = spanGaps ? start : segment.start;
2698
+ let prev = points[start % count];
2699
+ let style;
2700
+ for(i = start + 1; i <= segment.end; i++){
2701
+ const pt = points[i % count];
2702
+ style = readStyle(segmentOptions.setContext(createContext(chartContext, {
2703
+ type: 'segment',
2704
+ p0: prev,
2705
+ p1: pt,
2706
+ p0DataIndex: (i - 1) % count,
2707
+ p1DataIndex: i % count,
2708
+ datasetIndex
2709
+ })));
2710
+ if (styleChanged(style, prevStyle)) {
2711
+ addStyle(start, i - 1, segment.loop, prevStyle);
2712
+ }
2713
+ prev = pt;
2714
+ prevStyle = style;
2715
+ }
2716
+ if (start < i - 1) {
2717
+ addStyle(start, i - 1, segment.loop, prevStyle);
2718
+ }
2719
+ }
2720
+ return result;
2721
+ }
2722
+ function readStyle(options) {
2723
+ return {
2724
+ backgroundColor: options.backgroundColor,
2725
+ borderCapStyle: options.borderCapStyle,
2726
+ borderDash: options.borderDash,
2727
+ borderDashOffset: options.borderDashOffset,
2728
+ borderJoinStyle: options.borderJoinStyle,
2729
+ borderWidth: options.borderWidth,
2730
+ borderColor: options.borderColor
2731
+ };
2732
+ }
2733
+ function styleChanged(style, prevStyle) {
2734
+ if (!prevStyle) {
2735
+ return false;
2736
+ }
2737
+ const cache = [];
2738
+ const replacer = function(key, value) {
2739
+ if (!isPatternOrGradient(value)) {
2740
+ return value;
2741
+ }
2742
+ if (!cache.includes(value)) {
2743
+ cache.push(value);
2744
+ }
2745
+ return cache.indexOf(value);
2746
+ };
2747
+ return JSON.stringify(style, replacer) !== JSON.stringify(prevStyle, replacer);
2748
+ }
2749
+
2750
+ exports.HALF_PI = HALF_PI;
2751
+ exports.INFINITY = INFINITY;
2752
+ exports.PI = PI;
2753
+ exports.PITAU = PITAU;
2754
+ exports.QUARTER_PI = QUARTER_PI;
2755
+ exports.RAD_PER_DEG = RAD_PER_DEG;
2756
+ exports.TAU = TAU;
2757
+ exports.TWO_THIRDS_PI = TWO_THIRDS_PI;
2758
+ exports.Ticks = Ticks;
2759
+ exports._addGrace = _addGrace;
2760
+ exports._alignPixel = _alignPixel;
2761
+ exports._alignStartEnd = _alignStartEnd;
2762
+ exports._angleBetween = _angleBetween;
2763
+ exports._angleDiff = _angleDiff;
2764
+ exports._arrayUnique = _arrayUnique;
2765
+ exports._attachContext = _attachContext;
2766
+ exports._bezierCurveTo = _bezierCurveTo;
2767
+ exports._bezierInterpolation = _bezierInterpolation;
2768
+ exports._boundSegment = _boundSegment;
2769
+ exports._boundSegments = _boundSegments;
2770
+ exports._capitalize = _capitalize;
2771
+ exports._computeSegments = _computeSegments;
2772
+ exports._createResolver = _createResolver;
2773
+ exports._decimalPlaces = _decimalPlaces;
2774
+ exports._deprecated = _deprecated;
2775
+ exports._descriptors = _descriptors;
2776
+ exports._elementsEqual = _elementsEqual;
2777
+ exports._factorize = _factorize;
2778
+ exports._filterBetween = _filterBetween;
2779
+ exports._getParentNode = _getParentNode;
2780
+ exports._getStartAndCountOfVisiblePoints = _getStartAndCountOfVisiblePoints;
2781
+ exports._int16Range = _int16Range;
2782
+ exports._isBetween = _isBetween;
2783
+ exports._isClickEvent = _isClickEvent;
2784
+ exports._isDomSupported = _isDomSupported;
2785
+ exports._isPointInArea = _isPointInArea;
2786
+ exports._limitValue = _limitValue;
2787
+ exports._longestText = _longestText;
2788
+ exports._lookup = _lookup;
2789
+ exports._lookupByKey = _lookupByKey;
2790
+ exports._measureText = _measureText;
2791
+ exports._merger = _merger;
2792
+ exports._mergerIf = _mergerIf;
2793
+ exports._normalizeAngle = _normalizeAngle;
2794
+ exports._parseObjectDataRadialScale = _parseObjectDataRadialScale;
2795
+ exports._pointInLine = _pointInLine;
2796
+ exports._readValueToProps = _readValueToProps;
2797
+ exports._rlookupByKey = _rlookupByKey;
2798
+ exports._scaleRangesChanged = _scaleRangesChanged;
2799
+ exports._setMinAndMaxByKey = _setMinAndMaxByKey;
2800
+ exports._splitKey = _splitKey;
2801
+ exports._steppedInterpolation = _steppedInterpolation;
2802
+ exports._steppedLineTo = _steppedLineTo;
2803
+ exports._textX = _textX;
2804
+ exports._toLeftRightCenter = _toLeftRightCenter;
2805
+ exports._updateBezierControlPoints = _updateBezierControlPoints;
2806
+ exports.addRoundedRectPath = addRoundedRectPath;
2807
+ exports.almostEquals = almostEquals;
2808
+ exports.almostWhole = almostWhole;
2809
+ exports.callback = callback;
2810
+ exports.clearCanvas = clearCanvas;
2811
+ exports.clipArea = clipArea;
2812
+ exports.clone = clone;
2813
+ exports.color = color;
2814
+ exports.createContext = createContext;
2815
+ exports.debounce = debounce;
2816
+ exports.defaults = defaults;
2817
+ exports.defined = defined;
2818
+ exports.descriptors = descriptors;
2819
+ exports.distanceBetweenPoints = distanceBetweenPoints;
2820
+ exports.drawPoint = drawPoint;
2821
+ exports.drawPointLegend = drawPointLegend;
2822
+ exports.each = each;
2823
+ exports.effects = effects;
2824
+ exports.finiteOrDefault = finiteOrDefault;
2825
+ exports.fontString = fontString;
2826
+ exports.formatNumber = formatNumber;
2827
+ exports.getAngleFromPoint = getAngleFromPoint;
2828
+ exports.getHoverColor = getHoverColor;
2829
+ exports.getMaximumSize = getMaximumSize;
2830
+ exports.getRelativePosition = getRelativePosition;
2831
+ exports.getRtlAdapter = getRtlAdapter;
2832
+ exports.getStyle = getStyle;
2833
+ exports.isArray = isArray;
2834
+ exports.isFunction = isFunction;
2835
+ exports.isNullOrUndef = isNullOrUndef;
2836
+ exports.isNumber = isNumber;
2837
+ exports.isNumberFinite = isNumberFinite;
2838
+ exports.isObject = isObject;
2839
+ exports.isPatternOrGradient = isPatternOrGradient;
2840
+ exports.listenArrayEvents = listenArrayEvents;
2841
+ exports.log10 = log10;
2842
+ exports.merge = merge;
2843
+ exports.mergeIf = mergeIf;
2844
+ exports.niceNum = niceNum;
2845
+ exports.noop = noop;
2846
+ exports.overrideTextDirection = overrideTextDirection;
2847
+ exports.overrides = overrides;
2848
+ exports.readUsedSize = readUsedSize;
2849
+ exports.renderText = renderText;
2850
+ exports.requestAnimFrame = requestAnimFrame;
2851
+ exports.resolve = resolve;
2852
+ exports.resolveObjectKey = resolveObjectKey;
2853
+ exports.restoreTextDirection = restoreTextDirection;
2854
+ exports.retinaScale = retinaScale;
2855
+ exports.setsEqual = setsEqual;
2856
+ exports.sign = sign;
2857
+ exports.splineCurve = splineCurve;
2858
+ exports.splineCurveMonotone = splineCurveMonotone;
2859
+ exports.supportsEventListenerOptions = supportsEventListenerOptions;
2860
+ exports.throttled = throttled;
2861
+ exports.toDegrees = toDegrees;
2862
+ exports.toDimension = toDimension;
2863
+ exports.toFont = toFont;
2864
+ exports.toFontString = toFontString;
2865
+ exports.toLineHeight = toLineHeight;
2866
+ exports.toPadding = toPadding;
2867
+ exports.toPercentage = toPercentage;
2868
+ exports.toRadians = toRadians;
2869
+ exports.toTRBL = toTRBL;
2870
+ exports.toTRBLCorners = toTRBLCorners;
2871
+ exports.uid = uid;
2872
+ exports.unclipArea = unclipArea;
2873
+ exports.unlistenArrayEvents = unlistenArrayEvents;
2874
+ exports.valueOrDefault = valueOrDefault;
2875
+ //# sourceMappingURL=helpers.segment.cjs.map