1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e5f04e8a-85d9-446b-b9ed-d33721cb436b",e._sentryDebugIdIdentifier="sentry-dbid-e5f04e8a-85d9-446b-b9ed-d33721cb436b");}catch(e){}}(); 2"use strict"; 3(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([[2196],{ 4 5/***/ 23148: 6/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { 7 8/* harmony export */ __webpack_require__.d(__webpack_exports__, { 9/* harmony export */ De: function() { return /* binding */ plugin_legend; }, 10/* harmony export */ ZL: function() { return /* binding */ BarElement; }, 11/* harmony export */ f$: function() { return /* binding */ LinearScale; }, 12/* harmony export */ kL: function() { return /* binding */ Chart; }, 13/* harmony export */ u: function() { return /* binding */ plugin_tooltip; }, 14/* harmony export */ uw: function() { return /* binding */ CategoryScale; }, 15/* harmony export */ vn: function() { return /* binding */ BarController; } 16/* harmony export */ }); 17/* unused harmony exports Animation, Animations, ArcElement, BasePlatform, BasicPlatform, BubbleController, Colors, DatasetController, Decimation, DomPlatform, DoughnutController, Element, Filler, Interaction, LineController, LineElement, LogarithmicScale, PieController, PointElement, PolarAreaController, RadarController, RadialLinearScale, Scale, ScatterController, SubTitle, TimeScale, TimeSeriesScale, Title, _adapters, _detectPlatform, animator, controllers, elements, layouts, plugins, registerables, registry, scales */ 18/* harmony import */ var _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(95411); 19/*! 20 * Chart.js v4.5.1 21 * https://www.chartjs.org 22 * (c) 2025 Chart.js Contributors 23 * Released under the MIT License 24 */ 25 26 27 28class Animator { 29 constructor(){ 30 this._request = null; 31 this._charts = new Map(); 32 this._running = false; 33 this._lastDate = undefined; 34 } 35 _notify(chart, anims, date, type) { 36 const callbacks = anims.listeners[type]; 37 const numSteps = anims.duration; 38 callbacks.forEach((fn)=>fn({ 39 chart, 40 initial: anims.initial, 41 numSteps, 42 currentStep: Math.min(date - anims.start, numSteps) 43 })); 44 } 45 _refresh() { 46 if (this._request) { 47 return; 48 } 49 this._running = true; 50 this._request = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.r.call(window, ()=>{ 51 this._update(); 52 this._request = null; 53 if (this._running) { 54 this._refresh(); 55 } 56 }); 57 } 58 _update(date = Date.now()) { 59 let remaining = 0; 60 this._charts.forEach((anims, chart)=>{ 61 if (!anims.running || !anims.items.length) { 62 return; 63 } 64 const items = anims.items; 65 let i = items.length - 1; 66 let draw = false; 67 let item; 68 for(; i >= 0; --i){ 69 item = items[i]; 70 if (item._active) { 71 if (item._total > anims.duration) { 72 anims.duration = item._total; 73 } 74 item.tick(date); 75 draw = true; 76 } else { 77 items[i] = items[items.length - 1]; 78 items.pop(); 79 } 80 } 81 if (draw) { 82 chart.draw(); 83 this._notify(chart, anims, date, 'progress'); 84 } 85 if (!items.length) { 86 anims.running = false; 87 this._notify(chart, anims, date, 'complete'); 88 anims.initial = false; 89 } 90 remaining += items.length; 91 }); 92 this._lastDate = date; 93 if (remaining === 0) { 94 this._running = false;
vendor: 51,594 bytes, lines 95-1570
95 } 96 } 97 _getAnims(chart) { 98 const charts = this._charts; 99 let anims = charts.get(chart); 100 if (!anims) { 101 anims = { 102 running: false, 103 initial: true, 104 items: [], 105 listeners: { 106 complete: [], 107 progress: [] 108 } 109 }; 110 charts.set(chart, anims); 111 } 112 return anims; 113 } 114 listen(chart, event, cb) { 115 this._getAnims(chart).listeners[event].push(cb); 116 } 117 add(chart, items) { 118 if (!items || !items.length) { 119 return; 120 } 121 this._getAnims(chart).items.push(...items); 122 } 123 has(chart) { 124 return this._getAnims(chart).items.length > 0; 125 } 126 start(chart) { 127 const anims = this._charts.get(chart); 128 if (!anims) { 129 return; 130 } 131 anims.running = true; 132 anims.start = Date.now(); 133 anims.duration = anims.items.reduce((acc, cur)=>Math.max(acc, cur._duration), 0); 134 this._refresh(); 135 } 136 running(chart) { 137 if (!this._running) { 138 return false; 139 } 140 const anims = this._charts.get(chart); 141 if (!anims || !anims.running || !anims.items.length) { 142 return false; 143 } 144 return true; 145 } 146 stop(chart) { 147 const anims = this._charts.get(chart); 148 if (!anims || !anims.items.length) { 149 return; 150 } 151 const items = anims.items; 152 let i = items.length - 1; 153 for(; i >= 0; --i){ 154 items[i].cancel(); 155 } 156 anims.items = []; 157 this._notify(chart, anims, Date.now(), 'complete'); 158 } 159 remove(chart) { 160 return this._charts.delete(chart); 161 } 162} 163var animator = /* #__PURE__ */ new Animator(); 164 165const transparent = 'transparent'; 166const interpolators = { 167 boolean (from, to, factor) { 168 return factor > 0.5 ? to : from; 169 }, 170 color (from, to, factor) { 171 const c0 = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.c)(from || transparent); 172 const c1 = c0.valid && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.c)(to || transparent); 173 return c1 && c1.valid ? c1.mix(c0, factor).hexString() : to; 174 }, 175 number (from, to, factor) { 176 return from + (to - from) * factor; 177 } 178}; 179class Animation { 180 constructor(cfg, target, prop, to){ 181 const currentValue = target[prop]; 182 to = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a)([ 183 cfg.to, 184 to, 185 currentValue, 186 cfg.from 187 ]); 188 const from = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a)([ 189 cfg.from, 190 currentValue, 191 to 192 ]); 193 this._active = true; 194 this._fn = cfg.fn || interpolators[cfg.type || typeof from]; 195 this._easing = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.e[cfg.easing] || _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.e.linear; 196 this._start = Math.floor(Date.now() + (cfg.delay || 0)); 197 this._duration = this._total = Math.floor(cfg.duration); 198 this._loop = !!cfg.loop; 199 this._target = target; 200 this._prop = prop; 201 this._from = from; 202 this._to = to; 203 this._promises = undefined; 204 } 205 active() { 206 return this._active; 207 } 208 update(cfg, to, date) { 209 if (this._active) { 210 this._notify(false); 211 const currentValue = this._target[this._prop]; 212 const elapsed = date - this._start; 213 const remain = this._duration - elapsed; 214 this._start = date; 215 this._duration = Math.floor(Math.max(remain, cfg.duration)); 216 this._total += elapsed; 217 this._loop = !!cfg.loop; 218 this._to = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a)([ 219 cfg.to, 220 to, 221 currentValue, 222 cfg.from 223 ]); 224 this._from = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a)([ 225 cfg.from, 226 currentValue, 227 to 228 ]); 229 } 230 } 231 cancel() { 232 if (this._active) { 233 this.tick(Date.now()); 234 this._active = false; 235 this._notify(false); 236 } 237 } 238 tick(date) { 239 const elapsed = date - this._start; 240 const duration = this._duration; 241 const prop = this._prop; 242 const from = this._from; 243 const loop = this._loop; 244 const to = this._to; 245 let factor; 246 this._active = from !== to && (loop || elapsed < duration); 247 if (!this._active) { 248 this._target[prop] = to; 249 this._notify(true); 250 return; 251 } 252 if (elapsed < 0) { 253 this._target[prop] = from; 254 return; 255 } 256 factor = elapsed / duration % 2; 257 factor = loop && factor > 1 ? 2 - factor : factor; 258 factor = this._easing(Math.min(1, Math.max(0, factor))); 259 this._target[prop] = this._fn(from, to, factor); 260 } 261 wait() { 262 const promises = this._promises || (this._promises = []); 263 return new Promise((res, rej)=>{ 264 promises.push({ 265 res, 266 rej 267 }); 268 }); 269 } 270 _notify(resolved) { 271 const method = resolved ? 'res' : 'rej'; 272 const promises = this._promises || []; 273 for(let i = 0; i < promises.length; i++){ 274 promises[i][method](); 275 } 276 } 277} 278 279class Animations { 280 constructor(chart, config){ 281 this._chart = chart; 282 this._properties = new Map(); 283 this.configure(config); 284 } 285 configure(config) { 286 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(config)) { 287 return; 288 } 289 const animationOptions = Object.keys(_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.animation); 290 const animatedProps = this._properties; 291 Object.getOwnPropertyNames(config).forEach((key)=>{ 292 const cfg = config[key]; 293 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(cfg)) { 294 return; 295 } 296 const resolved = {}; 297 for (const option of animationOptions){ 298 resolved[option] = cfg[option]; 299 } 300 ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(cfg.properties) && cfg.properties || [ 301 key 302 ]).forEach((prop)=>{ 303 if (prop === key || !animatedProps.has(prop)) { 304 animatedProps.set(prop, resolved); 305 } 306 }); 307 }); 308 } 309 _animateOptions(target, values) { 310 const newOptions = values.options; 311 const options = resolveTargetOptions(target, newOptions); 312 if (!options) { 313 return []; 314 } 315 const animations = this._createAnimations(options, newOptions); 316 if (newOptions.$shared) { 317 awaitAll(target.options.$animations, newOptions).then(()=>{ 318 target.options = newOptions; 319 }, ()=>{ 320 }); 321 } 322 return animations; 323 } 324 _createAnimations(target, values) { 325 const animatedProps = this._properties; 326 const animations = []; 327 const running = target.$animations || (target.$animations = {}); 328 const props = Object.keys(values); 329 const date = Date.now(); 330 let i; 331 for(i = props.length - 1; i >= 0; --i){ 332 const prop = props[i]; 333 if (prop.charAt(0) === '$') { 334 continue; 335 } 336 if (prop === 'options') { 337 animations.push(...this._animateOptions(target, values)); 338 continue; 339 } 340 const value = values[prop]; 341 let animation = running[prop]; 342 const cfg = animatedProps.get(prop); 343 if (animation) { 344 if (cfg && animation.active()) { 345 animation.update(cfg, value, date); 346 continue; 347 } else { 348 animation.cancel(); 349 } 350 } 351 if (!cfg || !cfg.duration) { 352 target[prop] = value; 353 continue; 354 } 355 running[prop] = animation = new Animation(cfg, target, prop, value); 356 animations.push(animation); 357 } 358 return animations; 359 } 360 update(target, values) { 361 if (this._properties.size === 0) { 362 Object.assign(target, values); 363 return; 364 } 365 const animations = this._createAnimations(target, values); 366 if (animations.length) { 367 animator.add(this._chart, animations); 368 return true; 369 } 370 } 371} 372function awaitAll(animations, properties) { 373 const running = []; 374 const keys = Object.keys(properties); 375 for(let i = 0; i < keys.length; i++){ 376 const anim = animations[keys[i]]; 377 if (anim && anim.active()) { 378 running.push(anim.wait()); 379 } 380 } 381 return Promise.all(running); 382} 383function resolveTargetOptions(target, newOptions) { 384 if (!newOptions) { 385 return; 386 } 387 let options = target.options; 388 if (!options) { 389 target.options = newOptions; 390 return; 391 } 392 if (options.$shared) { 393 target.options = options = Object.assign({}, options, { 394 $shared: false, 395 $animations: {} 396 }); 397 } 398 return options; 399} 400 401function scaleClip(scale, allowedOverflow) { 402 const opts = scale && scale.options || {}; 403 const reverse = opts.reverse; 404 const min = opts.min === undefined ? allowedOverflow : 0; 405 const max = opts.max === undefined ? allowedOverflow : 0; 406 return { 407 start: reverse ? max : min, 408 end: reverse ? min : max 409 }; 410} 411function defaultClip(xScale, yScale, allowedOverflow) { 412 if (allowedOverflow === false) { 413 return false; 414 } 415 const x = scaleClip(xScale, allowedOverflow); 416 const y = scaleClip(yScale, allowedOverflow); 417 return { 418 top: y.end, 419 right: x.end, 420 bottom: y.start, 421 left: x.start 422 }; 423} 424function toClip(value) { 425 let t, r, b, l; 426 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(value)) { 427 t = value.top; 428 r = value.right; 429 b = value.bottom; 430 l = value.left; 431 } else { 432 t = r = b = l = value; 433 } 434 return { 435 top: t, 436 right: r, 437 bottom: b, 438 left: l, 439 disabled: value === false 440 }; 441} 442function getSortedDatasetIndices(chart, filterVisible) { 443 const keys = []; 444 const metasets = chart._getSortedDatasetMetas(filterVisible); 445 let i, ilen; 446 for(i = 0, ilen = metasets.length; i < ilen; ++i){ 447 keys.push(metasets[i].index); 448 } 449 return keys; 450} 451function applyStack(stack, value, dsIndex, options = {}) { 452 const keys = stack.keys; 453 const singleMode = options.mode === 'single'; 454 let i, ilen, datasetIndex, otherValue; 455 if (value === null) { 456 return; 457 } 458 let found = false; 459 for(i = 0, ilen = keys.length; i < ilen; ++i){ 460 datasetIndex = +keys[i]; 461 if (datasetIndex === dsIndex) { 462 found = true; 463 if (options.all) { 464 continue; 465 } 466 break; 467 } 468 otherValue = stack.values[datasetIndex]; 469 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(otherValue) && (singleMode || value === 0 || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(value) === (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(otherValue))) { 470 value += otherValue; 471 } 472 } 473 if (!found && !options.all) { 474 return 0; 475 } 476 return value; 477} 478function convertObjectDataToArray(data, meta) { 479 const { iScale , vScale } = meta; 480 const iAxisKey = iScale.axis === 'x' ? 'x' : 'y'; 481 const vAxisKey = vScale.axis === 'x' ? 'x' : 'y'; 482 const keys = Object.keys(data); 483 const adata = new Array(keys.length); 484 let i, ilen, key; 485 for(i = 0, ilen = keys.length; i < ilen; ++i){ 486 key = keys[i]; 487 adata[i] = { 488 [iAxisKey]: key, 489 [vAxisKey]: data[key] 490 }; 491 } 492 return adata; 493} 494function isStacked(scale, meta) { 495 const stacked = scale && scale.options.stacked; 496 return stacked || stacked === undefined && meta.stack !== undefined; 497} 498function getStackKey(indexScale, valueScale, meta) { 499 return `${indexScale.id}.${valueScale.id}.${meta.stack || meta.type}`; 500} 501function getUserBounds(scale) { 502 const { min , max , minDefined , maxDefined } = scale.getUserBounds(); 503 return { 504 min: minDefined ? min : Number.NEGATIVE_INFINITY, 505 max: maxDefined ? max : Number.POSITIVE_INFINITY 506 }; 507} 508function getOrCreateStack(stacks, stackKey, indexValue) { 509 const subStack = stacks[stackKey] || (stacks[stackKey] = {}); 510 return subStack[indexValue] || (subStack[indexValue] = {}); 511} 512function getLastIndexInStack(stack, vScale, positive, type) { 513 for (const meta of vScale.getMatchingVisibleMetas(type).reverse()){ 514 const value = stack[meta.index]; 515 if (positive && value > 0 || !positive && value < 0) { 516 return meta.index; 517 } 518 } 519 return null; 520} 521function updateStacks(controller, parsed) { 522 const { chart , _cachedMeta: meta } = controller; 523 const stacks = chart._stacks || (chart._stacks = {}); 524 const { iScale , vScale , index: datasetIndex } = meta; 525 const iAxis = iScale.axis; 526 const vAxis = vScale.axis; 527 const key = getStackKey(iScale, vScale, meta); 528 const ilen = parsed.length; 529 let stack; 530 for(let i = 0; i < ilen; ++i){ 531 const item = parsed[i]; 532 const { [iAxis]: index , [vAxis]: value } = item; 533 const itemStacks = item._stacks || (item._stacks = {}); 534 stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, index); 535 stack[datasetIndex] = value; 536 stack._top = getLastIndexInStack(stack, vScale, true, meta.type); 537 stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type); 538 const visualValues = stack._visualValues || (stack._visualValues = {}); 539 visualValues[datasetIndex] = value; 540 } 541} 542function getFirstScaleId(chart, axis) { 543 const scales = chart.scales; 544 return Object.keys(scales).filter((key)=>scales[key].axis === axis).shift(); 545} 546function createDatasetContext(parent, index) { 547 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(parent, { 548 active: false, 549 dataset: undefined, 550 datasetIndex: index, 551 index, 552 mode: 'default', 553 type: 'dataset' 554 }); 555} 556function createDataContext(parent, index, element) { 557 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(parent, { 558 active: false, 559 dataIndex: index, 560 parsed: undefined, 561 raw: undefined, 562 element, 563 index, 564 mode: 'default', 565 type: 'data' 566 }); 567} 568function clearStacks(meta, items) { 569 const datasetIndex = meta.controller.index; 570 const axis = meta.vScale && meta.vScale.axis; 571 if (!axis) { 572 return; 573 } 574 items = items || meta._parsed; 575 for (const parsed of items){ 576 const stacks = parsed._stacks; 577 if (!stacks || stacks[axis] === undefined || stacks[axis][datasetIndex] === undefined) { 578 return; 579 } 580 delete stacks[axis][datasetIndex]; 581 if (stacks[axis]._visualValues !== undefined && stacks[axis]._visualValues[datasetIndex] !== undefined) { 582 delete stacks[axis]._visualValues[datasetIndex]; 583 } 584 } 585} 586const isDirectUpdateMode = (mode)=>mode === 'reset' || mode === 'none'; 587const cloneIfNotShared = (cached, shared)=>shared ? cached : Object.assign({}, cached); 588const createStack = (canStack, meta, chart)=>canStack && !meta.hidden && meta._stacked && { 589 keys: getSortedDatasetIndices(chart, true), 590 values: null 591 }; 592class DatasetController { 593 static defaults = {}; 594 static datasetElementType = null; 595 static dataElementType = null; 596 constructor(chart, datasetIndex){ 597 this.chart = chart; 598 this._ctx = chart.ctx; 599 this.index = datasetIndex; 600 this._cachedDataOpts = {}; 601 this._cachedMeta = this.getMeta(); 602 this._type = this._cachedMeta.type; 603 this.options = undefined; 604 this._parsing = false; 605 this._data = undefined; 606 this._objectData = undefined; 607 this._sharedOptions = undefined; 608 this._drawStart = undefined; 609 this._drawCount = undefined; 610 this.enableOptionSharing = false; 611 this.supportsDecimation = false; 612 this.$context = undefined; 613 this._syncList = []; 614 this.datasetElementType = new.target.datasetElementType; 615 this.dataElementType = new.target.dataElementType; 616 this.initialize(); 617 } 618 initialize() { 619 const meta = this._cachedMeta; 620 this.configure(); 621 this.linkScales(); 622 meta._stacked = isStacked(meta.vScale, meta); 623 this.addElements(); 624 if (this.options.fill && !this.chart.isPluginEnabled('filler')) { 625 console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options"); 626 } 627 } 628 updateIndex(datasetIndex) { 629 if (this.index !== datasetIndex) { 630 clearStacks(this._cachedMeta); 631 } 632 this.index = datasetIndex; 633 } 634 linkScales() { 635 const chart = this.chart; 636 const meta = this._cachedMeta; 637 const dataset = this.getDataset(); 638 const chooseId = (axis, x, y, r)=>axis === 'x' ? x : axis === 'r' ? r : y; 639 const xid = meta.xAxisID = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(dataset.xAxisID, getFirstScaleId(chart, 'x')); 640 const yid = meta.yAxisID = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(dataset.yAxisID, getFirstScaleId(chart, 'y')); 641 const rid = meta.rAxisID = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(dataset.rAxisID, getFirstScaleId(chart, 'r')); 642 const indexAxis = meta.indexAxis; 643 const iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid); 644 const vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid); 645 meta.xScale = this.getScaleForId(xid); 646 meta.yScale = this.getScaleForId(yid); 647 meta.rScale = this.getScaleForId(rid); 648 meta.iScale = this.getScaleForId(iid); 649 meta.vScale = this.getScaleForId(vid); 650 } 651 getDataset() { 652 return this.chart.data.datasets[this.index]; 653 } 654 getMeta() { 655 return this.chart.getDatasetMeta(this.index); 656 } 657 getScaleForId(scaleID) { 658 return this.chart.scales[scaleID]; 659 } 660 _getOtherScale(scale) { 661 const meta = this._cachedMeta; 662 return scale === meta.iScale ? meta.vScale : meta.iScale; 663 } 664 reset() { 665 this._update('reset'); 666 } 667 _destroy() { 668 const meta = this._cachedMeta; 669 if (this._data) { 670 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.u)(this._data, this); 671 } 672 if (meta._stacked) { 673 clearStacks(meta); 674 } 675 } 676 _dataCheck() { 677 const dataset = this.getDataset(); 678 const data = dataset.data || (dataset.data = []); 679 const _data = this._data; 680 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(data)) { 681 const meta = this._cachedMeta; 682 this._data = convertObjectDataToArray(data, meta); 683 } else if (_data !== data) { 684 if (_data) { 685 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.u)(_data, this); 686 const meta = this._cachedMeta; 687 clearStacks(meta); 688 meta._parsed = []; 689 } 690 if (data && Object.isExtensible(data)) { 691 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.l)(data, this); 692 } 693 this._syncList = []; 694 this._data = data; 695 } 696 } 697 addElements() { 698 const meta = this._cachedMeta; 699 this._dataCheck(); 700 if (this.datasetElementType) { 701 meta.dataset = new this.datasetElementType(); 702 } 703 } 704 buildOrUpdateElements(resetNewElements) { 705 const meta = this._cachedMeta; 706 const dataset = this.getDataset(); 707 let stackChanged = false; 708 this._dataCheck(); 709 const oldStacked = meta._stacked; 710 meta._stacked = isStacked(meta.vScale, meta); 711 if (meta.stack !== dataset.stack) { 712 stackChanged = true; 713 clearStacks(meta); 714 meta.stack = dataset.stack; 715 } 716 this._resyncElements(resetNewElements); 717 if (stackChanged || oldStacked !== meta._stacked) { 718 updateStacks(this, meta._parsed); 719 meta._stacked = isStacked(meta.vScale, meta); 720 } 721 } 722 configure() { 723 const config = this.chart.config; 724 const scopeKeys = config.datasetScopeKeys(this._type); 725 const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true); 726 this.options = config.createResolver(scopes, this.getContext()); 727 this._parsing = this.options.parsing; 728 this._cachedDataOpts = {}; 729 } 730 parse(start, count) { 731 const { _cachedMeta: meta , _data: data } = this; 732 const { iScale , _stacked } = meta; 733 const iAxis = iScale.axis; 734 let sorted = start === 0 && count === data.length ? true : meta._sorted; 735 let prev = start > 0 && meta._parsed[start - 1]; 736 let i, cur, parsed; 737 if (this._parsing === false) { 738 meta._parsed = data; 739 meta._sorted = true; 740 parsed = data; 741 } else { 742 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(data[start])) { 743 parsed = this.parseArrayData(meta, data, start, count); 744 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(data[start])) { 745 parsed = this.parseObjectData(meta, data, start, count); 746 } else { 747 parsed = this.parsePrimitiveData(meta, data, start, count); 748 } 749 const isNotInOrderComparedToPrev = ()=>cur[iAxis] === null || prev && cur[iAxis] < prev[iAxis]; 750 for(i = 0; i < count; ++i){ 751 meta._parsed[i + start] = cur = parsed[i]; 752 if (sorted) { 753 if (isNotInOrderComparedToPrev()) { 754 sorted = false; 755 } 756 prev = cur; 757 } 758 } 759 meta._sorted = sorted; 760 } 761 if (_stacked) { 762 updateStacks(this, parsed); 763 } 764 } 765 parsePrimitiveData(meta, data, start, count) { 766 const { iScale , vScale } = meta; 767 const iAxis = iScale.axis; 768 const vAxis = vScale.axis; 769 const labels = iScale.getLabels(); 770 const singleScale = iScale === vScale; 771 const parsed = new Array(count); 772 let i, ilen, index; 773 for(i = 0, ilen = count; i < ilen; ++i){ 774 index = i + start; 775 parsed[i] = { 776 [iAxis]: singleScale || iScale.parse(labels[index], index), 777 [vAxis]: vScale.parse(data[index], index) 778 }; 779 } 780 return parsed; 781 } 782 parseArrayData(meta, data, start, count) { 783 const { xScale , yScale } = meta; 784 const parsed = new Array(count); 785 let i, ilen, index, item; 786 for(i = 0, ilen = count; i < ilen; ++i){ 787 index = i + start; 788 item = data[index]; 789 parsed[i] = { 790 x: xScale.parse(item[0], index), 791 y: yScale.parse(item[1], index) 792 }; 793 } 794 return parsed; 795 } 796 parseObjectData(meta, data, start, count) { 797 const { xScale , yScale } = meta; 798 const { xAxisKey ='x' , yAxisKey ='y' } = this._parsing; 799 const parsed = new Array(count); 800 let i, ilen, index, item; 801 for(i = 0, ilen = count; i < ilen; ++i){ 802 index = i + start; 803 item = data[index]; 804 parsed[i] = { 805 x: xScale.parse((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.f)(item, xAxisKey), index), 806 y: yScale.parse((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.f)(item, yAxisKey), index) 807 }; 808 } 809 return parsed; 810 } 811 getParsed(index) { 812 return this._cachedMeta._parsed[index]; 813 } 814 getDataElement(index) { 815 return this._cachedMeta.data[index]; 816 } 817 applyStack(scale, parsed, mode) { 818 const chart = this.chart; 819 const meta = this._cachedMeta; 820 const value = parsed[scale.axis]; 821 const stack = { 822 keys: getSortedDatasetIndices(chart, true), 823 values: parsed._stacks[scale.axis]._visualValues 824 }; 825 return applyStack(stack, value, meta.index, { 826 mode 827 }); 828 } 829 updateRangeFromParsed(range, scale, parsed, stack) { 830 const parsedValue = parsed[scale.axis]; 831 let value = parsedValue === null ? NaN : parsedValue; 832 const values = stack && parsed._stacks[scale.axis]; 833 if (stack && values) { 834 stack.values = values; 835 value = applyStack(stack, parsedValue, this._cachedMeta.index); 836 } 837 range.min = Math.min(range.min, value); 838 range.max = Math.max(range.max, value); 839 } 840 getMinMax(scale, canStack) { 841 const meta = this._cachedMeta; 842 const _parsed = meta._parsed; 843 const sorted = meta._sorted && scale === meta.iScale; 844 const ilen = _parsed.length; 845 const otherScale = this._getOtherScale(scale); 846 const stack = createStack(canStack, meta, this.chart); 847 const range = { 848 min: Number.POSITIVE_INFINITY, 849 max: Number.NEGATIVE_INFINITY 850 }; 851 const { min: otherMin , max: otherMax } = getUserBounds(otherScale); 852 let i, parsed; 853 function _skip() { 854 parsed = _parsed[i]; 855 const otherValue = parsed[otherScale.axis]; 856 return !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue; 857 } 858 for(i = 0; i < ilen; ++i){ 859 if (_skip()) { 860 continue; 861 } 862 this.updateRangeFromParsed(range, scale, parsed, stack); 863 if (sorted) { 864 break; 865 } 866 } 867 if (sorted) { 868 for(i = ilen - 1; i >= 0; --i){ 869 if (_skip()) { 870 continue; 871 } 872 this.updateRangeFromParsed(range, scale, parsed, stack); 873 break; 874 } 875 } 876 return range; 877 } 878 getAllParsedValues(scale) { 879 const parsed = this._cachedMeta._parsed; 880 const values = []; 881 let i, ilen, value; 882 for(i = 0, ilen = parsed.length; i < ilen; ++i){ 883 value = parsed[i][scale.axis]; 884 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(value)) { 885 values.push(value); 886 } 887 } 888 return values; 889 } 890 getMaxOverflow() { 891 return false; 892 } 893 getLabelAndValue(index) { 894 const meta = this._cachedMeta; 895 const iScale = meta.iScale; 896 const vScale = meta.vScale; 897 const parsed = this.getParsed(index); 898 return { 899 label: iScale ? '' + iScale.getLabelForValue(parsed[iScale.axis]) : '', 900 value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : '' 901 }; 902 } 903 _update(mode) { 904 const meta = this._cachedMeta; 905 this.update(mode || 'default'); 906 meta._clip = toClip((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow()))); 907 } 908 update(mode) {} 909 draw() { 910 const ctx = this._ctx; 911 const chart = this.chart; 912 const meta = this._cachedMeta; 913 const elements = meta.data || []; 914 const area = chart.chartArea; 915 const active = []; 916 const start = this._drawStart || 0; 917 const count = this._drawCount || elements.length - start; 918 const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop; 919 let i; 920 if (meta.dataset) { 921 meta.dataset.draw(ctx, area, start, count); 922 } 923 for(i = start; i < start + count; ++i){ 924 const element = elements[i]; 925 if (element.hidden) { 926 continue; 927 } 928 if (element.active && drawActiveElementsOnTop) { 929 active.push(element); 930 } else { 931 element.draw(ctx, area); 932 } 933 } 934 for(i = 0; i < active.length; ++i){ 935 active[i].draw(ctx, area); 936 } 937 } 938 getStyle(index, active) { 939 const mode = active ? 'active' : 'default'; 940 return index === undefined && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(mode) : this.resolveDataElementOptions(index || 0, mode); 941 } 942 getContext(index, active, mode) { 943 const dataset = this.getDataset(); 944 let context; 945 if (index >= 0 && index < this._cachedMeta.data.length) { 946 const element = this._cachedMeta.data[index]; 947 context = element.$context || (element.$context = createDataContext(this.getContext(), index, element)); 948 context.parsed = this.getParsed(index); 949 context.raw = dataset.data[index]; 950 context.index = context.dataIndex = index; 951 } else { 952 context = this.$context || (this.$context = createDatasetContext(this.chart.getContext(), this.index)); 953 context.dataset = dataset; 954 context.index = context.datasetIndex = this.index; 955 } 956 context.active = !!active; 957 context.mode = mode; 958 return context; 959 } 960 resolveDatasetElementOptions(mode) { 961 return this._resolveElementOptions(this.datasetElementType.id, mode); 962 } 963 resolveDataElementOptions(index, mode) { 964 return this._resolveElementOptions(this.dataElementType.id, mode, index); 965 } 966 _resolveElementOptions(elementType, mode = 'default', index) { 967 const active = mode === 'active'; 968 const cache = this._cachedDataOpts; 969 const cacheKey = elementType + '-' + mode; 970 const cached = cache[cacheKey]; 971 const sharing = this.enableOptionSharing && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.h)(index); 972 if (cached) { 973 return cloneIfNotShared(cached, sharing); 974 } 975 const config = this.chart.config; 976 const scopeKeys = config.datasetElementScopeKeys(this._type, elementType); 977 const prefixes = active ? [ 978 `${elementType}Hover`, 979 'hover', 980 elementType, 981 '' 982 ] : [ 983 elementType, 984 '' 985 ]; 986 const scopes = config.getOptionScopes(this.getDataset(), scopeKeys); 987 const names = Object.keys(_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.elements[elementType]); 988 const context = ()=>this.getContext(index, active, mode); 989 const values = config.resolveNamedOptions(scopes, names, context, prefixes); 990 if (values.$shared) { 991 values.$shared = sharing; 992 cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing)); 993 } 994 return values; 995 } 996 _resolveAnimations(index, transition, active) { 997 const chart = this.chart; 998 const cache = this._cachedDataOpts; 999 const cacheKey = `animation-${transition}`; 1000 const cached = cache[cacheKey]; 1001 if (cached) { 1002 return cached; 1003 } 1004 let options; 1005 if (chart.options.animation !== false) { 1006 const config = this.chart.config; 1007 const scopeKeys = config.datasetAnimationScopeKeys(this._type, transition); 1008 const scopes = config.getOptionScopes(this.getDataset(), scopeKeys); 1009 options = config.createResolver(scopes, this.getContext(index, active, transition)); 1010 } 1011 const animations = new Animations(chart, options && options.animations); 1012 if (options && options._cacheable) { 1013 cache[cacheKey] = Object.freeze(animations); 1014 } 1015 return animations; 1016 } 1017 getSharedOptions(options) { 1018 if (!options.$shared) { 1019 return; 1020 } 1021 return this._sharedOptions || (this._sharedOptions = Object.assign({}, options)); 1022 } 1023 includeOptions(mode, sharedOptions) { 1024 return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled; 1025 } 1026 _getSharedOptions(start, mode) { 1027 const firstOpts = this.resolveDataElementOptions(start, mode); 1028 const previouslySharedOptions = this._sharedOptions; 1029 const sharedOptions = this.getSharedOptions(firstOpts); 1030 const includeOptions = this.includeOptions(mode, sharedOptions) || sharedOptions !== previouslySharedOptions; 1031 this.updateSharedOptions(sharedOptions, mode, firstOpts); 1032 return { 1033 sharedOptions, 1034 includeOptions 1035 }; 1036 } 1037 updateElement(element, index, properties, mode) { 1038 if (isDirectUpdateMode(mode)) { 1039 Object.assign(element, properties); 1040 } else { 1041 this._resolveAnimations(index, mode).update(element, properties); 1042 } 1043 } 1044 updateSharedOptions(sharedOptions, mode, newOptions) { 1045 if (sharedOptions && !isDirectUpdateMode(mode)) { 1046 this._resolveAnimations(undefined, mode).update(sharedOptions, newOptions); 1047 } 1048 } 1049 _setStyle(element, index, mode, active) { 1050 element.active = active; 1051 const options = this.getStyle(index, active); 1052 this._resolveAnimations(index, mode, active).update(element, { 1053 options: !active && this.getSharedOptions(options) || options 1054 }); 1055 } 1056 removeHoverStyle(element, datasetIndex, index) { 1057 this._setStyle(element, index, 'active', false); 1058 } 1059 setHoverStyle(element, datasetIndex, index) { 1060 this._setStyle(element, index, 'active', true); 1061 } 1062 _removeDatasetHoverStyle() { 1063 const element = this._cachedMeta.dataset; 1064 if (element) { 1065 this._setStyle(element, undefined, 'active', false); 1066 } 1067 } 1068 _setDatasetHoverStyle() { 1069 const element = this._cachedMeta.dataset; 1070 if (element) { 1071 this._setStyle(element, undefined, 'active', true); 1072 } 1073 } 1074 _resyncElements(resetNewElements) { 1075 const data = this._data; 1076 const elements = this._cachedMeta.data; 1077 for (const [method, arg1, arg2] of this._syncList){ 1078 this[method](arg1, arg2); 1079 } 1080 this._syncList = []; 1081 const numMeta = elements.length; 1082 const numData = data.length; 1083 const count = Math.min(numData, numMeta); 1084 if (count) { 1085 this.parse(0, count); 1086 } 1087 if (numData > numMeta) { 1088 this._insertElements(numMeta, numData - numMeta, resetNewElements); 1089 } else if (numData < numMeta) { 1090 this._removeElements(numData, numMeta - numData); 1091 } 1092 } 1093 _insertElements(start, count, resetNewElements = true) { 1094 const meta = this._cachedMeta; 1095 const data = meta.data; 1096 const end = start + count; 1097 let i; 1098 const move = (arr)=>{ 1099 arr.length += count; 1100 for(i = arr.length - 1; i >= end; i--){ 1101 arr[i] = arr[i - count]; 1102 } 1103 }; 1104 move(data); 1105 for(i = start; i < end; ++i){ 1106 data[i] = new this.dataElementType(); 1107 } 1108 if (this._parsing) { 1109 move(meta._parsed); 1110 } 1111 this.parse(start, count); 1112 if (resetNewElements) { 1113 this.updateElements(data, start, count, 'reset'); 1114 } 1115 } 1116 updateElements(element, start, count, mode) {} 1117 _removeElements(start, count) { 1118 const meta = this._cachedMeta; 1119 if (this._parsing) { 1120 const removed = meta._parsed.splice(start, count); 1121 if (meta._stacked) { 1122 clearStacks(meta, removed); 1123 } 1124 } 1125 meta.data.splice(start, count); 1126 } 1127 _sync(args) { 1128 if (this._parsing) { 1129 this._syncList.push(args); 1130 } else { 1131 const [method, arg1, arg2] = args; 1132 this[method](arg1, arg2); 1133 } 1134 this.chart._dataChanges.push([ 1135 this.index, 1136 ...args 1137 ]); 1138 } 1139 _onDataPush() { 1140 const count = arguments.length; 1141 this._sync([ 1142 '_insertElements', 1143 this.getDataset().data.length - count, 1144 count 1145 ]); 1146 } 1147 _onDataPop() { 1148 this._sync([ 1149 '_removeElements', 1150 this._cachedMeta.data.length - 1, 1151 1 1152 ]); 1153 } 1154 _onDataShift() { 1155 this._sync([ 1156 '_removeElements', 1157 0, 1158 1 1159 ]); 1160 } 1161 _onDataSplice(start, count) { 1162 if (count) { 1163 this._sync([ 1164 '_removeElements', 1165 start, 1166 count 1167 ]); 1168 } 1169 const newCount = arguments.length - 2; 1170 if (newCount) { 1171 this._sync([ 1172 '_insertElements', 1173 start, 1174 newCount 1175 ]); 1176 } 1177 } 1178 _onDataUnshift() { 1179 this._sync([ 1180 '_insertElements', 1181 0, 1182 arguments.length 1183 ]); 1184 } 1185} 1186 1187function getAllScaleValues(scale, type) { 1188 if (!scale._cache.$bar) { 1189 const visibleMetas = scale.getMatchingVisibleMetas(type); 1190 let values = []; 1191 for(let i = 0, ilen = visibleMetas.length; i < ilen; i++){ 1192 values = values.concat(visibleMetas[i].controller.getAllParsedValues(scale)); 1193 } 1194 scale._cache.$bar = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__._)(values.sort((a, b)=>a - b)); 1195 } 1196 return scale._cache.$bar; 1197} 1198 function computeMinSampleSize(meta) { 1199 const scale = meta.iScale; 1200 const values = getAllScaleValues(scale, meta.type); 1201 let min = scale._length; 1202 let i, ilen, curr, prev; 1203 const updateMinAndPrev = ()=>{ 1204 if (curr === 32767 || curr === -32768) { 1205 return; 1206 } 1207 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.h)(prev)) { 1208 min = Math.min(min, Math.abs(curr - prev) || min); 1209 } 1210 prev = curr; 1211 }; 1212 for(i = 0, ilen = values.length; i < ilen; ++i){ 1213 curr = scale.getPixelForValue(values[i]); 1214 updateMinAndPrev(); 1215 } 1216 prev = undefined; 1217 for(i = 0, ilen = scale.ticks.length; i < ilen; ++i){ 1218 curr = scale.getPixelForTick(i); 1219 updateMinAndPrev(); 1220 } 1221 return min; 1222} 1223 function computeFitCategoryTraits(index, ruler, options, stackCount) { 1224 const thickness = options.barThickness; 1225 let size, ratio; 1226 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(thickness)) { 1227 size = ruler.min * options.categoryPercentage; 1228 ratio = options.barPercentage; 1229 } else { 1230 size = thickness * stackCount; 1231 ratio = 1; 1232 } 1233 return { 1234 chunk: size / stackCount, 1235 ratio, 1236 start: ruler.pixels[index] - size / 2 1237 }; 1238} 1239 function computeFlexCategoryTraits(index, ruler, options, stackCount) { 1240 const pixels = ruler.pixels; 1241 const curr = pixels[index]; 1242 let prev = index > 0 ? pixels[index - 1] : null; 1243 let next = index < pixels.length - 1 ? pixels[index + 1] : null; 1244 const percent = options.categoryPercentage; 1245 if (prev === null) { 1246 prev = curr - (next === null ? ruler.end - ruler.start : next - curr); 1247 } 1248 if (next === null) { 1249 next = curr + curr - prev; 1250 } 1251 const start = curr - (curr - Math.min(prev, next)) / 2 * percent; 1252 const size = Math.abs(next - prev) / 2 * percent; 1253 return { 1254 chunk: size / stackCount, 1255 ratio: options.barPercentage, 1256 start 1257 }; 1258} 1259function parseFloatBar(entry, item, vScale, i) { 1260 const startValue = vScale.parse(entry[0], i); 1261 const endValue = vScale.parse(entry[1], i); 1262 const min = Math.min(startValue, endValue); 1263 const max = Math.max(startValue, endValue); 1264 let barStart = min; 1265 let barEnd = max; 1266 if (Math.abs(min) > Math.abs(max)) { 1267 barStart = max; 1268 barEnd = min; 1269 } 1270 item[vScale.axis] = barEnd; 1271 item._custom = { 1272 barStart, 1273 barEnd, 1274 start: startValue, 1275 end: endValue, 1276 min, 1277 max 1278 }; 1279} 1280function parseValue(entry, item, vScale, i) { 1281 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(entry)) { 1282 parseFloatBar(entry, item, vScale, i); 1283 } else { 1284 item[vScale.axis] = vScale.parse(entry, i); 1285 } 1286 return item; 1287} 1288function parseArrayOrPrimitive(meta, data, start, count) { 1289 const iScale = meta.iScale; 1290 const vScale = meta.vScale; 1291 const labels = iScale.getLabels(); 1292 const singleScale = iScale === vScale; 1293 const parsed = []; 1294 let i, ilen, item, entry; 1295 for(i = start, ilen = start + count; i < ilen; ++i){ 1296 entry = data[i]; 1297 item = {}; 1298 item[iScale.axis] = singleScale || iScale.parse(labels[i], i); 1299 parsed.push(parseValue(entry, item, vScale, i)); 1300 } 1301 return parsed; 1302} 1303function isFloatBar(custom) { 1304 return custom && custom.barStart !== undefined && custom.barEnd !== undefined; 1305} 1306function barSign(size, vScale, actualBase) { 1307 if (size !== 0) { 1308 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(size); 1309 } 1310 return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1); 1311} 1312function borderProps(properties) { 1313 let reverse, start, end, top, bottom; 1314 if (properties.horizontal) { 1315 reverse = properties.base > properties.x; 1316 start = 'left'; 1317 end = 'right'; 1318 } else { 1319 reverse = properties.base < properties.y; 1320 start = 'bottom'; 1321 end = 'top'; 1322 } 1323 if (reverse) { 1324 top = 'end'; 1325 bottom = 'start'; 1326 } else { 1327 top = 'start'; 1328 bottom = 'end'; 1329 } 1330 return { 1331 start, 1332 end, 1333 reverse, 1334 top, 1335 bottom 1336 }; 1337} 1338function setBorderSkipped(properties, options, stack, index) { 1339 let edge = options.borderSkipped; 1340 const res = {}; 1341 if (!edge) { 1342 properties.borderSkipped = res; 1343 return; 1344 } 1345 if (edge === true) { 1346 properties.borderSkipped = { 1347 top: true, 1348 right: true, 1349 bottom: true, 1350 left: true 1351 }; 1352 return; 1353 } 1354 const { start , end , reverse , top , bottom } = borderProps(properties); 1355 if (edge === 'middle' && stack) { 1356 properties.enableBorderRadius = true; 1357 if ((stack._top || 0) === index) { 1358 edge = top; 1359 } else if ((stack._bottom || 0) === index) { 1360 edge = bottom; 1361 } else { 1362 res[parseEdge(bottom, start, end, reverse)] = true; 1363 edge = top; 1364 } 1365 } 1366 res[parseEdge(edge, start, end, reverse)] = true; 1367 properties.borderSkipped = res; 1368} 1369function parseEdge(edge, a, b, reverse) { 1370 if (reverse) { 1371 edge = swap(edge, a, b); 1372 edge = startEnd(edge, b, a); 1373 } else { 1374 edge = startEnd(edge, a, b); 1375 } 1376 return edge; 1377} 1378function swap(orig, v1, v2) { 1379 return orig === v1 ? v2 : orig === v2 ? v1 : orig; 1380} 1381function startEnd(v, start, end) { 1382 return v === 'start' ? start : v === 'end' ? end : v; 1383} 1384function setInflateAmount(properties, { inflateAmount }, ratio) { 1385 properties.inflateAmount = inflateAmount === 'auto' ? ratio === 1 ? 0.33 : 0 : inflateAmount; 1386} 1387class BarController extends DatasetController { 1388 static id = 'bar'; 1389 static defaults = { 1390 datasetElementType: false, 1391 dataElementType: 'bar', 1392 categoryPercentage: 0.8, 1393 barPercentage: 0.9, 1394 grouped: true, 1395 animations: { 1396 numbers: { 1397 type: 'number', 1398 properties: [ 1399 'x', 1400 'y', 1401 'base', 1402 'width', 1403 'height' 1404 ] 1405 } 1406 } 1407 }; 1408 static overrides = { 1409 scales: { 1410 _index_: { 1411 type: 'category', 1412 offset: true, 1413 grid: { 1414 offset: true 1415 } 1416 }, 1417 _value_: { 1418 type: 'linear', 1419 beginAtZero: true 1420 } 1421 } 1422 }; 1423 parsePrimitiveData(meta, data, start, count) { 1424 return parseArrayOrPrimitive(meta, data, start, count); 1425 } 1426 parseArrayData(meta, data, start, count) { 1427 return parseArrayOrPrimitive(meta, data, start, count); 1428 } 1429 parseObjectData(meta, data, start, count) { 1430 const { iScale , vScale } = meta; 1431 const { xAxisKey ='x' , yAxisKey ='y' } = this._parsing; 1432 const iAxisKey = iScale.axis === 'x' ? xAxisKey : yAxisKey; 1433 const vAxisKey = vScale.axis === 'x' ? xAxisKey : yAxisKey; 1434 const parsed = []; 1435 let i, ilen, item, obj; 1436 for(i = start, ilen = start + count; i < ilen; ++i){ 1437 obj = data[i]; 1438 item = {}; 1439 item[iScale.axis] = iScale.parse((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.f)(obj, iAxisKey), i); 1440 parsed.push(parseValue((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.f)(obj, vAxisKey), item, vScale, i)); 1441 } 1442 return parsed; 1443 } 1444 updateRangeFromParsed(range, scale, parsed, stack) { 1445 super.updateRangeFromParsed(range, scale, parsed, stack); 1446 const custom = parsed._custom; 1447 if (custom && scale === this._cachedMeta.vScale) { 1448 range.min = Math.min(range.min, custom.min); 1449 range.max = Math.max(range.max, custom.max); 1450 } 1451 } 1452 getMaxOverflow() { 1453 return 0; 1454 } 1455 getLabelAndValue(index) { 1456 const meta = this._cachedMeta; 1457 const { iScale , vScale } = meta; 1458 const parsed = this.getParsed(index); 1459 const custom = parsed._custom; 1460 const value = isFloatBar(custom) ? '[' + custom.start + ', ' + custom.end + ']' : '' + vScale.getLabelForValue(parsed[vScale.axis]); 1461 return { 1462 label: '' + iScale.getLabelForValue(parsed[iScale.axis]), 1463 value 1464 }; 1465 } 1466 initialize() { 1467 this.enableOptionSharing = true; 1468 super.initialize(); 1469 const meta = this._cachedMeta; 1470 meta.stack = this.getDataset().stack; 1471 } 1472 update(mode) { 1473 const meta = this._cachedMeta; 1474 this.updateElements(meta.data, 0, meta.data.length, mode); 1475 } 1476 updateElements(bars, start, count, mode) { 1477 const reset = mode === 'reset'; 1478 const { index , _cachedMeta: { vScale } } = this; 1479 const base = vScale.getBasePixel(); 1480 const horizontal = vScale.isHorizontal(); 1481 const ruler = this._getRuler(); 1482 const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode); 1483 for(let i = start; i < start + count; i++){ 1484 const parsed = this.getParsed(i); 1485 const vpixels = reset || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(parsed[vScale.axis]) ? { 1486 base, 1487 head: base 1488 } : this._calculateBarValuePixels(i); 1489 const ipixels = this._calculateBarIndexPixels(i, ruler); 1490 const stack = (parsed._stacks || {})[vScale.axis]; 1491 const properties = { 1492 horizontal, 1493 base: vpixels.base, 1494 enableBorderRadius: !stack || isFloatBar(parsed._custom) || index === stack._top || index === stack._bottom, 1495 x: horizontal ? vpixels.head : ipixels.center, 1496 y: horizontal ? ipixels.center : vpixels.head, 1497 height: horizontal ? ipixels.size : Math.abs(vpixels.size), 1498 width: horizontal ? Math.abs(vpixels.size) : ipixels.size 1499 }; 1500 if (includeOptions) { 1501 properties.options = sharedOptions || this.resolveDataElementOptions(i, bars[i].active ? 'active' : mode); 1502 } 1503 const options = properties.options || bars[i].options; 1504 setBorderSkipped(properties, options, stack, index); 1505 setInflateAmount(properties, options, ruler.ratio); 1506 this.updateElement(bars[i], i, properties, mode); 1507 } 1508 } 1509 _getStacks(last, dataIndex) { 1510 const { iScale } = this._cachedMeta; 1511 const metasets = iScale.getMatchingVisibleMetas(this._type).filter((meta)=>meta.controller.options.grouped); 1512 const stacked = iScale.options.stacked; 1513 const stacks = []; 1514 const currentParsed = this._cachedMeta.controller.getParsed(dataIndex); 1515 const iScaleValue = currentParsed && currentParsed[iScale.axis]; 1516 const skipNull = (meta)=>{ 1517 const parsed = meta._parsed.find((item)=>item[iScale.axis] === iScaleValue); 1518 const val = parsed && parsed[meta.vScale.axis]; 1519 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(val) || isNaN(val)) { 1520 return true; 1521 } 1522 }; 1523 for (const meta of metasets){ 1524 if (dataIndex !== undefined && skipNull(meta)) { 1525 continue; 1526 } 1527 if (stacked === false || stacks.indexOf(meta.stack) === -1 || stacked === undefined && meta.stack === undefined) { 1528 stacks.push(meta.stack); 1529 } 1530 if (meta.index === last) { 1531 break; 1532 } 1533 } 1534 if (!stacks.length) { 1535 stacks.push(undefined); 1536 } 1537 return stacks; 1538 } 1539 _getStackCount(index) { 1540 return this._getStacks(undefined, index).length; 1541 } 1542 _getAxisCount() { 1543 return this._getAxis().length; 1544 } 1545 getFirstScaleIdForIndexAxis() { 1546 const scales = this.chart.scales; 1547 const indexScaleId = this.chart.options.indexAxis; 1548 return Object.keys(scales).filter((key)=>scales[key].axis === indexScaleId).shift(); 1549 } 1550 _getAxis() { 1551 const axis = {}; 1552 const firstScaleAxisId = this.getFirstScaleIdForIndexAxis(); 1553 for (const dataset of this.chart.data.datasets){ 1554 axis[(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(this.chart.options.indexAxis === 'x' ? dataset.xAxisID : dataset.yAxisID, firstScaleAxisId)] = true; 1555 } 1556 return Object.keys(axis); 1557 } 1558 _getStackIndex(datasetIndex, name, dataIndex) { 1559 const stacks = this._getStacks(datasetIndex, dataIndex); 1560 const index = name !== undefined ? stacks.indexOf(name) : -1; 1561 return index === -1 ? stacks.length - 1 : index; 1562 } 1563 _getRuler() { 1564 const opts = this.options; 1565 const meta = this._cachedMeta; 1566 const iScale = meta.iScale; 1567 const pixels = []; 1568 let i, ilen; 1569 for(i = 0, ilen = meta.data.length; i < ilen; ++i){ 1570 pixels.push(iScale.getPixelForValue(this.getParsed(i)[iScale.axis
1570], i)); 1571 } 1572 const barThickness = opts.barThickness; 1573 const min = barThickness || computeMinSampleSize(meta); 1574 return { 1575 min, 1576 pixels, 1577 start: iScale._startPixel, 1578 end: iScale._endPixel, 1579 stackCount: this._getStackCount(), 1580 scale: iScale, 1581 grouped: opts.grouped, 1582 ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage 1583 }; 1584 } 1585 _calculateBarValuePixels(index) { 1586 const { _cachedMeta: { vScale , _stacked , index: datasetIndex } , options: { base: baseValue , minBarLength } } = this; 1587 const actualBase = baseValue || 0; 1588 const parsed = this.getParsed(index); 1589 const custom = parsed._custom; 1590 const floating = isFloatBar(custom); 1591 let value = parsed[vScale.axis]; 1592 let start = 0; 1593 let length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value; 1594 let head, size; 1595 if (length !== value) { 1596 start = length - value; 1597 length = value; 1598 } 1599 if (floating) { 1600 value = custom.barStart; 1601 length = custom.barEnd - custom.barStart; 1602 if (value !== 0 && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(value) !== (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(custom.barEnd)) { 1603 start = 0; 1604 } 1605 start += value; 1606 } 1607 const startValue = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(baseValue) && !floating ? baseValue : start; 1608 let base = vScale.getPixelForValue(startValue); 1609 if (this.chart.getDataVisibility(index)) { 1610 head = vScale.getPixelForValue(start + length); 1611 } else { 1612 head = base; 1613 } 1614 size = head - base; 1615 if (Math.abs(size) < minBarLength) { 1616 size = barSign(size, vScale, actualBase) * minBarLength; 1617 if (value === actualBase) { 1618 base -= size / 2; 1619 } 1620 const startPixel = vScale.getPixelForDecimal(0); 1621 const endPixel = vScale.getPixelForDecimal(1); 1622 const min = Math.min(startPixel, endPixel); 1623 const max = Math.max(startPixel, endPixel); 1624 base = Math.max(Math.min(base, max), min); 1625 head = base + size; 1626 if (_stacked && !floating) { 1627 parsed._stacks[vScale.axis]._visualValues[datasetIndex] = vScale.getValueForPixel(head) - vScale.getValueForPixel(base); 1628 } 1629 } 1630 if (base === vScale.getPixelForValue(actualBase)) { 1631 const halfGrid = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(size) * vScale.getLineWidthForValue(actualBase) / 2; 1632 base += halfGrid; 1633 size -= halfGrid; 1634 } 1635 return { 1636 size, 1637 base, 1638 head, 1639 center: head + size / 2 1640 }; 1641 } 1642 _calculateBarIndexPixels(index, ruler) { 1643 const scale = ruler.scale; 1644 const options = this.options; 1645 const skipNull = options.skipNull; 1646 const maxBarThickness = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(options.maxBarThickness, Infinity); 1647 let center, size; 1648 const axisCount = this._getAxisCount(); 1649 if (ruler.grouped) { 1650 const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount; 1651 const range = options.barThickness === 'flex' ? computeFlexCategoryTraits(index, ruler, options, stackCount * axisCount) : computeFitCategoryTraits(index, ruler, options, stackCount * axisCount); 1652 const axisID = this.chart.options.indexAxis === 'x' ? this.getDataset().xAxisID : this.getDataset().yAxisID; 1653 const axisNumber = this._getAxis().indexOf((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(axisID, this.getFirstScaleIdForIndexAxis())); 1654 const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined) + axisNumber; 1655 center = range.start + range.chunk * stackIndex + range.chunk / 2; 1656 size = Math.min(maxBarThickness, range.chunk * range.ratio); 1657 } else { 1658 center = scale.getPixelForValue(this.getParsed(index)[scale.axis
vendor: 39,672 bytes, lines 1658-2684
1658], index); 1659 size = Math.min(maxBarThickness, ruler.min * ruler.ratio); 1660 } 1661 return { 1662 base: center - size / 2, 1663 head: center + size / 2, 1664 center, 1665 size 1666 }; 1667 } 1668 draw() { 1669 const meta = this._cachedMeta; 1670 const vScale = meta.vScale; 1671 const rects = meta.data; 1672 const ilen = rects.length; 1673 let i = 0; 1674 for(; i < ilen; ++i){ 1675 if (this.getParsed(i)[vScale.axis] !== null && !rects[i].hidden) { 1676 rects[i].draw(this._ctx); 1677 } 1678 } 1679 } 1680} 1681 1682class BubbleController extends DatasetController { 1683 static id = 'bubble'; 1684 static defaults = { 1685 datasetElementType: false, 1686 dataElementType: 'point', 1687 animations: { 1688 numbers: { 1689 type: 'number', 1690 properties: [ 1691 'x', 1692 'y', 1693 'borderWidth', 1694 'radius' 1695 ] 1696 } 1697 } 1698 }; 1699 static overrides = { 1700 scales: { 1701 x: { 1702 type: 'linear' 1703 }, 1704 y: { 1705 type: 'linear' 1706 } 1707 } 1708 }; 1709 initialize() { 1710 this.enableOptionSharing = true; 1711 super.initialize(); 1712 } 1713 parsePrimitiveData(meta, data, start, count) { 1714 const parsed = super.parsePrimitiveData(meta, data, start, count); 1715 for(let i = 0; i < parsed.length; i++){ 1716 parsed[i]._custom = this.resolveDataElementOptions(i + start).radius; 1717 } 1718 return parsed; 1719 } 1720 parseArrayData(meta, data, start, count) { 1721 const parsed = super.parseArrayData(meta, data, start, count); 1722 for(let i = 0; i < parsed.length; i++){ 1723 const item = data[start + i]; 1724 parsed[i]._custom = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(item[2], this.resolveDataElementOptions(i + start).radius); 1725 } 1726 return parsed; 1727 } 1728 parseObjectData(meta, data, start, count) { 1729 const parsed = super.parseObjectData(meta, data, start, count); 1730 for(let i = 0; i < parsed.length; i++){ 1731 const item = data[start + i]; 1732 parsed[i]._custom = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(item && item.r && +item.r, this.resolveDataElementOptions(i + start).radius); 1733 } 1734 return parsed; 1735 } 1736 getMaxOverflow() { 1737 const data = this._cachedMeta.data; 1738 let max = 0; 1739 for(let i = data.length - 1; i >= 0; --i){ 1740 max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2); 1741 } 1742 return max > 0 && max; 1743 } 1744 getLabelAndValue(index) { 1745 const meta = this._cachedMeta; 1746 const labels = this.chart.data.labels || []; 1747 const { xScale , yScale } = meta; 1748 const parsed = this.getParsed(index); 1749 const x = xScale.getLabelForValue(parsed.x); 1750 const y = yScale.getLabelForValue(parsed.y); 1751 const r = parsed._custom; 1752 return { 1753 label: labels[index] || '', 1754 value: '(' + x + ', ' + y + (r ? ', ' + r : '') + ')' 1755 }; 1756 } 1757 update(mode) { 1758 const points = this._cachedMeta.data; 1759 this.updateElements(points, 0, points.length, mode); 1760 } 1761 updateElements(points, start, count, mode) { 1762 const reset = mode === 'reset'; 1763 const { iScale , vScale } = this._cachedMeta; 1764 const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode); 1765 const iAxis = iScale.axis; 1766 const vAxis = vScale.axis; 1767 for(let i = start; i < start + count; i++){ 1768 const point = points[i]; 1769 const parsed = !reset && this.getParsed(i); 1770 const properties = {}; 1771 const iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]); 1772 const vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]); 1773 properties.skip = isNaN(iPixel) || isNaN(vPixel); 1774 if (includeOptions) { 1775 properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode); 1776 if (reset) { 1777 properties.options.radius = 0; 1778 } 1779 } 1780 this.updateElement(point, i, properties, mode); 1781 } 1782 } 1783 resolveDataElementOptions(index, mode) { 1784 const parsed = this.getParsed(index); 1785 let values = super.resolveDataElementOptions(index, mode); 1786 if (values.$shared) { 1787 values = Object.assign({}, values, { 1788 $shared: false 1789 }); 1790 } 1791 const radius = values.radius; 1792 if (mode !== 'active') { 1793 values.radius = 0; 1794 } 1795 values.radius += (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(parsed && parsed._custom, radius); 1796 return values; 1797 } 1798} 1799 1800function getRatioAndOffset(rotation, circumference, cutout) { 1801 let ratioX = 1; 1802 let ratioY = 1; 1803 let offsetX = 0; 1804 let offsetY = 0; 1805 if (circumference < _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T) { 1806 const startAngle = rotation; 1807 const endAngle = startAngle + circumference; 1808 const startX = Math.cos(startAngle); 1809 const startY = Math.sin(startAngle); 1810 const endX = Math.cos(endAngle); 1811 const endY = Math.sin(endAngle); 1812 const calcMax = (angle, a, b)=>(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.p)(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout); 1813 const calcMin = (angle, a, b)=>(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.p)(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout); 1814 const maxX = calcMax(0, startX, endX); 1815 const maxY = calcMax(_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H, startY, endY); 1816 const minX = calcMin(_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P, startX, endX); 1817 const minY = calcMin(_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H, startY, endY); 1818 ratioX = (maxX - minX) / 2; 1819 ratioY = (maxY - minY) / 2; 1820 offsetX = -(maxX + minX) / 2; 1821 offsetY = -(maxY + minY) / 2; 1822 } 1823 return { 1824 ratioX, 1825 ratioY, 1826 offsetX, 1827 offsetY 1828 }; 1829} 1830class DoughnutController extends DatasetController { 1831 static id = 'doughnut'; 1832 static defaults = { 1833 datasetElementType: false, 1834 dataElementType: 'arc', 1835 animation: { 1836 animateRotate: true, 1837 animateScale: false 1838 }, 1839 animations: { 1840 numbers: { 1841 type: 'number', 1842 properties: [ 1843 'circumference', 1844 'endAngle', 1845 'innerRadius', 1846 'outerRadius', 1847 'startAngle', 1848 'x', 1849 'y', 1850 'offset', 1851 'borderWidth', 1852 'spacing' 1853 ] 1854 } 1855 }, 1856 cutout: '50%', 1857 rotation: 0, 1858 circumference: 360, 1859 radius: '100%', 1860 spacing: 0, 1861 indexAxis: 'r' 1862 }; 1863 static descriptors = { 1864 _scriptable: (name)=>name !== 'spacing', 1865 _indexable: (name)=>name !== 'spacing' && !name.startsWith('borderDash') && !name.startsWith('hoverBorderDash') 1866 }; 1867 static overrides = { 1868 aspectRatio: 1, 1869 plugins: { 1870 legend: { 1871 labels: { 1872 generateLabels (chart) { 1873 const data = chart.data; 1874 const { labels: { pointStyle , textAlign , color , useBorderRadius , borderRadius } } = chart.legend.options; 1875 if (data.labels.length && data.datasets.length) { 1876 return data.labels.map((label, i)=>{ 1877 const meta = chart.getDatasetMeta(0); 1878 const style = meta.controller.getStyle(i); 1879 return { 1880 text: label, 1881 fillStyle: style.backgroundColor, 1882 fontColor: color, 1883 hidden: !chart.getDataVisibility(i), 1884 lineDash: style.borderDash, 1885 lineDashOffset: style.borderDashOffset, 1886 lineJoin: style.borderJoinStyle, 1887 lineWidth: style.borderWidth, 1888 strokeStyle: style.borderColor, 1889 textAlign: textAlign, 1890 pointStyle: pointStyle, 1891 borderRadius: useBorderRadius && (borderRadius || style.borderRadius), 1892 index: i 1893 }; 1894 }); 1895 } 1896 return []; 1897 } 1898 }, 1899 onClick (e, legendItem, legend) { 1900 legend.chart.toggleDataVisibility(legendItem.index); 1901 legend.chart.update(); 1902 } 1903 } 1904 } 1905 }; 1906 constructor(chart, datasetIndex){ 1907 super(chart, datasetIndex); 1908 this.enableOptionSharing = true; 1909 this.innerRadius = undefined; 1910 this.outerRadius = undefined; 1911 this.offsetX = undefined; 1912 this.offsetY = undefined; 1913 } 1914 linkScales() {} 1915 parse(start, count) { 1916 const data = this.getDataset().data; 1917 const meta = this._cachedMeta; 1918 if (this._parsing === false) { 1919 meta._parsed = data; 1920 } else { 1921 let getter = (i)=>+data[i]; 1922 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(data[start])) { 1923 const { key ='value' } = this._parsing; 1924 getter = (i)=>+(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.f)(data[i], key); 1925 } 1926 let i, ilen; 1927 for(i = start, ilen = start + count; i < ilen; ++i){ 1928 meta._parsed[i] = getter(i); 1929 } 1930 } 1931 } 1932 _getRotation() { 1933 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.options.rotation - 90); 1934 } 1935 _getCircumference() { 1936 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.options.circumference); 1937 } 1938 _getRotationExtents() { 1939 let min = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T; 1940 let max = -_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T; 1941 for(let i = 0; i < this.chart.data.datasets.length; ++i){ 1942 if (this.chart.isDatasetVisible(i) && this.chart.getDatasetMeta(i).type === this._type) { 1943 const controller = this.chart.getDatasetMeta(i).controller; 1944 const rotation = controller._getRotation(); 1945 const circumference = controller._getCircumference(); 1946 min = Math.min(min, rotation); 1947 max = Math.max(max, rotation + circumference); 1948 } 1949 } 1950 return { 1951 rotation: min, 1952 circumference: max - min 1953 }; 1954 } 1955 update(mode) { 1956 const chart = this.chart; 1957 const { chartArea } = chart; 1958 const meta = this._cachedMeta; 1959 const arcs = meta.data; 1960 const spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing; 1961 const maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0); 1962 const cutout = Math.min((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.m)(this.options.cutout, maxSize), 1); 1963 const chartWeight = this._getRingWeight(this.index); 1964 const { circumference , rotation } = this._getRotationExtents(); 1965 const { ratioX , ratioY , offsetX , offsetY } = getRatioAndOffset(rotation, circumference, cutout); 1966 const maxWidth = (chartArea.width - spacing) / ratioX; 1967 const maxHeight = (chartArea.height - spacing) / ratioY; 1968 const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); 1969 const outerRadius = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.n)(this.options.radius, maxRadius); 1970 const innerRadius = Math.max(outerRadius * cutout, 0); 1971 const radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal(); 1972 this.offsetX = offsetX * outerRadius; 1973 this.offsetY = offsetY * outerRadius; 1974 meta.total = this.calculateTotal(); 1975 this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index); 1976 this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0); 1977 this.updateElements(arcs, 0, arcs.length, mode); 1978 } 1979 _circumference(i, reset) { 1980 const opts = this.options; 1981 const meta = this._cachedMeta; 1982 const circumference = this._getCircumference(); 1983 if (reset && opts.animation.animateRotate || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) { 1984 return 0; 1985 } 1986 return this.calculateCircumference(meta._parsed[i] * circumference / _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T); 1987 } 1988 updateElements(arcs, start, count, mode) { 1989 const reset = mode === 'reset'; 1990 const chart = this.chart; 1991 const chartArea = chart.chartArea; 1992 const opts = chart.options; 1993 const animationOpts = opts.animation; 1994 const centerX = (chartArea.left + chartArea.right) / 2; 1995 const centerY = (chartArea.top + chartArea.bottom) / 2; 1996 const animateScale = reset && animationOpts.animateScale; 1997 const innerRadius = animateScale ? 0 : this.innerRadius; 1998 const outerRadius = animateScale ? 0 : this.outerRadius; 1999 const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode); 2000 let startAngle = this._getRotation(); 2001 let i; 2002 for(i = 0; i < start; ++i){ 2003 startAngle += this._circumference(i, reset); 2004 } 2005 for(i = start; i < start + count; ++i){ 2006 const circumference = this._circumference(i, reset); 2007 const arc = arcs[i]; 2008 const properties = { 2009 x: centerX + this.offsetX, 2010 y: centerY + this.offsetY, 2011 startAngle, 2012 endAngle: startAngle + circumference, 2013 circumference, 2014 outerRadius, 2015 innerRadius 2016 }; 2017 if (includeOptions) { 2018 properties.options = sharedOptions || this.resolveDataElementOptions(i, arc.active ? 'active' : mode); 2019 } 2020 startAngle += circumference; 2021 this.updateElement(arc, i, properties, mode); 2022 } 2023 } 2024 calculateTotal() { 2025 const meta = this._cachedMeta; 2026 const metaData = meta.data; 2027 let total = 0; 2028 let i; 2029 for(i = 0; i < metaData.length; i++){ 2030 const value = meta._parsed[i]; 2031 if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) { 2032 total += Math.abs(value); 2033 } 2034 } 2035 return total; 2036 } 2037 calculateCircumference(value) { 2038 const total = this._cachedMeta.total; 2039 if (total > 0 && !isNaN(value)) { 2040 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T * (Math.abs(value) / total); 2041 } 2042 return 0; 2043 } 2044 getLabelAndValue(index) { 2045 const meta = this._cachedMeta; 2046 const chart = this.chart; 2047 const labels = chart.data.labels || []; 2048 const value = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.o)(meta._parsed[index], chart.options.locale); 2049 return { 2050 label: labels[index] || '', 2051 value 2052 }; 2053 } 2054 getMaxBorderWidth(arcs) { 2055 let max = 0; 2056 const chart = this.chart; 2057 let i, ilen, meta, controller, options; 2058 if (!arcs) { 2059 for(i = 0, ilen = chart.data.datasets.length; i < ilen; ++i){ 2060 if (chart.isDatasetVisible(i)) { 2061 meta = chart.getDatasetMeta(i); 2062 arcs = meta.data; 2063 controller = meta.controller; 2064 break; 2065 } 2066 } 2067 } 2068 if (!arcs) { 2069 return 0; 2070 } 2071 for(i = 0, ilen = arcs.length; i < ilen; ++i){ 2072 options = controller.resolveDataElementOptions(i); 2073 if (options.borderAlign !== 'inner') { 2074 max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0); 2075 } 2076 } 2077 return max; 2078 } 2079 getMaxOffset(arcs) { 2080 let max = 0; 2081 for(let i = 0, ilen = arcs.length; i < ilen; ++i){ 2082 const options = this.resolveDataElementOptions(i); 2083 max = Math.max(max, options.offset || 0, options.hoverOffset || 0); 2084 } 2085 return max; 2086 } 2087 _getRingWeightOffset(datasetIndex) { 2088 let ringWeightOffset = 0; 2089 for(let i = 0; i < datasetIndex; ++i){ 2090 if (this.chart.isDatasetVisible(i)) { 2091 ringWeightOffset += this._getRingWeight(i); 2092 } 2093 } 2094 return ringWeightOffset; 2095 } 2096 _getRingWeight(datasetIndex) { 2097 return Math.max((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(this.chart.data.datasets[datasetIndex].weight, 1), 0); 2098 } 2099 _getVisibleDatasetWeightTotal() { 2100 return this._getRingWeightOffset(this.chart.data.datasets.length) || 1; 2101 } 2102} 2103 2104class LineController extends DatasetController { 2105 static id = 'line'; 2106 static defaults = { 2107 datasetElementType: 'line', 2108 dataElementType: 'point', 2109 showLine: true, 2110 spanGaps: false 2111 }; 2112 static overrides = { 2113 scales: { 2114 _index_: { 2115 type: 'category' 2116 }, 2117 _value_: { 2118 type: 'linear' 2119 } 2120 } 2121 }; 2122 initialize() { 2123 this.enableOptionSharing = true; 2124 this.supportsDecimation = true; 2125 super.initialize(); 2126 } 2127 update(mode) { 2128 const meta = this._cachedMeta; 2129 const { dataset: line , data: points = [] , _dataset } = meta; 2130 const animationsDisabled = this.chart._animationsDisabled; 2131 let { start , count } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.q)(meta, points, animationsDisabled); 2132 this._drawStart = start; 2133 this._drawCount = count; 2134 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.w)(meta)) { 2135 start = 0; 2136 count = points.length; 2137 } 2138 line._chart = this.chart; 2139 line._datasetIndex = this.index; 2140 line._decimated = !!_dataset._decimated; 2141 line.points = points; 2142 const options = this.resolveDatasetElementOptions(mode); 2143 if (!this.options.showLine) { 2144 options.borderWidth = 0; 2145 } 2146 options.segment = this.options.segment; 2147 this.updateElement(line, undefined, { 2148 animated: !animationsDisabled, 2149 options 2150 }, mode); 2151 this.updateElements(points, start, count, mode); 2152 } 2153 updateElements(points, start, count, mode) { 2154 const reset = mode === 'reset'; 2155 const { iScale , vScale , _stacked , _dataset } = this._cachedMeta; 2156 const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode); 2157 const iAxis = iScale.axis; 2158 const vAxis = vScale.axis; 2159 const { spanGaps , segment } = this.options; 2160 const maxGapLength = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.x)(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY; 2161 const directUpdate = this.chart._animationsDisabled || reset || mode === 'none'; 2162 const end = start + count; 2163 const pointsCount = points.length; 2164 let prevParsed = start > 0 && this.getParsed(start - 1); 2165 for(let i = 0; i < pointsCount; ++i){ 2166 const point = points[i]; 2167 const properties = directUpdate ? point : {}; 2168 if (i < start || i >= end) { 2169 properties.skip = true; 2170 continue; 2171 } 2172 const parsed = this.getParsed(i); 2173 const nullData = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(parsed[vAxis]); 2174 const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i); 2175 const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i); 2176 properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData; 2177 properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength; 2178 if (segment) { 2179 properties.parsed = parsed; 2180 properties.raw = _dataset.data[i]; 2181 } 2182 if (includeOptions) { 2183 properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode); 2184 } 2185 if (!directUpdate) { 2186 this.updateElement(point, i, properties, mode); 2187 } 2188 prevParsed = parsed; 2189 } 2190 } 2191 getMaxOverflow() { 2192 const meta = this._cachedMeta; 2193 const dataset = meta.dataset; 2194 const border = dataset.options && dataset.options.borderWidth || 0; 2195 const data = meta.data || []; 2196 if (!data.length) { 2197 return border; 2198 } 2199 const firstPoint = data[0].size(this.resolveDataElementOptions(0)); 2200 const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1)); 2201 return Math.max(border, firstPoint, lastPoint) / 2; 2202 } 2203 draw() { 2204 const meta = this._cachedMeta; 2205 meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis); 2206 super.draw(); 2207 } 2208} 2209 2210class PolarAreaController extends DatasetController { 2211 static id = 'polarArea'; 2212 static defaults = { 2213 dataElementType: 'arc', 2214 animation: { 2215 animateRotate: true, 2216 animateScale: true 2217 }, 2218 animations: { 2219 numbers: { 2220 type: 'number', 2221 properties: [ 2222 'x', 2223 'y', 2224 'startAngle', 2225 'endAngle', 2226 'innerRadius', 2227 'outerRadius' 2228 ] 2229 } 2230 }, 2231 indexAxis: 'r', 2232 startAngle: 0 2233 }; 2234 static overrides = { 2235 aspectRatio: 1, 2236 plugins: { 2237 legend: { 2238 labels: { 2239 generateLabels (chart) { 2240 const data = chart.data; 2241 if (data.labels.length && data.datasets.length) { 2242 const { labels: { pointStyle , color } } = chart.legend.options; 2243 return data.labels.map((label, i)=>{ 2244 const meta = chart.getDatasetMeta(0); 2245 const style = meta.controller.getStyle(i); 2246 return { 2247 text: label, 2248 fillStyle: style.backgroundColor, 2249 strokeStyle: style.borderColor, 2250 fontColor: color, 2251 lineWidth: style.borderWidth, 2252 pointStyle: pointStyle, 2253 hidden: !chart.getDataVisibility(i), 2254 index: i 2255 }; 2256 }); 2257 } 2258 return []; 2259 } 2260 }, 2261 onClick (e, legendItem, legend) { 2262 legend.chart.toggleDataVisibility(legendItem.index); 2263 legend.chart.update(); 2264 } 2265 } 2266 }, 2267 scales: { 2268 r: { 2269 type: 'radialLinear', 2270 angleLines: { 2271 display: false 2272 }, 2273 beginAtZero: true, 2274 grid: { 2275 circular: true 2276 }, 2277 pointLabels: { 2278 display: false 2279 }, 2280 startAngle: 0 2281 } 2282 } 2283 }; 2284 constructor(chart, datasetIndex){ 2285 super(chart, datasetIndex); 2286 this.innerRadius = undefined; 2287 this.outerRadius = undefined; 2288 } 2289 getLabelAndValue(index) { 2290 const meta = this._cachedMeta; 2291 const chart = this.chart; 2292 const labels = chart.data.labels || []; 2293 const value = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.o)(meta._parsed[index].r, chart.options.locale); 2294 return { 2295 label: labels[index] || '', 2296 value 2297 }; 2298 } 2299 parseObjectData(meta, data, start, count) { 2300 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.y.bind(this)(meta, data, start, count); 2301 } 2302 update(mode) { 2303 const arcs = this._cachedMeta.data; 2304 this._updateRadius(); 2305 this.updateElements(arcs, 0, arcs.length, mode); 2306 } 2307 getMinMax() { 2308 const meta = this._cachedMeta; 2309 const range = { 2310 min: Number.POSITIVE_INFINITY, 2311 max: Number.NEGATIVE_INFINITY 2312 }; 2313 meta.data.forEach((element, index)=>{ 2314 const parsed = this.getParsed(index).r; 2315 if (!isNaN(parsed) && this.chart.getDataVisibility(index)) { 2316 if (parsed < range.min) { 2317 range.min = parsed; 2318 } 2319 if (parsed > range.max) { 2320 range.max = parsed; 2321 } 2322 } 2323 }); 2324 return range; 2325 } 2326 _updateRadius() { 2327 const chart = this.chart; 2328 const chartArea = chart.chartArea; 2329 const opts = chart.options; 2330 const minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); 2331 const outerRadius = Math.max(minSize / 2, 0); 2332 const innerRadius = Math.max(opts.cutoutPercentage ? outerRadius / 100 * opts.cutoutPercentage : 1, 0); 2333 const radiusLength = (outerRadius - innerRadius) / chart.getVisibleDatasetCount(); 2334 this.outerRadius = outerRadius - radiusLength * this.index; 2335 this.innerRadius = this.outerRadius - radiusLength; 2336 } 2337 updateElements(arcs, start, count, mode) { 2338 const reset = mode === 'reset'; 2339 const chart = this.chart; 2340 const opts = chart.options; 2341 const animationOpts = opts.animation; 2342 const scale = this._cachedMeta.rScale; 2343 const centerX = scale.xCenter; 2344 const centerY = scale.yCenter; 2345 const datasetStartAngle = scale.getIndexAngle(0) - 0.5 * _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P; 2346 let angle = datasetStartAngle; 2347 let i; 2348 const defaultAngle = 360 / this.countVisibleElements(); 2349 for(i = 0; i < start; ++i){ 2350 angle += this._computeAngle(i, mode, defaultAngle); 2351 } 2352 for(i = start; i < start + count; i++){ 2353 const arc = arcs[i]; 2354 let startAngle = angle; 2355 let endAngle = angle + this._computeAngle(i, mode, defaultAngle); 2356 let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(this.getParsed(i).r) : 0; 2357 angle = endAngle; 2358 if (reset) { 2359 if (animationOpts.animateScale) { 2360 outerRadius = 0; 2361 } 2362 if (animationOpts.animateRotate) { 2363 startAngle = endAngle = datasetStartAngle; 2364 } 2365 } 2366 const properties = { 2367 x: centerX, 2368 y: centerY, 2369 innerRadius: 0, 2370 outerRadius, 2371 startAngle, 2372 endAngle, 2373 options: this.resolveDataElementOptions(i, arc.active ? 'active' : mode) 2374 }; 2375 this.updateElement(arc, i, properties, mode); 2376 } 2377 } 2378 countVisibleElements() { 2379 const meta = this._cachedMeta; 2380 let count = 0; 2381 meta.data.forEach((element, index)=>{ 2382 if (!isNaN(this.getParsed(index).r) && this.chart.getDataVisibility(index)) { 2383 count++; 2384 } 2385 }); 2386 return count; 2387 } 2388 _computeAngle(index, mode, defaultAngle) { 2389 return this.chart.getDataVisibility(index) ? (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.resolveDataElementOptions(index, mode).angle || defaultAngle) : 0; 2390 } 2391} 2392 2393class PieController extends DoughnutController { 2394 static id = 'pie'; 2395 static defaults = { 2396 cutout: 0, 2397 rotation: 0, 2398 circumference: 360, 2399 radius: '100%' 2400 }; 2401} 2402 2403class RadarController extends DatasetController { 2404 static id = 'radar'; 2405 static defaults = { 2406 datasetElementType: 'line', 2407 dataElementType: 'point', 2408 indexAxis: 'r', 2409 showLine: true, 2410 elements: { 2411 line: { 2412 fill: 'start' 2413 } 2414 } 2415 }; 2416 static overrides = { 2417 aspectRatio: 1, 2418 scales: { 2419 r: { 2420 type: 'radialLinear' 2421 } 2422 } 2423 }; 2424 getLabelAndValue(index) { 2425 const vScale = this._cachedMeta.vScale; 2426 const parsed = this.getParsed(index); 2427 return { 2428 label: vScale.getLabels()[index], 2429 value: '' + vScale.getLabelForValue(parsed[vScale.axis]) 2430 }; 2431 } 2432 parseObjectData(meta, data, start, count) { 2433 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.y.bind(this)(meta, data, start, count); 2434 } 2435 update(mode) { 2436 const meta = this._cachedMeta; 2437 const line = meta.dataset; 2438 const points = meta.data || []; 2439 const labels = meta.iScale.getLabels(); 2440 line.points = points; 2441 if (mode !== 'resize') { 2442 const options = this.resolveDatasetElementOptions(mode); 2443 if (!this.options.showLine) { 2444 options.borderWidth = 0; 2445 } 2446 const properties = { 2447 _loop: true, 2448 _fullLoop: labels.length === points.length, 2449 options 2450 }; 2451 this.updateElement(line, undefined, properties, mode); 2452 } 2453 this.updateElements(points, 0, points.length, mode); 2454 } 2455 updateElements(points, start, count, mode) { 2456 const scale = this._cachedMeta.rScale; 2457 const reset = mode === 'reset'; 2458 for(let i = start; i < start + count; i++){ 2459 const point = points[i]; 2460 const options = this.resolveDataElementOptions(i, point.active ? 'active' : mode); 2461 const pointPosition = scale.getPointPositionForValue(i, this.getParsed(i).r); 2462 const x = reset ? scale.xCenter : pointPosition.x; 2463 const y = reset ? scale.yCenter : pointPosition.y; 2464 const properties = { 2465 x, 2466 y, 2467 angle: pointPosition.angle, 2468 skip: isNaN(x) || isNaN(y), 2469 options 2470 }; 2471 this.updateElement(point, i, properties, mode); 2472 } 2473 } 2474} 2475 2476class ScatterController extends DatasetController { 2477 static id = 'scatter'; 2478 static defaults = { 2479 datasetElementType: false, 2480 dataElementType: 'point', 2481 showLine: false, 2482 fill: false 2483 }; 2484 static overrides = { 2485 interaction: { 2486 mode: 'point' 2487 }, 2488 scales: { 2489 x: { 2490 type: 'linear' 2491 }, 2492 y: { 2493 type: 'linear' 2494 } 2495 } 2496 }; 2497 getLabelAndValue(index) { 2498 const meta = this._cachedMeta; 2499 const labels = this.chart.data.labels || []; 2500 const { xScale , yScale } = meta; 2501 const parsed = this.getParsed(index); 2502 const x = xScale.getLabelForValue(parsed.x); 2503 const y = yScale.getLabelForValue(parsed.y); 2504 return { 2505 label: labels[index] || '', 2506 value: '(' + x + ', ' + y + ')' 2507 }; 2508 } 2509 update(mode) { 2510 const meta = this._cachedMeta; 2511 const { data: points = [] } = meta; 2512 const animationsDisabled = this.chart._animationsDisabled; 2513 let { start , count } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.q)(meta, points, animationsDisabled); 2514 this._drawStart = start; 2515 this._drawCount = count; 2516 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.w)(meta)) { 2517 start = 0; 2518 count = points.length; 2519 } 2520 if (this.options.showLine) { 2521 if (!this.datasetElementType) { 2522 this.addElements(); 2523 } 2524 const { dataset: line , _dataset } = meta; 2525 line._chart = this.chart; 2526 line._datasetIndex = this.index; 2527 line._decimated = !!_dataset._decimated; 2528 line.points = points; 2529 const options = this.resolveDatasetElementOptions(mode); 2530 options.segment = this.options.segment; 2531 this.updateElement(line, undefined, { 2532 animated: !animationsDisabled, 2533 options 2534 }, mode); 2535 } else if (this.datasetElementType) { 2536 delete meta.dataset; 2537 this.datasetElementType = false; 2538 } 2539 this.updateElements(points, start, count, mode); 2540 } 2541 addElements() { 2542 const { showLine } = this.options; 2543 if (!this.datasetElementType && showLine) { 2544 this.datasetElementType = this.chart.registry.getElement('line'); 2545 } 2546 super.addElements(); 2547 } 2548 updateElements(points, start, count, mode) { 2549 const reset = mode === 'reset'; 2550 const { iScale , vScale , _stacked , _dataset } = this._cachedMeta; 2551 const firstOpts = this.resolveDataElementOptions(start, mode); 2552 const sharedOptions = this.getSharedOptions(firstOpts); 2553 const includeOptions = this.includeOptions(mode, sharedOptions); 2554 const iAxis = iScale.axis; 2555 const vAxis = vScale.axis; 2556 const { spanGaps , segment } = this.options; 2557 const maxGapLength = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.x)(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY; 2558 const directUpdate = this.chart._animationsDisabled || reset || mode === 'none'; 2559 let prevParsed = start > 0 && this.getParsed(start - 1); 2560 for(let i = start; i < start + count; ++i){ 2561 const point = points[i]; 2562 const parsed = this.getParsed(i); 2563 const properties = directUpdate ? point : {}; 2564 const nullData = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(parsed[vAxis]); 2565 const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i); 2566 const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i); 2567 properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData; 2568 properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength; 2569 if (segment) { 2570 properties.parsed = parsed; 2571 properties.raw = _dataset.data[i]; 2572 } 2573 if (includeOptions) { 2574 properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode); 2575 } 2576 if (!directUpdate) { 2577 this.updateElement(point, i, properties, mode); 2578 } 2579 prevParsed = parsed; 2580 } 2581 this.updateSharedOptions(sharedOptions, mode, firstOpts); 2582 } 2583 getMaxOverflow() { 2584 const meta = this._cachedMeta; 2585 const data = meta.data || []; 2586 if (!this.options.showLine) { 2587 let max = 0; 2588 for(let i = data.length - 1; i >= 0; --i){ 2589 max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2); 2590 } 2591 return max > 0 && max; 2592 } 2593 const dataset = meta.dataset; 2594 const border = dataset.options && dataset.options.borderWidth || 0; 2595 if (!data.length) { 2596 return border; 2597 } 2598 const firstPoint = data[0].size(this.resolveDataElementOptions(0)); 2599 const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1)); 2600 return Math.max(border, firstPoint, lastPoint) / 2; 2601 } 2602} 2603 2604var controllers = /*#__PURE__*/Object.freeze({ 2605__proto__: null, 2606BarController: BarController, 2607BubbleController: BubbleController, 2608DoughnutController: DoughnutController, 2609LineController: LineController, 2610PieController: PieController, 2611PolarAreaController: PolarAreaController, 2612RadarController: RadarController, 2613ScatterController: ScatterController 2614}); 2615 2616/** 2617 * @namespace Chart._adapters 2618 * @since 2.8.0 2619 * @private 2620 */ function abstract() { 2621 throw new Error('This method is not implemented: Check that a complete date adapter is provided.'); 2622} 2623/** 2624 * Date adapter (current used by the time scale) 2625 * @namespace Chart._adapters._date 2626 * @memberof Chart._adapters 2627 * @private 2628 */ class DateAdapterBase { 2629 /** 2630 * Override default date adapter methods. 2631 * Accepts type parameter to define options type. 2632 * @example 2633 * Chart._adapters._date.override<{myAdapterOption: string}>({ 2634 * init() { 2635 * console.log(this.options.myAdapterOption); 2636 * } 2637 * }) 2638 */ static override(members) { 2639 Object.assign(DateAdapterBase.prototype, members); 2640 } 2641 options; 2642 constructor(options){ 2643 this.options = options || {}; 2644 } 2645 // eslint-disable-next-line @typescript-eslint/no-empty-function 2646 init() {} 2647 formats() { 2648 return abstract(); 2649 } 2650 parse() { 2651 return abstract(); 2652 } 2653 format() { 2654 return abstract(); 2655 } 2656 add() { 2657 return abstract(); 2658 } 2659 diff() { 2660 return abstract(); 2661 } 2662 startOf() { 2663 return abstract(); 2664 } 2665 endOf() { 2666 return abstract(); 2667 } 2668} 2669var adapters = { 2670 _date: DateAdapterBase 2671}; 2672 2673function binarySearch(metaset, axis, value, intersect) { 2674 const { controller , data , _sorted } = metaset; 2675 const iScale = controller._cachedMeta.iScale; 2676 const spanGaps = metaset.dataset ? metaset.dataset.options ? metaset.dataset.options.spanGaps : null : null; 2677 if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) { 2678 const lookupMethod = iScale._reversePixels ? _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.A : _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.B; 2679 if (!intersect) { 2680 const result = lookupMethod(data, axis, value); 2681 if (spanGaps) { 2682 const { vScale } = controller._cachedMeta; 2683 const { _parsed } = metaset; 2684 const distanceToDefinedLo = _parsed.slice(0, result.lo + 1).reverse().findIndex((point)=>!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(point[vScale.axis
vendor: 5,105 bytes, lines 2684-2817
2684])); 2685 result.lo -= Math.max(0, distanceToDefinedLo); 2686 const distanceToDefinedHi = _parsed.slice(result.hi).findIndex((point)=>!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(point[vScale.axis])); 2687 result.hi += Math.max(0, distanceToDefinedHi); 2688 } 2689 return result; 2690 } else if (controller._sharedOptions) { 2691 const el = data[0]; 2692 const range = typeof el.getRange === 'function' && el.getRange(axis); 2693 if (range) { 2694 const start = lookupMethod(data, axis, value - range); 2695 const end = lookupMethod(data, axis, value + range); 2696 return { 2697 lo: start.lo, 2698 hi: end.hi 2699 }; 2700 } 2701 } 2702 } 2703 return { 2704 lo: 0, 2705 hi: data.length - 1 2706 }; 2707} 2708 function evaluateInteractionItems(chart, axis, position, handler, intersect) { 2709 const metasets = chart.getSortedVisibleDatasetMetas(); 2710 const value = position[axis]; 2711 for(let i = 0, ilen = metasets.length; i < ilen; ++i){ 2712 const { index , data } = metasets[i]; 2713 const { lo , hi } = binarySearch(metasets[i], axis, value, intersect); 2714 for(let j = lo; j <= hi; ++j){ 2715 const element = data[j]; 2716 if (!element.skip) { 2717 handler(element, index, j); 2718 } 2719 } 2720 } 2721} 2722 function getDistanceMetricForAxis(axis) { 2723 const useX = axis.indexOf('x') !== -1; 2724 const useY = axis.indexOf('y') !== -1; 2725 return function(pt1, pt2) { 2726 const deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; 2727 const deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; 2728 return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); 2729 }; 2730} 2731 function getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) { 2732 const items = []; 2733 if (!includeInvisible && !chart.isPointInArea(position)) { 2734 return items; 2735 } 2736 const evaluationFunc = function(element, datasetIndex, index) { 2737 if (!includeInvisible && !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)(element, chart.chartArea, 0)) { 2738 return; 2739 } 2740 if (element.inRange(position.x, position.y, useFinalPosition)) { 2741 items.push({ 2742 element, 2743 datasetIndex, 2744 index 2745 }); 2746 } 2747 }; 2748 evaluateInteractionItems(chart, axis, position, evaluationFunc, true); 2749 return items; 2750} 2751 function getNearestRadialItems(chart, position, axis, useFinalPosition) { 2752 let items = []; 2753 function evaluationFunc(element, datasetIndex, index) { 2754 const { startAngle , endAngle } = element.getProps([ 2755 'startAngle', 2756 'endAngle' 2757 ], useFinalPosition); 2758 const { angle } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.D)(element, { 2759 x: position.x, 2760 y: position.y 2761 }); 2762 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.p)(angle, startAngle, endAngle)) { 2763 items.push({ 2764 element, 2765 datasetIndex, 2766 index 2767 }); 2768 } 2769 } 2770 evaluateInteractionItems(chart, axis, position, evaluationFunc); 2771 return items; 2772} 2773 function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) { 2774 let items = []; 2775 const distanceMetric = getDistanceMetricForAxis(axis); 2776 let minDistance = Number.POSITIVE_INFINITY; 2777 function evaluationFunc(element, datasetIndex, index) { 2778 const inRange = element.inRange(position.x, position.y, useFinalPosition); 2779 if (intersect && !inRange) { 2780 return; 2781 } 2782 const center = element.getCenterPoint(useFinalPosition); 2783 const pointInArea = !!includeInvisible || chart.isPointInArea(center); 2784 if (!pointInArea && !inRange) { 2785 return; 2786 } 2787 const distance = distanceMetric(position, center); 2788 if (distance < minDistance) { 2789 items = [ 2790 { 2791 element, 2792 datasetIndex, 2793 index 2794 } 2795 ]; 2796 minDistance = distance; 2797 } else if (distance === minDistance) { 2798 items.push({ 2799 element, 2800 datasetIndex, 2801 index 2802 }); 2803 } 2804 } 2805 evaluateInteractionItems(chart, axis, position, evaluationFunc); 2806 return items; 2807} 2808 function getNearestItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) { 2809 if (!includeInvisible && !chart.isPointInArea(position)) { 2810 return []; 2811 } 2812 return axis === 'r' && !intersect ? getNearestRadialItems(chart, position, axis, useFinalPosition) : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible); 2813} 2814 function getAxisItems(chart, position, axis, intersect, useFinalPosition) { 2815 const items = []; 2816 const rangeMethod = axis === 'x' ? 'inXRange' : 'inYRange'; 2817 let intersectsItem = false;
vendor: 28,984 bytes, lines 2818-3624
2818 evaluateInteractionItems(chart, axis, position, (element, datasetIndex, index)=>{ 2819 if (element[rangeMethod] && element[rangeMethod](position[axis], useFinalPosition)) { 2820 items.push({ 2821 element, 2822 datasetIndex, 2823 index 2824 }); 2825 intersectsItem = intersectsItem || element.inRange(position.x, position.y, useFinalPosition); 2826 } 2827 }); 2828 if (intersect && !intersectsItem) { 2829 return []; 2830 } 2831 return items; 2832} 2833 var Interaction = { 2834 evaluateInteractionItems, 2835 modes: { 2836 index (chart, e, options, useFinalPosition) { 2837 const position = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(e, chart); 2838 const axis = options.axis || 'x'; 2839 const includeInvisible = options.includeInvisible || false; 2840 const items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible); 2841 const elements = []; 2842 if (!items.length) { 2843 return []; 2844 } 2845 chart.getSortedVisibleDatasetMetas().forEach((meta)=>{ 2846 const index = items[0].index; 2847 const element = meta.data[index]; 2848 if (element && !element.skip) { 2849 elements.push({ 2850 element, 2851 datasetIndex: meta.index, 2852 index 2853 }); 2854 } 2855 }); 2856 return elements; 2857 }, 2858 dataset (chart, e, options, useFinalPosition) { 2859 const position = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(e, chart); 2860 const axis = options.axis || 'xy'; 2861 const includeInvisible = options.includeInvisible || false; 2862 let items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible); 2863 if (items.length > 0) { 2864 const datasetIndex = items[0].datasetIndex; 2865 const data = chart.getDatasetMeta(datasetIndex).data; 2866 items = []; 2867 for(let i = 0; i < data.length; ++i){ 2868 items.push({ 2869 element: data[i], 2870 datasetIndex, 2871 index: i 2872 }); 2873 } 2874 } 2875 return items; 2876 }, 2877 point (chart, e, options, useFinalPosition) { 2878 const position = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(e, chart); 2879 const axis = options.axis || 'xy'; 2880 const includeInvisible = options.includeInvisible || false; 2881 return getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible); 2882 }, 2883 nearest (chart, e, options, useFinalPosition) { 2884 const position = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(e, chart); 2885 const axis = options.axis || 'xy'; 2886 const includeInvisible = options.includeInvisible || false; 2887 return getNearestItems(chart, position, axis, options.intersect, useFinalPosition, includeInvisible); 2888 }, 2889 x (chart, e, options, useFinalPosition) { 2890 const position = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(e, chart); 2891 return getAxisItems(chart, position, 'x', options.intersect, useFinalPosition); 2892 }, 2893 y (chart, e, options, useFinalPosition) { 2894 const position = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(e, chart); 2895 return getAxisItems(chart, position, 'y', options.intersect, useFinalPosition); 2896 } 2897 } 2898}; 2899 2900const STATIC_POSITIONS = [ 2901 'left', 2902 'top', 2903 'right', 2904 'bottom' 2905]; 2906function filterByPosition(array, position) { 2907 return array.filter((v)=>v.pos === position); 2908} 2909function filterDynamicPositionByAxis(array, axis) { 2910 return array.filter((v)=>STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis); 2911} 2912function sortByWeight(array, reverse) { 2913 return array.sort((a, b)=>{ 2914 const v0 = reverse ? b : a; 2915 const v1 = reverse ? a : b; 2916 return v0.weight === v1.weight ? v0.index - v1.index : v0.weight - v1.weight; 2917 }); 2918} 2919function wrapBoxes(boxes) { 2920 const layoutBoxes = []; 2921 let i, ilen, box, pos, stack, stackWeight; 2922 for(i = 0, ilen = (boxes || []).length; i < ilen; ++i){ 2923 box = boxes[i]; 2924 ({ position: pos , options: { stack , stackWeight =1 } } = box); 2925 layoutBoxes.push({ 2926 index: i, 2927 box, 2928 pos, 2929 horizontal: box.isHorizontal(), 2930 weight: box.weight, 2931 stack: stack && pos + stack, 2932 stackWeight 2933 }); 2934 } 2935 return layoutBoxes; 2936} 2937function buildStacks(layouts) { 2938 const stacks = {}; 2939 for (const wrap of layouts){ 2940 const { stack , pos , stackWeight } = wrap; 2941 if (!stack || !STATIC_POSITIONS.includes(pos)) { 2942 continue; 2943 } 2944 const _stack = stacks[stack] || (stacks[stack] = { 2945 count: 0, 2946 placed: 0, 2947 weight: 0, 2948 size: 0 2949 }); 2950 _stack.count++; 2951 _stack.weight += stackWeight; 2952 } 2953 return stacks; 2954} 2955 function setLayoutDims(layouts, params) { 2956 const stacks = buildStacks(layouts); 2957 const { vBoxMaxWidth , hBoxMaxHeight } = params; 2958 let i, ilen, layout; 2959 for(i = 0, ilen = layouts.length; i < ilen; ++i){ 2960 layout = layouts[i]; 2961 const { fullSize } = layout.box; 2962 const stack = stacks[layout.stack]; 2963 const factor = stack && layout.stackWeight / stack.weight; 2964 if (layout.horizontal) { 2965 layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth; 2966 layout.height = hBoxMaxHeight; 2967 } else { 2968 layout.width = vBoxMaxWidth; 2969 layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight; 2970 } 2971 } 2972 return stacks; 2973} 2974function buildLayoutBoxes(boxes) { 2975 const layoutBoxes = wrapBoxes(boxes); 2976 const fullSize = sortByWeight(layoutBoxes.filter((wrap)=>wrap.box.fullSize), true); 2977 const left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true); 2978 const right = sortByWeight(filterByPosition(layoutBoxes, 'right')); 2979 const top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true); 2980 const bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom')); 2981 const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, 'x'); 2982 const centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y'); 2983 return { 2984 fullSize, 2985 leftAndTop: left.concat(top), 2986 rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal), 2987 chartArea: filterByPosition(layoutBoxes, 'chartArea'), 2988 vertical: left.concat(right).concat(centerVertical), 2989 horizontal: top.concat(bottom).concat(centerHorizontal) 2990 }; 2991} 2992function getCombinedMax(maxPadding, chartArea, a, b) { 2993 return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]); 2994} 2995function updateMaxPadding(maxPadding, boxPadding) { 2996 maxPadding.top = Math.max(maxPadding.top, boxPadding.top); 2997 maxPadding.left = Math.max(maxPadding.left, boxPadding.left); 2998 maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom); 2999 maxPadding.right = Math.max(maxPadding.right, boxPadding.right); 3000} 3001function updateDims(chartArea, params, layout, stacks) { 3002 const { pos , box } = layout; 3003 const maxPadding = chartArea.maxPadding; 3004 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(pos)) { 3005 if (layout.size) { 3006 chartArea[pos] -= layout.size; 3007 } 3008 const stack = stacks[layout.stack] || { 3009 size: 0, 3010 count: 1 3011 }; 3012 stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width); 3013 layout.size = stack.size / stack.count; 3014 chartArea[pos] += layout.size; 3015 } 3016 if (box.getPadding) { 3017 updateMaxPadding(maxPadding, box.getPadding()); 3018 } 3019 const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right')); 3020 const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom')); 3021 const widthChanged = newWidth !== chartArea.w; 3022 const heightChanged = newHeight !== chartArea.h; 3023 chartArea.w = newWidth; 3024 chartArea.h = newHeight; 3025 return layout.horizontal ? { 3026 same: widthChanged, 3027 other: heightChanged 3028 } : { 3029 same: heightChanged, 3030 other: widthChanged 3031 }; 3032} 3033function handleMaxPadding(chartArea) { 3034 const maxPadding = chartArea.maxPadding; 3035 function updatePos(pos) { 3036 const change = Math.max(maxPadding[pos] - chartArea[pos], 0); 3037 chartArea[pos] += change; 3038 return change; 3039 } 3040 chartArea.y += updatePos('top'); 3041 chartArea.x += updatePos('left'); 3042 updatePos('right'); 3043 updatePos('bottom'); 3044} 3045function getMargins(horizontal, chartArea) { 3046 const maxPadding = chartArea.maxPadding; 3047 function marginForPositions(positions) { 3048 const margin = { 3049 left: 0, 3050 top: 0, 3051 right: 0, 3052 bottom: 0 3053 }; 3054 positions.forEach((pos)=>{ 3055 margin[pos] = Math.max(chartArea[pos], maxPadding[pos]); 3056 }); 3057 return margin; 3058 } 3059 return horizontal ? marginForPositions([ 3060 'left', 3061 'right' 3062 ]) : marginForPositions([ 3063 'top', 3064 'bottom' 3065 ]); 3066} 3067function fitBoxes(boxes, chartArea, params, stacks) { 3068 const refitBoxes = []; 3069 let i, ilen, layout, box, refit, changed; 3070 for(i = 0, ilen = boxes.length, refit = 0; i < ilen; ++i){ 3071 layout = boxes[i]; 3072 box = layout.box; 3073 box.update(layout.width || chartArea.w, layout.height || chartArea.h, getMargins(layout.horizontal, chartArea)); 3074 const { same , other } = updateDims(chartArea, params, layout, stacks); 3075 refit |= same && refitBoxes.length; 3076 changed = changed || other; 3077 if (!box.fullSize) { 3078 refitBoxes.push(layout); 3079 } 3080 } 3081 return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed; 3082} 3083function setBoxDims(box, left, top, width, height) { 3084 box.top = top; 3085 box.left = left; 3086 box.right = left + width; 3087 box.bottom = top + height; 3088 box.width = width; 3089 box.height = height; 3090} 3091function placeBoxes(boxes, chartArea, params, stacks) { 3092 const userPadding = params.padding; 3093 let { x , y } = chartArea; 3094 for (const layout of boxes){ 3095 const box = layout.box; 3096 const stack = stacks[layout.stack] || { 3097 count: 1, 3098 placed: 0, 3099 weight: 1 3100 }; 3101 const weight = layout.stackWeight / stack.weight || 1; 3102 if (layout.horizontal) { 3103 const width = chartArea.w * weight; 3104 const height = stack.size || box.height; 3105 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.h)(stack.start)) { 3106 y = stack.start; 3107 } 3108 if (box.fullSize) { 3109 setBoxDims(box, userPadding.left, y, params.outerWidth - userPadding.right - userPadding.left, height); 3110 } else { 3111 setBoxDims(box, chartArea.left + stack.placed, y, width, height); 3112 } 3113 stack.start = y; 3114 stack.placed += width; 3115 y = box.bottom; 3116 } else { 3117 const height = chartArea.h * weight; 3118 const width = stack.size || box.width; 3119 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.h)(stack.start)) { 3120 x = stack.start; 3121 } 3122 if (box.fullSize) { 3123 setBoxDims(box, x, userPadding.top, width, params.outerHeight - userPadding.bottom - userPadding.top); 3124 } else { 3125 setBoxDims(box, x, chartArea.top + stack.placed, width, height); 3126 } 3127 stack.start = x; 3128 stack.placed += height; 3129 x = box.right; 3130 } 3131 } 3132 chartArea.x = x; 3133 chartArea.y = y; 3134} 3135var layouts = { 3136 addBox (chart, item) { 3137 if (!chart.boxes) { 3138 chart.boxes = []; 3139 } 3140 item.fullSize = item.fullSize || false; 3141 item.position = item.position || 'top'; 3142 item.weight = item.weight || 0; 3143 item._layers = item._layers || function() { 3144 return [ 3145 { 3146 z: 0, 3147 draw (chartArea) { 3148 item.draw(chartArea); 3149 } 3150 } 3151 ]; 3152 }; 3153 chart.boxes.push(item); 3154 }, 3155 removeBox (chart, layoutItem) { 3156 const index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; 3157 if (index !== -1) { 3158 chart.boxes.splice(index, 1); 3159 } 3160 }, 3161 configure (chart, item, options) { 3162 item.fullSize = options.fullSize; 3163 item.position = options.position; 3164 item.weight = options.weight; 3165 }, 3166 update (chart, width, height, minPadding) { 3167 if (!chart) { 3168 return; 3169 } 3170 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(chart.options.layout.padding); 3171 const availableWidth = Math.max(width - padding.width, 0); 3172 const availableHeight = Math.max(height - padding.height, 0); 3173 const boxes = buildLayoutBoxes(chart.boxes); 3174 const verticalBoxes = boxes.vertical; 3175 const horizontalBoxes = boxes.horizontal; 3176 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(chart.boxes, (box)=>{ 3177 if (typeof box.beforeLayout === 'function') { 3178 box.beforeLayout(); 3179 } 3180 }); 3181 const visibleVerticalBoxCount = verticalBoxes.reduce((total, wrap)=>wrap.box.options && wrap.box.options.display === false ? total : total + 1, 0) || 1; 3182 const params = Object.freeze({ 3183 outerWidth: width, 3184 outerHeight: height, 3185 padding, 3186 availableWidth, 3187 availableHeight, 3188 vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount, 3189 hBoxMaxHeight: availableHeight / 2 3190 }); 3191 const maxPadding = Object.assign({}, padding); 3192 updateMaxPadding(maxPadding, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(minPadding)); 3193 const chartArea = Object.assign({ 3194 maxPadding, 3195 w: availableWidth, 3196 h: availableHeight, 3197 x: padding.left, 3198 y: padding.top 3199 }, padding); 3200 const stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params); 3201 fitBoxes(boxes.fullSize, chartArea, params, stacks); 3202 fitBoxes(verticalBoxes, chartArea, params, stacks); 3203 if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) { 3204 fitBoxes(verticalBoxes, chartArea, params, stacks); 3205 } 3206 handleMaxPadding(chartArea); 3207 placeBoxes(boxes.leftAndTop, chartArea, params, stacks); 3208 chartArea.x += chartArea.w; 3209 chartArea.y += chartArea.h; 3210 placeBoxes(boxes.rightAndBottom, chartArea, params, stacks); 3211 chart.chartArea = { 3212 left: chartArea.left, 3213 top: chartArea.top, 3214 right: chartArea.left + chartArea.w, 3215 bottom: chartArea.top + chartArea.h, 3216 height: chartArea.h, 3217 width: chartArea.w 3218 }; 3219 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(boxes.chartArea, (layout)=>{ 3220 const box = layout.box; 3221 Object.assign(box, chart.chartArea); 3222 box.update(chartArea.w, chartArea.h, { 3223 left: 0, 3224 top: 0, 3225 right: 0, 3226 bottom: 0 3227 }); 3228 }); 3229 } 3230}; 3231 3232class BasePlatform { 3233 acquireContext(canvas, aspectRatio) {} 3234 releaseContext(context) { 3235 return false; 3236 } 3237 addEventListener(chart, type, listener) {} 3238 removeEventListener(chart, type, listener) {} 3239 getDevicePixelRatio() { 3240 return 1; 3241 } 3242 getMaximumSize(element, width, height, aspectRatio) { 3243 width = Math.max(0, width || element.width); 3244 height = height || element.height; 3245 return { 3246 width, 3247 height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height) 3248 }; 3249 } 3250 isAttached(canvas) { 3251 return true; 3252 } 3253 updateConfig(config) { 3254 } 3255} 3256 3257class BasicPlatform extends BasePlatform { 3258 acquireContext(item) { 3259 return item && item.getContext && item.getContext('2d') || null; 3260 } 3261 updateConfig(config) { 3262 config.options.animation = false; 3263 } 3264} 3265 3266const EXPANDO_KEY = '$chartjs'; 3267 const EVENT_TYPES = { 3268 touchstart: 'mousedown', 3269 touchmove: 'mousemove', 3270 touchend: 'mouseup', 3271 pointerenter: 'mouseenter', 3272 pointerdown: 'mousedown', 3273 pointermove: 'mousemove', 3274 pointerup: 'mouseup', 3275 pointerleave: 'mouseout', 3276 pointerout: 'mouseout' 3277}; 3278const isNullOrEmpty = (value)=>value === null || value === ''; 3279 function initCanvas(canvas, aspectRatio) { 3280 const style = canvas.style; 3281 const renderHeight = canvas.getAttribute('height'); 3282 const renderWidth = canvas.getAttribute('width'); 3283 canvas[EXPANDO_KEY] = { 3284 initial: { 3285 height: renderHeight, 3286 width: renderWidth, 3287 style: { 3288 display: style.display, 3289 height: style.height, 3290 width: style.width 3291 } 3292 } 3293 }; 3294 style.display = style.display || 'block'; 3295 style.boxSizing = style.boxSizing || 'border-box'; 3296 if (isNullOrEmpty(renderWidth)) { 3297 const displayWidth = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.J)(canvas, 'width'); 3298 if (displayWidth !== undefined) { 3299 canvas.width = displayWidth; 3300 } 3301 } 3302 if (isNullOrEmpty(renderHeight)) { 3303 if (canvas.style.height === '') { 3304 canvas.height = canvas.width / (aspectRatio || 2); 3305 } else { 3306 const displayHeight = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.J)(canvas, 'height'); 3307 if (displayHeight !== undefined) { 3308 canvas.height = displayHeight; 3309 } 3310 } 3311 } 3312 return canvas; 3313} 3314const eventListenerOptions = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.K ? { 3315 passive: true 3316} : false; 3317function addListener(node, type, listener) { 3318 if (node) { 3319 node.addEventListener(type, listener, eventListenerOptions); 3320 } 3321} 3322function removeListener(chart, type, listener) { 3323 if (chart && chart.canvas) { 3324 chart.canvas.removeEventListener(type, listener, eventListenerOptions); 3325 } 3326} 3327function fromNativeEvent(event, chart) { 3328 const type = EVENT_TYPES[event.type] || event.type; 3329 const { x , y } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.z)(event, chart); 3330 return { 3331 type, 3332 chart, 3333 native: event, 3334 x: x !== undefined ? x : null, 3335 y: y !== undefined ? y : null 3336 }; 3337} 3338function nodeListContains(nodeList, canvas) { 3339 for (const node of nodeList){ 3340 if (node === canvas || node.contains(canvas)) { 3341 return true; 3342 } 3343 } 3344} 3345function createAttachObserver(chart, type, listener) { 3346 const canvas = chart.canvas; 3347 const observer = new MutationObserver((entries)=>{ 3348 let trigger = false; 3349 for (const entry of entries){ 3350 trigger = trigger || nodeListContains(entry.addedNodes, canvas); 3351 trigger = trigger && !nodeListContains(entry.removedNodes, canvas); 3352 } 3353 if (trigger) { 3354 listener(); 3355 } 3356 }); 3357 observer.observe(document, { 3358 childList: true, 3359 subtree: true 3360 }); 3361 return observer; 3362} 3363function createDetachObserver(chart, type, listener) { 3364 const canvas = chart.canvas; 3365 const observer = new MutationObserver((entries)=>{ 3366 let trigger = false; 3367 for (const entry of entries){ 3368 trigger = trigger || nodeListContains(entry.removedNodes, canvas); 3369 trigger = trigger && !nodeListContains(entry.addedNodes, canvas); 3370 } 3371 if (trigger) { 3372 listener(); 3373 } 3374 }); 3375 observer.observe(document, { 3376 childList: true, 3377 subtree: true 3378 }); 3379 return observer; 3380} 3381const drpListeningCharts = new Map(); 3382let oldDevicePixelRatio = 0; 3383function onWindowResize() { 3384 const dpr = window.devicePixelRatio; 3385 if (dpr === oldDevicePixelRatio) { 3386 return; 3387 } 3388 oldDevicePixelRatio = dpr; 3389 drpListeningCharts.forEach((resize, chart)=>{ 3390 if (chart.currentDevicePixelRatio !== dpr) { 3391 resize(); 3392 } 3393 }); 3394} 3395function listenDevicePixelRatioChanges(chart, resize) { 3396 if (!drpListeningCharts.size) { 3397 window.addEventListener('resize', onWindowResize); 3398 } 3399 drpListeningCharts.set(chart, resize); 3400} 3401function unlistenDevicePixelRatioChanges(chart) { 3402 drpListeningCharts.delete(chart); 3403 if (!drpListeningCharts.size) { 3404 window.removeEventListener('resize', onWindowResize); 3405 } 3406} 3407function createResizeObserver(chart, type, listener) { 3408 const canvas = chart.canvas; 3409 const container = canvas && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.I)(canvas); 3410 if (!container) { 3411 return; 3412 } 3413 const resize = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.L)((width, height)=>{ 3414 const w = container.clientWidth; 3415 listener(width, height); 3416 if (w < container.clientWidth) { 3417 listener(); 3418 } 3419 }, window); 3420 const observer = new ResizeObserver((entries)=>{ 3421 const entry = entries[0]; 3422 const width = entry.contentRect.width; 3423 const height = entry.contentRect.height; 3424 if (width === 0 && height === 0) { 3425 return; 3426 } 3427 resize(width, height); 3428 }); 3429 observer.observe(container); 3430 listenDevicePixelRatioChanges(chart, resize); 3431 return observer; 3432} 3433function releaseObserver(chart, type, observer) { 3434 if (observer) { 3435 observer.disconnect(); 3436 } 3437 if (type === 'resize') { 3438 unlistenDevicePixelRatioChanges(chart); 3439 } 3440} 3441function createProxyAndListen(chart, type, listener) { 3442 const canvas = chart.canvas; 3443 const proxy = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.L)((event)=>{ 3444 if (chart.ctx !== null) { 3445 listener(fromNativeEvent(event, chart)); 3446 } 3447 }, chart); 3448 addListener(canvas, type, proxy); 3449 return proxy; 3450} 3451 class DomPlatform extends BasePlatform { 3452 acquireContext(canvas, aspectRatio) { 3453 const context = canvas && canvas.getContext && canvas.getContext('2d'); 3454 if (context && context.canvas === canvas) { 3455 initCanvas(canvas, aspectRatio); 3456 return context; 3457 } 3458 return null; 3459 } 3460 releaseContext(context) { 3461 const canvas = context.canvas; 3462 if (!canvas[EXPANDO_KEY]) { 3463 return false; 3464 } 3465 const initial = canvas[EXPANDO_KEY].initial; 3466 [ 3467 'height', 3468 'width' 3469 ].forEach((prop)=>{ 3470 const value = initial[prop]; 3471 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(value)) { 3472 canvas.removeAttribute(prop); 3473 } else { 3474 canvas.setAttribute(prop, value); 3475 } 3476 }); 3477 const style = initial.style || {}; 3478 Object.keys(style).forEach((key)=>{ 3479 canvas.style[key] = style[key]; 3480 }); 3481 canvas.width = canvas.width; 3482 delete canvas[EXPANDO_KEY]; 3483 return true; 3484 } 3485 addEventListener(chart, type, listener) { 3486 this.removeEventListener(chart, type); 3487 const proxies = chart.$proxies || (chart.$proxies = {}); 3488 const handlers = { 3489 attach: createAttachObserver, 3490 detach: createDetachObserver, 3491 resize: createResizeObserver 3492 }; 3493 const handler = handlers[type] || createProxyAndListen; 3494 proxies[type] = handler(chart, type, listener); 3495 } 3496 removeEventListener(chart, type) { 3497 const proxies = chart.$proxies || (chart.$proxies = {}); 3498 const proxy = proxies[type]; 3499 if (!proxy) { 3500 return; 3501 } 3502 const handlers = { 3503 attach: releaseObserver, 3504 detach: releaseObserver, 3505 resize: releaseObserver 3506 }; 3507 const handler = handlers[type] || removeListener; 3508 handler(chart, type, proxy); 3509 proxies[type] = undefined; 3510 } 3511 getDevicePixelRatio() { 3512 return window.devicePixelRatio; 3513 } 3514 getMaximumSize(canvas, width, height, aspectRatio) { 3515 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.G)(canvas, width, height, aspectRatio); 3516 } 3517 isAttached(canvas) { 3518 const container = canvas && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.I)(canvas); 3519 return !!(container && container.isConnected); 3520 } 3521} 3522 3523function _detectPlatform(canvas) { 3524 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.M)() || typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas) { 3525 return BasicPlatform; 3526 } 3527 return DomPlatform; 3528} 3529 3530class Element { 3531 static defaults = {}; 3532 static defaultRoutes = undefined; 3533 x; 3534 y; 3535 active = false; 3536 options; 3537 $animations; 3538 tooltipPosition(useFinalPosition) { 3539 const { x , y } = this.getProps([ 3540 'x', 3541 'y' 3542 ], useFinalPosition); 3543 return { 3544 x, 3545 y 3546 }; 3547 } 3548 hasValue() { 3549 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.x)(this.x) && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.x)(this.y); 3550 } 3551 getProps(props, final) { 3552 const anims = this.$animations; 3553 if (!final || !anims) { 3554 // let's not create an object, if not needed 3555 return this; 3556 } 3557 const ret = {}; 3558 props.forEach((prop)=>{ 3559 ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop]; 3560 }); 3561 return ret; 3562 } 3563} 3564 3565function autoSkip(scale, ticks) { 3566 const tickOpts = scale.options.ticks; 3567 const determinedMaxTicks = determineMaxTicks(scale); 3568 const ticksLimit = Math.min(tickOpts.maxTicksLimit || determinedMaxTicks, determinedMaxTicks); 3569 const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : []; 3570 const numMajorIndices = majorIndices.length; 3571 const first = majorIndices[0]; 3572 const last = majorIndices[numMajorIndices - 1]; 3573 const newTicks = []; 3574 if (numMajorIndices > ticksLimit) { 3575 skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit); 3576 return newTicks; 3577 } 3578 const spacing = calculateSpacing(majorIndices, ticks, ticksLimit); 3579 if (numMajorIndices > 0) { 3580 let i, ilen; 3581 const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null; 3582 skip(ticks, newTicks, spacing, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first); 3583 for(i = 0, ilen = numMajorIndices - 1; i < ilen; i++){ 3584 skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]); 3585 } 3586 skip(ticks, newTicks, spacing, last, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing); 3587 return newTicks; 3588 } 3589 skip(ticks, newTicks, spacing); 3590 return newTicks; 3591} 3592function determineMaxTicks(scale) { 3593 const offset = scale.options.offset; 3594 const tickLength = scale._tickSize(); 3595 const maxScale = scale._length / tickLength + (offset ? 0 : 1); 3596 const maxChart = scale._maxLength / tickLength; 3597 return Math.floor(Math.min(maxScale, maxChart)); 3598} 3599 function calculateSpacing(majorIndices, ticks, ticksLimit) { 3600 const evenMajorSpacing = getEvenSpacing(majorIndices); 3601 const spacing = ticks.length / ticksLimit; 3602 if (!evenMajorSpacing) { 3603 return Math.max(spacing, 1); 3604 } 3605 const factors = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.N)(evenMajorSpacing); 3606 for(let i = 0, ilen = factors.length - 1; i < ilen; i++){ 3607 const factor = factors[i]; 3608 if (factor > spacing) { 3609 return factor; 3610 } 3611 } 3612 return Math.max(spacing, 1); 3613} 3614 function getMajorIndices(ticks) { 3615 const result = []; 3616 let i, ilen; 3617 for(i = 0, ilen = ticks.length; i < ilen; i++){ 3618 if (ticks[i].major) { 3619 result.push(i); 3620 } 3621 } 3622 return result; 3623} 3624 function skipMajors(ticks, newTicks, majorIndices, spacing) {
vendor: 4,532 bytes, lines 3625-3757
3625 let count = 0; 3626 let next = majorIndices[0]; 3627 let i; 3628 spacing = Math.ceil(spacing); 3629 for(i = 0; i < ticks.length; i++){ 3630 if (i === next) { 3631 newTicks.push(ticks[i]); 3632 count++; 3633 next = majorIndices[count * spacing]; 3634 } 3635 } 3636} 3637 function skip(ticks, newTicks, spacing, majorStart, majorEnd) { 3638 const start = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(majorStart, 0); 3639 const end = Math.min((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(majorEnd, ticks.length), ticks.length); 3640 let count = 0; 3641 let length, i, next; 3642 spacing = Math.ceil(spacing); 3643 if (majorEnd) { 3644 length = majorEnd - majorStart; 3645 spacing = length / Math.floor(length / spacing); 3646 } 3647 next = start; 3648 while(next < 0){ 3649 count++; 3650 next = Math.round(start + count * spacing); 3651 } 3652 for(i = Math.max(start, 0); i < end; i++){ 3653 if (i === next) { 3654 newTicks.push(ticks[i]); 3655 count++; 3656 next = Math.round(start + count * spacing); 3657 } 3658 } 3659} 3660 function getEvenSpacing(arr) { 3661 const len = arr.length; 3662 let i, diff; 3663 if (len < 2) { 3664 return false; 3665 } 3666 for(diff = arr[0], i = 1; i < len; ++i){ 3667 if (arr[i] - arr[i - 1] !== diff) { 3668 return false; 3669 } 3670 } 3671 return diff; 3672} 3673 3674const reverseAlign = (align)=>align === 'left' ? 'right' : align === 'right' ? 'left' : align; 3675const offsetFromEdge = (scale, edge, offset)=>edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset; 3676const getTicksLimit = (ticksLength, maxTicksLimit)=>Math.min(maxTicksLimit || ticksLength, ticksLength); 3677 function sample(arr, numItems) { 3678 const result = []; 3679 const increment = arr.length / numItems; 3680 const len = arr.length; 3681 let i = 0; 3682 for(; i < len; i += increment){ 3683 result.push(arr[Math.floor(i)]); 3684 } 3685 return result; 3686} 3687 function getPixelForGridLine(scale, index, offsetGridLines) { 3688 const length = scale.ticks.length; 3689 const validIndex = Math.min(index, length - 1); 3690 const start = scale._startPixel; 3691 const end = scale._endPixel; 3692 const epsilon = 1e-6; 3693 let lineValue = scale.getPixelForTick(validIndex); 3694 let offset; 3695 if (offsetGridLines) { 3696 if (length === 1) { 3697 offset = Math.max(lineValue - start, end - lineValue); 3698 } else if (index === 0) { 3699 offset = (scale.getPixelForTick(1) - lineValue) / 2; 3700 } else { 3701 offset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2; 3702 } 3703 lineValue += validIndex < index ? offset : -offset; 3704 if (lineValue < start - epsilon || lineValue > end + epsilon) { 3705 return; 3706 } 3707 } 3708 return lineValue; 3709} 3710 function garbageCollect(caches, length) { 3711 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(caches, (cache)=>{ 3712 const gc = cache.gc; 3713 const gcLen = gc.length / 2; 3714 let i; 3715 if (gcLen > length) { 3716 for(i = 0; i < gcLen; ++i){ 3717 delete cache.data[gc[i]]; 3718 } 3719 gc.splice(0, gcLen); 3720 } 3721 }); 3722} 3723 function getTickMarkLength(options) { 3724 return options.drawTicks ? options.tickLength : 0; 3725} 3726 function getTitleHeight(options, fallback) { 3727 if (!options.display) { 3728 return 0; 3729 } 3730 const font = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.font, fallback); 3731 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(options.padding); 3732 const lines = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(options.text) ? options.text.length : 1; 3733 return lines * font.lineHeight + padding.height; 3734} 3735function createScaleContext(parent, scale) { 3736 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(parent, { 3737 scale, 3738 type: 'scale' 3739 }); 3740} 3741function createTickContext(parent, index, tick) { 3742 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(parent, { 3743 tick, 3744 index, 3745 type: 'tick' 3746 }); 3747} 3748function titleAlign(align, position, reverse) { 3749 let ret = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a1)(align); 3750 if (reverse && position !== 'right' || !reverse && position === 'right') { 3751 ret = reverseAlign(ret); 3752 } 3753 return ret; 3754} 3755function titleArgs(scale, offset, position, align) { 3756 const { top , left , bottom , right , chart } = scale; 3757 const { chartArea , scales }
3757 = chart; 3758 let rotation = 0; 3759 let maxWidth, titleX, titleY; 3760 const height = bottom - top; 3761 const width = right - left; 3762 if (scale.isHorizontal()) { 3763 titleX = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, left, right); 3764 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 3765 const positionAxisID = Object.keys(position)[0]; 3766 const value = position[positionAxisID]; 3767 titleY = scales[positionAxisID].getPixelForValue(value) + height - offset; 3768 } else if (position === 'center') { 3769 titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset; 3770 } else { 3771 titleY = offsetFromEdge(scale, position, offset); 3772 } 3773 maxWidth = right - left; 3774 } else { 3775 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 3776 const positionAxisID = Object.keys(position)[0]; 3777 const value = position[positionAxisID]; 3778 titleX = scales[positionAxisID].getPixelForValue(value) - width + offset; 3779 } else if (position === 'center') { 3780 titleX = (chartArea.left + chartArea.right) / 2 - width + offset; 3781 } else { 3782 titleX = offsetFromEdge(scale, position, offset); 3783 } 3784 titleY = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, bottom, top); 3785 rotation = position === 'left' ? -_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H : _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H; 3786 } 3787 return { 3788 titleX, 3789 titleY, 3790 maxWidth, 3791 rotation 3792 }; 3793} 3794class Scale extends Element { 3795 constructor(cfg){ 3796 super(); 3797 this.id = cfg.id; 3798 this.type = cfg.type; 3799 this.options = undefined; 3800 this.ctx = cfg.ctx; 3801 this.chart = cfg.chart; 3802 this.top = undefined; 3803 this.bottom = undefined; 3804 this.left = undefined; 3805 this.right = undefined; 3806 this.width = undefined; 3807 this.height = undefined; 3808 this._margins = { 3809 left: 0, 3810 right: 0, 3811 top: 0, 3812 bottom: 0 3813 }; 3814 this.maxWidth = undefined; 3815 this.maxHeight = undefined; 3816 this.paddingTop = undefined; 3817 this.paddingBottom = undefined; 3818 this.paddingLeft = undefined; 3819 this.paddingRight = undefined; 3820 this.axis = undefined; 3821 this.labelRotation = undefined; 3822 this.min = undefined; 3823 this.max = undefined; 3824 this._range = undefined; 3825 this.ticks = []; 3826 this._gridLineItems = null; 3827 this._labelItems = null; 3828 this._labelSizes = null; 3829 this._length = 0; 3830 this._maxLength = 0; 3831 this._longestTextCache = {}; 3832 this._startPixel = undefined; 3833 this._endPixel = undefined; 3834 this._reversePixels = false; 3835 this._userMax = undefined; 3836 this._userMin = undefined; 3837 this._suggestedMax = undefined; 3838 this._suggestedMin = undefined; 3839 this._ticksLength = 0; 3840 this._borderValue = 0; 3841 this._cache = {}; 3842 this._dataLimitsCached = false; 3843 this.$context = undefined; 3844 } 3845 init(options) { 3846 this.options = options.setContext(this.getContext()); 3847 this.axis = options.axis; 3848 this._userMin = this.parse(options.min); 3849 this._userMax = this.parse(options.max); 3850 this._suggestedMin = this.parse(options.suggestedMin); 3851 this._suggestedMax = this.parse(options.suggestedMax); 3852 } 3853 parse(raw, index) { 3854 return raw; 3855 } 3856 getUserBounds() { 3857 let { _userMin , _userMax , _suggestedMin , _suggestedMax } = this; 3858 _userMin = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(_userMin, Number.POSITIVE_INFINITY); 3859 _userMax = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(_userMax, Number.NEGATIVE_INFINITY); 3860 _suggestedMin = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(_suggestedMin, Number.POSITIVE_INFINITY); 3861 _suggestedMax = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(_suggestedMax, Number.NEGATIVE_INFINITY); 3862 return { 3863 min: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(_userMin, _suggestedMin), 3864 max: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(_userMax, _suggestedMax), 3865 minDefined: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(_userMin), 3866 maxDefined: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(_userMax) 3867 }; 3868 } 3869 getMinMax(canStack) { 3870 let { min , max , minDefined , maxDefined } = this.getUserBounds(); 3871 let range; 3872 if (minDefined && maxDefined) { 3873 return { 3874 min, 3875 max 3876 }; 3877 } 3878 const metas = this.getMatchingVisibleMetas(); 3879 for(let i = 0, ilen = metas.length; i < ilen; ++i){ 3880 range = metas[i].controller.getMinMax(this, canStack); 3881 if (!minDefined) { 3882 min = Math.min(min, range.min); 3883 } 3884 if (!maxDefined) { 3885 max = Math.max(max, range.max); 3886 } 3887 } 3888 min = maxDefined && min > max ? max : min; 3889 max = minDefined && min > max ? min : max; 3890 return { 3891 min: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(min, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(max, min)), 3892 max: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(max, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(min, max)) 3893 }; 3894 } 3895 getPadding() { 3896 return { 3897 left: this.paddingLeft || 0, 3898 top: this.paddingTop || 0, 3899 right: this.paddingRight || 0, 3900 bottom: this.paddingBottom || 0 3901 }; 3902 } 3903 getTicks() { 3904 return this.ticks; 3905 } 3906 getLabels() { 3907 const data = this.chart.data; 3908 return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || []; 3909 } 3910 getLabelItems(chartArea = this.chart.chartArea) { 3911 const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea)); 3912 return items; 3913 } 3914 beforeLayout() { 3915 this._cache = {}; 3916 this._dataLimitsCached = false;
vendor: 14,999 bytes, lines 3917-4265
3917 } 3918 beforeUpdate() { 3919 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.beforeUpdate, [ 3920 this 3921 ]); 3922 } 3923 update(maxWidth, maxHeight, margins) { 3924 const { beginAtZero , grace , ticks: tickOpts } = this.options; 3925 const sampleSize = tickOpts.sampleSize; 3926 this.beforeUpdate(); 3927 this.maxWidth = maxWidth; 3928 this.maxHeight = maxHeight; 3929 this._margins = margins = Object.assign({ 3930 left: 0, 3931 right: 0, 3932 top: 0, 3933 bottom: 0 3934 }, margins); 3935 this.ticks = null; 3936 this._labelSizes = null; 3937 this._gridLineItems = null; 3938 this._labelItems = null; 3939 this.beforeSetDimensions(); 3940 this.setDimensions(); 3941 this.afterSetDimensions(); 3942 this._maxLength = this.isHorizontal() ? this.width + margins.left + margins.right : this.height + margins.top + margins.bottom; 3943 if (!this._dataLimitsCached) { 3944 this.beforeDataLimits(); 3945 this.determineDataLimits(); 3946 this.afterDataLimits(); 3947 this._range = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.R)(this, grace, beginAtZero); 3948 this._dataLimitsCached = true; 3949 } 3950 this.beforeBuildTicks(); 3951 this.ticks = this.buildTicks() || []; 3952 this.afterBuildTicks(); 3953 const samplingEnabled = sampleSize < this.ticks.length; 3954 this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks); 3955 this.configure(); 3956 this.beforeCalculateLabelRotation(); 3957 this.calculateLabelRotation(); 3958 this.afterCalculateLabelRotation(); 3959 if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) { 3960 this.ticks = autoSkip(this, this.ticks); 3961 this._labelSizes = null; 3962 this.afterAutoSkip(); 3963 } 3964 if (samplingEnabled) { 3965 this._convertTicksToLabels(this.ticks); 3966 } 3967 this.beforeFit(); 3968 this.fit(); 3969 this.afterFit(); 3970 this.afterUpdate(); 3971 } 3972 configure() { 3973 let reversePixels = this.options.reverse; 3974 let startPixel, endPixel; 3975 if (this.isHorizontal()) { 3976 startPixel = this.left; 3977 endPixel = this.right; 3978 } else { 3979 startPixel = this.top; 3980 endPixel = this.bottom; 3981 reversePixels = !reversePixels; 3982 } 3983 this._startPixel = startPixel; 3984 this._endPixel = endPixel; 3985 this._reversePixels = reversePixels; 3986 this._length = endPixel - startPixel; 3987 this._alignToPixels = this.options.alignToPixels; 3988 } 3989 afterUpdate() { 3990 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.afterUpdate, [ 3991 this 3992 ]); 3993 } 3994 beforeSetDimensions() { 3995 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.beforeSetDimensions, [ 3996 this 3997 ]); 3998 } 3999 setDimensions() { 4000 if (this.isHorizontal()) { 4001 this.width = this.maxWidth; 4002 this.left = 0; 4003 this.right = this.width; 4004 } else { 4005 this.height = this.maxHeight; 4006 this.top = 0; 4007 this.bottom = this.height; 4008 } 4009 this.paddingLeft = 0; 4010 this.paddingTop = 0; 4011 this.paddingRight = 0; 4012 this.paddingBottom = 0; 4013 } 4014 afterSetDimensions() { 4015 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.afterSetDimensions, [ 4016 this 4017 ]); 4018 } 4019 _callHooks(name) { 4020 this.chart.notifyPlugins(name, this.getContext()); 4021 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options[name], [ 4022 this 4023 ]); 4024 } 4025 beforeDataLimits() { 4026 this._callHooks('beforeDataLimits'); 4027 } 4028 determineDataLimits() {} 4029 afterDataLimits() { 4030 this._callHooks('afterDataLimits'); 4031 } 4032 beforeBuildTicks() { 4033 this._callHooks('beforeBuildTicks'); 4034 } 4035 buildTicks() { 4036 return []; 4037 } 4038 afterBuildTicks() { 4039 this._callHooks('afterBuildTicks'); 4040 } 4041 beforeTickToLabelConversion() { 4042 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.beforeTickToLabelConversion, [ 4043 this 4044 ]); 4045 } 4046 generateTickLabels(ticks) { 4047 const tickOpts = this.options.ticks; 4048 let i, ilen, tick; 4049 for(i = 0, ilen = ticks.length; i < ilen; i++){ 4050 tick = ticks[i]; 4051 tick.label = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(tickOpts.callback, [ 4052 tick.value, 4053 i, 4054 ticks 4055 ], this); 4056 } 4057 } 4058 afterTickToLabelConversion() { 4059 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.afterTickToLabelConversion, [ 4060 this 4061 ]); 4062 } 4063 beforeCalculateLabelRotation() { 4064 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.beforeCalculateLabelRotation, [ 4065 this 4066 ]); 4067 } 4068 calculateLabelRotation() { 4069 const options = this.options; 4070 const tickOpts = options.ticks; 4071 const numTicks = getTicksLimit(this.ticks.length, options.ticks.maxTicksLimit); 4072 const minRotation = tickOpts.minRotation || 0; 4073 const maxRotation = tickOpts.maxRotation; 4074 let labelRotation = minRotation; 4075 let tickWidth, maxHeight, maxLabelDiagonal; 4076 if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) { 4077 this.labelRotation = minRotation; 4078 return; 4079 } 4080 const labelSizes = this._getLabelSizes(); 4081 const maxLabelWidth = labelSizes.widest.width; 4082 const maxLabelHeight = labelSizes.highest.height; 4083 const maxWidth = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(this.chart.width - maxLabelWidth, 0, this.maxWidth); 4084 tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1); 4085 if (maxLabelWidth + 6 > tickWidth) { 4086 tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1)); 4087 maxHeight = this.maxHeight - getTickMarkLength(options.grid) - tickOpts.padding - getTitleHeight(options.title, this.chart.options.font); 4088 maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight); 4089 labelRotation = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.U)(Math.min(Math.asin((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)((labelSizes.highest.height + 6) / tickWidth, -1, 1)), Math.asin((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(maxLabelHeight / maxLabelDiagonal, -1, 1)))); 4090 labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation)); 4091 } 4092 this.labelRotation = labelRotation; 4093 } 4094 afterCalculateLabelRotation() { 4095 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.afterCalculateLabelRotation, [ 4096 this 4097 ]); 4098 } 4099 afterAutoSkip() {} 4100 beforeFit() { 4101 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.beforeFit, [ 4102 this 4103 ]); 4104 } 4105 fit() { 4106 const minSize = { 4107 width: 0, 4108 height: 0 4109 }; 4110 const { chart , options: { ticks: tickOpts , title: titleOpts , grid: gridOpts } } = this; 4111 const display = this._isVisible(); 4112 const isHorizontal = this.isHorizontal(); 4113 if (display) { 4114 const titleHeight = getTitleHeight(titleOpts, chart.options.font); 4115 if (isHorizontal) { 4116 minSize.width = this.maxWidth; 4117 minSize.height = getTickMarkLength(gridOpts) + titleHeight; 4118 } else { 4119 minSize.height = this.maxHeight; 4120 minSize.width = getTickMarkLength(gridOpts) + titleHeight; 4121 } 4122 if (tickOpts.display && this.ticks.length) { 4123 const { first , last , widest , highest } = this._getLabelSizes(); 4124 const tickPadding = tickOpts.padding * 2; 4125 const angleRadians = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.labelRotation); 4126 const cos = Math.cos(angleRadians); 4127 const sin = Math.sin(angleRadians); 4128 if (isHorizontal) { 4129 const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height; 4130 minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding); 4131 } else { 4132 const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height; 4133 minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding); 4134 } 4135 this._calculatePadding(first, last, sin, cos); 4136 } 4137 } 4138 this._handleMargins(); 4139 if (isHorizontal) { 4140 this.width = this._length = chart.width - this._margins.left - this._margins.right; 4141 this.height = minSize.height; 4142 } else { 4143 this.width = minSize.width; 4144 this.height = this._length = chart.height - this._margins.top - this._margins.bottom; 4145 } 4146 } 4147 _calculatePadding(first, last, sin, cos) { 4148 const { ticks: { align , padding } , position } = this.options; 4149 const isRotated = this.labelRotation !== 0; 4150 const labelsBelowTicks = position !== 'top' && this.axis === 'x'; 4151 if (this.isHorizontal()) { 4152 const offsetLeft = this.getPixelForTick(0) - this.left; 4153 const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1); 4154 let paddingLeft = 0; 4155 let paddingRight = 0; 4156 if (isRotated) { 4157 if (labelsBelowTicks) { 4158 paddingLeft = cos * first.width; 4159 paddingRight = sin * last.height; 4160 } else { 4161 paddingLeft = sin * first.height; 4162 paddingRight = cos * last.width; 4163 } 4164 } else if (align === 'start') { 4165 paddingRight = last.width; 4166 } else if (align === 'end') { 4167 paddingLeft = first.width; 4168 } else if (align !== 'inner') { 4169 paddingLeft = first.width / 2; 4170 paddingRight = last.width / 2; 4171 } 4172 this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0); 4173 this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0); 4174 } else { 4175 let paddingTop = last.height / 2; 4176 let paddingBottom = first.height / 2; 4177 if (align === 'start') { 4178 paddingTop = 0; 4179 paddingBottom = first.height; 4180 } else if (align === 'end') { 4181 paddingTop = last.height; 4182 paddingBottom = 0; 4183 } 4184 this.paddingTop = paddingTop + padding; 4185 this.paddingBottom = paddingBottom + padding; 4186 } 4187 } 4188 _handleMargins() { 4189 if (this._margins) { 4190 this._margins.left = Math.max(this.paddingLeft, this._margins.left); 4191 this._margins.top = Math.max(this.paddingTop, this._margins.top); 4192 this._margins.right = Math.max(this.paddingRight, this._margins.right); 4193 this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom); 4194 } 4195 } 4196 afterFit() { 4197 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.afterFit, [ 4198 this 4199 ]); 4200 } 4201 isHorizontal() { 4202 const { axis , position } = this.options; 4203 return position === 'top' || position === 'bottom' || axis === 'x'; 4204 } 4205 isFullSize() { 4206 return this.options.fullSize; 4207 } 4208 _convertTicksToLabels(ticks) { 4209 this.beforeTickToLabelConversion(); 4210 this.generateTickLabels(ticks); 4211 let i, ilen; 4212 for(i = 0, ilen = ticks.length; i < ilen; i++){ 4213 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(ticks[i].label)) { 4214 ticks.splice(i, 1); 4215 ilen--; 4216 i--; 4217 } 4218 } 4219 this.afterTickToLabelConversion(); 4220 } 4221 _getLabelSizes() { 4222 let labelSizes = this._labelSizes; 4223 if (!labelSizes) { 4224 const sampleSize = this.options.ticks.sampleSize; 4225 let ticks = this.ticks; 4226 if (sampleSize < ticks.length) { 4227 ticks = sample(ticks, sampleSize); 4228 } 4229 this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit); 4230 } 4231 return labelSizes; 4232 } 4233 _computeLabelSizes(ticks, length, maxTicksLimit) { 4234 const { ctx , _longestTextCache: caches } = this; 4235 const widths = []; 4236 const heights = []; 4237 const increment = Math.floor(length / getTicksLimit(length, maxTicksLimit)); 4238 let widestLabelSize = 0; 4239 let highestLabelSize = 0; 4240 let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel; 4241 for(i = 0; i < length; i += increment){ 4242 label = ticks[i].label; 4243 tickFont = this._resolveTickFontOptions(i); 4244 ctx.font = fontString = tickFont.string; 4245 cache = caches[fontString] = caches[fontString] || { 4246 data: {}, 4247 gc: [] 4248 }; 4249 lineHeight = tickFont.lineHeight; 4250 width = height = 0; 4251 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(label) && !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(label)) { 4252 width = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.V)(ctx, cache.data, cache.gc, width, label); 4253 height = lineHeight; 4254 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(label)) { 4255 for(j = 0, jlen = label.length; j < jlen; ++j){ 4256 nestedLabel = label[j]; 4257 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(nestedLabel) && !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(nestedLabel)) { 4258 width = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.V)(ctx, cache.data, cache.gc, width, nestedLabel); 4259 height += lineHeight; 4260 } 4261 } 4262 } 4263 widths.push(width); 4264 heights.push(height); 4265 widestLabelSize = Math.max(width, widestLabelSize);
vendor: 16,384 bytes, lines 4266-4648
4266 highestLabelSize = Math.max(height, highestLabelSize); 4267 } 4268 garbageCollect(caches, length); 4269 const widest = widths.indexOf(widestLabelSize); 4270 const highest = heights.indexOf(highestLabelSize); 4271 const valueAt = (idx)=>({ 4272 width: widths[idx] || 0, 4273 height: heights[idx] || 0 4274 }); 4275 return { 4276 first: valueAt(0), 4277 last: valueAt(length - 1), 4278 widest: valueAt(widest), 4279 highest: valueAt(highest), 4280 widths, 4281 heights 4282 }; 4283 } 4284 getLabelForValue(value) { 4285 return value; 4286 } 4287 getPixelForValue(value, index) { 4288 return NaN; 4289 } 4290 getValueForPixel(pixel) {} 4291 getPixelForTick(index) { 4292 const ticks = this.ticks; 4293 if (index < 0 || index > ticks.length - 1) { 4294 return null; 4295 } 4296 return this.getPixelForValue(ticks[index].value); 4297 } 4298 getPixelForDecimal(decimal) { 4299 if (this._reversePixels) { 4300 decimal = 1 - decimal; 4301 } 4302 const pixel = this._startPixel + decimal * this._length; 4303 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.W)(this._alignToPixels ? (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(this.chart, pixel, 0) : pixel); 4304 } 4305 getDecimalForPixel(pixel) { 4306 const decimal = (pixel - this._startPixel) / this._length; 4307 return this._reversePixels ? 1 - decimal : decimal; 4308 } 4309 getBasePixel() { 4310 return this.getPixelForValue(this.getBaseValue()); 4311 } 4312 getBaseValue() { 4313 const { min , max } = this; 4314 return min < 0 && max < 0 ? max : min > 0 && max > 0 ? min : 0; 4315 } 4316 getContext(index) { 4317 const ticks = this.ticks || []; 4318 if (index >= 0 && index < ticks.length) { 4319 const tick = ticks[index]; 4320 return tick.$context || (tick.$context = createTickContext(this.getContext(), index, tick)); 4321 } 4322 return this.$context || (this.$context = createScaleContext(this.chart.getContext(), this)); 4323 } 4324 _tickSize() { 4325 const optionTicks = this.options.ticks; 4326 const rot = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.labelRotation); 4327 const cos = Math.abs(Math.cos(rot)); 4328 const sin = Math.abs(Math.sin(rot)); 4329 const labelSizes = this._getLabelSizes(); 4330 const padding = optionTicks.autoSkipPadding || 0; 4331 const w = labelSizes ? labelSizes.widest.width + padding : 0; 4332 const h = labelSizes ? labelSizes.highest.height + padding : 0; 4333 return this.isHorizontal() ? h * cos > w * sin ? w / cos : h / sin : h * sin < w * cos ? h / cos : w / sin; 4334 } 4335 _isVisible() { 4336 const display = this.options.display; 4337 if (display !== 'auto') { 4338 return !!display; 4339 } 4340 return this.getMatchingVisibleMetas().length > 0; 4341 } 4342 _computeGridLineItems(chartArea) { 4343 const axis = this.axis; 4344 const chart = this.chart; 4345 const options = this.options; 4346 const { grid , position , border } = options; 4347 const offset = grid.offset; 4348 const isHorizontal = this.isHorizontal(); 4349 const ticks = this.ticks; 4350 const ticksLength = ticks.length + (offset ? 1 : 0); 4351 const tl = getTickMarkLength(grid); 4352 const items = []; 4353 const borderOpts = border.setContext(this.getContext()); 4354 const axisWidth = borderOpts.display ? borderOpts.width : 0; 4355 const axisHalfWidth = axisWidth / 2; 4356 const alignBorderValue = function(pixel) { 4357 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(chart, pixel, axisWidth); 4358 }; 4359 let borderValue, i, lineValue, alignedLineValue; 4360 let tx1, ty1, tx2, ty2, x1, y1, x2, y2; 4361 if (position === 'top') { 4362 borderValue = alignBorderValue(this.bottom); 4363 ty1 = this.bottom - tl; 4364 ty2 = borderValue - axisHalfWidth; 4365 y1 = alignBorderValue(chartArea.top) + axisHalfWidth; 4366 y2 = chartArea.bottom; 4367 } else if (position === 'bottom') { 4368 borderValue = alignBorderValue(this.top); 4369 y1 = chartArea.top; 4370 y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth; 4371 ty1 = borderValue + axisHalfWidth; 4372 ty2 = this.top + tl; 4373 } else if (position === 'left') { 4374 borderValue = alignBorderValue(this.right); 4375 tx1 = this.right - tl; 4376 tx2 = borderValue - axisHalfWidth; 4377 x1 = alignBorderValue(chartArea.left) + axisHalfWidth; 4378 x2 = chartArea.right; 4379 } else if (position === 'right') { 4380 borderValue = alignBorderValue(this.left); 4381 x1 = chartArea.left; 4382 x2 = alignBorderValue(chartArea.right) - axisHalfWidth; 4383 tx1 = borderValue + axisHalfWidth; 4384 tx2 = this.left + tl; 4385 } else if (axis === 'x') { 4386 if (position === 'center') { 4387 borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5); 4388 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 4389 const positionAxisID = Object.keys(position)[0]; 4390 const value = position[positionAxisID]; 4391 borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); 4392 } 4393 y1 = chartArea.top; 4394 y2 = chartArea.bottom; 4395 ty1 = borderValue + axisHalfWidth; 4396 ty2 = ty1 + tl; 4397 } else if (axis === 'y') { 4398 if (position === 'center') { 4399 borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2); 4400 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 4401 const positionAxisID = Object.keys(position)[0]; 4402 const value = position[positionAxisID]; 4403 borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); 4404 } 4405 tx1 = borderValue - axisHalfWidth; 4406 tx2 = tx1 - tl; 4407 x1 = chartArea.left; 4408 x2 = chartArea.right; 4409 } 4410 const limit = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(options.ticks.maxTicksLimit, ticksLength); 4411 const step = Math.max(1, Math.ceil(ticksLength / limit)); 4412 for(i = 0; i < ticksLength; i += step){ 4413 const context = this.getContext(i); 4414 const optsAtIndex = grid.setContext(context); 4415 const optsAtIndexBorder = border.setContext(context); 4416 const lineWidth = optsAtIndex.lineWidth; 4417 const lineColor = optsAtIndex.color; 4418 const borderDash = optsAtIndexBorder.dash || []; 4419 const borderDashOffset = optsAtIndexBorder.dashOffset; 4420 const tickWidth = optsAtIndex.tickWidth; 4421 const tickColor = optsAtIndex.tickColor; 4422 const tickBorderDash = optsAtIndex.tickBorderDash || []; 4423 const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset; 4424 lineValue = getPixelForGridLine(this, i, offset); 4425 if (lineValue === undefined) { 4426 continue; 4427 } 4428 alignedLineValue = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(chart, lineValue, lineWidth); 4429 if (isHorizontal) { 4430 tx1 = tx2 = x1 = x2 = alignedLineValue; 4431 } else { 4432 ty1 = ty2 = y1 = y2 = alignedLineValue; 4433 } 4434 items.push({ 4435 tx1, 4436 ty1, 4437 tx2, 4438 ty2, 4439 x1, 4440 y1, 4441 x2, 4442 y2, 4443 width: lineWidth, 4444 color: lineColor, 4445 borderDash, 4446 borderDashOffset, 4447 tickWidth, 4448 tickColor, 4449 tickBorderDash, 4450 tickBorderDashOffset 4451 }); 4452 } 4453 this._ticksLength = ticksLength; 4454 this._borderValue = borderValue; 4455 return items; 4456 } 4457 _computeLabelItems(chartArea) { 4458 const axis = this.axis; 4459 const options = this.options; 4460 const { position , ticks: optionTicks } = options; 4461 const isHorizontal = this.isHorizontal(); 4462 const ticks = this.ticks; 4463 const { align , crossAlign , padding , mirror } = optionTicks; 4464 const tl = getTickMarkLength(options.grid); 4465 const tickAndPadding = tl + padding; 4466 const hTickAndPadding = mirror ? -padding : tickAndPadding; 4467 const rotation = -(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.labelRotation); 4468 const items = []; 4469 let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset; 4470 let textBaseline = 'middle'; 4471 if (position === 'top') { 4472 y = this.bottom - hTickAndPadding; 4473 textAlign = this._getXAxisLabelAlignment(); 4474 } else if (position === 'bottom') { 4475 y = this.top + hTickAndPadding; 4476 textAlign = this._getXAxisLabelAlignment(); 4477 } else if (position === 'left') { 4478 const ret = this._getYAxisLabelAlignment(tl); 4479 textAlign = ret.textAlign; 4480 x = ret.x; 4481 } else if (position === 'right') { 4482 const ret = this._getYAxisLabelAlignment(tl); 4483 textAlign = ret.textAlign; 4484 x = ret.x; 4485 } else if (axis === 'x') { 4486 if (position === 'center') { 4487 y = (chartArea.top + chartArea.bottom) / 2 + tickAndPadding; 4488 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 4489 const positionAxisID = Object.keys(position)[0]; 4490 const value = position[positionAxisID]; 4491 y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding; 4492 } 4493 textAlign = this._getXAxisLabelAlignment(); 4494 } else if (axis === 'y') { 4495 if (position === 'center') { 4496 x = (chartArea.left + chartArea.right) / 2 - tickAndPadding; 4497 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 4498 const positionAxisID = Object.keys(position)[0]; 4499 const value = position[positionAxisID]; 4500 x = this.chart.scales[positionAxisID].getPixelForValue(value); 4501 } 4502 textAlign = this._getYAxisLabelAlignment(tl).textAlign; 4503 } 4504 if (axis === 'y') { 4505 if (align === 'start') { 4506 textBaseline = 'top'; 4507 } else if (align === 'end') { 4508 textBaseline = 'bottom'; 4509 } 4510 } 4511 const labelSizes = this._getLabelSizes(); 4512 for(i = 0, ilen = ticks.length; i < ilen; ++i){ 4513 tick = ticks[i]; 4514 label = tick.label; 4515 const optsAtIndex = optionTicks.setContext(this.getContext(i)); 4516 pixel = this.getPixelForTick(i) + optionTicks.labelOffset; 4517 font = this._resolveTickFontOptions(i); 4518 lineHeight = font.lineHeight; 4519 lineCount = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(label) ? label.length : 1; 4520 const halfCount = lineCount / 2; 4521 const color = optsAtIndex.color; 4522 const strokeColor = optsAtIndex.textStrokeColor; 4523 const strokeWidth = optsAtIndex.textStrokeWidth; 4524 let tickTextAlign = textAlign; 4525 if (isHorizontal) { 4526 x = pixel; 4527 if (textAlign === 'inner') { 4528 if (i === ilen - 1) { 4529 tickTextAlign = !this.options.reverse ? 'right' : 'left'; 4530 } else if (i === 0) { 4531 tickTextAlign = !this.options.reverse ? 'left' : 'right'; 4532 } else { 4533 tickTextAlign = 'center'; 4534 } 4535 } 4536 if (position === 'top') { 4537 if (crossAlign === 'near' || rotation !== 0) { 4538 textOffset = -lineCount * lineHeight + lineHeight / 2; 4539 } else if (crossAlign === 'center') { 4540 textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight; 4541 } else { 4542 textOffset = -labelSizes.highest.height + lineHeight / 2; 4543 } 4544 } else { 4545 if (crossAlign === 'near' || rotation !== 0) { 4546 textOffset = lineHeight / 2; 4547 } else if (crossAlign === 'center') { 4548 textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight; 4549 } else { 4550 textOffset = labelSizes.highest.height - lineCount * lineHeight; 4551 } 4552 } 4553 if (mirror) { 4554 textOffset *= -1; 4555 } 4556 if (rotation !== 0 && !optsAtIndex.showLabelBackdrop) { 4557 x += lineHeight / 2 * Math.sin(rotation); 4558 } 4559 } else { 4560 y = pixel; 4561 textOffset = (1 - lineCount) * lineHeight / 2; 4562 } 4563 let backdrop; 4564 if (optsAtIndex.showLabelBackdrop) { 4565 const labelPadding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(optsAtIndex.backdropPadding); 4566 const height = labelSizes.heights[i]; 4567 const width = labelSizes.widths[i]; 4568 let top = textOffset - labelPadding.top; 4569 let left = 0 - labelPadding.left; 4570 switch(textBaseline){ 4571 case 'middle': 4572 top -= height / 2; 4573 break; 4574 case 'bottom': 4575 top -= height; 4576 break; 4577 } 4578 switch(textAlign){ 4579 case 'center': 4580 left -= width / 2; 4581 break; 4582 case 'right': 4583 left -= width; 4584 break; 4585 case 'inner': 4586 if (i === ilen - 1) { 4587 left -= width; 4588 } else if (i > 0) { 4589 left -= width / 2; 4590 } 4591 break; 4592 } 4593 backdrop = { 4594 left, 4595 top, 4596 width: width + labelPadding.width, 4597 height: height + labelPadding.height, 4598 color: optsAtIndex.backdropColor 4599 }; 4600 } 4601 items.push({ 4602 label, 4603 font, 4604 textOffset, 4605 options: { 4606 rotation, 4607 color, 4608 strokeColor, 4609 strokeWidth, 4610 textAlign: tickTextAlign, 4611 textBaseline, 4612 translation: [ 4613 x, 4614 y 4615 ], 4616 backdrop 4617 } 4618 }); 4619 } 4620 return items; 4621 } 4622 _getXAxisLabelAlignment() { 4623 const { position , ticks } = this.options; 4624 const rotation = -(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.labelRotation); 4625 if (rotation) { 4626 return position === 'top' ? 'left' : 'right'; 4627 } 4628 let align = 'center'; 4629 if (ticks.align === 'start') { 4630 align = 'left'; 4631 } else if (ticks.align === 'end') { 4632 align = 'right'; 4633 } else if (ticks.align === 'inner') { 4634 align = 'inner'; 4635 } 4636 return align; 4637 } 4638 _getYAxisLabelAlignment(tl) { 4639 const { position , ticks: { crossAlign , mirror , padding } } = this.options; 4640 const labelSizes = this._getLabelSizes(); 4641 const tickAndPadding = tl + padding; 4642 const widest = labelSizes.widest.width; 4643 let textAlign; 4644 let x; 4645 if (position === 'left') { 4646 if (mirror) { 4647 x = this.right + padding; 4648 if (crossAlign =
vendor: 6,083 bytes, lines 4648-4820
4648== 'near') { 4649 textAlign = 'left'; 4650 } else if (crossAlign === 'center') { 4651 textAlign = 'center'; 4652 x += widest / 2; 4653 } else { 4654 textAlign = 'right'; 4655 x += widest; 4656 } 4657 } else { 4658 x = this.right - tickAndPadding; 4659 if (crossAlign === 'near') { 4660 textAlign = 'right'; 4661 } else if (crossAlign === 'center') { 4662 textAlign = 'center'; 4663 x -= widest / 2; 4664 } else { 4665 textAlign = 'left'; 4666 x = this.left; 4667 } 4668 } 4669 } else if (position === 'right') { 4670 if (mirror) { 4671 x = this.left + padding; 4672 if (crossAlign === 'near') { 4673 textAlign = 'right'; 4674 } else if (crossAlign === 'center') { 4675 textAlign = 'center'; 4676 x -= widest / 2; 4677 } else { 4678 textAlign = 'left'; 4679 x -= widest; 4680 } 4681 } else { 4682 x = this.left + tickAndPadding; 4683 if (crossAlign === 'near') { 4684 textAlign = 'left'; 4685 } else if (crossAlign === 'center') { 4686 textAlign = 'center'; 4687 x += widest / 2; 4688 } else { 4689 textAlign = 'right'; 4690 x = this.right; 4691 } 4692 } 4693 } else { 4694 textAlign = 'right'; 4695 } 4696 return { 4697 textAlign, 4698 x 4699 }; 4700 } 4701 _computeLabelArea() { 4702 if (this.options.ticks.mirror) { 4703 return; 4704 } 4705 const chart = this.chart; 4706 const position = this.options.position; 4707 if (position === 'left' || position === 'right') { 4708 return { 4709 top: 0, 4710 left: this.left, 4711 bottom: chart.height, 4712 right: this.right 4713 }; 4714 } 4715 if (position === 'top' || position === 'bottom') { 4716 return { 4717 top: this.top, 4718 left: 0, 4719 bottom: this.bottom, 4720 right: chart.width 4721 }; 4722 } 4723 } 4724 drawBackground() { 4725 const { ctx , options: { backgroundColor } , left , top , width , height } = this; 4726 if (backgroundColor) { 4727 ctx.save(); 4728 ctx.fillStyle = backgroundColor; 4729 ctx.fillRect(left, top, width, height); 4730 ctx.restore(); 4731 } 4732 } 4733 getLineWidthForValue(value) { 4734 const grid = this.options.grid; 4735 if (!this._isVisible() || !grid.display) { 4736 return 0; 4737 } 4738 const ticks = this.ticks; 4739 const index = ticks.findIndex((t)=>t.value === value); 4740 if (index >= 0) { 4741 const opts = grid.setContext(this.getContext(index)); 4742 return opts.lineWidth; 4743 } 4744 return 0; 4745 } 4746 drawGrid(chartArea) { 4747 const grid = this.options.grid; 4748 const ctx = this.ctx; 4749 const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea)); 4750 let i, ilen; 4751 const drawLine = (p1, p2, style)=>{ 4752 if (!style.width || !style.color) { 4753 return; 4754 } 4755 ctx.save(); 4756 ctx.lineWidth = style.width; 4757 ctx.strokeStyle = style.color; 4758 ctx.setLineDash(style.borderDash || []); 4759 ctx.lineDashOffset = style.borderDashOffset; 4760 ctx.beginPath(); 4761 ctx.moveTo(p1.x, p1.y); 4762 ctx.lineTo(p2.x, p2.y); 4763 ctx.stroke(); 4764 ctx.restore(); 4765 }; 4766 if (grid.display) { 4767 for(i = 0, ilen = items.length; i < ilen; ++i){ 4768 const item = items[i]; 4769 if (grid.drawOnChartArea) { 4770 drawLine({ 4771 x: item.x1, 4772 y: item.y1 4773 }, { 4774 x: item.x2, 4775 y: item.y2 4776 }, item); 4777 } 4778 if (grid.drawTicks) { 4779 drawLine({ 4780 x: item.tx1, 4781 y: item.ty1 4782 }, { 4783 x: item.tx2, 4784 y: item.ty2 4785 }, { 4786 color: item.tickColor, 4787 width: item.tickWidth, 4788 borderDash: item.tickBorderDash, 4789 borderDashOffset: item.tickBorderDashOffset 4790 }); 4791 } 4792 } 4793 } 4794 } 4795 drawBorder() { 4796 const { chart , ctx , options: { border , grid } } = this; 4797 const borderOpts = border.setContext(this.getContext()); 4798 const axisWidth = border.display ? borderOpts.width : 0; 4799 if (!axisWidth) { 4800 return; 4801 } 4802 const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth; 4803 const borderValue = this._borderValue; 4804 let x1, x2, y1, y2; 4805 if (this.isHorizontal()) { 4806 x1 = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(chart, this.left, axisWidth) - axisWidth / 2; 4807 x2 = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(chart, this.right, lastLineWidth) + lastLineWidth / 2; 4808 y1 = y2 = borderValue; 4809 } else { 4810 y1 = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(chart, this.top, axisWidth) - axisWidth / 2; 4811 y2 = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.X)(chart, this.bottom, lastLineWidth) + lastLineWidth / 2; 4812 x1 = x2 = borderValue; 4813 } 4814 ctx.save(); 4815 ctx.lineWidth = borderOpts.width; 4816 ctx.strokeStyle = borderOpts.color; 4817 ctx.beginPath(); 4818 ctx.moveTo(x1, y1); 4819 ctx.lineTo(x2, y2); 4820 ctx.stroke();
4821 ctx.restore(); 4822 } 4823 drawLabels(chartArea) { 4824 const optionTicks = this.options.ticks; 4825 if (!optionTicks.display) { 4826 return; 4827 } 4828 const ctx = this.ctx; 4829 const area = this._computeLabelArea(); 4830 if (area) { 4831 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Y)(ctx, area); 4832 } 4833 const items = this.getLabelItems(chartArea); 4834 for (const item of items){ 4835 const renderTextOptions = item.options; 4836 const tickFont = item.font; 4837 const label = item.label; 4838 const y = item.textOffset; 4839 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, label, 0, y, tickFont, renderTextOptions); 4840 } 4841 if (area) { 4842 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.$)(ctx); 4843 } 4844 } 4845 drawTitle() { 4846 const { ctx , options: { position , title , reverse } } = this; 4847 if (!title.display) { 4848 return; 4849 } 4850 const font = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(title.font); 4851 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(title.padding); 4852 const align = title.align; 4853 let offset = font.lineHeight / 2; 4854 if (position === 'bottom' || position === 'center' || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(position)) { 4855 offset += padding.bottom; 4856 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(title.text)) { 4857 offset += font.lineHeight * (title.text.length - 1); 4858 } 4859 } else { 4860 offset += padding.top; 4861 } 4862 const { titleX , titleY , maxWidth , rotation } = titleArgs(this, offset, position, align); 4863 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, title.text, 0, 0, font, { 4864 color: title.color, 4865 maxWidth, 4866 rotation, 4867 textAlign: titleAlign(align, position, reverse), 4868 textBaseline: 'middle', 4869 translation: [ 4870 titleX, 4871 titleY 4872 ] 4873 }); 4874 } 4875 draw(chartArea) { 4876 if (!this._isVisible()) { 4877 return; 4878 } 4879 this.drawBackground(); 4880 this.drawGrid(chartArea); 4881 this.drawBorder(); 4882 this.drawTitle(); 4883 this.drawLabels(chartArea); 4884 } 4885 _layers() { 4886 const opts = this.options; 4887 const tz = opts.ticks && opts.ticks.z || 0; 4888 const gz = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(opts.grid && opts.grid.z, -1); 4889 const bz = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(opts.border && opts.border.z, 0); 4890 if (!this._isVisible() || this.draw !== Scale.prototype.draw) { 4891 return [ 4892 { 4893 z: tz, 4894 draw: (chartArea)=>{ 4895 this.draw(chartArea); 4896 } 4897 } 4898 ]; 4899 } 4900 return [ 4901 { 4902 z: gz, 4903 draw: (chartArea)=>{ 4904 this.drawBackground(); 4905 this.drawGrid(chartArea); 4906 this.drawTitle(); 4907 } 4908 }, 4909 { 4910 z: bz, 4911 draw: ()=>{ 4912 this.drawBorder(); 4913 } 4914 }, 4915 { 4916 z: tz, 4917 draw: (chartArea)=>{ 4918 this.drawLabels(chartArea); 4919 } 4920 } 4921 ]; 4922 } 4923 getMatchingVisibleMetas(type) { 4924 const metas = this.chart.getSortedVisibleDatasetMetas(); 4925 const axisID = this.axis + 'AxisID'; 4926 const result = []; 4927 let i, ilen; 4928 for(i = 0, ilen = metas.length; i < ilen; ++i){ 4929 const meta = metas[i]; 4930 if (meta[axisID] === this.id && (!type || meta.type === type)) { 4931 result.push(meta); 4932 } 4933 } 4934 return result; 4935 } 4936 _resolveTickFontOptions(index) { 4937 const opts = this.options.ticks.setContext(this.getContext(index)); 4938 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(opts.font); 4939 } 4940 _maxDigits() { 4941 const fontSize = this._resolveTickFontOptions(0).lineHeight; 4942 return (this.isHorizontal() ? this.width : this.height) / fontSize; 4943 } 4944} 4945 4946class TypedRegistry { 4947 constructor(type, scope, override){ 4948 this.type = type; 4949 this.scope = scope; 4950 this.override = override; 4951 this.items = Object.create(null); 4952 } 4953 isForType(type) {
vendor: 17,669 bytes, lines 4954-5475
4954 return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype); 4955 } 4956 register(item) { 4957 const proto = Object.getPrototypeOf(item); 4958 let parentScope; 4959 if (isIChartComponent(proto)) { 4960 parentScope = this.register(proto); 4961 } 4962 const items = this.items; 4963 const id = item.id; 4964 const scope = this.scope + '.' + id; 4965 if (!id) { 4966 throw new Error('class does not have id: ' + item); 4967 } 4968 if (id in items) { 4969 return scope; 4970 } 4971 items[id] = item; 4972 registerDefaults(item, scope, parentScope); 4973 if (this.override) { 4974 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.override(item.id, item.overrides); 4975 } 4976 return scope; 4977 } 4978 get(id) { 4979 return this.items[id]; 4980 } 4981 unregister(item) { 4982 const items = this.items; 4983 const id = item.id; 4984 const scope = this.scope; 4985 if (id in items) { 4986 delete items[id]; 4987 } 4988 if (scope && id in _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d[scope]) { 4989 delete _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d[scope][id]; 4990 if (this.override) { 4991 delete _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a3[id]; 4992 } 4993 } 4994 } 4995} 4996function registerDefaults(item, scope, parentScope) { 4997 const itemDefaults = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a4)(Object.create(null), [ 4998 parentScope ? _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.get(parentScope) : {}, 4999 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.get(scope), 5000 item.defaults 5001 ]); 5002 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.set(scope, itemDefaults); 5003 if (item.defaultRoutes) { 5004 routeDefaults(scope, item.defaultRoutes); 5005 } 5006 if (item.descriptors) { 5007 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.describe(scope, item.descriptors); 5008 } 5009} 5010function routeDefaults(scope, routes) { 5011 Object.keys(routes).forEach((property)=>{ 5012 const propertyParts = property.split('.'); 5013 const sourceName = propertyParts.pop(); 5014 const sourceScope = [ 5015 scope 5016 ].concat(propertyParts).join('.'); 5017 const parts = routes[property].split('.'); 5018 const targetName = parts.pop(); 5019 const targetScope = parts.join('.'); 5020 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.route(sourceScope, sourceName, targetScope, targetName); 5021 }); 5022} 5023function isIChartComponent(proto) { 5024 return 'id' in proto && 'defaults' in proto; 5025} 5026 5027class Registry { 5028 constructor(){ 5029 this.controllers = new TypedRegistry(DatasetController, 'datasets', true); 5030 this.elements = new TypedRegistry(Element, 'elements'); 5031 this.plugins = new TypedRegistry(Object, 'plugins'); 5032 this.scales = new TypedRegistry(Scale, 'scales'); 5033 this._typedRegistries = [ 5034 this.controllers, 5035 this.scales, 5036 this.elements 5037 ]; 5038 } 5039 add(...args) { 5040 this._each('register', args); 5041 } 5042 remove(...args) { 5043 this._each('unregister', args); 5044 } 5045 addControllers(...args) { 5046 this._each('register', args, this.controllers); 5047 } 5048 addElements(...args) { 5049 this._each('register', args, this.elements); 5050 } 5051 addPlugins(...args) { 5052 this._each('register', args, this.plugins); 5053 } 5054 addScales(...args) { 5055 this._each('register', args, this.scales); 5056 } 5057 getController(id) { 5058 return this._get(id, this.controllers, 'controller'); 5059 } 5060 getElement(id) { 5061 return this._get(id, this.elements, 'element'); 5062 } 5063 getPlugin(id) { 5064 return this._get(id, this.plugins, 'plugin'); 5065 } 5066 getScale(id) { 5067 return this._get(id, this.scales, 'scale'); 5068 } 5069 removeControllers(...args) { 5070 this._each('unregister', args, this.controllers); 5071 } 5072 removeElements(...args) { 5073 this._each('unregister', args, this.elements); 5074 } 5075 removePlugins(...args) { 5076 this._each('unregister', args, this.plugins); 5077 } 5078 removeScales(...args) { 5079 this._each('unregister', args, this.scales); 5080 } 5081 _each(method, args, typedRegistry) { 5082 [ 5083 ...args 5084 ].forEach((arg)=>{ 5085 const reg = typedRegistry || this._getRegistryForType(arg); 5086 if (typedRegistry || reg.isForType(arg) || reg === this.plugins && arg.id) { 5087 this._exec(method, reg, arg); 5088 } else { 5089 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(arg, (item)=>{ 5090 const itemReg = typedRegistry || this._getRegistryForType(item); 5091 this._exec(method, itemReg, item); 5092 }); 5093 } 5094 }); 5095 } 5096 _exec(method, registry, component) { 5097 const camelMethod = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a5)(method); 5098 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(component['before' + camelMethod], [], component); 5099 registry[method](component); 5100 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(component['after' + camelMethod], [], component); 5101 } 5102 _getRegistryForType(type) { 5103 for(let i = 0; i < this._typedRegistries.length; i++){ 5104 const reg = this._typedRegistries[i]; 5105 if (reg.isForType(type)) { 5106 return reg; 5107 } 5108 } 5109 return this.plugins; 5110 } 5111 _get(id, typedRegistry, type) { 5112 const item = typedRegistry.get(id); 5113 if (item === undefined) { 5114 throw new Error('"' + id + '" is not a registered ' + type + '.'); 5115 } 5116 return item; 5117 } 5118} 5119var registry = /* #__PURE__ */ new Registry(); 5120 5121class PluginService { 5122 constructor(){ 5123 this._init = undefined; 5124 } 5125 notify(chart, hook, args, filter) { 5126 if (hook === 'beforeInit') { 5127 this._init = this._createDescriptors(chart, true); 5128 this._notify(this._init, chart, 'install'); 5129 } 5130 if (this._init === undefined) { 5131 return; 5132 } 5133 const descriptors = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart); 5134 const result = this._notify(descriptors, chart, hook, args); 5135 if (hook === 'afterDestroy') { 5136 this._notify(descriptors, chart, 'stop'); 5137 this._notify(this._init, chart, 'uninstall'); 5138 this._init = undefined; 5139 } 5140 return result; 5141 } 5142 _notify(descriptors, chart, hook, args) { 5143 args = args || {}; 5144 for (const descriptor of descriptors){ 5145 const plugin = descriptor.plugin; 5146 const method = plugin[hook]; 5147 const params = [ 5148 chart, 5149 args, 5150 descriptor.options 5151 ]; 5152 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(method, params, plugin) === false && args.cancelable) { 5153 return false; 5154 } 5155 } 5156 return true; 5157 } 5158 invalidate() { 5159 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(this._cache)) { 5160 this._oldCache = this._cache; 5161 this._cache = undefined; 5162 } 5163 } 5164 _descriptors(chart) { 5165 if (this._cache) { 5166 return this._cache; 5167 } 5168 const descriptors = this._cache = this._createDescriptors(chart); 5169 this._notifyStateChanges(chart); 5170 return descriptors; 5171 } 5172 _createDescriptors(chart, all) { 5173 const config = chart && chart.config; 5174 const options = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(config.options && config.options.plugins, {}); 5175 const plugins = allPlugins(config); 5176 return options === false && !all ? [] : createDescriptors(chart, plugins, options, all); 5177 } 5178 _notifyStateChanges(chart) { 5179 const previousDescriptors = this._oldCache || []; 5180 const descriptors = this._cache; 5181 const diff = (a, b)=>a.filter((x)=>!b.some((y)=>x.plugin.id === y.plugin.id)); 5182 this._notify(diff(previousDescriptors, descriptors), chart, 'stop'); 5183 this._notify(diff(descriptors, previousDescriptors), chart, 'start'); 5184 } 5185} 5186 function allPlugins(config) { 5187 const localIds = {}; 5188 const plugins = []; 5189 const keys = Object.keys(registry.plugins.items); 5190 for(let i = 0; i < keys.length; i++){ 5191 plugins.push(registry.getPlugin(keys[i])); 5192 } 5193 const local = config.plugins || []; 5194 for(let i = 0; i < local.length; i++){ 5195 const plugin = local[i]; 5196 if (plugins.indexOf(plugin) === -1) { 5197 plugins.push(plugin); 5198 localIds[plugin.id] = true; 5199 } 5200 } 5201 return { 5202 plugins, 5203 localIds 5204 }; 5205} 5206function getOpts(options, all) { 5207 if (!all && options === false) { 5208 return null; 5209 } 5210 if (options === true) { 5211 return {}; 5212 } 5213 return options; 5214} 5215function createDescriptors(chart, { plugins , localIds }, options, all) { 5216 const result = []; 5217 const context = chart.getContext(); 5218 for (const plugin of plugins){ 5219 const id = plugin.id; 5220 const opts = getOpts(options[id], all); 5221 if (opts === null) { 5222 continue; 5223 } 5224 result.push({ 5225 plugin, 5226 options: pluginOpts(chart.config, { 5227 plugin, 5228 local: localIds[id] 5229 }, opts, context) 5230 }); 5231 } 5232 return result; 5233} 5234function pluginOpts(config, { plugin , local }, opts, context) { 5235 const keys = config.pluginScopeKeys(plugin); 5236 const scopes = config.getOptionScopes(opts, keys); 5237 if (local && plugin.defaults) { 5238 scopes.push(plugin.defaults); 5239 } 5240 return config.createResolver(scopes, context, [ 5241 '' 5242 ], { 5243 scriptable: false, 5244 indexable: false, 5245 allKeys: true 5246 }); 5247} 5248 5249function getIndexAxis(type, options) { 5250 const datasetDefaults = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.datasets[type] || {}; 5251 const datasetOptions = (options.datasets || {})[type] || {}; 5252 return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x'; 5253} 5254function getAxisFromDefaultScaleID(id, indexAxis) { 5255 let axis = id; 5256 if (id === '_index_') { 5257 axis = indexAxis; 5258 } else if (id === '_value_') { 5259 axis = indexAxis === 'x' ? 'y' : 'x'; 5260 } 5261 return axis; 5262} 5263function getDefaultScaleIDFromAxis(axis, indexAxis) { 5264 return axis === indexAxis ? '_index_' : '_value_'; 5265} 5266function idMatchesAxis(id) { 5267 if (id === 'x' || id === 'y' || id === 'r') { 5268 return id; 5269 } 5270} 5271function axisFromPosition(position) { 5272 if (position === 'top' || position === 'bottom') { 5273 return 'x'; 5274 } 5275 if (position === 'left' || position === 'right') { 5276 return 'y'; 5277 } 5278} 5279function determineAxis(id, ...scaleOptions) { 5280 if (idMatchesAxis(id)) { 5281 return id; 5282 } 5283 for (const opts of scaleOptions){ 5284 const axis = opts.axis || axisFromPosition(opts.position) || id.length > 1 && idMatchesAxis(id[0].toLowerCase()); 5285 if (axis) { 5286 return axis; 5287 } 5288 } 5289 throw new Error(`Cannot determine type of '${id}' axis. Please provide 'axis' or 'position' option.`); 5290} 5291function getAxisFromDataset(id, axis, dataset) { 5292 if (dataset[axis + 'AxisID'] === id) { 5293 return { 5294 axis 5295 }; 5296 } 5297} 5298function retrieveAxisFromDatasets(id, config) { 5299 if (config.data && config.data.datasets) { 5300 const boundDs = config.data.datasets.filter((d)=>d.xAxisID === id || d.yAxisID === id); 5301 if (boundDs.length) { 5302 return getAxisFromDataset(id, 'x', boundDs[0]) || getAxisFromDataset(id, 'y', boundDs[0]); 5303 } 5304 } 5305 return {}; 5306} 5307function mergeScaleConfig(config, options) { 5308 const chartDefaults = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a3[config.type] || { 5309 scales: {} 5310 }; 5311 const configScales = options.scales || {}; 5312 const chartIndexAxis = getIndexAxis(config.type, options); 5313 const scales = Object.create(null); 5314 Object.keys(configScales).forEach((id)=>{ 5315 const scaleConf = configScales[id]; 5316 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(scaleConf)) { 5317 return console.error(`Invalid scale configuration for scale: ${id}`); 5318 } 5319 if (scaleConf._proxy) { 5320 return console.warn(`Ignoring resolver passed as options for scale: ${id}`); 5321 } 5322 const axis = determineAxis(id, scaleConf, retrieveAxisFromDatasets(id, config), _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.scales[scaleConf.type]); 5323 const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis); 5324 const defaultScaleOptions = chartDefaults.scales || {}; 5325 scales[id] = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ab)(Object.create(null), [ 5326 { 5327 axis 5328 }, 5329 scaleConf, 5330 defaultScaleOptions[axis], 5331 defaultScaleOptions[defaultId] 5332 ]); 5333 }); 5334 config.data.datasets.forEach((dataset)=>{ 5335 const type = dataset.type || config.type; 5336 const indexAxis = dataset.indexAxis || getIndexAxis(type, options); 5337 const datasetDefaults = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a3[type] || {}; 5338 const defaultScaleOptions = datasetDefaults.scales || {}; 5339 Object.keys(defaultScaleOptions).forEach((defaultID)=>{ 5340 const axis = getAxisFromDefaultScaleID(defaultID, indexAxis); 5341 const id = dataset[axis + 'AxisID'] || axis; 5342 scales[id] = scales[id] || Object.create(null); 5343 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ab)(scales[id], [ 5344 { 5345 axis 5346 }, 5347 configScales[id], 5348 defaultScaleOptions[defaultID] 5349 ]); 5350 }); 5351 }); 5352 Object.keys(scales).forEach((key)=>{ 5353 const scale = scales[key]; 5354 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ab)(scale, [ 5355 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.scales[scale.type], 5356 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.scale 5357 ]); 5358 }); 5359 return scales; 5360} 5361function initOptions(config) { 5362 const options = config.options || (config.options = {}); 5363 options.plugins = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(options.plugins, {}); 5364 options.scales = mergeScaleConfig(config, options); 5365} 5366function initData(data) { 5367 data = data || {}; 5368 data.datasets = data.datasets || []; 5369 data.labels = data.labels || []; 5370 return data; 5371} 5372function initConfig(config) { 5373 config = config || {}; 5374 config.data = initData(config.data); 5375 initOptions(config); 5376 return config; 5377} 5378const keyCache = new Map(); 5379const keysCached = new Set(); 5380function cachedKeys(cacheKey, generate) { 5381 let keys = keyCache.get(cacheKey); 5382 if (!keys) { 5383 keys = generate(); 5384 keyCache.set(cacheKey, keys); 5385 keysCached.add(keys); 5386 } 5387 return keys; 5388} 5389const addIfFound = (set, obj, key)=>{ 5390 const opts = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.f)(obj, key); 5391 if (opts !== undefined) { 5392 set.add(opts); 5393 } 5394}; 5395class Config { 5396 constructor(config){ 5397 this._config = initConfig(config); 5398 this._scopeCache = new Map(); 5399 this._resolverCache = new Map(); 5400 } 5401 get platform() { 5402 return this._config.platform; 5403 } 5404 get type() { 5405 return this._config.type; 5406 } 5407 set type(type) { 5408 this._config.type = type; 5409 } 5410 get data() { 5411 return this._config.data; 5412 } 5413 set data(data) { 5414 this._config.data = initData(data); 5415 } 5416 get options() { 5417 return this._config.options; 5418 } 5419 set options(options) { 5420 this._config.options = options; 5421 } 5422 get plugins() { 5423 return this._config.plugins; 5424 } 5425 update() { 5426 const config = this._config; 5427 this.clearCache(); 5428 initOptions(config); 5429 } 5430 clearCache() { 5431 this._scopeCache.clear(); 5432 this._resolverCache.clear(); 5433 } 5434 datasetScopeKeys(datasetType) { 5435 return cachedKeys(datasetType, ()=>[ 5436 [ 5437 `datasets.${datasetType}`, 5438 '' 5439 ] 5440 ]); 5441 } 5442 datasetAnimationScopeKeys(datasetType, transition) { 5443 return cachedKeys(`${datasetType}.transition.${transition}`, ()=>[ 5444 [ 5445 `datasets.${datasetType}.transitions.${transition}`, 5446 `transitions.${transition}` 5447 ], 5448 [ 5449 `datasets.${datasetType}`, 5450 '' 5451 ] 5452 ]); 5453 } 5454 datasetElementScopeKeys(datasetType, elementType) { 5455 return cachedKeys(`${datasetType}-${elementType}`, ()=>[ 5456 [ 5457 `datasets.${datasetType}.elements.${elementType}`, 5458 `datasets.${datasetType}`, 5459 `elements.${elementType}`, 5460 '' 5461 ] 5462 ]); 5463 } 5464 pluginScopeKeys(plugin) { 5465 const id = plugin.id; 5466 const type = this.type; 5467 return cachedKeys(`${type}-plugin-${id}`, ()=>[ 5468 [ 5469 `plugins.${id}`, 5470 ...plugin.additionalOptionScopes || [] 5471 ] 5472 ]); 5473 } 5474 _cachedScopes(mainScope, resetCache) { 5475 const _scopeCache = this._scopeCache;
5476 let cache = _scopeCache.get(mainScope); 5477 if (!cache || resetCache) { 5478 cache = new Map(); 5479 _scopeCache.set(mainScope, cache); 5480 } 5481 return cache; 5482 } 5483 getOptionScopes(mainScope, keyLists, resetCache) { 5484 const { options , type } = this; 5485 const cache = this._cachedScopes(mainScope, resetCache); 5486 const cached = cache.get(keyLists); 5487 if (cached) { 5488 return cached; 5489 } 5490 const scopes = new Set(); 5491 keyLists.forEach((keys)=>{ 5492 if (mainScope) { 5493 scopes.add(mainScope); 5494 keys.forEach((key)=>addIfFound(scopes, mainScope, key)); 5495 } 5496 keys.forEach((key)=>addIfFound(scopes, options, key)); 5497 keys.forEach((key)=>addIfFound(scopes, _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a3[type] || {}, key)); 5498 keys.forEach((key)=>addIfFound(scopes, _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d, key)); 5499 keys.forEach((key)=>addIfFound(scopes, _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a6, key)); 5500 }); 5501 const array = Array.from(scopes); 5502 if (array.length === 0) { 5503 array.push(Object.create(null)); 5504 } 5505 if (keysCached.has(keyLists)) { 5506 cache.set(keyLists, array); 5507 } 5508 return array; 5509 } 5510 chartOptionScopes() { 5511 const { options , type } = this; 5512 return [ 5513 options, 5514 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a3[type] || {}, 5515 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.datasets[type] || {}, 5516 { 5517 type 5518 }, 5519 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d, 5520 _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a6 5521 ]; 5522 } 5523 resolveNamedOptions(scopes, names, context, prefixes = [ 5524 '' 5525 ]) { 5526 const result = { 5527 $shared: true 5528 }; 5529 const { resolver , subPrefixes } = getResolver(this._resolverCache, scopes, prefixes); 5530 let options = resolver; 5531 if (needContext(resolver, names)) { 5532 result.$shared = false; 5533 context = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a7)(context) ? context() : context; 5534 const subResolver = this.createResolver(scopes, context, subPrefixes); 5535 options = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a8)(resolver, context, subResolver); 5536 } 5537 for (const prop of names){ 5538 result[prop] = options[prop]; 5539 } 5540 return result; 5541 } 5542 createResolver(scopes, context, prefixes = [ 5543 '' 5544 ], descriptorDefaults) { 5545 const { resolver } = getResolver(this._resolverCache, scopes, prefixes); 5546 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(context) ? (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a8)(resolver, context, undefined, descriptorDefaults) : resolver; 5547 } 5548} 5549function getResolver(resolverCache, scopes, prefixes) {
5550 let cache = resolverCache.get(scopes); 5551 if (!cache) { 5552 cache = new Map(); 5553 resolverCache.set(scopes, cache); 5554 } 5555 const cacheKey = prefixes.join(); 5556 let cached = cache.get(cacheKey); 5557 if (!cached) { 5558 const resolver = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a9)(scopes, prefixes); 5559 cached = { 5560 resolver, 5561 subPrefixes: prefixes.filter((p)=>!p.toLowerCase().includes('hover')) 5562 }; 5563 cache.set(cacheKey, cached); 5564 } 5565 return cached; 5566} 5567const hasFunction = (value)=>(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(value) && Object.getOwnPropertyNames(value).some((key)=>(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a7)(value[key])); 5568function needContext(proxy, names) { 5569 const { isScriptable , isIndexable } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aa)(proxy); 5570 for (const prop of names){ 5571 const scriptable = isScriptable(prop); 5572 const indexable = isIndexable(prop); 5573 const value = (indexable || scriptable) && proxy[prop]; 5574 if (scriptable && ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a7)(value) || hasFunction(value)) || indexable && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(value)) { 5575 return true; 5576 } 5577 } 5578 return false; 5579} 5580 5581var version = "4.5.1"; 5582 5583const KNOWN_POSITIONS = [ 5584 'top', 5585 'bottom', 5586 'left', 5587 'right', 5588 'chartArea' 5589]; 5590function positionIsHorizontal(position, axis) { 5591 return position === 'top' || position === 'bottom' || KNOWN_POSITIONS.indexOf(position) === -1 && axis === 'x'; 5592} 5593function compare2Level(l1, l2) { 5594 return function(a, b) { 5595 return a[l1] === b[l1] ? a[l2] - b[l2] : a[l1] - b[l1]; 5596 }; 5597} 5598function onAnimationsComplete(context) { 5599 const chart = context.chart; 5600 const animationOptions = chart.options.animation; 5601 chart.notifyPlugins('afterRender'); 5602 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(animationOptions && animationOptions.onComplete, [ 5603 context 5604 ], chart); 5605} 5606function onAnimationProgress(context) { 5607 const chart = context.chart; 5608 const animationOptions = chart.options.animation; 5609 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(animationOptions && animationOptions.onProgress, [ 5610 context 5611 ], chart); 5612} 5613 function getCanvas(item) { 5614 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.M)() && typeof item === 'string') { 5615 item = document.getElementById(item); 5616 } else if (item && item.length) { 5617 item = item[0]; 5618 } 5619 if (item && item.canvas) { 5620 item = item.canvas; 5621 } 5622 return item; 5623} 5624const instances = {}; 5625const getChart = (key)=>{ 5626 const canvas = getCanvas(key); 5627 return Object.values(instances).filter((c)=>c.canvas === canvas).pop(); 5628}; 5629function moveNumericKeys(obj, start, move) { 5630 const keys = Object.keys(obj); 5631 for (const key of keys){ 5632 const intKey = +key; 5633 if (intKey >= start) { 5634 const value = obj[key]; 5635 delete obj[key]; 5636 if (move > 0 || intKey > start) { 5637 obj[intKey + move] = value; 5638 } 5639 } 5640 } 5641} 5642 function determineLastEvent(e, lastEvent, inChartArea, isClick) { 5643 if (!inChartArea || e.type === 'mouseout') { 5644 return null; 5645 } 5646 if (isClick) { 5647 return lastEvent; 5648 } 5649 return e; 5650} 5651class Chart { 5652 static defaults = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d; 5653 static instances = instances; 5654 static overrides = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a3; 5655 static registry = registry; 5656 static version = version; 5657 static getChart = getChart; 5658 static register(...items) { 5659 registry.add(...items); 5660 invalidatePlugins(); 5661 } 5662 static unregister(...items) { 5663 registry.remove(...items); 5664 invalidatePlugins(); 5665 } 5666 constructor(item, userConfig){ 5667 const config = this.config = new Config(userConfig); 5668 const initialCanvas = getCanvas(item); 5669 const existingChart = getChart(initialCanvas); 5670 if (existingChart) { 5671 throw new Error('Canvas is already in use. Chart with ID \'' + existingChart.id + '\'' + ' must be destroyed before the canvas with ID \'' + existingChart.canvas.id + '\' can be reused.'); 5672 } 5673 const options = config.createResolver(config.chartOptionScopes(), this.getContext()); 5674 this.platform = new (config.platform || _detectPlatform(initialCanvas))(); 5675 this.platform.updateConfig(config); 5676 const context = this.platform.acquireContext(initialCanvas, options.aspectRatio); 5677 const canvas = context && context.canvas; 5678 const height = canvas && canvas.height; 5679 const width = canvas && canvas.width; 5680 this.id = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ac)(); 5681 this.ctx = context; 5682 this.canvas = canvas; 5683 this.width = width; 5684 this.height = height; 5685 this._options = options; 5686 this._aspectRatio = this.aspectRatio; 5687 this._layers = []; 5688 this._metasets = []; 5689 this._stacks = undefined; 5690 this.boxes = []; 5691 this.currentDevicePixelRatio = undefined; 5692 this.chartArea = undefined; 5693 this._active = []; 5694 this._lastEvent = undefined; 5695 this._listeners = {}; 5696 this._responsiveListeners = undefined; 5697 this._sortedMetasets = []; 5698 this.scales = {}; 5699 this._plugins = new PluginService(); 5700 this.$proxies = {}; 5701 this._hiddenIndices = {}; 5702 this.attached = false;
5703 this._animationsDisabled = undefined; 5704 this.$context = undefined; 5705 this._doResize = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ad)((mode)=>this.update(mode), options.resizeDelay || 0); 5706 this._dataChanges = []; 5707 instances[this.id] = this; 5708 if (!context || !canvas) { 5709 console.error("Failed to create chart: can't acquire context from the given item"); 5710 return; 5711 } 5712 animator.listen(this, 'complete', onAnimationsComplete); 5713 animator.listen(this, 'progress', onAnimationProgress); 5714 this._initialize(); 5715 if (this.attached) { 5716 this.update(); 5717 } 5718 } 5719 get aspectRatio() { 5720 const { options: { aspectRatio , maintainAspectRatio } , width , height , _aspectRatio } = this; 5721 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(aspectRatio)) { 5722 return aspectRatio; 5723 } 5724 if (maintainAspectRatio && _aspectRatio) { 5725 return _aspectRatio; 5726 } 5727 return height ? width / height : null; 5728 } 5729 get data() { 5730 return this.config.data; 5731 } 5732 set data(data) { 5733 this.config.data = data; 5734 } 5735 get options() { 5736 return this._options; 5737 } 5738 set options(options) { 5739 this.config.options = options; 5740 } 5741 get registry() { 5742 return registry; 5743 } 5744 _initialize() { 5745 this.notifyPlugins('beforeInit'); 5746 if (this.options.responsive) { 5747 this.resize(); 5748 } else { 5749 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ae)(this, this.options.devicePixelRatio); 5750 } 5751 this.bindEvents(); 5752 this.notifyPlugins('afterInit'); 5753 return this; 5754 } 5755 clear() { 5756 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.af)(this.canvas, this.ctx); 5757 return this; 5758 } 5759 stop() { 5760 animator.stop(this); 5761 return this; 5762 } 5763 resize(width, height) { 5764 if (!animator.running(this)) { 5765 this._resize(width, height); 5766 } else { 5767 this._resizeBeforeDraw = { 5768 width, 5769 height 5770 }; 5771 } 5772 } 5773 _resize(width, height) { 5774 const options = this.options; 5775 const canvas = this.canvas; 5776 const aspectRatio = options.maintainAspectRatio && this.aspectRatio; 5777 const newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio); 5778 const newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio(); 5779 const mode = this.width ? 'resize' : 'attach'; 5780 this.width = newSize.width; 5781 this.height = newSize.height; 5782 this._aspectRatio = this.aspectRatio; 5783 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ae)(this, newRatio, true)) { 5784 return; 5785 } 5786 this.notifyPlugins('resize', { 5787 size: newSize 5788 }); 5789 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(options.onResize, [ 5790 this, 5791 newSize 5792 ], this); 5793 if (this.attached) { 5794 if (this._doResize(mode)) { 5795 this.render(); 5796 } 5797 } 5798 } 5799 ensureScalesHaveIDs() { 5800 const options = this.options; 5801 const scalesOptions = options.scales || {}; 5802 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(scalesOptions, (axisOptions, axisID)=>{ 5803 axisOptions.id = axisID; 5804 }); 5805 } 5806 buildOrUpdateScales() { 5807 const options = this.options; 5808 const scaleOpts = options.scales; 5809 const scales = this.scales; 5810 const updated = Object.keys(scales).reduce((obj, id)=>{ 5811 obj[id] = false; 5812 return obj; 5813 }, {}); 5814 let items = []; 5815 if (scaleOpts) { 5816 items = items.concat(Object.keys(scaleOpts).map((id)=>{ 5817 const scaleOptions = scaleOpts[id]; 5818 const axis = determineAxis(id, scaleOptions); 5819 const isRadial = axis === 'r'; 5820 const isHorizontal = axis === 'x'; 5821 return { 5822 options: scaleOptions, 5823 dposition: isRadial ? 'chartArea' : isHorizontal ? 'bottom' : 'left', 5824 dtype: isRadial ? 'radialLinear' : isHorizontal ? 'category' : 'linear' 5825 }; 5826 })); 5827 } 5828 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(items, (item)=>{ 5829 const scaleOptions = item.options; 5830 const id = scaleOptions.id; 5831 const axis = determineAxis(id, scaleOptions); 5832 const scaleType = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(scaleOptions.type, item.dtype); 5833 if (scaleOptions.position === undefined || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) { 5834 scaleOptions.position = item.dposition; 5835 } 5836 updated[id] = true; 5837 let scale = null; 5838 if (id in scales && scales[id].type === scaleType) { 5839 scale = scales[id]; 5840 } else { 5841 const scaleClass = registry.getScale(scaleType); 5842 scale = new scaleClass({ 5843 id, 5844 type: scaleType, 5845 ctx: this.ctx, 5846 chart: this 5847 }); 5848 scales[scale.id] = scale; 5849 } 5850 scale.init(scaleOptions, options); 5851 }); 5852 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(updated, (hasUpdated, id)=>{ 5853 if (!hasUpdated) { 5854 delete scales[id]; 5855 } 5856 }); 5857 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(scales, (scale)=>{ 5858 layouts.configure(this, scale, scale.options); 5859 layouts.addBox(this, scale); 5860 }); 5861 } 5862 _updateMetasets() { 5863 const metasets = this._metasets; 5864 const numData = this.data.datasets.length; 5865 const numMeta = metasets.length; 5866 metasets.sort((a, b)=>a.index - b.index); 5867 if (numMeta > numData) { 5868 for(let i = numData; i < numMeta; ++i){ 5869 this._destroyDatasetMeta(i); 5870 } 5871 metasets.splice(numData, numMeta - numData); 5872 } 5873 this._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index')); 5874 } 5875 _removeUnreferencedMetasets() { 5876 const { _metasets: metasets , data: { datasets } } = this; 5877 if (metasets.length > datasets.length) { 5878 delete this._stacks; 5879 }
vendor: 20,282 bytes, lines 5880-6436
5880 metasets.forEach((meta, index)=>{ 5881 if (datasets.filter((x)=>x === meta._dataset).length === 0) { 5882 this._destroyDatasetMeta(index); 5883 } 5884 }); 5885 } 5886 buildOrUpdateControllers() { 5887 const newControllers = []; 5888 const datasets = this.data.datasets; 5889 let i, ilen; 5890 this._removeUnreferencedMetasets(); 5891 for(i = 0, ilen = datasets.length; i < ilen; i++){ 5892 const dataset = datasets[i]; 5893 let meta = this.getDatasetMeta(i); 5894 const type = dataset.type || this.config.type; 5895 if (meta.type && meta.type !== type) { 5896 this._destroyDatasetMeta(i); 5897 meta = this.getDatasetMeta(i); 5898 } 5899 meta.type = type; 5900 meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options); 5901 meta.order = dataset.order || 0; 5902 meta.index = i; 5903 meta.label = '' + dataset.label; 5904 meta.visible = this.isDatasetVisible(i); 5905 if (meta.controller) { 5906 meta.controller.updateIndex(i); 5907 meta.controller.linkScales(); 5908 } else { 5909 const ControllerClass = registry.getController(type); 5910 const { datasetElementType , dataElementType } = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.datasets[type]; 5911 Object.assign(ControllerClass, { 5912 dataElementType: registry.getElement(dataElementType), 5913 datasetElementType: datasetElementType && registry.getElement(datasetElementType) 5914 }); 5915 meta.controller = new ControllerClass(this, i); 5916 newControllers.push(meta.controller); 5917 } 5918 } 5919 this._updateMetasets(); 5920 return newControllers; 5921 } 5922 _resetElements() { 5923 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this.data.datasets, (dataset, datasetIndex)=>{ 5924 this.getDatasetMeta(datasetIndex).controller.reset(); 5925 }, this); 5926 } 5927 reset() { 5928 this._resetElements(); 5929 this.notifyPlugins('reset'); 5930 } 5931 update(mode) { 5932 const config = this.config; 5933 config.update(); 5934 const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext()); 5935 const animsDisabled = this._animationsDisabled = !options.animation; 5936 this._updateScales(); 5937 this._checkEventBindings(); 5938 this._updateHiddenIndices(); 5939 this._plugins.invalidate(); 5940 if (this.notifyPlugins('beforeUpdate', { 5941 mode, 5942 cancelable: true 5943 }) === false) { 5944 return; 5945 } 5946 const newControllers = this.buildOrUpdateControllers(); 5947 this.notifyPlugins('beforeElementsUpdate'); 5948 let minPadding = 0; 5949 for(let i = 0, ilen = this.data.datasets.length; i < ilen; i++){ 5950 const { controller } = this.getDatasetMeta(i); 5951 const reset = !animsDisabled && newControllers.indexOf(controller) === -1; 5952 controller.buildOrUpdateElements(reset); 5953 minPadding = Math.max(+controller.getMaxOverflow(), minPadding); 5954 } 5955 minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0; 5956 this._updateLayout(minPadding); 5957 if (!animsDisabled) { 5958 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(newControllers, (controller)=>{ 5959 controller.reset(); 5960 }); 5961 } 5962 this._updateDatasets(mode); 5963 this.notifyPlugins('afterUpdate', { 5964 mode 5965 }); 5966 this._layers.sort(compare2Level('z', '_idx')); 5967 const { _active , _lastEvent } = this; 5968 if (_lastEvent) { 5969 this._eventHandler(_lastEvent, true); 5970 } else if (_active.length) { 5971 this._updateHoverStyles(_active, _active, true); 5972 } 5973 this.render(); 5974 } 5975 _updateScales() { 5976 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this.scales, (scale)=>{ 5977 layouts.removeBox(this, scale); 5978 }); 5979 this.ensureScalesHaveIDs(); 5980 this.buildOrUpdateScales(); 5981 } 5982 _checkEventBindings() { 5983 const options = this.options; 5984 const existingEvents = new Set(Object.keys(this._listeners)); 5985 const newEvents = new Set(options.events); 5986 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ag)(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) { 5987 this.unbindEvents(); 5988 this.bindEvents(); 5989 } 5990 } 5991 _updateHiddenIndices() { 5992 const { _hiddenIndices } = this; 5993 const changes = this._getUniformDataChanges() || []; 5994 for (const { method , start , count } of changes){ 5995 const move = method === '_removeElements' ? -count : count; 5996 moveNumericKeys(_hiddenIndices, start, move); 5997 } 5998 } 5999 _getUniformDataChanges() { 6000 const _dataChanges = this._dataChanges; 6001 if (!_dataChanges || !_dataChanges.length) { 6002 return; 6003 } 6004 this._dataChanges = []; 6005 const datasetCount = this.data.datasets.length; 6006 const makeSet = (idx)=>new Set(_dataChanges.filter((c)=>c[0] === idx).map((c, i)=>i + ',' + c.splice(1).join(','))); 6007 const changeSet = makeSet(0); 6008 for(let i = 1; i < datasetCount; i++){ 6009 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ag)(changeSet, makeSet(i))) { 6010 return; 6011 } 6012 } 6013 return Array.from(changeSet).map((c)=>c.split(',')).map((a)=>({ 6014 method: a[1], 6015 start: +a[2], 6016 count: +a[3] 6017 })); 6018 } 6019 _updateLayout(minPadding) { 6020 if (this.notifyPlugins('beforeLayout', { 6021 cancelable: true 6022 }) === false) { 6023 return; 6024 } 6025 layouts.update(this, this.width, this.height, minPadding); 6026 const area = this.chartArea; 6027 const noArea = area.width <= 0 || area.height <= 0; 6028 this._layers = []; 6029 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this.boxes, (box)=>{ 6030 if (noArea && box.position === 'chartArea') { 6031 return; 6032 } 6033 if (box.configure) { 6034 box.configure(); 6035 } 6036 this._layers.push(...box._layers()); 6037 }, this); 6038 this._layers.forEach((item, index)=>{ 6039 item._idx = index; 6040 }); 6041 this.notifyPlugins('afterLayout'); 6042 } 6043 _updateDatasets(mode) { 6044 if (this.notifyPlugins('beforeDatasetsUpdate', { 6045 mode, 6046 cancelable: true 6047 }) === false) { 6048 return; 6049 } 6050 for(let i = 0, ilen = this.data.datasets.length; i < ilen; ++i){ 6051 this.getDatasetMeta(i).controller.configure(); 6052 } 6053 for(let i = 0, ilen = this.data.datasets.length; i < ilen; ++i){ 6054 this._updateDataset(i, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a7)(mode) ? mode({ 6055 datasetIndex: i 6056 }) : mode); 6057 } 6058 this.notifyPlugins('afterDatasetsUpdate', { 6059 mode 6060 }); 6061 } 6062 _updateDataset(index, mode) { 6063 const meta = this.getDatasetMeta(index); 6064 const args = { 6065 meta, 6066 index, 6067 mode, 6068 cancelable: true 6069 }; 6070 if (this.notifyPlugins('beforeDatasetUpdate', args) === false) { 6071 return; 6072 } 6073 meta.controller._update(mode); 6074 args.cancelable = false; 6075 this.notifyPlugins('afterDatasetUpdate', args); 6076 } 6077 render() { 6078 if (this.notifyPlugins('beforeRender', { 6079 cancelable: true 6080 }) === false) { 6081 return; 6082 } 6083 if (animator.has(this)) { 6084 if (this.attached && !animator.running(this)) { 6085 animator.start(this); 6086 } 6087 } else { 6088 this.draw(); 6089 onAnimationsComplete({ 6090 chart: this 6091 }); 6092 } 6093 } 6094 draw() { 6095 let i; 6096 if (this._resizeBeforeDraw) { 6097 const { width , height } = this._resizeBeforeDraw; 6098 this._resizeBeforeDraw = null; 6099 this._resize(width, height); 6100 } 6101 this.clear(); 6102 if (this.width <= 0 || this.height <= 0) { 6103 return; 6104 } 6105 if (this.notifyPlugins('beforeDraw', { 6106 cancelable: true 6107 }) === false) { 6108 return; 6109 } 6110 const layers = this._layers; 6111 for(i = 0; i < layers.length && layers[i].z <= 0; ++i){ 6112 layers[i].draw(this.chartArea); 6113 } 6114 this._drawDatasets(); 6115 for(; i < layers.length; ++i){ 6116 layers[i].draw(this.chartArea); 6117 } 6118 this.notifyPlugins('afterDraw'); 6119 } 6120 _getSortedDatasetMetas(filterVisible) { 6121 const metasets = this._sortedMetasets; 6122 const result = []; 6123 let i, ilen; 6124 for(i = 0, ilen = metasets.length; i < ilen; ++i){ 6125 const meta = metasets[i]; 6126 if (!filterVisible || meta.visible) { 6127 result.push(meta); 6128 } 6129 } 6130 return result; 6131 } 6132 getSortedVisibleDatasetMetas() { 6133 return this._getSortedDatasetMetas(true); 6134 } 6135 _drawDatasets() { 6136 if (this.notifyPlugins('beforeDatasetsDraw', { 6137 cancelable: true 6138 }) === false) { 6139 return; 6140 } 6141 const metasets = this.getSortedVisibleDatasetMetas(); 6142 for(let i = metasets.length - 1; i >= 0; --i){ 6143 this._drawDataset(metasets[i]); 6144 } 6145 this.notifyPlugins('afterDatasetsDraw'); 6146 } 6147 _drawDataset(meta) { 6148 const ctx = this.ctx; 6149 const args = { 6150 meta, 6151 index: meta.index, 6152 cancelable: true 6153 }; 6154 const clip = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ah)(this, meta); 6155 if (this.notifyPlugins('beforeDatasetDraw', args) === false) { 6156 return; 6157 } 6158 if (clip) { 6159 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Y)(ctx, clip); 6160 } 6161 meta.controller.draw(); 6162 if (clip) { 6163 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.$)(ctx); 6164 } 6165 args.cancelable = false; 6166 this.notifyPlugins('afterDatasetDraw', args); 6167 } 6168 isPointInArea(point) { 6169 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)(point, this.chartArea, this._minPadding); 6170 } 6171 getElementsAtEventForMode(e, mode, options, useFinalPosition) { 6172 const method = Interaction.modes[mode]; 6173 if (typeof method === 'function') { 6174 return method(this, e, options, useFinalPosition); 6175 } 6176 return []; 6177 } 6178 getDatasetMeta(datasetIndex) { 6179 const dataset = this.data.datasets[datasetIndex]; 6180 const metasets = this._metasets; 6181 let meta = metasets.filter((x)=>x && x._dataset === dataset).pop(); 6182 if (!meta) { 6183 meta = { 6184 type: null, 6185 data: [], 6186 dataset: null, 6187 controller: null, 6188 hidden: null, 6189 xAxisID: null, 6190 yAxisID: null, 6191 order: dataset && dataset.order || 0, 6192 index: datasetIndex, 6193 _dataset: dataset, 6194 _parsed: [], 6195 _sorted: false 6196 }; 6197 metasets.push(meta); 6198 } 6199 return meta; 6200 } 6201 getContext() { 6202 return this.$context || (this.$context = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(null, { 6203 chart: this, 6204 type: 'chart' 6205 })); 6206 } 6207 getVisibleDatasetCount() { 6208 return this.getSortedVisibleDatasetMetas().length; 6209 } 6210 isDatasetVisible(datasetIndex) { 6211 const dataset = this.data.datasets[datasetIndex]; 6212 if (!dataset) { 6213 return false; 6214 } 6215 const meta = this.getDatasetMeta(datasetIndex); 6216 return typeof meta.hidden === 'boolean' ? !meta.hidden : !dataset.hidden; 6217 } 6218 setDatasetVisibility(datasetIndex, visible) { 6219 const meta = this.getDatasetMeta(datasetIndex); 6220 meta.hidden = !visible; 6221 } 6222 toggleDataVisibility(index) { 6223 this._hiddenIndices[index] = !this._hiddenIndices[index]; 6224 } 6225 getDataVisibility(index) { 6226 return !this._hiddenIndices[index]; 6227 } 6228 _updateVisibility(datasetIndex, dataIndex, visible) { 6229 const mode = visible ? 'show' : 'hide'; 6230 const meta = this.getDatasetMeta(datasetIndex); 6231 const anims = meta.controller._resolveAnimations(undefined, mode); 6232 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.h)(dataIndex)) { 6233 meta.data[dataIndex].hidden = !visible; 6234 this.update(); 6235 } else { 6236 this.setDatasetVisibility(datasetIndex, visible); 6237 anims.update(meta, { 6238 visible 6239 }); 6240 this.update((ctx)=>ctx.datasetIndex === datasetIndex ? mode : undefined); 6241 } 6242 } 6243 hide(datasetIndex, dataIndex) { 6244 this._updateVisibility(datasetIndex, dataIndex, false); 6245 } 6246 show(datasetIndex, dataIndex) { 6247 this._updateVisibility(datasetIndex, dataIndex, true); 6248 } 6249 _destroyDatasetMeta(datasetIndex) { 6250 const meta = this._metasets[datasetIndex]; 6251 if (meta && meta.controller) { 6252 meta.controller._destroy(); 6253 } 6254 delete this._metasets[datasetIndex]; 6255 } 6256 _stop() { 6257 let i, ilen; 6258 this.stop(); 6259 animator.remove(this); 6260 for(i = 0, ilen = this.data.datasets.length; i < ilen; ++i){ 6261 this._destroyDatasetMeta(i); 6262 } 6263 } 6264 destroy() { 6265 this.notifyPlugins('beforeDestroy'); 6266 const { canvas , ctx } = this; 6267 this._stop(); 6268 this.config.clearCache(); 6269 if (canvas) { 6270 this.unbindEvents(); 6271 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.af)(canvas, ctx); 6272 this.platform.releaseContext(ctx); 6273 this.canvas = null; 6274 this.ctx = null; 6275 } 6276 delete instances[this.id]; 6277 this.notifyPlugins('afterDestroy'); 6278 } 6279 toBase64Image(...args) { 6280 return this.canvas.toDataURL(...args); 6281 } 6282 bindEvents() { 6283 this.bindUserEvents(); 6284 if (this.options.responsive) { 6285 this.bindResponsiveEvents(); 6286 } else { 6287 this.attached = true; 6288 } 6289 } 6290 bindUserEvents() { 6291 const listeners = this._listeners; 6292 const platform = this.platform; 6293 const _add = (type, listener)=>{ 6294 platform.addEventListener(this, type, listener); 6295 listeners[type] = listener; 6296 }; 6297 const listener = (e, x, y)=>{ 6298 e.offsetX = x; 6299 e.offsetY = y; 6300 this._eventHandler(e); 6301 }; 6302 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this.options.events, (type)=>_add(type, listener)); 6303 } 6304 bindResponsiveEvents() { 6305 if (!this._responsiveListeners) { 6306 this._responsiveListeners = {}; 6307 } 6308 const listeners = this._responsiveListeners; 6309 const platform = this.platform; 6310 const _add = (type, listener)=>{ 6311 platform.addEventListener(this, type, listener); 6312 listeners[type] = listener; 6313 }; 6314 const _remove = (type, listener)=>{ 6315 if (listeners[type]) { 6316 platform.removeEventListener(this, type, listener); 6317 delete listeners[type]; 6318 } 6319 }; 6320 const listener = (width, height)=>{ 6321 if (this.canvas) { 6322 this.resize(width, height); 6323 } 6324 }; 6325 let detached; 6326 const attached = ()=>{ 6327 _remove('attach', attached); 6328 this.attached = true; 6329 this.resize(); 6330 _add('resize', listener); 6331 _add('detach', detached); 6332 }; 6333 detached = ()=>{ 6334 this.attached = false; 6335 _remove('resize', listener); 6336 this._stop(); 6337 this._resize(0, 0); 6338 _add('attach', attached); 6339 }; 6340 if (platform.isAttached(this.canvas)) { 6341 attached(); 6342 } else { 6343 detached(); 6344 } 6345 } 6346 unbindEvents() { 6347 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this._listeners, (listener, type)=>{ 6348 this.platform.removeEventListener(this, type, listener); 6349 }); 6350 this._listeners = {}; 6351 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this._responsiveListeners, (listener, type)=>{ 6352 this.platform.removeEventListener(this, type, listener); 6353 }); 6354 this._responsiveListeners = undefined; 6355 } 6356 updateHoverStyle(items, mode, enabled) { 6357 const prefix = enabled ? 'set' : 'remove'; 6358 let meta, item, i, ilen; 6359 if (mode === 'dataset') { 6360 meta = this.getDatasetMeta(items[0].datasetIndex); 6361 meta.controller['_' + prefix + 'DatasetHoverStyle'](); 6362 } 6363 for(i = 0, ilen = items.length; i < ilen; ++i){ 6364 item = items[i]; 6365 const controller = item && this.getDatasetMeta(item.datasetIndex).controller; 6366 if (controller) { 6367 controller[prefix + 'HoverStyle'](item.element, item.datasetIndex, item.index); 6368 } 6369 } 6370 } 6371 getActiveElements() { 6372 return this._active || []; 6373 } 6374 setActiveElements(activeElements) { 6375 const lastActive = this._active || []; 6376 const active = activeElements.map(({ datasetIndex , index })=>{ 6377 const meta = this.getDatasetMeta(datasetIndex); 6378 if (!meta) { 6379 throw new Error('No dataset found at index ' + datasetIndex); 6380 } 6381 return { 6382 datasetIndex, 6383 element: meta.data[index], 6384 index 6385 }; 6386 }); 6387 const changed = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ai)(active, lastActive); 6388 if (changed) { 6389 this._active = active; 6390 this._lastEvent = null; 6391 this._updateHoverStyles(active, lastActive); 6392 } 6393 } 6394 notifyPlugins(hook, args, filter) { 6395 return this._plugins.notify(this, hook, args, filter); 6396 } 6397 isPluginEnabled(pluginId) { 6398 return this._plugins._cache.filter((p)=>p.plugin.id === pluginId).length === 1; 6399 } 6400 _updateHoverStyles(active, lastActive, replay) { 6401 const hoverOptions = this.options.hover; 6402 const diff = (a, b)=>a.filter((x)=>!b.some((y)=>x.datasetIndex === y.datasetIndex && x.index === y.index)); 6403 const deactivated = diff(lastActive, active); 6404 const activated = replay ? active : diff(active, lastActive); 6405 if (deactivated.length) { 6406 this.updateHoverStyle(deactivated, hoverOptions.mode, false); 6407 } 6408 if (activated.length && hoverOptions.mode) { 6409 this.updateHoverStyle(activated, hoverOptions.mode, true); 6410 } 6411 } 6412 _eventHandler(e, replay) { 6413 const args = { 6414 event: e, 6415 replay, 6416 cancelable: true, 6417 inChartArea: this.isPointInArea(e) 6418 }; 6419 const eventFilter = (plugin)=>(plugin.options.events || this.options.events).includes(e.native.type); 6420 if (this.notifyPlugins('beforeEvent', args, eventFilter) === false) { 6421 return; 6422 } 6423 const changed = this._handleEvent(e, replay, args.inChartArea); 6424 args.cancelable = false; 6425 this.notifyPlugins('afterEvent', args, eventFilter); 6426 if (changed || args.changed) { 6427 this.render(); 6428 } 6429 return this; 6430 } 6431 _handleEvent(e, replay, inChartArea) { 6432 const { _active: lastActive = [] , options } = this; 6433 const useFinalPosition = replay; 6434 const active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition); 6435 const isClick = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aj)(e); 6436 const lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isCl
6436ick); 6437 if (inChartArea) { 6438 this._lastEvent = null; 6439 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(options.onHover, [ 6440 e, 6441 active, 6442 this 6443 ], this); 6444 if (isClick) { 6445 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(options.onClick, [ 6446 e, 6447 active, 6448 this 6449 ], this); 6450 } 6451 } 6452 const changed = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ai)(active, lastActive); 6453 if (changed || replay) { 6454 this._active = active; 6455 this._updateHoverStyles(active, lastActive, replay); 6456 } 6457 this._lastEvent = lastEvent; 6458 return changed; 6459 } 6460 _getActiveElements(e, lastActive, inChartArea, useFinalPosition) { 6461 if (e.type === 'mouseout') { 6462 return []; 6463 } 6464 if (!inChartArea) { 6465 return lastActive; 6466 } 6467 const hoverOptions = this.options.hover; 6468 return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition); 6469 } 6470}
vendor: 71,405 bytes, lines 6471-8445
6471function invalidatePlugins() { 6472 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(Chart.instances, (chart)=>chart._plugins.invalidate()); 6473} 6474 6475function clipSelf(ctx, element, endAngle) { 6476 const { startAngle , x , y , outerRadius , innerRadius , options } = element; 6477 const { borderWidth , borderJoinStyle } = options; 6478 const outerAngleClip = Math.min(borderWidth / outerRadius, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(startAngle - endAngle)); 6479 ctx.beginPath(); 6480 ctx.arc(x, y, outerRadius - borderWidth / 2, startAngle + outerAngleClip / 2, endAngle - outerAngleClip / 2); 6481 if (innerRadius > 0) { 6482 const innerAngleClip = Math.min(borderWidth / innerRadius, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(startAngle - endAngle)); 6483 ctx.arc(x, y, innerRadius + borderWidth / 2, endAngle - innerAngleClip / 2, startAngle + innerAngleClip / 2, true); 6484 } else { 6485 const clipWidth = Math.min(borderWidth / 2, outerRadius * (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(startAngle - endAngle)); 6486 if (borderJoinStyle === 'round') { 6487 ctx.arc(x, y, clipWidth, endAngle - _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / 2, startAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / 2, true); 6488 } else if (borderJoinStyle === 'bevel') { 6489 const r = 2 * clipWidth * clipWidth; 6490 const endX = -r * Math.cos(endAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / 2) + x; 6491 const endY = -r * Math.sin(endAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / 2) + y; 6492 const startX = r * Math.cos(startAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / 2) + x; 6493 const startY = r * Math.sin(startAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / 2) + y; 6494 ctx.lineTo(endX, endY); 6495 ctx.lineTo(startX, startY); 6496 } 6497 } 6498 ctx.closePath(); 6499 ctx.moveTo(0, 0); 6500 ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height); 6501 ctx.clip('evenodd'); 6502} 6503function clipArc(ctx, element, endAngle) { 6504 const { startAngle , pixelMargin , x , y , outerRadius , innerRadius } = element; 6505 let angleMargin = pixelMargin / outerRadius; 6506 // Draw an inner border by clipping the arc and drawing a double-width border 6507 // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders 6508 ctx.beginPath(); 6509 ctx.arc(x, y, outerRadius, startAngle - angleMargin, endAngle + angleMargin); 6510 if (innerRadius > pixelMargin) { 6511 angleMargin = pixelMargin / innerRadius; 6512 ctx.arc(x, y, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true); 6513 } else { 6514 ctx.arc(x, y, pixelMargin, endAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H, startAngle - _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H); 6515 } 6516 ctx.closePath(); 6517 ctx.clip(); 6518} 6519function toRadiusCorners(value) { 6520 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.am)(value, [ 6521 'outerStart', 6522 'outerEnd', 6523 'innerStart', 6524 'innerEnd' 6525 ]); 6526} 6527/** 6528 * Parse border radius from the provided options 6529 */ function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) { 6530 const o = toRadiusCorners(arc.options.borderRadius); 6531 const halfThickness = (outerRadius - innerRadius) / 2; 6532 const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2); 6533 // Outer limits are complicated. We want to compute the available angular distance at 6534 // a radius of outerRadius - borderRadius because for small angular distances, this term limits. 6535 // We compute at r = outerRadius - borderRadius because this circle defines the center of the border corners. 6536 // 6537 // If the borderRadius is large, that value can become negative. 6538 // This causes the outer borders to lose their radius entirely, which is rather unexpected. To solve that, if borderRadius > outerRadius 6539 // we know that the thickness term will dominate and compute the limits at that point 6540 const computeOuterLimit = (val)=>{ 6541 const outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2; 6542 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(val, 0, Math.min(halfThickness, outerArcLimit)); 6543 }; 6544 return { 6545 outerStart: computeOuterLimit(o.outerStart), 6546 outerEnd: computeOuterLimit(o.outerEnd), 6547 innerStart: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(o.innerStart, 0, innerLimit), 6548 innerEnd: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(o.innerEnd, 0, innerLimit) 6549 }; 6550} 6551/** 6552 * Convert (r, ð) to (x, y) 6553 */ function rThetaToXY(r, theta, x, y) { 6554 return { 6555 x: x + r * Math.cos(theta), 6556 y: y + r * Math.sin(theta) 6557 }; 6558} 6559/** 6560 * Path the arc, respecting border radius by separating into left and right halves. 6561 * 6562 * Start End 6563 * 6564 * 1--->a--->2 Outer 6565 * / \ 6566 * 8 3 6567 * | | 6568 * | | 6569 * 7 4 6570 * \ / 6571 * 6<---b<---5 Inner 6572 */ function pathArc(ctx, element, offset, spacing, end, circular) { 6573 const { x , y , startAngle: start , pixelMargin , innerRadius: innerR } = element; 6574 const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0); 6575 const innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0; 6576 let spacingOffset = 0; 6577 const alpha = end - start; 6578 if (spacing) { 6579 // When spacing is present, it is the same for all items 6580 // So we adjust the start and end angle of the arc such that 6581 // the distance is the same as it would be without the spacing 6582 const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0; 6583 const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0; 6584 const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2; 6585 const adjustedAngle = avNogSpacingRadius !== 0 ? alpha * avNogSpacingRadius / (avNogSpacingRadius + spacing) : alpha; 6586 spacingOffset = (alpha - adjustedAngle) / 2; 6587 } 6588 const beta = Math.max(0.001, alpha * outerRadius - offset / _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P) / outerRadius; 6589 const angleOffset = (alpha - beta) / 2; 6590 const startAngle = start + angleOffset + spacingOffset; 6591 const endAngle = end - angleOffset - spacingOffset; 6592 const { outerStart , outerEnd , innerStart , innerEnd } = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle); 6593 const outerStartAdjustedRadius = outerRadius - outerStart; 6594 const outerEndAdjustedRadius = outerRadius - outerEnd; 6595 const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius; 6596 const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius; 6597 const innerStartAdjustedRadius = innerRadius + innerStart; 6598 const innerEndAdjustedRadius = innerRadius + innerEnd; 6599 const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius; 6600 const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius; 6601 ctx.beginPath(); 6602 if (circular) { 6603 // The first arc segments from point 1 to point a to point 2 6604 const outerMidAdjustedAngle = (outerStartAdjustedAngle + outerEndAdjustedAngle) / 2; 6605 ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerMidAdjustedAngle); 6606 ctx.arc(x, y, outerRadius, outerMidAdjustedAngle, outerEndAdjustedAngle); 6607 // The corner segment from point 2 to point 3 6608 if (outerEnd > 0) { 6609 const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y); 6610 ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H); 6611 } 6612 // The line from point 3 to point 4 6613 const p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x, y); 6614 ctx.lineTo(p4.x, p4.y); 6615 // The corner segment from point 4 to point 5 6616 if (innerEnd > 0) { 6617 const pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x, y); 6618 ctx.arc(pCenter.x, pCenter.y, innerEnd, endAngle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H, innerEndAdjustedAngle + Math.PI); 6619 } 6620 // The inner arc from point 5 to point b to point 6 6621 const innerMidAdjustedAngle = (endAngle - innerEnd / innerRadius + (startAngle + innerStart / innerRadius)) / 2; 6622 ctx.arc(x, y, innerRadius, endAngle - innerEnd / innerRadius, innerMidAdjustedAngle, true); 6623 ctx.arc(x, y, innerRadius, innerMidAdjustedAngle, startAngle + innerStart / innerRadius, true); 6624 // The corner segment from point 6 to point 7 6625 if (innerStart > 0) { 6626 const pCenter = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x, y); 6627 ctx.arc(pCenter.x, pCenter.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H); 6628 } 6629 // The line from point 7 to point 8 6630 const p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x, y); 6631 ctx.lineTo(p8.x, p8.y); 6632 // The corner segment from point 8 to point 1 6633 if (outerStart > 0) { 6634 const pCenter = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x, y); 6635 ctx.arc(pCenter.x, pCenter.y, outerStart, startAngle - _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H, outerStartAdjustedAngle); 6636 } 6637 } else { 6638 ctx.moveTo(x, y); 6639 const outerStartX = Math.cos(outerStartAdjustedAngle) * outerRadius + x; 6640 const outerStartY = Math.sin(outerStartAdjustedAngle) * outerRadius + y; 6641 ctx.lineTo(outerStartX, outerStartY); 6642 const outerEndX = Math.cos(outerEndAdjustedAngle) * outerRadius + x; 6643 const outerEndY = Math.sin(outerEndAdjustedAngle) * outerRadius + y; 6644 ctx.lineTo(outerEndX, outerEndY); 6645 } 6646 ctx.closePath(); 6647} 6648function drawArc(ctx, element, offset, spacing, circular) { 6649 const { fullCircles , startAngle , circumference } = element; 6650 let endAngle = element.endAngle; 6651 if (fullCircles) { 6652 pathArc(ctx, element, offset, spacing, endAngle, circular); 6653 for(let i = 0; i < fullCircles; ++i){ 6654 ctx.fill(); 6655 } 6656 if (!isNaN(circumference)) { 6657 endAngle = startAngle + (circumference % _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T || _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T); 6658 } 6659 } 6660 pathArc(ctx, element, offset, spacing, endAngle, circular); 6661 ctx.fill(); 6662 return endAngle; 6663} 6664function drawBorder(ctx, element, offset, spacing, circular) { 6665 const { fullCircles , startAngle , circumference , options } = element; 6666 const { borderWidth , borderJoinStyle , borderDash , borderDashOffset , borderRadius } = options; 6667 const inner = options.borderAlign === 'inner'; 6668 if (!borderWidth) { 6669 return; 6670 } 6671 ctx.setLineDash(borderDash || []); 6672 ctx.lineDashOffset = borderDashOffset; 6673 if (inner) { 6674 ctx.lineWidth = borderWidth * 2; 6675 ctx.lineJoin = borderJoinStyle || 'round'; 6676 } else { 6677 ctx.lineWidth = borderWidth; 6678 ctx.lineJoin = borderJoinStyle || 'bevel'; 6679 } 6680 let endAngle = element.endAngle; 6681 if (fullCircles) { 6682 pathArc(ctx, element, offset, spacing, endAngle, circular); 6683 for(let i = 0; i < fullCircles; ++i){ 6684 ctx.stroke(); 6685 } 6686 if (!isNaN(circumference)) { 6687 endAngle = startAngle + (circumference % _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T || _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T); 6688 } 6689 } 6690 if (inner) { 6691 clipArc(ctx, element, endAngle); 6692 } 6693 if (options.selfJoin && endAngle - startAngle >= _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P && borderRadius === 0 && borderJoinStyle !== 'miter') { 6694 clipSelf(ctx, element, endAngle); 6695 } 6696 if (!fullCircles) { 6697 pathArc(ctx, element, offset, spacing, endAngle, circular); 6698 ctx.stroke(); 6699 } 6700} 6701class ArcElement extends Element { 6702 static id = 'arc'; 6703 static defaults = { 6704 borderAlign: 'center', 6705 borderColor: '#fff', 6706 borderDash: [], 6707 borderDashOffset: 0, 6708 borderJoinStyle: undefined, 6709 borderRadius: 0, 6710 borderWidth: 2, 6711 offset: 0, 6712 spacing: 0, 6713 angle: undefined, 6714 circular: true, 6715 selfJoin: false 6716 }; 6717 static defaultRoutes = { 6718 backgroundColor: 'backgroundColor' 6719 }; 6720 static descriptors = { 6721 _scriptable: true, 6722 _indexable: (name)=>name !== 'borderDash' 6723 }; 6724 circumference; 6725 endAngle; 6726 fullCircles; 6727 innerRadius; 6728 outerRadius; 6729 pixelMargin; 6730 startAngle; 6731 constructor(cfg){ 6732 super(); 6733 this.options = undefined; 6734 this.circumference = undefined; 6735 this.startAngle = undefined; 6736 this.endAngle = undefined; 6737 this.innerRadius = undefined; 6738 this.outerRadius = undefined; 6739 this.pixelMargin = 0; 6740 this.fullCircles = 0; 6741 if (cfg) { 6742 Object.assign(this, cfg); 6743 } 6744 } 6745 inRange(chartX, chartY, useFinalPosition) { 6746 const point = this.getProps([ 6747 'x', 6748 'y' 6749 ], useFinalPosition); 6750 const { angle , distance } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.D)(point, { 6751 x: chartX, 6752 y: chartY 6753 }); 6754 const { startAngle , endAngle , innerRadius , outerRadius , circumference } = this.getProps([ 6755 'startAngle', 6756 'endAngle', 6757 'innerRadius', 6758 'outerRadius', 6759 'circumference' 6760 ], useFinalPosition); 6761 const rAdjust = (this.options.spacing + this.options.borderWidth) / 2; 6762 const _circumference = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(circumference, endAngle - startAngle); 6763 const nonZeroBetween = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.p)(angle, startAngle, endAngle) && startAngle !== endAngle; 6764 const betweenAngles = _circumference >= _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T || nonZeroBetween; 6765 const withinRadius = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(distance, innerRadius + rAdjust, outerRadius + rAdjust); 6766 return betweenAngles && withinRadius; 6767 } 6768 getCenterPoint(useFinalPosition) { 6769 const { x , y , startAngle , endAngle , innerRadius , outerRadius } = this.getProps([ 6770 'x', 6771 'y', 6772 'startAngle', 6773 'endAngle', 6774 'innerRadius', 6775 'outerRadius' 6776 ], useFinalPosition); 6777 const { offset , spacing } = this.options; 6778 const halfAngle = (startAngle + endAngle) / 2; 6779 const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2; 6780 return { 6781 x: x + Math.cos(halfAngle) * halfRadius, 6782 y: y + Math.sin(halfAngle) * halfRadius 6783 }; 6784 } 6785 tooltipPosition(useFinalPosition) { 6786 return this.getCenterPoint(useFinalPosition); 6787 } 6788 draw(ctx) { 6789 const { options , circumference } = this; 6790 const offset = (options.offset || 0) / 4; 6791 const spacing = (options.spacing || 0) / 2; 6792 const circular = options.circular; 6793 this.pixelMargin = options.borderAlign === 'inner' ? 0.33 : 0; 6794 this.fullCircles = circumference > _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T ? Math.floor(circumference / _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T) : 0; 6795 if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) { 6796 return; 6797 } 6798 ctx.save(); 6799 const halfAngle = (this.startAngle + this.endAngle) / 2; 6800 ctx.translate(Math.cos(halfAngle) * offset, Math.sin(halfAngle) * offset); 6801 const fix = 1 - Math.sin(Math.min(_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P, circumference || 0)); 6802 const radiusOffset = offset * fix; 6803 ctx.fillStyle = options.backgroundColor; 6804 ctx.strokeStyle = options.borderColor; 6805 drawArc(ctx, this, radiusOffset, spacing, circular); 6806 drawBorder(ctx, this, radiusOffset, spacing, circular); 6807 ctx.restore(); 6808 } 6809} 6810 6811function setStyle(ctx, options, style = options) { 6812 ctx.lineCap = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(style.borderCapStyle, options.borderCapStyle); 6813 ctx.setLineDash((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(style.borderDash, options.borderDash)); 6814 ctx.lineDashOffset = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(style.borderDashOffset, options.borderDashOffset); 6815 ctx.lineJoin = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(style.borderJoinStyle, options.borderJoinStyle); 6816 ctx.lineWidth = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(style.borderWidth, options.borderWidth); 6817 ctx.strokeStyle = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(style.borderColor, options.borderColor); 6818} 6819function lineTo(ctx, previous, target) { 6820 ctx.lineTo(target.x, target.y); 6821} 6822 function getLineMethod(options) { 6823 if (options.stepped) { 6824 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.at; 6825 } 6826 if (options.tension || options.cubicInterpolationMode === 'monotone') { 6827 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.au; 6828 } 6829 return lineTo; 6830} 6831function pathVars(points, segment, params = {}) { 6832 const count = points.length; 6833 const { start: paramsStart = 0 , end: paramsEnd = count - 1 } = params; 6834 const { start: segmentStart , end: segmentEnd } = segment; 6835 const start = Math.max(paramsStart, segmentStart); 6836 const end = Math.min(paramsEnd, segmentEnd); 6837 const outside = paramsStart < segmentStart && paramsEnd < segmentStart || paramsStart > segmentEnd && paramsEnd > segmentEnd; 6838 return { 6839 count, 6840 start, 6841 loop: segment.loop, 6842 ilen: end < start && !outside ? count + end - start : end - start 6843 }; 6844} 6845 function pathSegment(ctx, line, segment, params) { 6846 const { points , options } = line; 6847 const { count , start , loop , ilen } = pathVars(points, segment, params); 6848 const lineMethod = getLineMethod(options); 6849 let { move =true , reverse } = params || {}; 6850 let i, point, prev; 6851 for(i = 0; i <= ilen; ++i){ 6852 point = points[(start + (reverse ? ilen - i : i)) % count]; 6853 if (point.skip) { 6854 continue; 6855 } else if (move) { 6856 ctx.moveTo(point.x, point.y); 6857 move = false; 6858 } else { 6859 lineMethod(ctx, prev, point, reverse, options.stepped); 6860 } 6861 prev = point; 6862 } 6863 if (loop) { 6864 point = points[(start + (reverse ? ilen : 0)) % count]; 6865 lineMethod(ctx, prev, point, reverse, options.stepped); 6866 } 6867 return !!loop; 6868} 6869 function fastPathSegment(ctx, line, segment, params) { 6870 const points = line.points; 6871 const { count , start , ilen } = pathVars(points, segment, params); 6872 const { move =true , reverse } = params || {}; 6873 let avgX = 0; 6874 let countX = 0; 6875 let i, point, prevX, minY, maxY, lastY; 6876 const pointIndex = (index)=>(start + (reverse ? ilen - index : index)) % count; 6877 const drawX = ()=>{ 6878 if (minY !== maxY) { 6879 ctx.lineTo(avgX, maxY); 6880 ctx.lineTo(avgX, minY); 6881 ctx.lineTo(avgX, lastY); 6882 } 6883 }; 6884 if (move) { 6885 point = points[pointIndex(0)]; 6886 ctx.moveTo(point.x, point.y); 6887 } 6888 for(i = 0; i <= ilen; ++i){ 6889 point = points[pointIndex(i)]; 6890 if (point.skip) { 6891 continue; 6892 } 6893 const x = point.x; 6894 const y = point.y; 6895 const truncX = x | 0; 6896 if (truncX === prevX) { 6897 if (y < minY) { 6898 minY = y; 6899 } else if (y > maxY) { 6900 maxY = y; 6901 } 6902 avgX = (countX * avgX + x) / ++countX; 6903 } else { 6904 drawX(); 6905 ctx.lineTo(x, y); 6906 prevX = truncX; 6907 countX = 0; 6908 minY = maxY = y; 6909 } 6910 lastY = y; 6911 } 6912 drawX(); 6913} 6914 function _getSegmentMethod(line) { 6915 const opts = line.options; 6916 const borderDash = opts.borderDash && opts.borderDash.length; 6917 const useFastPath = !line._decimated && !line._loop && !opts.tension && opts.cubicInterpolationMode !== 'monotone' && !opts.stepped && !borderDash; 6918 return useFastPath ? fastPathSegment : pathSegment; 6919} 6920 function _getInterpolationMethod(options) { 6921 if (options.stepped) { 6922 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aq; 6923 } 6924 if (options.tension || options.cubicInterpolationMode === 'monotone') { 6925 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ar; 6926 } 6927 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.as; 6928} 6929function strokePathWithCache(ctx, line, start, count) { 6930 let path = line._path; 6931 if (!path) { 6932 path = line._path = new Path2D(); 6933 if (line.path(path, start, count)) { 6934 path.closePath(); 6935 } 6936 } 6937 setStyle(ctx, line.options); 6938 ctx.stroke(path); 6939} 6940function strokePathDirect(ctx, line, start, count) { 6941 const { segments , options } = line; 6942 const segmentMethod = _getSegmentMethod(line); 6943 for (const segment of segments){ 6944 setStyle(ctx, options, segment.style); 6945 ctx.beginPath(); 6946 if (segmentMethod(ctx, line, segment, { 6947 start, 6948 end: start + count - 1 6949 })) { 6950 ctx.closePath(); 6951 } 6952 ctx.stroke(); 6953 } 6954} 6955const usePath2D = typeof Path2D === 'function'; 6956function draw(ctx, line, start, count) { 6957 if (usePath2D && !line.options.segment) { 6958 strokePathWithCache(ctx, line, start, count); 6959 } else { 6960 strokePathDirect(ctx, line, start, count); 6961 } 6962} 6963class LineElement extends Element { 6964 static id = 'line'; 6965 static defaults = { 6966 borderCapStyle: 'butt', 6967 borderDash: [], 6968 borderDashOffset: 0, 6969 borderJoinStyle: 'miter', 6970 borderWidth: 3, 6971 capBezierPoints: true, 6972 cubicInterpolationMode: 'default', 6973 fill: false, 6974 spanGaps: false, 6975 stepped: false, 6976 tension: 0 6977 }; 6978 static defaultRoutes = { 6979 backgroundColor: 'backgroundColor', 6980 borderColor: 'borderColor' 6981 }; 6982 static descriptors = { 6983 _scriptable: true, 6984 _indexable: (name)=>name !== 'borderDash' && name !== 'fill' 6985 }; 6986 constructor(cfg){ 6987 super(); 6988 this.animated = true; 6989 this.options = undefined; 6990 this._chart = undefined; 6991 this._loop = undefined; 6992 this._fullLoop = undefined; 6993 this._path = undefined; 6994 this._points = undefined; 6995 this._segments = undefined; 6996 this._decimated = false; 6997 this._pointsUpdated = false; 6998 this._datasetIndex = undefined; 6999 if (cfg) { 7000 Object.assign(this, cfg); 7001 } 7002 } 7003 updateControlPoints(chartArea, indexAxis) { 7004 const options = this.options; 7005 if ((options.tension || options.cubicInterpolationMode === 'monotone') && !options.stepped && !this._pointsUpdated) { 7006 const loop = options.spanGaps ? this._loop : this._fullLoop; 7007 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.an)(this._points, options, chartArea, loop, indexAxis); 7008 this._pointsUpdated = true; 7009 } 7010 } 7011 set points(points) { 7012 this._points = points; 7013 delete this._segments; 7014 delete this._path; 7015 this._pointsUpdated = false; 7016 } 7017 get points() { 7018 return this._points; 7019 } 7020 get segments() { 7021 return this._segments || (this._segments = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ao)(this, this.options.segment)); 7022 } 7023 first() { 7024 const segments = this.segments; 7025 const points = this.points; 7026 return segments.length && points[segments[0].start]; 7027 } 7028 last() { 7029 const segments = this.segments; 7030 const points = this.points; 7031 const count = segments.length; 7032 return count && points[segments[count - 1].end]; 7033 } 7034 interpolate(point, property) { 7035 const options = this.options; 7036 const value = point[property]; 7037 const points = this.points; 7038 const segments = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ap)(this, { 7039 property, 7040 start: value, 7041 end: value 7042 }); 7043 if (!segments.length) { 7044 return; 7045 } 7046 const result = []; 7047 const _interpolate = _getInterpolationMethod(options); 7048 let i, ilen; 7049 for(i = 0, ilen = segments.length; i < ilen; ++i){ 7050 const { start , end } = segments[i]; 7051 const p1 = points[start]; 7052 const p2 = points[end]; 7053 if (p1 === p2) { 7054 result.push(p1); 7055 continue; 7056 } 7057 const t = Math.abs((value - p1[property]) / (p2[property] - p1[property])); 7058 const interpolated = _interpolate(p1, p2, t, options.stepped); 7059 interpolated[property] = point[property]; 7060 result.push(interpolated); 7061 } 7062 return result.length === 1 ? result[0] : result; 7063 } 7064 pathSegment(ctx, segment, params) { 7065 const segmentMethod = _getSegmentMethod(this); 7066 return segmentMethod(ctx, this, segment, params); 7067 } 7068 path(ctx, start, count) { 7069 const segments = this.segments; 7070 const segmentMethod = _getSegmentMethod(this); 7071 let loop = this._loop; 7072 start = start || 0; 7073 count = count || this.points.length - start; 7074 for (const segment of segments){ 7075 loop &= segmentMethod(ctx, this, segment, { 7076 start, 7077 end: start + count - 1 7078 }); 7079 } 7080 return !!loop; 7081 } 7082 draw(ctx, chartArea, start, count) { 7083 const options = this.options || {}; 7084 const points = this.points || []; 7085 if (points.length && options.borderWidth) { 7086 ctx.save(); 7087 draw(ctx, this, start, count); 7088 ctx.restore(); 7089 } 7090 if (this.animated) { 7091 this._pointsUpdated = false; 7092 this._path = undefined; 7093 } 7094 } 7095} 7096 7097function inRange$1(el, pos, axis, useFinalPosition) { 7098 const options = el.options; 7099 const { [axis]: value } = el.getProps([ 7100 axis 7101 ], useFinalPosition); 7102 return Math.abs(pos - value) < options.radius + options.hitRadius; 7103} 7104class PointElement extends Element { 7105 static id = 'point'; 7106 parsed; 7107 skip; 7108 stop; 7109 /** 7110 * @type {any} 7111 */ static defaults = { 7112 borderWidth: 1, 7113 hitRadius: 1, 7114 hoverBorderWidth: 1, 7115 hoverRadius: 4, 7116 pointStyle: 'circle', 7117 radius: 3, 7118 rotation: 0 7119 }; 7120 /** 7121 * @type {any} 7122 */ static defaultRoutes = { 7123 backgroundColor: 'backgroundColor', 7124 borderColor: 'borderColor' 7125 }; 7126 constructor(cfg){ 7127 super(); 7128 this.options = undefined; 7129 this.parsed = undefined; 7130 this.skip = undefined; 7131 this.stop = undefined; 7132 if (cfg) { 7133 Object.assign(this, cfg); 7134 } 7135 } 7136 inRange(mouseX, mouseY, useFinalPosition) { 7137 const options = this.options; 7138 const { x , y } = this.getProps([ 7139 'x', 7140 'y' 7141 ], useFinalPosition); 7142 return Math.pow(mouseX - x, 2) + Math.pow(mouseY - y, 2) < Math.pow(options.hitRadius + options.radius, 2); 7143 } 7144 inXRange(mouseX, useFinalPosition) { 7145 return inRange$1(this, mouseX, 'x', useFinalPosition); 7146 } 7147 inYRange(mouseY, useFinalPosition) { 7148 return inRange$1(this, mouseY, 'y', useFinalPosition); 7149 } 7150 getCenterPoint(useFinalPosition) { 7151 const { x , y } = this.getProps([ 7152 'x', 7153 'y' 7154 ], useFinalPosition); 7155 return { 7156 x, 7157 y 7158 }; 7159 } 7160 size(options) { 7161 options = options || this.options || {}; 7162 let radius = options.radius || 0; 7163 radius = Math.max(radius, radius && options.hoverRadius || 0); 7164 const borderWidth = radius && options.borderWidth || 0; 7165 return (radius + borderWidth) * 2; 7166 } 7167 draw(ctx, area) { 7168 const options = this.options; 7169 if (this.skip || options.radius < 0.1 || !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)(this, area, this.size(options) / 2)) { 7170 return; 7171 } 7172 ctx.strokeStyle = options.borderColor; 7173 ctx.lineWidth = options.borderWidth; 7174 ctx.fillStyle = options.backgroundColor; 7175 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.av)(ctx, options, this.x, this.y); 7176 } 7177 getRange() { 7178 const options = this.options || {}; 7179 // @ts-expect-error Fallbacks should never be hit in practice 7180 return options.radius + options.hitRadius; 7181 } 7182} 7183 7184function getBarBounds(bar, useFinalPosition) { 7185 const { x , y , base , width , height } = bar.getProps([ 7186 'x', 7187 'y', 7188 'base', 7189 'width', 7190 'height' 7191 ], useFinalPosition); 7192 let left, right, top, bottom, half; 7193 if (bar.horizontal) { 7194 half = height / 2; 7195 left = Math.min(x, base); 7196 right = Math.max(x, base); 7197 top = y - half; 7198 bottom = y + half; 7199 } else { 7200 half = width / 2; 7201 left = x - half; 7202 right = x + half; 7203 top = Math.min(y, base); 7204 bottom = Math.max(y, base); 7205 } 7206 return { 7207 left, 7208 top, 7209 right, 7210 bottom 7211 }; 7212} 7213function skipOrLimit(skip, value, min, max) { 7214 return skip ? 0 : (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(value, min, max); 7215} 7216function parseBorderWidth(bar, maxW, maxH) { 7217 const value = bar.options.borderWidth; 7218 const skip = bar.borderSkipped; 7219 const o = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ax)(value); 7220 return { 7221 t: skipOrLimit(skip.top, o.top, 0, maxH), 7222 r: skipOrLimit(skip.right, o.right, 0, maxW), 7223 b: skipOrLimit(skip.bottom, o.bottom, 0, maxH), 7224 l: skipOrLimit(skip.left, o.left, 0, maxW) 7225 }; 7226} 7227function parseBorderRadius(bar, maxW, maxH) { 7228 const { enableBorderRadius } = bar.getProps([ 7229 'enableBorderRadius' 7230 ]); 7231 const value = bar.options.borderRadius; 7232 const o = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(value); 7233 const maxR = Math.min(maxW, maxH); 7234 const skip = bar.borderSkipped; 7235 const enableBorder = enableBorderRadius || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(value); 7236 return { 7237 topLeft: skipOrLimit(!enableBorder || skip.top || skip.left, o.topLeft, 0, maxR), 7238 topRight: skipOrLimit(!enableBorder || skip.top || skip.right, o.topRight, 0, maxR), 7239 bottomLeft: skipOrLimit(!enableBorder || skip.bottom || skip.left, o.bottomLeft, 0, maxR), 7240 bottomRight: skipOrLimit(!enableBorder || skip.bottom || skip.right, o.bottomRight, 0, maxR) 7241 }; 7242} 7243function boundingRects(bar) { 7244 const bounds = getBarBounds(bar); 7245 const width = bounds.right - bounds.left; 7246 const height = bounds.bottom - bounds.top; 7247 const border = parseBorderWidth(bar, width / 2, height / 2); 7248 const radius = parseBorderRadius(bar, width / 2, height / 2); 7249 return { 7250 outer: { 7251 x: bounds.left, 7252 y: bounds.top, 7253 w: width, 7254 h: height, 7255 radius 7256 }, 7257 inner: { 7258 x: bounds.left + border.l, 7259 y: bounds.top + border.t, 7260 w: width - border.l - border.r, 7261 h: height - border.t - border.b, 7262 radius: { 7263 topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)), 7264 topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)), 7265 bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)), 7266 bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r)) 7267 } 7268 } 7269 }; 7270} 7271function inRange(bar, x, y, useFinalPosition) { 7272 const skipX = x === null; 7273 const skipY = y === null; 7274 const skipBoth = skipX && skipY; 7275 const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition); 7276 return bounds && (skipX || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(x, bounds.left, bounds.right)) && (skipY || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(y, bounds.top, bounds.bottom)); 7277} 7278function hasRadius(radius) { 7279 return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight; 7280} 7281 function addNormalRectPath(ctx, rect) { 7282 ctx.rect(rect.x, rect.y, rect.w, rect.h); 7283} 7284function inflateRect(rect, amount, refRect = {}) { 7285 const x = rect.x !== refRect.x ? -amount : 0; 7286 const y = rect.y !== refRect.y ? -amount : 0; 7287 const w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x; 7288 const h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y; 7289 return { 7290 x: rect.x + x, 7291 y: rect.y + y, 7292 w: rect.w + w, 7293 h: rect.h + h, 7294 radius: rect.radius 7295 }; 7296} 7297class BarElement extends Element { 7298 static id = 'bar'; 7299 static defaults = { 7300 borderSkipped: 'start', 7301 borderWidth: 0, 7302 borderRadius: 0, 7303 inflateAmount: 'auto', 7304 pointStyle: undefined 7305 }; 7306 static defaultRoutes = { 7307 backgroundColor: 'backgroundColor', 7308 borderColor: 'borderColor' 7309 }; 7310 constructor(cfg){ 7311 super(); 7312 this.options = undefined; 7313 this.horizontal = undefined; 7314 this.base = undefined; 7315 this.width = undefined; 7316 this.height = undefined; 7317 this.inflateAmount = undefined; 7318 if (cfg) { 7319 Object.assign(this, cfg); 7320 } 7321 } 7322 draw(ctx) { 7323 const { inflateAmount , options: { borderColor , backgroundColor } } = this; 7324 const { inner , outer } = boundingRects(this); 7325 const addRectPath = hasRadius(outer.radius) ? _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aw : addNormalRectPath; 7326 ctx.save(); 7327 if (outer.w !== inner.w || outer.h !== inner.h) { 7328 ctx.beginPath(); 7329 addRectPath(ctx, inflateRect(outer, inflateAmount, inner)); 7330 ctx.clip(); 7331 addRectPath(ctx, inflateRect(inner, -inflateAmount, outer)); 7332 ctx.fillStyle = borderColor; 7333 ctx.fill('evenodd'); 7334 } 7335 ctx.beginPath(); 7336 addRectPath(ctx, inflateRect(inner, inflateAmount)); 7337 ctx.fillStyle = backgroundColor; 7338 ctx.fill(); 7339 ctx.restore(); 7340 } 7341 inRange(mouseX, mouseY, useFinalPosition) { 7342 return inRange(this, mouseX, mouseY, useFinalPosition); 7343 } 7344 inXRange(mouseX, useFinalPosition) { 7345 return inRange(this, mouseX, null, useFinalPosition); 7346 } 7347 inYRange(mouseY, useFinalPosition) { 7348 return inRange(this, null, mouseY, useFinalPosition); 7349 } 7350 getCenterPoint(useFinalPosition) { 7351 const { x , y , base , horizontal } = this.getProps([ 7352 'x', 7353 'y', 7354 'base', 7355 'horizontal' 7356 ], useFinalPosition); 7357 return { 7358 x: horizontal ? (x + base) / 2 : x, 7359 y: horizontal ? y : (y + base) / 2 7360 }; 7361 } 7362 getRange(axis) { 7363 return axis === 'x' ? this.width / 2 : this.height / 2; 7364 } 7365} 7366 7367var elements = /*#__PURE__*/Object.freeze({ 7368__proto__: null, 7369ArcElement: ArcElement, 7370BarElement: BarElement, 7371LineElement: LineElement, 7372PointElement: PointElement 7373}); 7374 7375const BORDER_COLORS = [ 7376 'rgb(54, 162, 235)', 7377 'rgb(255, 99, 132)', 7378 'rgb(255, 159, 64)', 7379 'rgb(255, 205, 86)', 7380 'rgb(75, 192, 192)', 7381 'rgb(153, 102, 255)', 7382 'rgb(201, 203, 207)' // grey 7383]; 7384// Border colors with 50% transparency 7385const BACKGROUND_COLORS = /* #__PURE__ */ BORDER_COLORS.map((color)=>color.replace('rgb(', 'rgba(').replace(')', ', 0.5)')); 7386function getBorderColor(i) { 7387 return BORDER_COLORS[i % BORDER_COLORS.length]; 7388} 7389function getBackgroundColor(i) { 7390 return BACKGROUND_COLORS[i % BACKGROUND_COLORS.length]; 7391} 7392function colorizeDefaultDataset(dataset, i) { 7393 dataset.borderColor = getBorderColor(i); 7394 dataset.backgroundColor = getBackgroundColor(i); 7395 return ++i; 7396} 7397function colorizeDoughnutDataset(dataset, i) { 7398 dataset.backgroundColor = dataset.data.map(()=>getBorderColor(i++)); 7399 return i; 7400} 7401function colorizePolarAreaDataset(dataset, i) { 7402 dataset.backgroundColor = dataset.data.map(()=>getBackgroundColor(i++)); 7403 return i; 7404} 7405function getColorizer(chart) { 7406 let i = 0; 7407 return (dataset, datasetIndex)=>{ 7408 const controller = chart.getDatasetMeta(datasetIndex).controller; 7409 if (controller instanceof DoughnutController) { 7410 i = colorizeDoughnutDataset(dataset, i); 7411 } else if (controller instanceof PolarAreaController) { 7412 i = colorizePolarAreaDataset(dataset, i); 7413 } else if (controller) { 7414 i = colorizeDefaultDataset(dataset, i); 7415 } 7416 }; 7417} 7418function containsColorsDefinitions(descriptors) { 7419 let k; 7420 for(k in descriptors){ 7421 if (descriptors[k].borderColor || descriptors[k].backgroundColor) { 7422 return true; 7423 } 7424 } 7425 return false; 7426} 7427function containsColorsDefinition(descriptor) { 7428 return descriptor && (descriptor.borderColor || descriptor.backgroundColor); 7429} 7430function containsDefaultColorsDefenitions() { 7431 return _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.borderColor !== 'rgba(0,0,0,0.1)' || _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.backgroundColor !== 'rgba(0,0,0,0.1)'; 7432} 7433var plugin_colors = { 7434 id: 'colors', 7435 defaults: { 7436 enabled: true, 7437 forceOverride: false 7438 }, 7439 beforeLayout (chart, _args, options) { 7440 if (!options.enabled) { 7441 return; 7442 } 7443 const { data: { datasets } , options: chartOptions } = chart.config; 7444 const { elements } = chartOptions; 7445 const containsColorDefenition = containsColorsDefinitions(datasets) || containsColorsDefinition(chartOptions) || elements && containsColorsDefinitions(elements) || containsDefaultColorsDefenitions(); 7446 if (!options.forceOverride && containsColorDefenition) { 7447 return; 7448 } 7449 const colorizer = getColorizer(chart); 7450 datasets.forEach(colorizer); 7451 } 7452}; 7453 7454function lttbDecimation(data, start, count, availableWidth, options) { 7455 const samples = options.samples || availableWidth; 7456 if (samples >= count) { 7457 return data.slice(start, start + count); 7458 } 7459 const decimated = []; 7460 const bucketWidth = (count - 2) / (samples - 2); 7461 let sampledIndex = 0; 7462 const endIndex = start + count - 1; 7463 let a = start; 7464 let i, maxAreaPoint, maxArea, area, nextA; 7465 decimated[sampledIndex++] = data[a]; 7466 for(i = 0; i < samples - 2; i++){ 7467 let avgX = 0; 7468 let avgY = 0; 7469 let j; 7470 const avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start; 7471 const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start; 7472 const avgRangeLength = avgRangeEnd - avgRangeStart; 7473 for(j = avgRangeStart; j < avgRangeEnd; j++){ 7474 avgX += data[j].x; 7475 avgY += data[j].y; 7476 } 7477 avgX /= avgRangeLength; 7478 avgY /= avgRangeLength; 7479 const rangeOffs = Math.floor(i * bucketWidth) + 1 + start; 7480 const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start; 7481 const { x: pointAx , y: pointAy } = data[a]; 7482 maxArea = area = -1; 7483 for(j = rangeOffs; j < rangeTo; j++){ 7484 area = 0.5 * Math.abs((pointAx - avgX) * (data[j].y - pointAy) - (pointAx - data[j].x) * (avgY - pointAy)); 7485 if (area > maxArea) { 7486 maxArea = area; 7487 maxAreaPoint = data[j]; 7488 nextA = j; 7489 } 7490 } 7491 decimated[sampledIndex++] = maxAreaPoint; 7492 a = nextA; 7493 } 7494 decimated[sampledIndex++] = data[endIndex]; 7495 return decimated; 7496} 7497function minMaxDecimation(data, start, count, availableWidth) { 7498 let avgX = 0; 7499 let countX = 0; 7500 let i, point, x, y, prevX, minIndex, maxIndex, startIndex, minY, maxY; 7501 const decimated = []; 7502 const endIndex = start + count - 1; 7503 const xMin = data[start].x; 7504 const xMax = data[endIndex].x; 7505 const dx = xMax - xMin; 7506 for(i = start; i < start + count; ++i){ 7507 point = data[i]; 7508 x = (point.x - xMin) / dx * availableWidth; 7509 y = point.y; 7510 const truncX = x | 0; 7511 if (truncX === prevX) { 7512 if (y < minY) { 7513 minY = y; 7514 minIndex = i; 7515 } else if (y > maxY) { 7516 maxY = y; 7517 maxIndex = i; 7518 } 7519 avgX = (countX * avgX + point.x) / ++countX; 7520 } else { 7521 const lastIndex = i - 1; 7522 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(minIndex) && !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(maxIndex)) { 7523 const intermediateIndex1 = Math.min(minIndex, maxIndex); 7524 const intermediateIndex2 = Math.max(minIndex, maxIndex); 7525 if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) { 7526 decimated.push({ 7527 ...data[intermediateIndex1], 7528 x: avgX 7529 }); 7530 } 7531 if (intermediateIndex2 !== startIndex && intermediateIndex2 !== lastIndex) { 7532 decimated.push({ 7533 ...data[intermediateIndex2], 7534 x: avgX 7535 }); 7536 } 7537 } 7538 if (i > 0 && lastIndex !== startIndex) { 7539 decimated.push(data[lastIndex]); 7540 } 7541 decimated.push(point); 7542 prevX = truncX; 7543 countX = 0; 7544 minY = maxY = y; 7545 minIndex = maxIndex = startIndex = i; 7546 } 7547 } 7548 return decimated; 7549} 7550function cleanDecimatedDataset(dataset) { 7551 if (dataset._decimated) { 7552 const data = dataset._data; 7553 delete dataset._decimated; 7554 delete dataset._data; 7555 Object.defineProperty(dataset, 'data', { 7556 configurable: true, 7557 enumerable: true, 7558 writable: true, 7559 value: data 7560 }); 7561 } 7562} 7563function cleanDecimatedData(chart) { 7564 chart.data.datasets.forEach((dataset)=>{ 7565 cleanDecimatedDataset(dataset); 7566 }); 7567} 7568function getStartAndCountOfVisiblePointsSimplified(meta, points) { 7569 const pointCount = points.length; 7570 let start = 0; 7571 let count; 7572 const { iScale } = meta; 7573 const { min , max , minDefined , maxDefined } = iScale.getUserBounds(); 7574 if (minDefined) { 7575 start = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.B)(points, iScale.axis, min).lo, 0, pointCount - 1); 7576 } 7577 if (maxDefined) { 7578 count = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.B)(points, iScale.axis, max).hi + 1, start, pointCount) - start; 7579 } else { 7580 count = pointCount - start; 7581 } 7582 return { 7583 start, 7584 count 7585 }; 7586} 7587var plugin_decimation = { 7588 id: 'decimation', 7589 defaults: { 7590 algorithm: 'min-max', 7591 enabled: false 7592 }, 7593 beforeElementsUpdate: (chart, args, options)=>{ 7594 if (!options.enabled) { 7595 cleanDecimatedData(chart); 7596 return; 7597 } 7598 const availableWidth = chart.width; 7599 chart.data.datasets.forEach((dataset, datasetIndex)=>{ 7600 const { _data , indexAxis } = dataset; 7601 const meta = chart.getDatasetMeta(datasetIndex); 7602 const data = _data || dataset.data; 7603 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a)([ 7604 indexAxis, 7605 chart.options.indexAxis 7606 ]) === 'y') { 7607 return; 7608 } 7609 if (!meta.controller.supportsDecimation) { 7610 return; 7611 } 7612 const xAxis = chart.scales[meta.xAxisID]; 7613 if (xAxis.type !== 'linear' && xAxis.type !== 'time') { 7614 return; 7615 } 7616 if (chart.options.parsing) { 7617 return; 7618 } 7619 let { start , count } = getStartAndCountOfVisiblePointsSimplified(meta, data); 7620 const threshold = options.threshold || 4 * availableWidth; 7621 if (count <= threshold) { 7622 cleanDecimatedDataset(dataset); 7623 return; 7624 } 7625 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(_data)) { 7626 dataset._data = data; 7627 delete dataset.data; 7628 Object.defineProperty(dataset, 'data', { 7629 configurable: true, 7630 enumerable: true, 7631 get: function() { 7632 return this._decimated; 7633 }, 7634 set: function(d) { 7635 this._data = d; 7636 } 7637 }); 7638 } 7639 let decimated; 7640 switch(options.algorithm){ 7641 case 'lttb': 7642 decimated = lttbDecimation(data, start, count, availableWidth, options); 7643 break; 7644 case 'min-max': 7645 decimated = minMaxDecimation(data, start, count, availableWidth); 7646 break; 7647 default: 7648 throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`); 7649 } 7650 dataset._decimated = decimated; 7651 }); 7652 }, 7653 destroy (chart) { 7654 cleanDecimatedData(chart); 7655 } 7656}; 7657 7658function _segments(line, target, property) { 7659 const segments = line.segments; 7660 const points = line.points; 7661 const tpoints = target.points; 7662 const parts = []; 7663 for (const segment of segments){ 7664 let { start , end } = segment; 7665 end = _findSegmentEnd(start, end, points); 7666 const bounds = _getBounds(property, points[start], points[end], segment.loop); 7667 if (!target.segments) { 7668 parts.push({ 7669 source: segment, 7670 target: bounds, 7671 start: points[start], 7672 end: points[end] 7673 }); 7674 continue; 7675 } 7676 const targetSegments = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ap)(target, bounds); 7677 for (const tgt of targetSegments){ 7678 const subBounds = _getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop); 7679 const fillSources = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.az)(segment, points, subBounds); 7680 for (const fillSource of fillSources){ 7681 parts.push({ 7682 source: fillSource, 7683 target: tgt, 7684 start: { 7685 [property]: _getEdge(bounds, subBounds, 'start', Math.max) 7686 }, 7687 end: { 7688 [property]: _getEdge(bounds, subBounds, 'end', Math.min) 7689 } 7690 }); 7691 } 7692 } 7693 } 7694 return parts; 7695} 7696function _getBounds(property, first, last, loop) { 7697 if (loop) { 7698 return; 7699 } 7700 let start = first[property]; 7701 let end = last[property]; 7702 if (property === 'angle') { 7703 start = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(start); 7704 end = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(end); 7705 } 7706 return { 7707 property, 7708 start, 7709 end 7710 }; 7711} 7712function _pointsFromSegments(boundary, line) { 7713 const { x =null , y =null } = boundary || {}; 7714 const linePoints = line.points; 7715 const points = []; 7716 line.segments.forEach(({ start , end })=>{ 7717 end = _findSegmentEnd(start, end, linePoints); 7718 const first = linePoints[start]; 7719 const last = linePoints[end]; 7720 if (y !== null) { 7721 points.push({ 7722 x: first.x, 7723 y 7724 }); 7725 points.push({ 7726 x: last.x, 7727 y 7728 }); 7729 } else if (x !== null) { 7730 points.push({ 7731 x, 7732 y: first.y 7733 }); 7734 points.push({ 7735 x, 7736 y: last.y 7737 }); 7738 } 7739 }); 7740 return points; 7741} 7742function _findSegmentEnd(start, end, points) { 7743 for(; end > start; end--){ 7744 const point = points[end]; 7745 if (!isNaN(point.x) && !isNaN(point.y)) { 7746 break; 7747 } 7748 } 7749 return end; 7750} 7751function _getEdge(a, b, prop, fn) { 7752 if (a && b) { 7753 return fn(a[prop], b[prop]); 7754 } 7755 return a ? a[prop] : b ? b[prop] : 0; 7756} 7757 7758function _createBoundaryLine(boundary, line) { 7759 let points = []; 7760 let _loop = false; 7761 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(boundary)) { 7762 _loop = true; 7763 points = boundary; 7764 } else { 7765 points = _pointsFromSegments(boundary, line); 7766 } 7767 return points.length ? new LineElement({ 7768 points, 7769 options: { 7770 tension: 0 7771 }, 7772 _loop, 7773 _fullLoop: _loop 7774 }) : null; 7775} 7776function _shouldApplyFill(source) { 7777 return source && source.fill !== false; 7778} 7779 7780function _resolveTarget(sources, index, propagate) { 7781 const source = sources[index]; 7782 let fill = source.fill; 7783 const visited = [ 7784 index 7785 ]; 7786 let target; 7787 if (!propagate) { 7788 return fill; 7789 } 7790 while(fill !== false && visited.indexOf(fill) === -1){ 7791 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(fill)) { 7792 return fill; 7793 } 7794 target = sources[fill]; 7795 if (!target) { 7796 return false; 7797 } 7798 if (target.visible) { 7799 return fill; 7800 } 7801 visited.push(fill); 7802 fill = target.fill; 7803 } 7804 return false; 7805} 7806 function _decodeFill(line, index, count) { 7807 const fill = parseFillOption(line); 7808 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(fill)) { 7809 return isNaN(fill.value) ? false : fill; 7810 } 7811 let target = parseFloat(fill); 7812 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(target) && Math.floor(target) === target) { 7813 return decodeTargetIndex(fill[0], index, target, count); 7814 } 7815 return [ 7816 'origin', 7817 'start', 7818 'end', 7819 'stack', 7820 'shape' 7821 ].indexOf(fill) >= 0 && fill; 7822} 7823function decodeTargetIndex(firstCh, index, target, count) { 7824 if (firstCh === '-' || firstCh === '+') { 7825 target = index + target; 7826 } 7827 if (target === index || target < 0 || target >= count) { 7828 return false; 7829 } 7830 return target; 7831} 7832 function _getTargetPixel(fill, scale) { 7833 let pixel = null; 7834 if (fill === 'start') { 7835 pixel = scale.bottom; 7836 } else if (fill === 'end') { 7837 pixel = scale.top; 7838 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(fill)) { 7839 pixel = scale.getPixelForValue(fill.value); 7840 } else if (scale.getBasePixel) { 7841 pixel = scale.getBasePixel(); 7842 } 7843 return pixel; 7844} 7845 function _getTargetValue(fill, scale, startValue) { 7846 let value; 7847 if (fill === 'start') { 7848 value = startValue; 7849 } else if (fill === 'end') { 7850 value = scale.options.reverse ? scale.min : scale.max; 7851 } else if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(fill)) { 7852 value = fill.value; 7853 } else { 7854 value = scale.getBaseValue(); 7855 } 7856 return value; 7857} 7858 function parseFillOption(line) { 7859 const options = line.options; 7860 const fillOption = options.fill; 7861 let fill = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(fillOption && fillOption.target, fillOption); 7862 if (fill === undefined) { 7863 fill = !!options.backgroundColor; 7864 } 7865 if (fill === false || fill === null) { 7866 return false; 7867 } 7868 if (fill === true) { 7869 return 'origin'; 7870 } 7871 return fill; 7872} 7873 7874function _buildStackLine(source) { 7875 const { scale , index , line } = source; 7876 const points = []; 7877 const segments = line.segments; 7878 const sourcePoints = line.points; 7879 const linesBelow = getLinesBelow(scale, index); 7880 linesBelow.push(_createBoundaryLine({ 7881 x: null, 7882 y: scale.bottom 7883 }, line)); 7884 for(let i = 0; i < segments.length; i++){ 7885 const segment = segments[i]; 7886 for(let j = segment.start; j <= segment.end; j++){ 7887 addPointsBelow(points, sourcePoints[j], linesBelow); 7888 } 7889 } 7890 return new LineElement({ 7891 points, 7892 options: {} 7893 }); 7894} 7895 function getLinesBelow(scale, index) { 7896 const below = []; 7897 const metas = scale.getMatchingVisibleMetas('line'); 7898 for(let i = 0; i < metas.length; i++){ 7899 const meta = metas[i]; 7900 if (meta.index === index) { 7901 break; 7902 } 7903 if (!meta.hidden) { 7904 below.unshift(meta.dataset); 7905 } 7906 } 7907 return below; 7908} 7909 function addPointsBelow(points, sourcePoint, linesBelow) { 7910 const postponed = []; 7911 for(let j = 0; j < linesBelow.length; j++){ 7912 const line = linesBelow[j]; 7913 const { first , last , point } = findPoint(line, sourcePoint, 'x'); 7914 if (!point || first && last) { 7915 continue; 7916 } 7917 if (first) { 7918 postponed.unshift(point); 7919 } else { 7920 points.push(point); 7921 if (!last) { 7922 break; 7923 } 7924 } 7925 } 7926 points.push(...postponed); 7927} 7928 function findPoint(line, sourcePoint, property) { 7929 const point = line.interpolate(sourcePoint, property); 7930 if (!point) { 7931 return {}; 7932 } 7933 const pointValue = point[property]; 7934 const segments = line.segments; 7935 const linePoints = line.points; 7936 let first = false; 7937 let last = false; 7938 for(let i = 0; i < segments.length; i++){ 7939 const segment = segments[i]; 7940 const firstValue = linePoints[segment.start][property]; 7941 const lastValue = linePoints[segment.end][property]; 7942 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(pointValue, firstValue, lastValue)) { 7943 first = pointValue === firstValue; 7944 last = pointValue === lastValue; 7945 break; 7946 } 7947 } 7948 return { 7949 first, 7950 last, 7951 point 7952 }; 7953} 7954 7955class simpleArc { 7956 constructor(opts){ 7957 this.x = opts.x; 7958 this.y = opts.y; 7959 this.radius = opts.radius; 7960 } 7961 pathSegment(ctx, bounds, opts) { 7962 const { x , y , radius } = this; 7963 bounds = bounds || { 7964 start: 0, 7965 end: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T 7966 }; 7967 ctx.arc(x, y, radius, bounds.end, bounds.start, true); 7968 return !opts.bounds; 7969 } 7970 interpolate(point) { 7971 const { x , y , radius } = this; 7972 const angle = point.angle; 7973 return { 7974 x: x + Math.cos(angle) * radius, 7975 y: y + Math.sin(angle) * radius, 7976 angle 7977 }; 7978 } 7979} 7980 7981function _getTarget(source) { 7982 const { chart , fill , line } = source; 7983 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(fill)) { 7984 return getLineByIndex(chart, fill); 7985 } 7986 if (fill === 'stack') { 7987 return _buildStackLine(source); 7988 } 7989 if (fill === 'shape') { 7990 return true; 7991 } 7992 const boundary = computeBoundary(source); 7993 if (boundary instanceof simpleArc) { 7994 return boundary; 7995 } 7996 return _createBoundaryLine(boundary, line); 7997} 7998 function getLineByIndex(chart, index) { 7999 const meta = chart.getDatasetMeta(index); 8000 const visible = meta && chart.isDatasetVisible(index); 8001 return visible ? meta.dataset : null; 8002} 8003function computeBoundary(source) { 8004 const scale = source.scale || {}; 8005 if (scale.getPointPositionForValue) { 8006 return computeCircularBoundary(source); 8007 } 8008 return computeLinearBoundary(source); 8009} 8010function computeLinearBoundary(source) { 8011 const { scale ={} , fill } = source; 8012 const pixel = _getTargetPixel(fill, scale); 8013 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(pixel)) { 8014 const horizontal = scale.isHorizontal(); 8015 return { 8016 x: horizontal ? pixel : null, 8017 y: horizontal ? null : pixel 8018 }; 8019 } 8020 return null; 8021} 8022function computeCircularBoundary(source) { 8023 const { scale , fill } = source; 8024 const options = scale.options; 8025 const length = scale.getLabels().length; 8026 const start = options.reverse ? scale.max : scale.min; 8027 const value = _getTargetValue(fill, scale, start); 8028 const target = []; 8029 if (options.grid.circular) { 8030 const center = scale.getPointPositionForValue(0, start); 8031 return new simpleArc({ 8032 x: center.x, 8033 y: center.y, 8034 radius: scale.getDistanceFromCenterForValue(value) 8035 }); 8036 } 8037 for(let i = 0; i < length; ++i){ 8038 target.push(scale.getPointPositionForValue(i, value)); 8039 } 8040 return target; 8041} 8042 8043function _drawfill(ctx, source, area) { 8044 const target = _getTarget(source); 8045 const { chart , index , line , scale , axis } = source; 8046 const lineOpts = line.options; 8047 const fillOption = lineOpts.fill; 8048 const color = lineOpts.backgroundColor; 8049 const { above =color , below =color } = fillOption || {}; 8050 const meta = chart.getDatasetMeta(index); 8051 const clip = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ah)(chart, meta); 8052 if (target && line.points.length) { 8053 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Y)(ctx, area); 8054 doFill(ctx, { 8055 line, 8056 target, 8057 above, 8058 below, 8059 area, 8060 scale, 8061 axis, 8062 clip 8063 }); 8064 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.$)(ctx); 8065 } 8066} 8067function doFill(ctx, cfg) { 8068 const { line , target , above , below , area , scale , clip } = cfg; 8069 const property = line._loop ? 'angle' : cfg.axis; 8070 ctx.save(); 8071 let fillColor = below; 8072 if (below !== above) { 8073 if (property === 'x') { 8074 clipVertical(ctx, target, area.top); 8075 fill(ctx, { 8076 line, 8077 target, 8078 color: above, 8079 scale, 8080 property, 8081 clip 8082 }); 8083 ctx.restore(); 8084 ctx.save(); 8085 clipVertical(ctx, target, area.bottom); 8086 } else if (property === 'y') { 8087 clipHorizontal(ctx, target, area.left); 8088 fill(ctx, { 8089 line, 8090 target, 8091 color: below, 8092 scale, 8093 property, 8094 clip 8095 }); 8096 ctx.restore(); 8097 ctx.save(); 8098 clipHorizontal(ctx, target, area.right); 8099 fillColor = above; 8100 } 8101 } 8102 fill(ctx, { 8103 line, 8104 target, 8105 color: fillColor, 8106 scale, 8107 property, 8108 clip 8109 }); 8110 ctx.restore(); 8111} 8112function clipVertical(ctx, target, clipY) { 8113 const { segments , points } = target; 8114 let first = true; 8115 let lineLoop = false; 8116 ctx.beginPath(); 8117 for (const segment of segments){ 8118 const { start , end } = segment; 8119 const firstPoint = points[start]; 8120 const lastPoint = points[_findSegmentEnd(start, end, points)]; 8121 if (first) { 8122 ctx.moveTo(firstPoint.x, firstPoint.y); 8123 first = false; 8124 } else { 8125 ctx.lineTo(firstPoint.x, clipY); 8126 ctx.lineTo(firstPoint.x, firstPoint.y); 8127 } 8128 lineLoop = !!target.pathSegment(ctx, segment, { 8129 move: lineLoop 8130 }); 8131 if (lineLoop) { 8132 ctx.closePath(); 8133 } else { 8134 ctx.lineTo(lastPoint.x, clipY); 8135 } 8136 } 8137 ctx.lineTo(target.first().x, clipY); 8138 ctx.closePath(); 8139 ctx.clip(); 8140} 8141function clipHorizontal(ctx, target, clipX) { 8142 const { segments , points } = target; 8143 let first = true; 8144 let lineLoop = false; 8145 ctx.beginPath(); 8146 for (const segment of segments){ 8147 const { start , end } = segment; 8148 const firstPoint = points[start]; 8149 const lastPoint = points[_findSegmentEnd(start, end, points)]; 8150 if (first) { 8151 ctx.moveTo(firstPoint.x, firstPoint.y); 8152 first = false; 8153 } else { 8154 ctx.lineTo(clipX, firstPoint.y); 8155 ctx.lineTo(firstPoint.x, firstPoint.y); 8156 } 8157 lineLoop = !!target.pathSegment(ctx, segment, { 8158 move: lineLoop 8159 }); 8160 if (lineLoop) { 8161 ctx.closePath(); 8162 } else { 8163 ctx.lineTo(clipX, lastPoint.y); 8164 } 8165 } 8166 ctx.lineTo(clipX, target.first().y); 8167 ctx.closePath(); 8168 ctx.clip(); 8169} 8170function fill(ctx, cfg) { 8171 const { line , target , property , color , scale , clip } = cfg; 8172 const segments = _segments(line, target, property); 8173 for (const { source: src , target: tgt , start , end } of segments){ 8174 const { style: { backgroundColor =color } = {} } = src; 8175 const notShape = target !== true; 8176 ctx.save(); 8177 ctx.fillStyle = backgroundColor; 8178 clipBounds(ctx, scale, clip, notShape && _getBounds(property, start, end)); 8179 ctx.beginPath(); 8180 const lineLoop = !!line.pathSegment(ctx, src); 8181 let loop; 8182 if (notShape) { 8183 if (lineLoop) { 8184 ctx.closePath(); 8185 } else { 8186 interpolatedLineTo(ctx, target, end, property); 8187 } 8188 const targetLoop = !!target.pathSegment(ctx, tgt, { 8189 move: lineLoop, 8190 reverse: true 8191 }); 8192 loop = lineLoop && targetLoop; 8193 if (!loop) { 8194 interpolatedLineTo(ctx, target, start, property); 8195 } 8196 } 8197 ctx.closePath(); 8198 ctx.fill(loop ? 'evenodd' : 'nonzero'); 8199 ctx.restore(); 8200 } 8201} 8202function clipBounds(ctx, scale, clip, bounds) { 8203 const chartArea = scale.chart.chartArea; 8204 const { property , start , end } = bounds || {}; 8205 if (property === 'x' || property === 'y') { 8206 let left, top, right, bottom; 8207 if (property === 'x') { 8208 left = start; 8209 top = chartArea.top; 8210 right = end; 8211 bottom = chartArea.bottom; 8212 } else { 8213 left = chartArea.left; 8214 top = start; 8215 right = chartArea.right; 8216 bottom = end; 8217 } 8218 ctx.beginPath(); 8219 if (clip) { 8220 left = Math.max(left, clip.left); 8221 right = Math.min(right, clip.right); 8222 top = Math.max(top, clip.top); 8223 bottom = Math.min(bottom, clip.bottom); 8224 } 8225 ctx.rect(left, top, right - left, bottom - top); 8226 ctx.clip(); 8227 } 8228} 8229function interpolatedLineTo(ctx, target, point, property) { 8230 const interpolatedPoint = target.interpolate(point, property); 8231 if (interpolatedPoint) { 8232 ctx.lineTo(interpolatedPoint.x, interpolatedPoint.y); 8233 } 8234} 8235 8236var index = { 8237 id: 'filler', 8238 afterDatasetsUpdate (chart, _args, options) { 8239 const count = (chart.data.datasets || []).length; 8240 const sources = []; 8241 let meta, i, line, source; 8242 for(i = 0; i < count; ++i){ 8243 meta = chart.getDatasetMeta(i); 8244 line = meta.dataset; 8245 source = null; 8246 if (line && line.options && line instanceof LineElement) { 8247 source = { 8248 visible: chart.isDatasetVisible(i), 8249 index: i, 8250 fill: _decodeFill(line, i, count), 8251 chart, 8252 axis: meta.controller.options.indexAxis, 8253 scale: meta.vScale, 8254 line 8255 }; 8256 } 8257 meta.$filler = source; 8258 sources.push(source); 8259 } 8260 for(i = 0; i < count; ++i){ 8261 source = sources[i]; 8262 if (!source || source.fill === false) { 8263 continue; 8264 } 8265 source.fill = _resolveTarget(sources, i, options.propagate); 8266 } 8267 }, 8268 beforeDraw (chart, _args, options) { 8269 const draw = options.drawTime === 'beforeDraw'; 8270 const metasets = chart.getSortedVisibleDatasetMetas(); 8271 const area = chart.chartArea; 8272 for(let i = metasets.length - 1; i >= 0; --i){ 8273 const source = metasets[i].$filler; 8274 if (!source) { 8275 continue; 8276 } 8277 source.line.updateControlPoints(area, source.axis); 8278 if (draw && source.fill) { 8279 _drawfill(chart.ctx, source, area); 8280 } 8281 } 8282 }, 8283 beforeDatasetsDraw (chart, _args, options) { 8284 if (options.drawTime !== 'beforeDatasetsDraw') { 8285 return; 8286 } 8287 const metasets = chart.getSortedVisibleDatasetMetas(); 8288 for(let i = metasets.length - 1; i >= 0; --i){ 8289 const source = metasets[i].$filler; 8290 if (_shouldApplyFill(source)) { 8291 _drawfill(chart.ctx, source, chart.chartArea); 8292 } 8293 } 8294 }, 8295 beforeDatasetDraw (chart, args, options) { 8296 const source = args.meta.$filler; 8297 if (!_shouldApplyFill(source) || options.drawTime !== 'beforeDatasetDraw') { 8298 return; 8299 } 8300 _drawfill(chart.ctx, source, chart.chartArea); 8301 }, 8302 defaults: { 8303 propagate: true, 8304 drawTime: 'beforeDatasetDraw' 8305 } 8306}; 8307 8308const getBoxSize = (labelOpts, fontSize)=>{ 8309 let { boxHeight =fontSize , boxWidth =fontSize } = labelOpts; 8310 if (labelOpts.usePointStyle) { 8311 boxHeight = Math.min(boxHeight, fontSize); 8312 boxWidth = labelOpts.pointStyleWidth || Math.min(boxWidth, fontSize); 8313 } 8314 return { 8315 boxWidth, 8316 boxHeight, 8317 itemHeight: Math.max(fontSize, boxHeight) 8318 }; 8319}; 8320const itemsEqual = (a, b)=>a !== null && b !== null && a.datasetIndex === b.datasetIndex && a.index === b.index; 8321class Legend extends Element { 8322 constructor(config){ 8323 super(); 8324 this._added = false; 8325 this.legendHitBoxes = []; 8326 this._hoveredItem = null; 8327 this.doughnutMode = false; 8328 this.chart = config.chart; 8329 this.options = config.options; 8330 this.ctx = config.ctx; 8331 this.legendItems = undefined; 8332 this.columnSizes = undefined; 8333 this.lineWidths = undefined; 8334 this.maxHeight = undefined; 8335 this.maxWidth = undefined; 8336 this.top = undefined; 8337 this.bottom = undefined; 8338 this.left = undefined; 8339 this.right = undefined; 8340 this.height = undefined; 8341 this.width = undefined; 8342 this._margins = undefined; 8343 this.position = undefined; 8344 this.weight = undefined; 8345 this.fullSize = undefined; 8346 } 8347 update(maxWidth, maxHeight, margins) { 8348 this.maxWidth = maxWidth; 8349 this.maxHeight = maxHeight; 8350 this._margins = margins; 8351 this.setDimensions(); 8352 this.buildLabels(); 8353 this.fit(); 8354 } 8355 setDimensions() { 8356 if (this.isHorizontal()) { 8357 this.width = this.maxWidth; 8358 this.left = this._margins.left; 8359 this.right = this.width; 8360 } else { 8361 this.height = this.maxHeight; 8362 this.top = this._margins.top; 8363 this.bottom = this.height; 8364 } 8365 } 8366 buildLabels() { 8367 const labelOpts = this.options.labels || {}; 8368 let legendItems = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(labelOpts.generateLabels, [ 8369 this.chart 8370 ], this) || []; 8371 if (labelOpts.filter) { 8372 legendItems = legendItems.filter((item)=>labelOpts.filter(item, this.chart.data)); 8373 } 8374 if (labelOpts.sort) { 8375 legendItems = legendItems.sort((a, b)=>labelOpts.sort(a, b, this.chart.data)); 8376 } 8377 if (this.options.reverse) { 8378 legendItems.reverse(); 8379 } 8380 this.legendItems = legendItems; 8381 } 8382 fit() { 8383 const { options , ctx } = this; 8384 if (!options.display) { 8385 this.width = this.height = 0; 8386 return; 8387 } 8388 const labelOpts = options.labels; 8389 const labelFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(labelOpts.font); 8390 const fontSize = labelFont.size; 8391 const titleHeight = this._computeTitleHeight(); 8392 const { boxWidth , itemHeight } = getBoxSize(labelOpts, fontSize); 8393 let width, height; 8394 ctx.font = labelFont.string; 8395 if (this.isHorizontal()) { 8396 width = this.maxWidth; 8397 height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10; 8398 } else { 8399 height = this.maxHeight; 8400 width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10; 8401 } 8402 this.width = Math.min(width, options.maxWidth || this.maxWidth); 8403 this.height = Math.min(height, options.maxHeight || this.maxHeight); 8404 } 8405 _fitRows(titleHeight, fontSize, boxWidth, itemHeight) { 8406 const { ctx , maxWidth , options: { labels: { padding } } } = this; 8407 const hitboxes = this.legendHitBoxes = []; 8408 const lineWidths = this.lineWidths = [ 8409 0 8410 ]; 8411 const lineHeight = itemHeight + padding; 8412 let totalHeight = titleHeight; 8413 ctx.textAlign = 'left'; 8414 ctx.textBaseline = 'middle'; 8415 let row = -1; 8416 let top = -lineHeight; 8417 this.legendItems.forEach((legendItem, i)=>{ 8418 const itemWidth = boxWidth + fontSize / 2 + ctx.measureText(legendItem.text).width; 8419 if (i === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) { 8420 totalHeight += lineHeight; 8421 lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0; 8422 top += lineHeight; 8423 row++; 8424 } 8425 hitboxes[i] = { 8426 left: 0, 8427 top, 8428 row, 8429 width: itemWidth, 8430 height: itemHeight 8431 }; 8432 lineWidths[lineWidths.length - 1] += itemWidth + padding; 8433 }); 8434 return totalHeight; 8435 } 8436 _fitCols(titleHeight, labelFont, boxWidth, _itemHeight) { 8437 const { ctx , maxHeight , options: { labels: { padding } } } = this; 8438 const hitboxes = this.legendHitBoxes = []; 8439 const columnSizes = this.columnSizes = []; 8440 const heightLimit = maxHeight - titleHeight; 8441 let totalWidth = padding; 8442 let currentColWidth = 0; 8443 let currentColHeight = 0; 8444 let left = 0; 8445 let col = 0;
8446 this.legendItems.forEach((legendItem, i)=>{ 8447 const { itemWidth , itemHeight } = calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight); 8448 if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) { 8449 totalWidth += currentColWidth + padding; 8450 columnSizes.push({ 8451 width: currentColWidth, 8452 height: currentColHeight 8453 }); 8454 left += currentColWidth + padding; 8455 col++; 8456 currentColWidth = currentColHeight = 0; 8457 } 8458 hitboxes[i] = { 8459 left, 8460 top: currentColHeight, 8461 col, 8462 width: itemWidth, 8463 height: itemHeight 8464 }; 8465 currentColWidth = Math.max(currentColWidth, itemWidth); 8466 currentColHeight += itemHeight + padding; 8467 }); 8468 totalWidth += currentColWidth; 8469 columnSizes.push({ 8470 width: currentColWidth, 8471 height: currentColHeight 8472 }); 8473 return totalWidth; 8474 } 8475 adjustHitBoxes() { 8476 if (!this.options.display) { 8477 return; 8478 } 8479 const titleHeight = this._computeTitleHeight(); 8480 const { legendHitBoxes: hitboxes , options: { align , labels: { padding } , rtl } } = this; 8481 const rtlHelper = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aA)(rtl, this.left, this.width); 8482 if (this.isHorizontal()) { 8483 let row = 0; 8484 let left = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.left + padding, this.right - this.lineWidths[row]); 8485 for (const hitbox of hitboxes){ 8486 if (row !== hitbox.row) { 8487 row = hitbox.row; 8488 left = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.left + padding, this.right - this.lineWidths[row]); 8489 } 8490 hitbox.top += this.top + titleHeight + padding; 8491 hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width); 8492 left += hitbox.width + padding; 8493 } 8494 } else { 8495 let col = 0; 8496 let top = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height); 8497 for (const hitbox of hitboxes){ 8498 if (hitbox.col !== col) {
8499 col = hitbox.col; 8500 top = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height); 8501 } 8502 hitbox.top = top; 8503 hitbox.left += this.left + padding; 8504 hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width); 8505 top += hitbox.height + padding; 8506 } 8507 } 8508 } 8509 isHorizontal() { 8510 return this.options.position === 'top' || this.options.position === 'bottom'; 8511 } 8512 draw() { 8513 if (this.options.display) { 8514 const ctx = this.ctx; 8515 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Y)(ctx, this); 8516 this._draw(); 8517 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.$)(ctx); 8518 } 8519 } 8520 _draw() { 8521 const { options: opts , columnSizes , lineWidths , ctx } = this; 8522 const { align , labels: labelOpts } = opts; 8523 const defaultColor = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.color; 8524 const rtlHelper = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aA)(opts.rtl, this.left, this.width); 8525 const labelFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(labelOpts.font); 8526 const { padding } = labelOpts; 8527 const fontSize = labelFont.size; 8528 const halfFontSize = fontSize / 2; 8529 let cursor; 8530 this.drawTitle(); 8531 ctx.textAlign = rtlHelper.textAlign('left'); 8532 ctx.textBaseline = 'middle'; 8533 ctx.lineWidth = 0.5; 8534 ctx.font = labelFont.string; 8535 const { boxWidth , boxHeight , itemHeight } = getBoxSize(labelOpts, fontSize); 8536 const drawLegendBox = function(x, y, legendItem) { 8537 if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) { 8538 return; 8539 } 8540 ctx.save(); 8541 const lineWidth = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.lineWidth, 1); 8542 ctx.fillStyle = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.fillStyle, defaultColor); 8543 ctx.lineCap = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.lineCap, 'butt'); 8544 ctx.lineDashOffset = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.lineDashOffset, 0); 8545 ctx.lineJoin = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.lineJoin, 'miter'); 8546 ctx.lineWidth = lineWidth; 8547 ctx.strokeStyle = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.strokeStyle, defaultColor); 8548 ctx.setLineDash((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(legendItem.lineDash, [])); 8549 if (labelOpts.usePointStyle) { 8550 const drawOptions = { 8551 radius: boxHeight * Math.SQRT2 / 2, 8552 pointStyle: legendItem.pointStyle, 8553 rotation: legendItem.rotation, 8554 borderWidth: lineWidth 8555 }; 8556 const centerX = rtlHelper.xPlus(x, boxWidth / 2); 8557 const centerY = y + halfFontSize; 8558 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aE)(ctx, drawOptions, centerX, centerY, labelOpts.pointStyleWidth && boxWidth); 8559 } else { 8560 const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0); 8561 const xBoxLeft = rtlHelper.leftForLtr(x, boxWidth); 8562 const borderRadius = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(legendItem.borderRadius); 8563 ctx.beginPath(); 8564 if (Object.values(borderRadius).some((v)=>v !== 0)) { 8565 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aw)(ctx, { 8566 x: xBoxLeft, 8567 y: yBoxTop, 8568 w: boxWidth, 8569 h: boxHeight, 8570 radius: borderRadius 8571 }); 8572 } else { 8573 ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight); 8574 } 8575 ctx.fill(); 8576 if (lineWidth !== 0) { 8577 ctx.stroke(); 8578 } 8579 }
8580 ctx.restore(); 8581 }; 8582 const fillText = function(x, y, legendItem) { 8583 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, legendItem.text, x, y + itemHeight / 2, labelFont, { 8584 strikethrough: legendItem.hidden, 8585 textAlign: rtlHelper.textAlign(legendItem.textAlign) 8586 }); 8587 }; 8588 const isHorizontal = this.isHorizontal(); 8589 const titleHeight = this._computeTitleHeight(); 8590 if (isHorizontal) { 8591 cursor = { 8592 x: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.left + padding, this.right - lineWidths[0]), 8593 y: this.top + padding + titleHeight, 8594 line: 0 8595 }; 8596 } else { 8597 cursor = { 8598 x: this.left + padding, 8599 y: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height), 8600 line: 0 8601 }; 8602 } 8603 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aB)(this.ctx, opts.textDirection); 8604 const lineHeight = itemHeight + padding; 8605 this.legendItems.forEach((legendItem, i)=>{ 8606 ctx.strokeStyle = legendItem.fontColor; 8607 ctx.fillStyle = legendItem.fontColor; 8608 const textWidth = ctx.measureText(legendItem.text).width; 8609 const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign)); 8610 const width = boxWidth + halfFontSize + textWidth; 8611 let x = cursor.x; 8612 let y = cursor.y; 8613 rtlHelper.setWidth(this.width); 8614 if (isHorizontal) { 8615 if (i > 0 && x + width + padding > this.right) { 8616 y = cursor.y += lineHeight; 8617 cursor.line++; 8618 x = cursor.x = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.left + padding, this.right - lineWidths[cursor.line]); 8619 } 8620 } else if (i > 0 && y + lineHeight > this.bottom) { 8621 x = cursor.x = x + columnSizes[cursor.line].width + padding; 8622 cursor.line++; 8623 y = cursor.y = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height); 8624 } 8625 const realX = rtlHelper.x(x); 8626 drawLegendBox(realX, y, legendItem); 8627 x = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aC)(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : this.right, opts.rtl); 8628 fillText(rtlHelper.x(x), y, legendItem); 8629 if (isHorizontal) { 8630 cursor.x += width + padding; 8631 } else if (typeof legendItem.text !== 'string') { 8632 const fontLineHeight = labelFont.lineHeight; 8633 cursor.y += calculateLegendItemHeight(legendItem, fontLineHeight) + padding; 8634 } else { 8635 cursor.y += lineHeight; 8636 } 8637 }); 8638 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aD)(this.ctx, opts.textDirection); 8639 } 8640 drawTitle() { 8641 const opts = this.options; 8642 const titleOpts = opts.title; 8643 const titleFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(titleOpts.font); 8644 const titlePadding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(titleOpts.padding); 8645 if (!titleOpts.display) { 8646 return; 8647 } 8648 const rtlHelper = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aA)(opts.rtl, this.left, this.width); 8649 const ctx = this.ctx; 8650 const position = titleOpts.position; 8651 const halfFontSize = titleFont.size / 2; 8652 const topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize; 8653 let y; 8654 let left = this.left; 8655 let maxWidth = this.width; 8656 if (this.isHorizontal()) { 8657 maxWidth = Math.max(...this.lineWidths); 8658 y = this.top + topPaddingPlusHalfFontSize; 8659 left = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(opts.align, left, this.right - maxWidth); 8660 } else { 8661 const maxHeight = this.columnSizes.reduce((acc, size)=>Math.max(acc, size.height), 0); 8662 y = topPaddingPlusHalfFontSize + (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight()); 8663 } 8664 const x = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(position, left, left + maxWidth); 8665 ctx.textAlign = rtlHelper.textAlign((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a1)(position)); 8666 ctx.textBaseline = 'middle'; 8667 ctx.strokeStyle = titleOpts.color; 8668 ctx.fillStyle = titleOpts.color; 8669 ctx.font = titleFont.string; 8670 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, titleOpts.text, x, y, titleFont); 8671 } 8672 _computeTitleHeight() { 8673 const titleOpts = this.options.title; 8674 const titleFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(titleOpts.font); 8675 const titlePadding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(titleOpts.padding); 8676 return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0; 8677 } 8678 _getLegendItemAt(x, y) { 8679 let i, hitBox, lh; 8680 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(x, this.left, this.right) && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(y, this.top, this.bottom)) { 8681 lh = this.legendHitBoxes; 8682 for(i = 0; i < lh.length; ++i){ 8683 hitBox = lh[i]; 8684 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(x, hitBox.left, hitBox.left + hitBox.width) && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ak)(y, hitBox.top, hitBox.top + hitBox.height)) { 8685 return this.legendItems[i]; 8686 } 8687 } 8688 } 8689 return null; 8690 } 8691 handleEvent(e) { 8692 const opts = this.options; 8693 if (!isListened(e.type, opts)) { 8694 return; 8695 } 8696 const hoveredItem = this._getLegendItemAt(e.x, e.y); 8697 if (e.type === 'mousemove' || e.type === 'mouseout') { 8698 const previous = this._hoveredItem; 8699 const sameItem = itemsEqual(previous, hoveredItem); 8700 if (previous && !sameItem) { 8701 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(opts.onLeave, [ 8702 e, 8703 previous, 8704 this 8705 ], this); 8706 } 8707 this._hoveredItem = hoveredItem; 8708 if (hoveredItem && !sameItem) { 8709 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(opts.onHover, [ 8710 e, 8711 hoveredItem, 8712 this 8713 ], this); 8714 } 8715 } else if (hoveredItem) { 8716 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(opts.onClick, [ 8717 e, 8718 hoveredItem, 8719 this 8720 ], this); 8721 } 8722 } 8723} 8724function calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight) { 8725 const itemWidth = calculateItemWidth(legendItem, boxWidth, labelFont, ctx); 8726 const itemHeight = calculateItemHeight(_itemHeight, legendItem, labelFont.lineHeight); 8727 return { 8728 itemWidth, 8729 itemHeight 8730 }; 8731} 8732function calculateItemWidth(legendItem, boxWidth, labelFont, ctx) { 8733 let legendItemText = legendItem.text; 8734 if (legendItemText && typeof legendItemText !== 'string') { 8735 legendItemText = legendItemText.reduce((a, b)=>a.length > b.length ? a : b); 8736 } 8737 return boxWidth + labelFont.size / 2 + ctx.measureText(legendItemText).width; 8738} 8739function calculateItemHeight(_itemHeight, legendItem, fontLineHeight) { 8740 let itemHeight = _itemHeight; 8741 if (typeof legendItem.text !== 'string') { 8742 itemHeight = calculateLegendItemHeight(legendItem, fontLineHeight); 8743 } 8744 return itemHeight; 8745} 8746function calculateLegendItemHeight(legendItem, fontLineHeight) { 8747 const labelHeight = legendItem.text ? legendItem.text.length : 0; 8748 return fontLineHeight * labelHeight; 8749} 8750function isListened(type, opts) { 8751 if ((type === 'mousemove' || type === 'mouseout') && (opts.onHover || opts.onLeave)) { 8752 return true; 8753 } 8754 if (opts.onClick && (type === 'click' || type === 'mouseup')) { 8755 return true; 8756 } 8757 return false;
vendor: 32,831 bytes, lines 8758-9626
8758} 8759var plugin_legend = { 8760 id: 'legend', 8761 _element: Legend, 8762 start (chart, _args, options) { 8763 const legend = chart.legend = new Legend({ 8764 ctx: chart.ctx, 8765 options, 8766 chart 8767 }); 8768 layouts.configure(chart, legend, options); 8769 layouts.addBox(chart, legend); 8770 }, 8771 stop (chart) { 8772 layouts.removeBox(chart, chart.legend); 8773 delete chart.legend; 8774 }, 8775 beforeUpdate (chart, _args, options) { 8776 const legend = chart.legend; 8777 layouts.configure(chart, legend, options); 8778 legend.options = options; 8779 }, 8780 afterUpdate (chart) { 8781 const legend = chart.legend; 8782 legend.buildLabels(); 8783 legend.adjustHitBoxes(); 8784 }, 8785 afterEvent (chart, args) { 8786 if (!args.replay) { 8787 chart.legend.handleEvent(args.event); 8788 } 8789 }, 8790 defaults: { 8791 display: true, 8792 position: 'top', 8793 align: 'center', 8794 fullSize: true, 8795 reverse: false, 8796 weight: 1000, 8797 onClick (e, legendItem, legend) { 8798 const index = legendItem.datasetIndex; 8799 const ci = legend.chart; 8800 if (ci.isDatasetVisible(index)) { 8801 ci.hide(index); 8802 legendItem.hidden = true; 8803 } else { 8804 ci.show(index); 8805 legendItem.hidden = false; 8806 } 8807 }, 8808 onHover: null, 8809 onLeave: null, 8810 labels: { 8811 color: (ctx)=>ctx.chart.options.color, 8812 boxWidth: 40, 8813 padding: 10, 8814 generateLabels (chart) { 8815 const datasets = chart.data.datasets; 8816 const { labels: { usePointStyle , pointStyle , textAlign , color , useBorderRadius , borderRadius } } = chart.legend.options; 8817 return chart._getSortedDatasetMetas().map((meta)=>{ 8818 const style = meta.controller.getStyle(usePointStyle ? 0 : undefined); 8819 const borderWidth = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(style.borderWidth); 8820 return { 8821 text: datasets[meta.index].label, 8822 fillStyle: style.backgroundColor, 8823 fontColor: color, 8824 hidden: !meta.visible, 8825 lineCap: style.borderCapStyle, 8826 lineDash: style.borderDash, 8827 lineDashOffset: style.borderDashOffset, 8828 lineJoin: style.borderJoinStyle, 8829 lineWidth: (borderWidth.width + borderWidth.height) / 4, 8830 strokeStyle: style.borderColor, 8831 pointStyle: pointStyle || style.pointStyle, 8832 rotation: style.rotation, 8833 textAlign: textAlign || style.textAlign, 8834 borderRadius: useBorderRadius && (borderRadius || style.borderRadius), 8835 datasetIndex: meta.index 8836 }; 8837 }, this); 8838 } 8839 }, 8840 title: { 8841 color: (ctx)=>ctx.chart.options.color, 8842 display: false, 8843 position: 'center', 8844 text: '' 8845 } 8846 }, 8847 descriptors: { 8848 _scriptable: (name)=>!name.startsWith('on'), 8849 labels: { 8850 _scriptable: (name)=>![ 8851 'generateLabels', 8852 'filter', 8853 'sort' 8854 ].includes(name) 8855 } 8856 } 8857}; 8858 8859class Title extends Element { 8860 constructor(config){ 8861 super(); 8862 this.chart = config.chart; 8863 this.options = config.options; 8864 this.ctx = config.ctx; 8865 this._padding = undefined; 8866 this.top = undefined; 8867 this.bottom = undefined; 8868 this.left = undefined; 8869 this.right = undefined; 8870 this.width = undefined; 8871 this.height = undefined; 8872 this.position = undefined; 8873 this.weight = undefined; 8874 this.fullSize = undefined; 8875 } 8876 update(maxWidth, maxHeight) { 8877 const opts = this.options; 8878 this.left = 0; 8879 this.top = 0; 8880 if (!opts.display) { 8881 this.width = this.height = this.right = this.bottom = 0; 8882 return; 8883 } 8884 this.width = this.right = maxWidth; 8885 this.height = this.bottom = maxHeight; 8886 const lineCount = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(opts.text) ? opts.text.length : 1; 8887 this._padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(opts.padding); 8888 const textSize = lineCount * (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(opts.font).lineHeight + this._padding.height; 8889 if (this.isHorizontal()) { 8890 this.height = textSize; 8891 } else { 8892 this.width = textSize; 8893 } 8894 } 8895 isHorizontal() { 8896 const pos = this.options.position; 8897 return pos === 'top' || pos === 'bottom'; 8898 } 8899 _drawArgs(offset) { 8900 const { top , left , bottom , right , options } = this; 8901 const align = options.align; 8902 let rotation = 0; 8903 let maxWidth, titleX, titleY; 8904 if (this.isHorizontal()) { 8905 titleX = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, left, right); 8906 titleY = top + offset; 8907 maxWidth = right - left; 8908 } else { 8909 if (options.position === 'left') { 8910 titleX = left + offset; 8911 titleY = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, bottom, top); 8912 rotation = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P * -0.5; 8913 } else { 8914 titleX = right - offset; 8915 titleY = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a2)(align, top, bottom); 8916 rotation = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P * 0.5; 8917 } 8918 maxWidth = bottom - top; 8919 } 8920 return { 8921 titleX, 8922 titleY, 8923 maxWidth, 8924 rotation 8925 }; 8926 } 8927 draw() { 8928 const ctx = this.ctx; 8929 const opts = this.options; 8930 if (!opts.display) { 8931 return; 8932 } 8933 const fontOpts = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(opts.font); 8934 const lineHeight = fontOpts.lineHeight; 8935 const offset = lineHeight / 2 + this._padding.top; 8936 const { titleX , titleY , maxWidth , rotation } = this._drawArgs(offset); 8937 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, opts.text, 0, 0, fontOpts, { 8938 color: opts.color, 8939 maxWidth, 8940 rotation, 8941 textAlign: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a1)(opts.align), 8942 textBaseline: 'middle', 8943 translation: [ 8944 titleX, 8945 titleY 8946 ] 8947 }); 8948 } 8949} 8950function createTitle(chart, titleOpts) { 8951 const title = new Title({ 8952 ctx: chart.ctx, 8953 options: titleOpts, 8954 chart 8955 }); 8956 layouts.configure(chart, title, titleOpts); 8957 layouts.addBox(chart, title); 8958 chart.titleBlock = title; 8959} 8960var plugin_title = { 8961 id: 'title', 8962 _element: Title, 8963 start (chart, _args, options) { 8964 createTitle(chart, options); 8965 }, 8966 stop (chart) { 8967 const titleBlock = chart.titleBlock; 8968 layouts.removeBox(chart, titleBlock); 8969 delete chart.titleBlock; 8970 }, 8971 beforeUpdate (chart, _args, options) { 8972 const title = chart.titleBlock; 8973 layouts.configure(chart, title, options); 8974 title.options = options; 8975 }, 8976 defaults: { 8977 align: 'center', 8978 display: false, 8979 font: { 8980 weight: 'bold' 8981 }, 8982 fullSize: true, 8983 padding: 10, 8984 position: 'top', 8985 text: '', 8986 weight: 2000 8987 }, 8988 defaultRoutes: { 8989 color: 'color' 8990 }, 8991 descriptors: { 8992 _scriptable: true, 8993 _indexable: false 8994 } 8995}; 8996 8997const map = new WeakMap(); 8998var plugin_subtitle = { 8999 id: 'subtitle', 9000 start (chart, _args, options) { 9001 const title = new Title({ 9002 ctx: chart.ctx, 9003 options, 9004 chart 9005 }); 9006 layouts.configure(chart, title, options); 9007 layouts.addBox(chart, title); 9008 map.set(chart, title); 9009 }, 9010 stop (chart) { 9011 layouts.removeBox(chart, map.get(chart)); 9012 map.delete(chart); 9013 }, 9014 beforeUpdate (chart, _args, options) { 9015 const title = map.get(chart); 9016 layouts.configure(chart, title, options); 9017 title.options = options; 9018 }, 9019 defaults: { 9020 align: 'center', 9021 display: false, 9022 font: { 9023 weight: 'normal' 9024 }, 9025 fullSize: true, 9026 padding: 0, 9027 position: 'top', 9028 text: '', 9029 weight: 1500 9030 }, 9031 defaultRoutes: { 9032 color: 'color' 9033 }, 9034 descriptors: { 9035 _scriptable: true, 9036 _indexable: false 9037 } 9038}; 9039 9040const positioners = { 9041 average (items) { 9042 if (!items.length) { 9043 return false; 9044 } 9045 let i, len; 9046 let xSet = new Set(); 9047 let y = 0; 9048 let count = 0; 9049 for(i = 0, len = items.length; i < len; ++i){ 9050 const el = items[i].element; 9051 if (el && el.hasValue()) { 9052 const pos = el.tooltipPosition(); 9053 xSet.add(pos.x); 9054 y += pos.y; 9055 ++count; 9056 } 9057 } 9058 if (count === 0 || xSet.size === 0) { 9059 return false; 9060 } 9061 const xAverage = [ 9062 ...xSet 9063 ].reduce((a, b)=>a + b) / xSet.size; 9064 return { 9065 x: xAverage, 9066 y: y / count 9067 }; 9068 }, 9069 nearest (items, eventPosition) { 9070 if (!items.length) { 9071 return false; 9072 } 9073 let x = eventPosition.x; 9074 let y = eventPosition.y; 9075 let minDistance = Number.POSITIVE_INFINITY; 9076 let i, len, nearestElement; 9077 for(i = 0, len = items.length; i < len; ++i){ 9078 const el = items[i].element; 9079 if (el && el.hasValue()) { 9080 const center = el.getCenterPoint(); 9081 const d = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aF)(eventPosition, center); 9082 if (d < minDistance) { 9083 minDistance = d; 9084 nearestElement = el; 9085 } 9086 } 9087 } 9088 if (nearestElement) { 9089 const tp = nearestElement.tooltipPosition(); 9090 x = tp.x; 9091 y = tp.y; 9092 } 9093 return { 9094 x, 9095 y 9096 }; 9097 } 9098}; 9099function pushOrConcat(base, toPush) { 9100 if (toPush) { 9101 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(toPush)) { 9102 Array.prototype.push.apply(base, toPush); 9103 } else { 9104 base.push(toPush); 9105 } 9106 } 9107 return base; 9108} 9109 function splitNewlines(str) { 9110 if ((typeof str === 'string' || str instanceof String) && str.indexOf('\n') > -1) { 9111 return str.split('\n'); 9112 } 9113 return str; 9114} 9115 function createTooltipItem(chart, item) { 9116 const { element , datasetIndex , index } = item; 9117 const controller = chart.getDatasetMeta(datasetIndex).controller; 9118 const { label , value } = controller.getLabelAndValue(index); 9119 return { 9120 chart, 9121 label, 9122 parsed: controller.getParsed(index), 9123 raw: chart.data.datasets[datasetIndex].data[index], 9124 formattedValue: value, 9125 dataset: controller.getDataset(), 9126 dataIndex: index, 9127 datasetIndex, 9128 element 9129 }; 9130} 9131 function getTooltipSize(tooltip, options) { 9132 const ctx = tooltip.chart.ctx; 9133 const { body , footer , title } = tooltip; 9134 const { boxWidth , boxHeight } = options; 9135 const bodyFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.bodyFont); 9136 const titleFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.titleFont); 9137 const footerFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.footerFont); 9138 const titleLineCount = title.length; 9139 const footerLineCount = footer.length; 9140 const bodyLineItemCount = body.length; 9141 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(options.padding); 9142 let height = padding.height; 9143 let width = 0; 9144 let combinedBodyLength = body.reduce((count, bodyItem)=>count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length, 0); 9145 combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length; 9146 if (titleLineCount) { 9147 height += titleLineCount * titleFont.lineHeight + (titleLineCount - 1) * options.titleSpacing + options.titleMarginBottom; 9148 } 9149 if (combinedBodyLength) { 9150 const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight; 9151 height += bodyLineItemCount * bodyLineHeight + (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight + (combinedBodyLength - 1) * options.bodySpacing; 9152 } 9153 if (footerLineCount) { 9154 height += options.footerMarginTop + footerLineCount * footerFont.lineHeight + (footerLineCount - 1) * options.footerSpacing; 9155 } 9156 let widthPadding = 0; 9157 const maxLineWidth = function(line) { 9158 width = Math.max(width, ctx.measureText(line).width + widthPadding); 9159 }; 9160 ctx.save(); 9161 ctx.font = titleFont.string; 9162 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(tooltip.title, maxLineWidth); 9163 ctx.font = bodyFont.string; 9164 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth); 9165 widthPadding = options.displayColors ? boxWidth + 2 + options.boxPadding : 0; 9166 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(body, (bodyItem)=>{ 9167 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(bodyItem.before, maxLineWidth); 9168 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(bodyItem.lines, maxLineWidth); 9169 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(bodyItem.after, maxLineWidth); 9170 }); 9171 widthPadding = 0; 9172 ctx.font = footerFont.string; 9173 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(tooltip.footer, maxLineWidth); 9174 ctx.restore(); 9175 width += padding.width; 9176 return { 9177 width, 9178 height 9179 }; 9180} 9181function determineYAlign(chart, size) { 9182 const { y , height } = size; 9183 if (y < height / 2) { 9184 return 'top'; 9185 } else if (y > chart.height - height / 2) { 9186 return 'bottom'; 9187 } 9188 return 'center'; 9189} 9190function doesNotFitWithAlign(xAlign, chart, options, size) { 9191 const { x , width } = size; 9192 const caret = options.caretSize + options.caretPadding; 9193 if (xAlign === 'left' && x + width + caret > chart.width) { 9194 return true; 9195 } 9196 if (xAlign === 'right' && x - width - caret < 0) { 9197 return true; 9198 } 9199} 9200function determineXAlign(chart, options, size, yAlign) { 9201 const { x , width } = size; 9202 const { width: chartWidth , chartArea: { left , right } } = chart; 9203 let xAlign = 'center'; 9204 if (yAlign === 'center') { 9205 xAlign = x <= (left + right) / 2 ? 'left' : 'right'; 9206 } else if (x <= width / 2) { 9207 xAlign = 'left'; 9208 } else if (x >= chartWidth - width / 2) { 9209 xAlign = 'right'; 9210 } 9211 if (doesNotFitWithAlign(xAlign, chart, options, size)) { 9212 xAlign = 'center'; 9213 } 9214 return xAlign; 9215} 9216 function determineAlignment(chart, options, size) { 9217 const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size); 9218 return { 9219 xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign), 9220 yAlign 9221 }; 9222} 9223function alignX(size, xAlign) { 9224 let { x , width } = size; 9225 if (xAlign === 'right') { 9226 x -= width; 9227 } else if (xAlign === 'center') { 9228 x -= width / 2; 9229 } 9230 return x; 9231} 9232function alignY(size, yAlign, paddingAndSize) { 9233 let { y , height } = size; 9234 if (yAlign === 'top') { 9235 y += paddingAndSize; 9236 } else if (yAlign === 'bottom') { 9237 y -= height + paddingAndSize; 9238 } else { 9239 y -= height / 2; 9240 } 9241 return y; 9242} 9243 function getBackgroundPoint(options, size, alignment, chart) { 9244 const { caretSize , caretPadding , cornerRadius } = options; 9245 const { xAlign , yAlign } = alignment; 9246 const paddingAndSize = caretSize + caretPadding; 9247 const { topLeft , topRight , bottomLeft , bottomRight } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(cornerRadius); 9248 let x = alignX(size, xAlign); 9249 const y = alignY(size, yAlign, paddingAndSize); 9250 if (yAlign === 'center') { 9251 if (xAlign === 'left') { 9252 x += paddingAndSize; 9253 } else if (xAlign === 'right') { 9254 x -= paddingAndSize; 9255 } 9256 } else if (xAlign === 'left') { 9257 x -= Math.max(topLeft, bottomLeft) + caretSize; 9258 } else if (xAlign === 'right') { 9259 x += Math.max(topRight, bottomRight) + caretSize; 9260 } 9261 return { 9262 x: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(x, 0, chart.width - size.width), 9263 y: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(y, 0, chart.height - size.height) 9264 }; 9265} 9266function getAlignedX(tooltip, align, options) { 9267 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(options.padding); 9268 return align === 'center' ? tooltip.x + tooltip.width / 2 : align === 'right' ? tooltip.x + tooltip.width - padding.right : tooltip.x + padding.left; 9269} 9270 function getBeforeAfterBodyLines(callback) { 9271 return pushOrConcat([], splitNewlines(callback)); 9272} 9273function createTooltipContext(parent, tooltip, tooltipItems) { 9274 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(parent, { 9275 tooltip, 9276 tooltipItems, 9277 type: 'tooltip' 9278 }); 9279} 9280function overrideCallbacks(callbacks, context) { 9281 const override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks; 9282 return override ? callbacks.override(override) : callbacks; 9283} 9284const defaultCallbacks = { 9285 beforeTitle: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9286 title (tooltipItems) { 9287 if (tooltipItems.length > 0) { 9288 const item = tooltipItems[0]; 9289 const labels = item.chart.data.labels; 9290 const labelCount = labels ? labels.length : 0; 9291 if (this && this.options && this.options.mode === 'dataset') { 9292 return item.dataset.label || ''; 9293 } else if (item.label) { 9294 return item.label; 9295 } else if (labelCount > 0 && item.dataIndex < labelCount) { 9296 return labels[item.dataIndex]; 9297 } 9298 } 9299 return ''; 9300 }, 9301 afterTitle: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9302 beforeBody: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9303 beforeLabel: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9304 label (tooltipItem) { 9305 if (this && this.options && this.options.mode === 'dataset') { 9306 return tooltipItem.label + ': ' + tooltipItem.formattedValue || tooltipItem.formattedValue; 9307 } 9308 let label = tooltipItem.dataset.label || ''; 9309 if (label) { 9310 label += ': '; 9311 } 9312 const value = tooltipItem.formattedValue; 9313 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(value)) { 9314 label += value; 9315 } 9316 return label; 9317 }, 9318 labelColor (tooltipItem) { 9319 const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex); 9320 const options = meta.controller.getStyle(tooltipItem.dataIndex); 9321 return { 9322 borderColor: options.borderColor, 9323 backgroundColor: options.backgroundColor, 9324 borderWidth: options.borderWidth, 9325 borderDash: options.borderDash, 9326 borderDashOffset: options.borderDashOffset, 9327 borderRadius: 0 9328 }; 9329 }, 9330 labelTextColor () { 9331 return this.options.bodyColor; 9332 }, 9333 labelPointStyle (tooltipItem) { 9334 const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex); 9335 const options = meta.controller.getStyle(tooltipItem.dataIndex); 9336 return { 9337 pointStyle: options.pointStyle, 9338 rotation: options.rotation 9339 }; 9340 }, 9341 afterLabel: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9342 afterBody: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9343 beforeFooter: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9344 footer: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG, 9345 afterFooter: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aG 9346}; 9347 function invokeCallbackWithFallback(callbacks, name, ctx, arg) { 9348 const result = callbacks[name].call(ctx, arg); 9349 if (typeof result === 'undefined') { 9350 return defaultCallbacks[name].call(ctx, arg); 9351 } 9352 return result; 9353} 9354class Tooltip extends Element { 9355 static positioners = positioners; 9356 constructor(config){ 9357 super(); 9358 this.opacity = 0; 9359 this._active = []; 9360 this._eventPosition = undefined; 9361 this._size = undefined; 9362 this._cachedAnimations = undefined; 9363 this._tooltipItems = []; 9364 this.$animations = undefined; 9365 this.$context = undefined; 9366 this.chart = config.chart; 9367 this.options = config.options; 9368 this.dataPoints = undefined; 9369 this.title = undefined; 9370 this.beforeBody = undefined; 9371 this.body = undefined; 9372 this.afterBody = undefined; 9373 this.footer = undefined; 9374 this.xAlign = undefined; 9375 this.yAlign = undefined; 9376 this.x = undefined; 9377 this.y = undefined; 9378 this.height = undefined; 9379 this.width = undefined; 9380 this.caretX = undefined; 9381 this.caretY = undefined; 9382 this.labelColors = undefined; 9383 this.labelPointStyles = undefined; 9384 this.labelTextColors = undefined; 9385 } 9386 initialize(options) { 9387 this.options = options; 9388 this._cachedAnimations = undefined; 9389 this.$context = undefined; 9390 } 9391 _resolveAnimations() { 9392 const cached = this._cachedAnimations; 9393 if (cached) { 9394 return cached; 9395 } 9396 const chart = this.chart; 9397 const options = this.options.setContext(this.getContext()); 9398 const opts = options.enabled && chart.options.animation && options.animations; 9399 const animations = new Animations(this.chart, opts); 9400 if (opts._cacheable) { 9401 this._cachedAnimations = Object.freeze(animations); 9402 } 9403 return animations; 9404 } 9405 getContext() { 9406 return this.$context || (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems)); 9407 } 9408 getTitle(context, options) { 9409 const { callbacks } = options; 9410 const beforeTitle = invokeCallbackWithFallback(callbacks, 'beforeTitle', this, context); 9411 const title = invokeCallbackWithFallback(callbacks, 'title', this, context); 9412 const afterTitle = invokeCallbackWithFallback(callbacks, 'afterTitle', this, context); 9413 let lines = []; 9414 lines = pushOrConcat(lines, splitNewlines(beforeTitle)); 9415 lines = pushOrConcat(lines, splitNewlines(title)); 9416 lines = pushOrConcat(lines, splitNewlines(afterTitle)); 9417 return lines; 9418 } 9419 getBeforeBody(tooltipItems, options) { 9420 return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, 'beforeBody', this, tooltipItems)); 9421 } 9422 getBody(tooltipItems, options) { 9423 const { callbacks } = options; 9424 const bodyItems = []; 9425 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(tooltipItems, (context)=>{ 9426 const bodyItem = { 9427 before: [], 9428 lines: [], 9429 after: [] 9430 }; 9431 const scoped = overrideCallbacks(callbacks, context); 9432 pushOrConcat(bodyItem.before, splitNewlines(invokeCallbackWithFallback(scoped, 'beforeLabel', this, context))); 9433 pushOrConcat(bodyItem.lines, invokeCallbackWithFallback(scoped, 'label', this, context)); 9434 pushOrConcat(bodyItem.after, splitNewlines(invokeCallbackWithFallback(scoped, 'afterLabel', this, context))); 9435 bodyItems.push(bodyItem); 9436 }); 9437 return bodyItems; 9438 } 9439 getAfterBody(tooltipItems, options) { 9440 return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, 'afterBody', this, tooltipItems)); 9441 } 9442 getFooter(tooltipItems, options) { 9443 const { callbacks } = options; 9444 const beforeFooter = invokeCallbackWithFallback(callbacks, 'beforeFooter', this, tooltipItems); 9445 const footer = invokeCallbackWithFallback(callbacks, 'footer', this, tooltipItems); 9446 const afterFooter = invokeCallbackWithFallback(callbacks, 'afterFooter', this, tooltipItems); 9447 let lines = []; 9448 lines = pushOrConcat(lines, splitNewlines(beforeFooter)); 9449 lines = pushOrConcat(lines, splitNewlines(footer)); 9450 lines = pushOrConcat(lines, splitNewlines(afterFooter)); 9451 return lines; 9452 } 9453 _createItems(options) { 9454 const active = this._active; 9455 const data = this.chart.data; 9456 const labelColors = []; 9457 const labelPointStyles = []; 9458 const labelTextColors = []; 9459 let tooltipItems = []; 9460 let i, len; 9461 for(i = 0, len = active.length; i < len; ++i){ 9462 tooltipItems.push(createTooltipItem(this.chart, active[i])); 9463 } 9464 if (options.filter) { 9465 tooltipItems = tooltipItems.filter((element, index, array)=>options.filter(element, index, array, data)); 9466 } 9467 if (options.itemSort) { 9468 tooltipItems = tooltipItems.sort((a, b)=>options.itemSort(a, b, data)); 9469 } 9470 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(tooltipItems, (context)=>{ 9471 const scoped = overrideCallbacks(options.callbacks, context); 9472 labelColors.push(invokeCallbackWithFallback(scoped, 'labelColor', this, context)); 9473 labelPointStyles.push(invokeCallbackWithFallback(scoped, 'labelPointStyle', this, context)); 9474 labelTextColors.push(invokeCallbackWithFallback(scoped, 'labelTextColor', this, context)); 9475 }); 9476 this.labelColors = labelColors; 9477 this.labelPointStyles = labelPointStyles; 9478 this.labelTextColors = labelTextColors; 9479 this.dataPoints = tooltipItems; 9480 return tooltipItems; 9481 } 9482 update(changed, replay) { 9483 const options = this.options.setContext(this.getContext()); 9484 const active = this._active; 9485 let properties; 9486 let tooltipItems = []; 9487 if (!active.length) { 9488 if (this.opacity !== 0) { 9489 properties = { 9490 opacity: 0 9491 }; 9492 } 9493 } else { 9494 const position = positioners[options.position].call(this, active, this._eventPosition); 9495 tooltipItems = this._createItems(options); 9496 this.title = this.getTitle(tooltipItems, options); 9497 this.beforeBody = this.getBeforeBody(tooltipItems, options); 9498 this.body = this.getBody(tooltipItems, options); 9499 this.afterBody = this.getAfterBody(tooltipItems, options); 9500 this.footer = this.getFooter(tooltipItems, options); 9501 const size = this._size = getTooltipSize(this, options); 9502 const positionAndSize = Object.assign({}, position, size); 9503 const alignment = determineAlignment(this.chart, options, positionAndSize); 9504 const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart); 9505 this.xAlign = alignment.xAlign; 9506 this.yAlign = alignment.yAlign; 9507 properties = { 9508 opacity: 1, 9509 x: backgroundPoint.x, 9510 y: backgroundPoint.y, 9511 width: size.width, 9512 height: size.height, 9513 caretX: position.x, 9514 caretY: position.y 9515 }; 9516 } 9517 this._tooltipItems = tooltipItems; 9518 this.$context = undefined; 9519 if (properties) { 9520 this._resolveAnimations().update(this, properties); 9521 } 9522 if (changed && options.external) { 9523 options.external.call(this, { 9524 chart: this.chart, 9525 tooltip: this, 9526 replay 9527 }); 9528 } 9529 } 9530 drawCaret(tooltipPoint, ctx, size, options) { 9531 const caretPosition = this.getCaretPosition(tooltipPoint, size, options); 9532 ctx.lineTo(caretPosition.x1, caretPosition.y1); 9533 ctx.lineTo(caretPosition.x2, caretPosition.y2); 9534 ctx.lineTo(caretPosition.x3, caretPosition.y3); 9535 } 9536 getCaretPosition(tooltipPoint, size, options) { 9537 const { xAlign , yAlign } = this; 9538 const { caretSize , cornerRadius } = options; 9539 const { topLeft , topRight , bottomLeft , bottomRight } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(cornerRadius); 9540 const { x: ptX , y: ptY } = tooltipPoint; 9541 const { width , height } = size; 9542 let x1, x2, x3, y1, y2, y3; 9543 if (yAlign === 'center') { 9544 y2 = ptY + height / 2; 9545 if (xAlign === 'left') { 9546 x1 = ptX; 9547 x2 = x1 - caretSize; 9548 y1 = y2 + caretSize; 9549 y3 = y2 - caretSize; 9550 } else { 9551 x1 = ptX + width; 9552 x2 = x1 + caretSize; 9553 y1 = y2 - caretSize; 9554 y3 = y2 + caretSize; 9555 } 9556 x3 = x1; 9557 } else { 9558 if (xAlign === 'left') { 9559 x2 = ptX + Math.max(topLeft, bottomLeft) + caretSize; 9560 } else if (xAlign === 'right') { 9561 x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize; 9562 } else { 9563 x2 = this.caretX; 9564 } 9565 if (yAlign === 'top') { 9566 y1 = ptY; 9567 y2 = y1 - caretSize; 9568 x1 = x2 - caretSize; 9569 x3 = x2 + caretSize; 9570 } else { 9571 y1 = ptY + height; 9572 y2 = y1 + caretSize; 9573 x1 = x2 + caretSize; 9574 x3 = x2 - caretSize; 9575 } 9576 y3 = y1; 9577 } 9578 return { 9579 x1, 9580 x2, 9581 x3, 9582 y1, 9583 y2, 9584 y3 9585 }; 9586 } 9587 drawTitle(pt, ctx, options) { 9588 const title = this.title; 9589 const length = title.length; 9590 let titleFont, titleSpacing, i; 9591 if (length) { 9592 const rtlHelper = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aA)(options.rtl, this.x, this.width); 9593 pt.x = getAlignedX(this, options.titleAlign, options); 9594 ctx.textAlign = rtlHelper.textAlign(options.titleAlign); 9595 ctx.textBaseline = 'middle'; 9596 titleFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.titleFont); 9597 titleSpacing = options.titleSpacing; 9598 ctx.fillStyle = options.titleColor; 9599 ctx.font = titleFont.string; 9600 for(i = 0; i < length; ++i){ 9601 ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.lineHeight / 2); 9602 pt.y += titleFont.lineHeight + titleSpacing; 9603 if (i + 1 === length) { 9604 pt.y += options.titleMarginBottom - titleSpacing; 9605 } 9606 } 9607 } 9608 } 9609 _drawColorBox(ctx, pt, i, rtlHelper, options) { 9610 const labelColor = this.labelColors[i]; 9611 const labelPointStyle = this.labelPointStyles[i]; 9612 const { boxHeight , boxWidth } = options; 9613 const bodyFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.bodyFont); 9614 const colorX = getAlignedX(this, 'left', options); 9615 const rtlColorX = rtlHelper.x(colorX); 9616 const yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0; 9617 const colorY = pt.y + yOffSet; 9618 if (options.usePointStyle) { 9619 const drawOptions = { 9620 radius: Math.min(boxWidth, boxHeight) / 2, 9621 pointStyle: labelPointStyle.pointStyle, 9622 rotation: labelPointStyle.rotation, 9623 borderWidth: 1 9624 }; 9625 const centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2; 9626 const centerY = colorY + boxHeight / 2;
9627 ctx.strokeStyle = options.multiKeyBackground; 9628 ctx.fillStyle = options.multiKeyBackground; 9629 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.av)(ctx, drawOptions, centerX, centerY); 9630 ctx.strokeStyle = labelColor.borderColor; 9631 ctx.fillStyle = labelColor.backgroundColor; 9632 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.av)(ctx, drawOptions, centerX, centerY); 9633 } else { 9634 ctx.lineWidth = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.i)(labelColor.borderWidth) ? Math.max(...Object.values(labelColor.borderWidth)) : labelColor.borderWidth || 1; 9635 ctx.strokeStyle = labelColor.borderColor; 9636 ctx.setLineDash(labelColor.borderDash || []); 9637 ctx.lineDashOffset = labelColor.borderDashOffset || 0; 9638 const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth); 9639 const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2); 9640 const borderRadius = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(labelColor.borderRadius); 9641 if (Object.values(borderRadius).some((v)=>v !== 0)) { 9642 ctx.beginPath(); 9643 ctx.fillStyle = options.multiKeyBackground; 9644 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aw)(ctx, { 9645 x: outerX, 9646 y: colorY, 9647 w: boxWidth, 9648 h: boxHeight, 9649 radius: borderRadius 9650 }); 9651 ctx.fill(); 9652 ctx.stroke(); 9653 ctx.fillStyle = labelColor.backgroundColor; 9654 ctx.beginPath(); 9655 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aw)(ctx, { 9656 x: innerX, 9657 y: colorY + 1, 9658 w: boxWidth - 2, 9659 h: boxHeight - 2, 9660 radius: borderRadius 9661 }); 9662 ctx.fill(); 9663 } else { 9664 ctx.fillStyle = options.multiKeyBackground; 9665 ctx.fillRect(outerX, colorY, boxWidth, boxHeight); 9666 ctx.strokeRect(outerX, colorY, boxWidth, boxHeight); 9667 ctx.fillStyle = labelColor.backgroundColor; 9668 ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2); 9669 } 9670 } 9671 ctx.fillStyle = this.labelTextColors[i]; 9672 } 9673 drawBody(pt, ctx, options) { 9674 const { body } = this; 9675 const { bodySpacing , bodyAlign , displayColors , boxHeight , boxWidth , boxPadding } = options; 9676 const bodyFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.bodyFont); 9677 let bodyLineHeight = bodyFont.lineHeight; 9678 let xLinePadding = 0; 9679 const rtlHelper = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aA)(options.rtl, this.x, this.width); 9680 const fillLineOfText = function(line) { 9681 ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2); 9682 pt.y += bodyLineHeight + bodySpacing; 9683 }; 9684 const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign); 9685 let bodyItem, textColor, lines, i, j, ilen, jlen; 9686 ctx.textAlign = bodyAlign; 9687 ctx.textBaseline = 'middle'; 9688 ctx.font = bodyFont.string; 9689 pt.x = getAlignedX(this, bodyAlignForCalculation, options); 9690 ctx.fillStyle = options.bodyColor; 9691 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this.beforeBody, fillLineOfText); 9692 xLinePadding = displayColors && bodyAlignForCalculation !== 'right' ? bodyAlign === 'center' ? boxWidth / 2 + boxPadding : boxWidth + 2 + boxPadding : 0; 9693 for(i = 0, ilen = body.length; i < ilen; ++i){ 9694 bodyItem = body[i]; 9695 textColor = this.labelTextColors[i]; 9696 ctx.fillStyle = textColor; 9697 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(bodyItem.before, fillLineOfText); 9698 lines = bodyItem.lines; 9699 if (displayColors && lines.length) { 9700 this._drawColorBox(ctx, pt, i, rtlHelper, options); 9701 bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight); 9702 } 9703 for(j = 0, jlen = lines.length; j < jlen; ++j){ 9704 fillLineOfText(lines[j]); 9705 bodyLineHeight = bodyFont.lineHeight; 9706 } 9707 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(bodyItem.after, fillLineOfText); 9708 } 9709 xLinePadding = 0; 9710 bodyLineHeight = bodyFont.lineHeight; 9711 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.F)(this.afterBody, fillLineOfText); 9712 pt.y -= bodySpacing; 9713 } 9714 drawFooter(pt, ctx, options) { 9715 const footer = this.footer; 9716 const length = footer.length; 9717 let footerFont, i; 9718 if (length) { 9719 const rtlHelper = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aA)(options.rtl, this.x, this.width); 9720 pt.x = getAlignedX(this, options.footerAlign, options); 9721 pt.y += options.footerMarginTop; 9722 ctx.textAlign = rtlHelper.textAlign(options.footerAlign); 9723 ctx.textBaseline = 'middle'; 9724 footerFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(options.footerFont); 9725 ctx.fillStyle = options.footerColor; 9726 ctx.font = footerFont.string; 9727 for(i = 0; i < length; ++i){ 9728 ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.lineHeight / 2); 9729 pt.y += footerFont.lineHeight + options.footerSpacing; 9730 } 9731 } 9732 }
vendor: 14,800 bytes, lines 9733-10164
9733 drawBackground(pt, ctx, tooltipSize, options) { 9734 const { xAlign , yAlign } = this; 9735 const { x , y } = pt; 9736 const { width , height } = tooltipSize; 9737 const { topLeft , topRight , bottomLeft , bottomRight } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(options.cornerRadius); 9738 ctx.fillStyle = options.backgroundColor; 9739 ctx.strokeStyle = options.borderColor; 9740 ctx.lineWidth = options.borderWidth; 9741 ctx.beginPath(); 9742 ctx.moveTo(x + topLeft, y); 9743 if (yAlign === 'top') { 9744 this.drawCaret(pt, ctx, tooltipSize, options); 9745 } 9746 ctx.lineTo(x + width - topRight, y); 9747 ctx.quadraticCurveTo(x + width, y, x + width, y + topRight); 9748 if (yAlign === 'center' && xAlign === 'right') { 9749 this.drawCaret(pt, ctx, tooltipSize, options); 9750 } 9751 ctx.lineTo(x + width, y + height - bottomRight); 9752 ctx.quadraticCurveTo(x + width, y + height, x + width - bottomRight, y + height); 9753 if (yAlign === 'bottom') { 9754 this.drawCaret(pt, ctx, tooltipSize, options); 9755 } 9756 ctx.lineTo(x + bottomLeft, y + height); 9757 ctx.quadraticCurveTo(x, y + height, x, y + height - bottomLeft); 9758 if (yAlign === 'center' && xAlign === 'left') { 9759 this.drawCaret(pt, ctx, tooltipSize, options); 9760 } 9761 ctx.lineTo(x, y + topLeft); 9762 ctx.quadraticCurveTo(x, y, x + topLeft, y); 9763 ctx.closePath(); 9764 ctx.fill(); 9765 if (options.borderWidth > 0) { 9766 ctx.stroke(); 9767 } 9768 } 9769 _updateAnimationTarget(options) { 9770 const chart = this.chart; 9771 const anims = this.$animations; 9772 const animX = anims && anims.x; 9773 const animY = anims && anims.y; 9774 if (animX || animY) { 9775 const position = positioners[options.position].call(this, this._active, this._eventPosition); 9776 if (!position) { 9777 return; 9778 } 9779 const size = this._size = getTooltipSize(this, options); 9780 const positionAndSize = Object.assign({}, position, this._size); 9781 const alignment = determineAlignment(chart, options, positionAndSize); 9782 const point = getBackgroundPoint(options, positionAndSize, alignment, chart); 9783 if (animX._to !== point.x || animY._to !== point.y) { 9784 this.xAlign = alignment.xAlign; 9785 this.yAlign = alignment.yAlign; 9786 this.width = size.width; 9787 this.height = size.height; 9788 this.caretX = position.x; 9789 this.caretY = position.y; 9790 this._resolveAnimations().update(this, point); 9791 } 9792 } 9793 } 9794 _willRender() { 9795 return !!this.opacity; 9796 } 9797 draw(ctx) { 9798 const options = this.options.setContext(this.getContext()); 9799 let opacity = this.opacity; 9800 if (!opacity) { 9801 return; 9802 } 9803 this._updateAnimationTarget(options); 9804 const tooltipSize = { 9805 width: this.width, 9806 height: this.height 9807 }; 9808 const pt = { 9809 x: this.x, 9810 y: this.y 9811 }; 9812 opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity; 9813 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(options.padding); 9814 const hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length; 9815 if (options.enabled && hasTooltipContent) { 9816 ctx.save(); 9817 ctx.globalAlpha = opacity; 9818 this.drawBackground(pt, ctx, tooltipSize, options); 9819 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aB)(ctx, options.textDirection); 9820 pt.y += padding.top; 9821 this.drawTitle(pt, ctx, options); 9822 this.drawBody(pt, ctx, options); 9823 this.drawFooter(pt, ctx, options); 9824 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aD)(ctx, options.textDirection); 9825 ctx.restore(); 9826 } 9827 } 9828 getActiveElements() { 9829 return this._active || []; 9830 } 9831 setActiveElements(activeElements, eventPosition) { 9832 const lastActive = this._active; 9833 const active = activeElements.map(({ datasetIndex , index })=>{ 9834 const meta = this.chart.getDatasetMeta(datasetIndex); 9835 if (!meta) { 9836 throw new Error('Cannot find a dataset at index ' + datasetIndex); 9837 } 9838 return { 9839 datasetIndex, 9840 element: meta.data[index], 9841 index 9842 }; 9843 }); 9844 const changed = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ai)(lastActive, active); 9845 const positionChanged = this._positionChanged(active, eventPosition); 9846 if (changed || positionChanged) { 9847 this._active = active; 9848 this._eventPosition = eventPosition; 9849 this._ignoreReplayEvents = true; 9850 this.update(true); 9851 } 9852 } 9853 handleEvent(e, replay, inChartArea = true) { 9854 if (replay && this._ignoreReplayEvents) { 9855 return false; 9856 } 9857 this._ignoreReplayEvents = false; 9858 const options = this.options; 9859 const lastActive = this._active || []; 9860 const active = this._getActiveElements(e, lastActive, replay, inChartArea); 9861 const positionChanged = this._positionChanged(active, e); 9862 const changed = replay || !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ai)(active, lastActive) || positionChanged; 9863 if (changed) { 9864 this._active = active; 9865 if (options.enabled || options.external) { 9866 this._eventPosition = { 9867 x: e.x, 9868 y: e.y 9869 }; 9870 this.update(true, replay); 9871 } 9872 } 9873 return changed; 9874 } 9875 _getActiveElements(e, lastActive, replay, inChartArea) { 9876 const options = this.options; 9877 if (e.type === 'mouseout') { 9878 return []; 9879 } 9880 if (!inChartArea) { 9881 return lastActive.filter((i)=>this.chart.data.datasets[i.datasetIndex] && this.chart.getDatasetMeta(i.datasetIndex).controller.getParsed(i.index) !== undefined); 9882 } 9883 const active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay); 9884 if (options.reverse) { 9885 active.reverse(); 9886 } 9887 return active; 9888 } 9889 _positionChanged(active, e) { 9890 const { caretX , caretY , options } = this; 9891 const position = positioners[options.position].call(this, active, e); 9892 return position !== false && (caretX !== position.x || caretY !== position.y); 9893 } 9894} 9895var plugin_tooltip = { 9896 id: 'tooltip', 9897 _element: Tooltip, 9898 positioners, 9899 afterInit (chart, _args, options) { 9900 if (options) { 9901 chart.tooltip = new Tooltip({ 9902 chart, 9903 options 9904 }); 9905 } 9906 }, 9907 beforeUpdate (chart, _args, options) { 9908 if (chart.tooltip) { 9909 chart.tooltip.initialize(options); 9910 } 9911 }, 9912 reset (chart, _args, options) { 9913 if (chart.tooltip) { 9914 chart.tooltip.initialize(options); 9915 } 9916 }, 9917 afterDraw (chart) { 9918 const tooltip = chart.tooltip; 9919 if (tooltip && tooltip._willRender()) { 9920 const args = { 9921 tooltip 9922 }; 9923 if (chart.notifyPlugins('beforeTooltipDraw', { 9924 ...args, 9925 cancelable: true 9926 }) === false) { 9927 return; 9928 } 9929 tooltip.draw(chart.ctx); 9930 chart.notifyPlugins('afterTooltipDraw', args); 9931 } 9932 }, 9933 afterEvent (chart, args) { 9934 if (chart.tooltip) { 9935 const useFinalPosition = args.replay; 9936 if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) { 9937 args.changed = true; 9938 } 9939 } 9940 }, 9941 defaults: { 9942 enabled: true, 9943 external: null, 9944 position: 'average', 9945 backgroundColor: 'rgba(0,0,0,0.8)', 9946 titleColor: '#fff', 9947 titleFont: { 9948 weight: 'bold' 9949 }, 9950 titleSpacing: 2, 9951 titleMarginBottom: 6, 9952 titleAlign: 'left', 9953 bodyColor: '#fff', 9954 bodySpacing: 2, 9955 bodyFont: {}, 9956 bodyAlign: 'left', 9957 footerColor: '#fff', 9958 footerSpacing: 2, 9959 footerMarginTop: 6, 9960 footerFont: { 9961 weight: 'bold' 9962 }, 9963 footerAlign: 'left', 9964 padding: 6, 9965 caretPadding: 2, 9966 caretSize: 5, 9967 cornerRadius: 6, 9968 boxHeight: (ctx, opts)=>opts.bodyFont.size, 9969 boxWidth: (ctx, opts)=>opts.bodyFont.size, 9970 multiKeyBackground: '#fff', 9971 displayColors: true, 9972 boxPadding: 0, 9973 borderColor: 'rgba(0,0,0,0)', 9974 borderWidth: 0, 9975 animation: { 9976 duration: 400, 9977 easing: 'easeOutQuart' 9978 }, 9979 animations: { 9980 numbers: { 9981 type: 'number', 9982 properties: [ 9983 'x', 9984 'y', 9985 'width', 9986 'height', 9987 'caretX', 9988 'caretY' 9989 ] 9990 }, 9991 opacity: { 9992 easing: 'linear', 9993 duration: 200 9994 } 9995 }, 9996 callbacks: defaultCallbacks 9997 }, 9998 defaultRoutes: { 9999 bodyFont: 'font', 10000 footerFont: 'font', 10001 titleFont: 'font' 10002 }, 10003 descriptors: { 10004 _scriptable: (name)=>name !== 'filter' && name !== 'itemSort' && name !== 'external', 10005 _indexable: false, 10006 callbacks: { 10007 _scriptable: false, 10008 _indexable: false 10009 }, 10010 animation: { 10011 _fallback: false 10012 }, 10013 animations: { 10014 _fallback: 'animation' 10015 } 10016 }, 10017 additionalOptionScopes: [ 10018 'interaction' 10019 ] 10020}; 10021 10022var plugins = /*#__PURE__*/Object.freeze({ 10023__proto__: null, 10024Colors: plugin_colors, 10025Decimation: plugin_decimation, 10026Filler: index, 10027Legend: plugin_legend, 10028SubTitle: plugin_subtitle, 10029Title: plugin_title, 10030Tooltip: plugin_tooltip 10031}); 10032 10033const addIfString = (labels, raw, index, addedLabels)=>{ 10034 if (typeof raw === 'string') { 10035 index = labels.push(raw) - 1; 10036 addedLabels.unshift({ 10037 index, 10038 label: raw 10039 }); 10040 } else if (isNaN(raw)) { 10041 index = null; 10042 } 10043 return index; 10044}; 10045function findOrAddLabel(labels, raw, index, addedLabels) { 10046 const first = labels.indexOf(raw); 10047 if (first === -1) { 10048 return addIfString(labels, raw, index, addedLabels); 10049 } 10050 const last = labels.lastIndexOf(raw); 10051 return first !== last ? index : first; 10052} 10053const validIndex = (index, max)=>index === null ? null : (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(Math.round(index), 0, max); 10054function _getLabelForValue(value) { 10055 const labels = this.getLabels(); 10056 if (value >= 0 && value < labels.length) { 10057 return labels[value]; 10058 } 10059 return value; 10060} 10061class CategoryScale extends Scale { 10062 static id = 'category'; 10063 static defaults = { 10064 ticks: { 10065 callback: _getLabelForValue 10066 } 10067 }; 10068 constructor(cfg){ 10069 super(cfg); 10070 this._startValue = undefined; 10071 this._valueRange = 0; 10072 this._addedLabels = []; 10073 } 10074 init(scaleOptions) { 10075 const added = this._addedLabels; 10076 if (added.length) { 10077 const labels = this.getLabels(); 10078 for (const { index , label } of added){ 10079 if (labels[index] === label) { 10080 labels.splice(index, 1); 10081 } 10082 } 10083 this._addedLabels = []; 10084 } 10085 super.init(scaleOptions); 10086 } 10087 parse(raw, index) { 10088 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(raw)) { 10089 return null; 10090 } 10091 const labels = this.getLabels(); 10092 index = isFinite(index) && labels[index] === raw ? index : findOrAddLabel(labels, raw, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(index, raw), this._addedLabels); 10093 return validIndex(index, labels.length - 1); 10094 } 10095 determineDataLimits() { 10096 const { minDefined , maxDefined } = this.getUserBounds(); 10097 let { min , max } = this.getMinMax(true); 10098 if (this.options.bounds === 'ticks') { 10099 if (!minDefined) { 10100 min = 0; 10101 } 10102 if (!maxDefined) { 10103 max = this.getLabels().length - 1; 10104 } 10105 } 10106 this.min = min; 10107 this.max = max; 10108 } 10109 buildTicks() { 10110 const min = this.min; 10111 const max = this.max; 10112 const offset = this.options.offset; 10113 const ticks = []; 10114 let labels = this.getLabels(); 10115 labels = min === 0 && max === labels.length - 1 ? labels : labels.slice(min, max + 1); 10116 this._valueRange = Math.max(labels.length - (offset ? 0 : 1), 1); 10117 this._startValue = this.min - (offset ? 0.5 : 0); 10118 for(let value = min; value <= max; value++){ 10119 ticks.push({ 10120 value 10121 }); 10122 } 10123 return ticks; 10124 } 10125 getLabelForValue(value) { 10126 return _getLabelForValue.call(this, value); 10127 } 10128 configure() { 10129 super.configure(); 10130 if (!this.isHorizontal()) { 10131 this._reversePixels = !this._reversePixels; 10132 } 10133 } 10134 getPixelForValue(value) { 10135 if (typeof value !== 'number') { 10136 value = this.parse(value); 10137 } 10138 return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); 10139 } 10140 getPixelForTick(index) { 10141 const ticks = this.ticks; 10142 if (index < 0 || index > ticks.length - 1) { 10143 return null; 10144 } 10145 return this.getPixelForValue(ticks[index].value); 10146 } 10147 getValueForPixel(pixel) { 10148 return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange); 10149 } 10150 getBasePixel() { 10151 return this.bottom; 10152 } 10153} 10154 10155function generateTicks$1(generationOptions, dataRange) { 10156 const ticks = []; 10157 const MIN_SPACING = 1e-14; 10158 const { bounds , step , min , max , precision , count , maxTicks , maxDigits , includeBounds } = generationOptions; 10159 const unit = step || 1; 10160 const maxSpaces = maxTicks - 1; 10161 const { min: rmin , max: rmax } = dataRange; 10162 const minDefined = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(min); 10163 const maxDefined = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(max); 10164 const countDefined = !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(count);
10165 const minSpacing = (rmax - rmin) / (maxDigits + 1); 10166 let spacing = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aI)((rmax - rmin) / maxSpaces / unit) * unit; 10167 let factor, niceMin, niceMax, numSpaces; 10168 if (spacing < MIN_SPACING && !minDefined && !maxDefined) { 10169 return [ 10170 { 10171 value: rmin 10172 }, 10173 { 10174 value: rmax 10175 } 10176 ]; 10177 } 10178 numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing); 10179 if (numSpaces > maxSpaces) { 10180 spacing = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aI)(numSpaces * spacing / maxSpaces / unit) * unit; 10181 } 10182 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(precision)) { 10183 factor = Math.pow(10, precision); 10184 spacing = Math.ceil(spacing * factor) / factor; 10185 } 10186 if (bounds === 'ticks') { 10187 niceMin = Math.floor(rmin / spacing) * spacing; 10188 niceMax = Math.ceil(rmax / spacing) * spacing; 10189 } else { 10190 niceMin = rmin; 10191 niceMax = rmax; 10192 } 10193 if (minDefined && maxDefined && step && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aJ)((max - min) / step, spacing / 1000)) { 10194 numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks)); 10195 spacing = (max - min) / numSpaces; 10196 niceMin = min; 10197 niceMax = max; 10198 } else if (countDefined) { 10199 niceMin = minDefined ? min : niceMin; 10200 niceMax = maxDefined ? max : niceMax; 10201 numSpaces = count - 1; 10202 spacing = (niceMax - niceMin) / numSpaces; 10203 } else { 10204 numSpaces = (niceMax - niceMin) / spacing; 10205 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aK)(numSpaces, Math.round(numSpaces), spacing / 1000)) { 10206 numSpaces = Math.round(numSpaces); 10207 } else { 10208 numSpaces = Math.ceil(numSpaces); 10209 } 10210 } 10211 const decimalPlaces = Math.max((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aL)(spacing), (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aL)(niceMin)); 10212 factor = Math.pow(10, (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(precision) ? decimalPlaces : precision); 10213 niceMin = Math.round(niceMin * factor) / factor; 10214 niceMax = Math.round(niceMax * factor) / factor; 10215 let j = 0; 10216 if (minDefined) { 10217 if (includeBounds && niceMin !== min) { 10218 ticks.push({ 10219 value: min 10220 }); 10221 if (niceMin < min) { 10222 j++; 10223 } 10224 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aK)(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) { 10225 j++; 10226 } 10227 } else if (niceMin < min) { 10228 j++; 10229 } 10230 } 10231 for(; j < numSpaces; ++j){ 10232 const tickValue = Math.round((niceMin + j * spacing) * factor) / factor; 10233 if (maxDefined && tickValue > max) { 10234 break; 10235 } 10236 ticks.push({ 10237 value: tickValue 10238 }); 10239 } 10240 if (maxDefined && includeBounds && niceMax !== max) { 10241 if (ticks.length && (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aK)(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) { 10242 ticks[ticks.length - 1].value = max; 10243 } else { 10244 ticks.push({ 10245 value: max 10246 }); 10247 } 10248 } else if (!maxDefined || niceMax === max) { 10249 ticks.push({ 10250 value: niceMax 10251 }); 10252 } 10253 return ticks; 10254} 10255function relativeLabelSize(value, minSpacing, { horizontal , minRotation }) { 10256 const rad = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(minRotation); 10257 const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 0.001; 10258 const length = 0.75 * minSpacing * ('' + value).length; 10259 return Math.min(minSpacing / ratio, length); 10260} 10261class LinearScaleBase extends Scale { 10262 constructor(cfg){ 10263 super(cfg); 10264 this.start = undefined; 10265 this.end = undefined; 10266 this._startValue = undefined; 10267 this._endValue = undefined; 10268 this._valueRange = 0; 10269 } 10270 parse(raw, index) { 10271 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(raw)) { 10272 return null; 10273 } 10274 if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(+raw)) { 10275 return null; 10276 } 10277 return +raw; 10278 } 10279 handleTickRangeOptions() { 10280 const { beginAtZero } = this.options; 10281 const { minDefined , maxDefined } = this.getUserBounds(); 10282 let { min , max } = this; 10283 const setMin = (v)=>min = minDefined ? min : v;
vendor: 8,728 bytes, lines 10284-10512
10284 const setMax = (v)=>max = maxDefined ? max : v; 10285 if (beginAtZero) { 10286 const minSign = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(min); 10287 const maxSign = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.s)(max); 10288 if (minSign < 0 && maxSign < 0) { 10289 setMax(0); 10290 } else if (minSign > 0 && maxSign > 0) { 10291 setMin(0); 10292 } 10293 } 10294 if (min === max) { 10295 let offset = max === 0 ? 1 : Math.abs(max * 0.05); 10296 setMax(max + offset); 10297 if (!beginAtZero) { 10298 setMin(min - offset); 10299 } 10300 } 10301 this.min = min; 10302 this.max = max; 10303 } 10304 getTickLimit() { 10305 const tickOpts = this.options.ticks; 10306 let { maxTicksLimit , stepSize } = tickOpts; 10307 let maxTicks; 10308 if (stepSize) { 10309 maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1; 10310 if (maxTicks > 1000) { 10311 console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`); 10312 maxTicks = 1000; 10313 } 10314 } else { 10315 maxTicks = this.computeTickLimit(); 10316 maxTicksLimit = maxTicksLimit || 11; 10317 } 10318 if (maxTicksLimit) { 10319 maxTicks = Math.min(maxTicksLimit, maxTicks); 10320 } 10321 return maxTicks; 10322 } 10323 computeTickLimit() { 10324 return Number.POSITIVE_INFINITY; 10325 } 10326 buildTicks() { 10327 const opts = this.options; 10328 const tickOpts = opts.ticks; 10329 let maxTicks = this.getTickLimit(); 10330 maxTicks = Math.max(2, maxTicks); 10331 const numericGeneratorOptions = { 10332 maxTicks, 10333 bounds: opts.bounds, 10334 min: opts.min, 10335 max: opts.max, 10336 precision: tickOpts.precision, 10337 step: tickOpts.stepSize, 10338 count: tickOpts.count, 10339 maxDigits: this._maxDigits(), 10340 horizontal: this.isHorizontal(), 10341 minRotation: tickOpts.minRotation || 0, 10342 includeBounds: tickOpts.includeBounds !== false 10343 }; 10344 const dataRange = this._range || this; 10345 const ticks = generateTicks$1(numericGeneratorOptions, dataRange); 10346 if (opts.bounds === 'ticks') { 10347 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aH)(ticks, this, 'value'); 10348 } 10349 if (opts.reverse) { 10350 ticks.reverse(); 10351 this.start = this.max; 10352 this.end = this.min; 10353 } else { 10354 this.start = this.min; 10355 this.end = this.max; 10356 } 10357 return ticks; 10358 } 10359 configure() { 10360 const ticks = this.ticks; 10361 let start = this.min; 10362 let end = this.max; 10363 super.configure(); 10364 if (this.options.offset && ticks.length) { 10365 const offset = (end - start) / Math.max(ticks.length - 1, 1) / 2; 10366 start -= offset; 10367 end += offset; 10368 } 10369 this._startValue = start; 10370 this._endValue = end; 10371 this._valueRange = end - start; 10372 } 10373 getLabelForValue(value) { 10374 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.o)(value, this.chart.options.locale, this.options.ticks.format); 10375 } 10376} 10377 10378class LinearScale extends LinearScaleBase { 10379 static id = 'linear'; 10380 static defaults = { 10381 ticks: { 10382 callback: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aM.formatters.numeric 10383 } 10384 }; 10385 determineDataLimits() { 10386 const { min , max } = this.getMinMax(true); 10387 this.min = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(min) ? min : 0; 10388 this.max = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(max) ? max : 1; 10389 this.handleTickRangeOptions(); 10390 } 10391 computeTickLimit() { 10392 const horizontal = this.isHorizontal(); 10393 const length = horizontal ? this.width : this.height; 10394 const minRotation = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.options.ticks.minRotation); 10395 const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 0.001; 10396 const tickFont = this._resolveTickFontOptions(0); 10397 return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio)); 10398 } 10399 getPixelForValue(value) { 10400 return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); 10401 } 10402 getValueForPixel(pixel) { 10403 return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange; 10404 } 10405} 10406 10407const log10Floor = (v)=>Math.floor((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aN)(v)); 10408const changeExponent = (v, m)=>Math.pow(10, log10Floor(v) + m); 10409function isMajor(tickVal) { 10410 const remain = tickVal / Math.pow(10, log10Floor(tickVal)); 10411 return remain === 1; 10412} 10413function steps(min, max, rangeExp) { 10414 const rangeStep = Math.pow(10, rangeExp); 10415 const start = Math.floor(min / rangeStep); 10416 const end = Math.ceil(max / rangeStep); 10417 return end - start; 10418} 10419function startExp(min, max) { 10420 const range = max - min; 10421 let rangeExp = log10Floor(range); 10422 while(steps(min, max, rangeExp) > 10){ 10423 rangeExp++; 10424 } 10425 while(steps(min, max, rangeExp) < 10){ 10426 rangeExp--; 10427 } 10428 return Math.min(rangeExp, log10Floor(min)); 10429} 10430 function generateTicks(generationOptions, { min , max }) { 10431 min = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(generationOptions.min, min); 10432 const ticks = []; 10433 const minExp = log10Floor(min); 10434 let exp = startExp(min, max); 10435 let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; 10436 const stepSize = Math.pow(10, exp); 10437 const base = minExp > exp ? Math.pow(10, minExp) : 0; 10438 const start = Math.round((min - base) * precision) / precision; 10439 const offset = Math.floor((min - base) / stepSize / 10) * stepSize * 10; 10440 let significand = Math.floor((start - offset) / Math.pow(10, exp)); 10441 let value = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(generationOptions.min, Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision); 10442 while(value < max){ 10443 ticks.push({ 10444 value, 10445 major: isMajor(value), 10446 significand 10447 }); 10448 if (significand >= 10) { 10449 significand = significand < 15 ? 15 : 20; 10450 } else { 10451 significand++; 10452 } 10453 if (significand >= 20) { 10454 exp++; 10455 significand = 2; 10456 precision = exp >= 0 ? 1 : precision; 10457 } 10458 value = Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision; 10459 } 10460 const lastTick = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.O)(generationOptions.max, value); 10461 ticks.push({ 10462 value: lastTick, 10463 major: isMajor(lastTick), 10464 significand 10465 }); 10466 return ticks; 10467} 10468class LogarithmicScale extends Scale { 10469 static id = 'logarithmic'; 10470 static defaults = { 10471 ticks: { 10472 callback: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aM.formatters.logarithmic, 10473 major: { 10474 enabled: true 10475 } 10476 } 10477 }; 10478 constructor(cfg){ 10479 super(cfg); 10480 this.start = undefined; 10481 this.end = undefined; 10482 this._startValue = undefined; 10483 this._valueRange = 0; 10484 } 10485 parse(raw, index) { 10486 const value = LinearScaleBase.prototype.parse.apply(this, [ 10487 raw, 10488 index 10489 ]); 10490 if (value === 0) { 10491 this._zero = true; 10492 return undefined; 10493 } 10494 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(value) && value > 0 ? value : null; 10495 } 10496 determineDataLimits() { 10497 const { min , max } = this.getMinMax(true); 10498 this.min = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(min) ? Math.max(0, min) : null; 10499 this.max = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(max) ? Math.max(0, max) : null; 10500 if (this.options.beginAtZero) { 10501 this._zero = true; 10502 } 10503 if (this._zero && this.min !== this._suggestedMin && !(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(this._userMin)) { 10504 this.min = min === changeExponent(this.min, 0) ? changeExponent(this.min, -1) : changeExponent(this.min, 0); 10505 } 10506 this.handleTickRangeOptions(); 10507 } 10508 handleTickRangeOptions() { 10509 const { minDefined , maxDefined } = this.getUserBounds(); 10510 let min = this.min; 10511 let max = this.max; 10512 const setMin = (v)=>min = minDefined ? min : v;
vendor: 31,701 bytes, lines 10513-11360
10513 const setMax = (v)=>max = maxDefined ? max : v; 10514 if (min === max) { 10515 if (min <= 0) { 10516 setMin(1); 10517 setMax(10); 10518 } else { 10519 setMin(changeExponent(min, -1)); 10520 setMax(changeExponent(max, +1)); 10521 } 10522 } 10523 if (min <= 0) { 10524 setMin(changeExponent(max, -1)); 10525 } 10526 if (max <= 0) { 10527 setMax(changeExponent(min, +1)); 10528 } 10529 this.min = min; 10530 this.max = max; 10531 } 10532 buildTicks() { 10533 const opts = this.options; 10534 const generationOptions = { 10535 min: this._userMin, 10536 max: this._userMax 10537 }; 10538 const ticks = generateTicks(generationOptions, this); 10539 if (opts.bounds === 'ticks') { 10540 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aH)(ticks, this, 'value'); 10541 } 10542 if (opts.reverse) { 10543 ticks.reverse(); 10544 this.start = this.max; 10545 this.end = this.min; 10546 } else { 10547 this.start = this.min; 10548 this.end = this.max; 10549 } 10550 return ticks; 10551 } 10552 getLabelForValue(value) { 10553 return value === undefined ? '0' : (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.o)(value, this.chart.options.locale, this.options.ticks.format); 10554 } 10555 configure() { 10556 const start = this.min; 10557 super.configure(); 10558 this._startValue = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aN)(start); 10559 this._valueRange = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aN)(this.max) - (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aN)(start); 10560 } 10561 getPixelForValue(value) { 10562 if (value === undefined || value === 0) { 10563 value = this.min; 10564 } 10565 if (value === null || isNaN(value)) { 10566 return NaN; 10567 } 10568 return this.getPixelForDecimal(value === this.min ? 0 : ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aN)(value) - this._startValue) / this._valueRange); 10569 } 10570 getValueForPixel(pixel) { 10571 const decimal = this.getDecimalForPixel(pixel); 10572 return Math.pow(10, this._startValue + decimal * this._valueRange); 10573 } 10574} 10575 10576function getTickBackdropHeight(opts) { 10577 const tickOpts = opts.ticks; 10578 if (tickOpts.display && opts.display) { 10579 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(tickOpts.backdropPadding); 10580 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(tickOpts.font && tickOpts.font.size, _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.d.font.size) + padding.height; 10581 } 10582 return 0; 10583} 10584function measureLabelSize(ctx, font, label) { 10585 label = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.b)(label) ? label : [ 10586 label 10587 ]; 10588 return { 10589 w: (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aO)(ctx, font.string, label), 10590 h: label.length * font.lineHeight 10591 }; 10592} 10593function determineLimits(angle, pos, size, min, max) { 10594 if (angle === min || angle === max) { 10595 return { 10596 start: pos - size / 2, 10597 end: pos + size / 2 10598 }; 10599 } else if (angle < min || angle > max) { 10600 return { 10601 start: pos - size, 10602 end: pos 10603 }; 10604 } 10605 return { 10606 start: pos, 10607 end: pos + size 10608 }; 10609} 10610 function fitWithPointLabels(scale) { 10611 const orig = { 10612 l: scale.left + scale._padding.left, 10613 r: scale.right - scale._padding.right, 10614 t: scale.top + scale._padding.top, 10615 b: scale.bottom - scale._padding.bottom 10616 }; 10617 const limits = Object.assign({}, orig); 10618 const labelSizes = []; 10619 const padding = []; 10620 const valueCount = scale._pointLabels.length; 10621 const pointLabelOpts = scale.options.pointLabels; 10622 const additionalAngle = pointLabelOpts.centerPointLabels ? _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / valueCount : 0; 10623 for(let i = 0; i < valueCount; i++){ 10624 const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i)); 10625 padding[i] = opts.padding; 10626 const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle); 10627 const plFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(opts.font); 10628 const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]); 10629 labelSizes[i] = textSize; 10630 const angleRadians = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(scale.getIndexAngle(i) + additionalAngle); 10631 const angle = Math.round((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.U)(angleRadians)); 10632 const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); 10633 const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); 10634 updateLimits(limits, orig, angleRadians, hLimits, vLimits); 10635 } 10636 scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b); 10637 scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding); 10638} 10639function updateLimits(limits, orig, angle, hLimits, vLimits) { 10640 const sin = Math.abs(Math.sin(angle)); 10641 const cos = Math.abs(Math.cos(angle)); 10642 let x = 0; 10643 let y = 0; 10644 if (hLimits.start < orig.l) { 10645 x = (orig.l - hLimits.start) / sin; 10646 limits.l = Math.min(limits.l, orig.l - x); 10647 } else if (hLimits.end > orig.r) { 10648 x = (hLimits.end - orig.r) / sin; 10649 limits.r = Math.max(limits.r, orig.r + x); 10650 } 10651 if (vLimits.start < orig.t) { 10652 y = (orig.t - vLimits.start) / cos; 10653 limits.t = Math.min(limits.t, orig.t - y); 10654 } else if (vLimits.end > orig.b) { 10655 y = (vLimits.end - orig.b) / cos; 10656 limits.b = Math.max(limits.b, orig.b + y); 10657 } 10658} 10659function createPointLabelItem(scale, index, itemOpts) { 10660 const outerDistance = scale.drawingArea; 10661 const { extra , additionalAngle , padding , size } = itemOpts; 10662 const pointLabelPosition = scale.getPointPosition(index, outerDistance + extra + padding, additionalAngle); 10663 const angle = Math.round((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.U)((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(pointLabelPosition.angle + _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H))); 10664 const y = yForAngle(pointLabelPosition.y, size.h, angle); 10665 const textAlign = getTextAlignForAngle(angle); 10666 const left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign); 10667 return { 10668 visible: true, 10669 x: pointLabelPosition.x, 10670 y, 10671 textAlign, 10672 left, 10673 top: y, 10674 right: left + size.w, 10675 bottom: y + size.h 10676 }; 10677} 10678function isNotOverlapped(item, area) { 10679 if (!area) { 10680 return true; 10681 } 10682 const { left , top , right , bottom } = item; 10683 const apexesInArea = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)({ 10684 x: left, 10685 y: top 10686 }, area) || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)({ 10687 x: left, 10688 y: bottom 10689 }, area) || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)({ 10690 x: right, 10691 y: top 10692 }, area) || (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.C)({ 10693 x: right, 10694 y: bottom 10695 }, area); 10696 return !apexesInArea; 10697} 10698function buildPointLabelItems(scale, labelSizes, padding) { 10699 const items = []; 10700 const valueCount = scale._pointLabels.length; 10701 const opts = scale.options; 10702 const { centerPointLabels , display } = opts.pointLabels; 10703 const itemOpts = { 10704 extra: getTickBackdropHeight(opts) / 2, 10705 additionalAngle: centerPointLabels ? _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.P / valueCount : 0 10706 }; 10707 let area; 10708 for(let i = 0; i < valueCount; i++){ 10709 itemOpts.padding = padding[i]; 10710 itemOpts.size = labelSizes[i]; 10711 const item = createPointLabelItem(scale, i, itemOpts); 10712 items.push(item); 10713 if (display === 'auto') { 10714 item.visible = isNotOverlapped(item, area); 10715 if (item.visible) { 10716 area = item; 10717 } 10718 } 10719 } 10720 return items; 10721} 10722function getTextAlignForAngle(angle) { 10723 if (angle === 0 || angle === 180) { 10724 return 'center'; 10725 } else if (angle < 180) { 10726 return 'left'; 10727 } 10728 return 'right'; 10729} 10730function leftForTextAlign(x, w, align) { 10731 if (align === 'right') { 10732 x -= w; 10733 } else if (align === 'center') { 10734 x -= w / 2; 10735 } 10736 return x; 10737} 10738function yForAngle(y, h, angle) { 10739 if (angle === 90 || angle === 270) { 10740 y -= h / 2; 10741 } else if (angle > 270 || angle < 90) { 10742 y -= h; 10743 } 10744 return y; 10745} 10746function drawPointLabelBox(ctx, opts, item) { 10747 const { left , top , right , bottom } = item; 10748 const { backdropColor } = opts; 10749 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(backdropColor)) { 10750 const borderRadius = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ay)(opts.borderRadius); 10751 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(opts.backdropPadding); 10752 ctx.fillStyle = backdropColor; 10753 const backdropLeft = left - padding.left; 10754 const backdropTop = top - padding.top; 10755 const backdropWidth = right - left + padding.width; 10756 const backdropHeight = bottom - top + padding.height; 10757 if (Object.values(borderRadius).some((v)=>v !== 0)) { 10758 ctx.beginPath(); 10759 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aw)(ctx, { 10760 x: backdropLeft, 10761 y: backdropTop, 10762 w: backdropWidth, 10763 h: backdropHeight, 10764 radius: borderRadius 10765 }); 10766 ctx.fill(); 10767 } else { 10768 ctx.fillRect(backdropLeft, backdropTop, backdropWidth, backdropHeight); 10769 } 10770 } 10771} 10772function drawPointLabels(scale, labelCount) { 10773 const { ctx , options: { pointLabels } } = scale; 10774 for(let i = labelCount - 1; i >= 0; i--){ 10775 const item = scale._pointLabelItems[i]; 10776 if (!item.visible) { 10777 continue; 10778 } 10779 const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i)); 10780 drawPointLabelBox(ctx, optsAtIndex, item); 10781 const plFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(optsAtIndex.font); 10782 const { x , y , textAlign } = item; 10783 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, scale._pointLabels[i], x, y + plFont.lineHeight / 2, plFont, { 10784 color: optsAtIndex.color, 10785 textAlign: textAlign, 10786 textBaseline: 'middle' 10787 }); 10788 } 10789} 10790function pathRadiusLine(scale, radius, circular, labelCount) { 10791 const { ctx } = scale; 10792 if (circular) { 10793 ctx.arc(scale.xCenter, scale.yCenter, radius, 0, _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T); 10794 } else { 10795 let pointPosition = scale.getPointPosition(0, radius); 10796 ctx.moveTo(pointPosition.x, pointPosition.y); 10797 for(let i = 1; i < labelCount; i++){ 10798 pointPosition = scale.getPointPosition(i, radius); 10799 ctx.lineTo(pointPosition.x, pointPosition.y); 10800 } 10801 } 10802} 10803function drawRadiusLine(scale, gridLineOpts, radius, labelCount, borderOpts) { 10804 const ctx = scale.ctx; 10805 const circular = gridLineOpts.circular; 10806 const { color , lineWidth } = gridLineOpts; 10807 if (!circular && !labelCount || !color || !lineWidth || radius < 0) { 10808 return; 10809 } 10810 ctx.save(); 10811 ctx.strokeStyle = color; 10812 ctx.lineWidth = lineWidth; 10813 ctx.setLineDash(borderOpts.dash || []); 10814 ctx.lineDashOffset = borderOpts.dashOffset; 10815 ctx.beginPath(); 10816 pathRadiusLine(scale, radius, circular, labelCount); 10817 ctx.closePath(); 10818 ctx.stroke(); 10819 ctx.restore(); 10820} 10821function createPointLabelContext(parent, index, label) { 10822 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.j)(parent, { 10823 label, 10824 index, 10825 type: 'pointLabel' 10826 }); 10827} 10828class RadialLinearScale extends LinearScaleBase { 10829 static id = 'radialLinear'; 10830 static defaults = { 10831 display: true, 10832 animate: true, 10833 position: 'chartArea', 10834 angleLines: { 10835 display: true, 10836 lineWidth: 1, 10837 borderDash: [], 10838 borderDashOffset: 0.0 10839 }, 10840 grid: { 10841 circular: false 10842 }, 10843 startAngle: 0, 10844 ticks: { 10845 showLabelBackdrop: true, 10846 callback: _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aM.formatters.numeric 10847 }, 10848 pointLabels: { 10849 backdropColor: undefined, 10850 backdropPadding: 2, 10851 display: true, 10852 font: { 10853 size: 10 10854 }, 10855 callback (label) { 10856 return label; 10857 }, 10858 padding: 5, 10859 centerPointLabels: false 10860 } 10861 }; 10862 static defaultRoutes = { 10863 'angleLines.color': 'borderColor', 10864 'pointLabels.color': 'color', 10865 'ticks.color': 'color' 10866 }; 10867 static descriptors = { 10868 angleLines: { 10869 _fallback: 'grid' 10870 } 10871 }; 10872 constructor(cfg){ 10873 super(cfg); 10874 this.xCenter = undefined; 10875 this.yCenter = undefined; 10876 this.drawingArea = undefined; 10877 this._pointLabels = []; 10878 this._pointLabelItems = []; 10879 } 10880 setDimensions() { 10881 const padding = this._padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(getTickBackdropHeight(this.options) / 2); 10882 const w = this.width = this.maxWidth - padding.width; 10883 const h = this.height = this.maxHeight - padding.height; 10884 this.xCenter = Math.floor(this.left + w / 2 + padding.left); 10885 this.yCenter = Math.floor(this.top + h / 2 + padding.top); 10886 this.drawingArea = Math.floor(Math.min(w, h) / 2); 10887 } 10888 determineDataLimits() { 10889 const { min , max } = this.getMinMax(false); 10890 this.min = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(min) && !isNaN(min) ? min : 0; 10891 this.max = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(max) && !isNaN(max) ? max : 0; 10892 this.handleTickRangeOptions(); 10893 } 10894 computeTickLimit() { 10895 return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options)); 10896 } 10897 generateTickLabels(ticks) { 10898 LinearScaleBase.prototype.generateTickLabels.call(this, ticks); 10899 this._pointLabels = this.getLabels().map((value, index)=>{ 10900 const label = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(this.options.pointLabels.callback, [ 10901 value, 10902 index 10903 ], this); 10904 return label || label === 0 ? label : ''; 10905 }).filter((v, i)=>this.chart.getDataVisibility(i)); 10906 } 10907 fit() { 10908 const opts = this.options; 10909 if (opts.display && opts.pointLabels.display) { 10910 fitWithPointLabels(this); 10911 } else { 10912 this.setCenterPoint(0, 0, 0, 0); 10913 } 10914 } 10915 setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) { 10916 this.xCenter += Math.floor((leftMovement - rightMovement) / 2); 10917 this.yCenter += Math.floor((topMovement - bottomMovement) / 2); 10918 this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement)); 10919 } 10920 getIndexAngle(index) { 10921 const angleMultiplier = _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.T / (this._pointLabels.length || 1); 10922 const startAngle = this.options.startAngle || 0; 10923 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.al)(index * angleMultiplier + (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(startAngle)); 10924 } 10925 getDistanceFromCenterForValue(value) { 10926 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(value)) { 10927 return NaN; 10928 } 10929 const scalingFactor = this.drawingArea / (this.max - this.min); 10930 if (this.options.reverse) { 10931 return (this.max - value) * scalingFactor; 10932 } 10933 return (value - this.min) * scalingFactor; 10934 } 10935 getValueForDistanceFromCenter(distance) { 10936 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(distance)) { 10937 return NaN; 10938 } 10939 const scaledDistance = distance / (this.drawingArea / (this.max - this.min)); 10940 return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance; 10941 } 10942 getPointLabelContext(index) { 10943 const pointLabels = this._pointLabels || []; 10944 if (index >= 0 && index < pointLabels.length) { 10945 const pointLabel = pointLabels[index]; 10946 return createPointLabelContext(this.getContext(), index, pointLabel); 10947 } 10948 } 10949 getPointPosition(index, distanceFromCenter, additionalAngle = 0) { 10950 const angle = this.getIndexAngle(index) - _chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.H + additionalAngle; 10951 return { 10952 x: Math.cos(angle) * distanceFromCenter + this.xCenter, 10953 y: Math.sin(angle) * distanceFromCenter + this.yCenter, 10954 angle 10955 }; 10956 } 10957 getPointPositionForValue(index, value) { 10958 return this.getPointPosition(index, this.getDistanceFromCenterForValue(value)); 10959 } 10960 getBasePosition(index) { 10961 return this.getPointPositionForValue(index || 0, this.getBaseValue()); 10962 } 10963 getPointLabelPosition(index) { 10964 const { left , top , right , bottom } = this._pointLabelItems[index]; 10965 return { 10966 left, 10967 top, 10968 right, 10969 bottom 10970 }; 10971 } 10972 drawBackground() { 10973 const { backgroundColor , grid: { circular } } = this.options; 10974 if (backgroundColor) { 10975 const ctx = this.ctx; 10976 ctx.save(); 10977 ctx.beginPath(); 10978 pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length); 10979 ctx.closePath(); 10980 ctx.fillStyle = backgroundColor; 10981 ctx.fill(); 10982 ctx.restore(); 10983 } 10984 } 10985 drawGrid() { 10986 const ctx = this.ctx; 10987 const opts = this.options; 10988 const { angleLines , grid , border } = opts; 10989 const labelCount = this._pointLabels.length; 10990 let i, offset, position; 10991 if (opts.pointLabels.display) { 10992 drawPointLabels(this, labelCount); 10993 } 10994 if (grid.display) { 10995 this.ticks.forEach((tick, index)=>{ 10996 if (index !== 0 || index === 0 && this.min < 0) { 10997 offset = this.getDistanceFromCenterForValue(tick.value); 10998 const context = this.getContext(index); 10999 const optsAtIndex = grid.setContext(context); 11000 const optsAtIndexBorder = border.setContext(context); 11001 drawRadiusLine(this, optsAtIndex, offset, labelCount, optsAtIndexBorder); 11002 } 11003 }); 11004 } 11005 if (angleLines.display) { 11006 ctx.save(); 11007 for(i = labelCount - 1; i >= 0; i--){ 11008 const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i)); 11009 const { color , lineWidth } = optsAtIndex; 11010 if (!lineWidth || !color) { 11011 continue; 11012 } 11013 ctx.lineWidth = lineWidth; 11014 ctx.strokeStyle = color; 11015 ctx.setLineDash(optsAtIndex.borderDash); 11016 ctx.lineDashOffset = optsAtIndex.borderDashOffset; 11017 offset = this.getDistanceFromCenterForValue(opts.reverse ? this.min : this.max); 11018 position = this.getPointPosition(i, offset); 11019 ctx.beginPath(); 11020 ctx.moveTo(this.xCenter, this.yCenter); 11021 ctx.lineTo(position.x, position.y); 11022 ctx.stroke(); 11023 } 11024 ctx.restore(); 11025 } 11026 } 11027 drawBorder() {} 11028 drawLabels() { 11029 const ctx = this.ctx; 11030 const opts = this.options; 11031 const tickOpts = opts.ticks; 11032 if (!tickOpts.display) { 11033 return; 11034 } 11035 const startAngle = this.getIndexAngle(0); 11036 let offset, width; 11037 ctx.save(); 11038 ctx.translate(this.xCenter, this.yCenter); 11039 ctx.rotate(startAngle); 11040 ctx.textAlign = 'center'; 11041 ctx.textBaseline = 'middle'; 11042 this.ticks.forEach((tick, index)=>{ 11043 if (index === 0 && this.min >= 0 && !opts.reverse) { 11044 return; 11045 } 11046 const optsAtIndex = tickOpts.setContext(this.getContext(index)); 11047 const tickFont = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.a0)(optsAtIndex.font); 11048 offset = this.getDistanceFromCenterForValue(this.ticks[index].value); 11049 if (optsAtIndex.showLabelBackdrop) { 11050 ctx.font = tickFont.string; 11051 width = ctx.measureText(tick.label).width; 11052 ctx.fillStyle = optsAtIndex.backdropColor; 11053 const padding = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.E)(optsAtIndex.backdropPadding); 11054 ctx.fillRect(-width / 2 - padding.left, -offset - tickFont.size / 2 - padding.top, width + padding.width, tickFont.size + padding.height); 11055 } 11056 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ctx, tick.label, 0, -offset, tickFont, { 11057 color: optsAtIndex.color, 11058 strokeColor: optsAtIndex.textStrokeColor, 11059 strokeWidth: optsAtIndex.textStrokeWidth 11060 }); 11061 }); 11062 ctx.restore(); 11063 } 11064 drawTitle() {} 11065} 11066 11067const INTERVALS = { 11068 millisecond: { 11069 common: true, 11070 size: 1, 11071 steps: 1000 11072 }, 11073 second: { 11074 common: true, 11075 size: 1000, 11076 steps: 60 11077 }, 11078 minute: { 11079 common: true, 11080 size: 60000, 11081 steps: 60 11082 }, 11083 hour: { 11084 common: true, 11085 size: 3600000, 11086 steps: 24 11087 }, 11088 day: { 11089 common: true, 11090 size: 86400000, 11091 steps: 30 11092 }, 11093 week: { 11094 common: false, 11095 size: 604800000, 11096 steps: 4 11097 }, 11098 month: { 11099 common: true, 11100 size: 2.628e9, 11101 steps: 12 11102 }, 11103 quarter: { 11104 common: false, 11105 size: 7.884e9, 11106 steps: 4 11107 }, 11108 year: { 11109 common: true, 11110 size: 3.154e10 11111 } 11112}; 11113 const UNITS = /* #__PURE__ */ Object.keys(INTERVALS); 11114 function sorter(a, b) { 11115 return a - b; 11116} 11117 function parse(scale, input) { 11118 if ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.k)(input)) { 11119 return null; 11120 } 11121 const adapter = scale._adapter; 11122 const { parser , round , isoWeekday } = scale._parseOpts; 11123 let value = input; 11124 if (typeof parser === 'function') { 11125 value = parser(value); 11126 } 11127 if (!(0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(value)) { 11128 value = typeof parser === 'string' ? adapter.parse(value, parser) : adapter.parse(value); 11129 } 11130 if (value === null) { 11131 return null; 11132 } 11133 if (round) { 11134 value = round === 'week' && ((0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.x)(isoWeekday) || isoWeekday === true) ? adapter.startOf(value, 'isoWeek', isoWeekday) : adapter.startOf(value, round); 11135 } 11136 return +value; 11137} 11138 function determineUnitForAutoTicks(minUnit, min, max, capacity) { 11139 const ilen = UNITS.length; 11140 for(let i = UNITS.indexOf(minUnit); i < ilen - 1; ++i){ 11141 const interval = INTERVALS[UNITS[i]]; 11142 const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER; 11143 if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { 11144 return UNITS[i]; 11145 } 11146 } 11147 return UNITS[ilen - 1]; 11148} 11149 function determineUnitForFormatting(scale, numTicks, minUnit, min, max) { 11150 for(let i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--){ 11151 const unit = UNITS[i]; 11152 if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) { 11153 return unit; 11154 } 11155 } 11156 return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; 11157} 11158 function determineMajorUnit(unit) { 11159 for(let i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i){ 11160 if (INTERVALS[UNITS[i]].common) { 11161 return UNITS[i]; 11162 } 11163 } 11164} 11165 function addTick(ticks, time, timestamps) { 11166 if (!timestamps) { 11167 ticks[time] = true; 11168 } else if (timestamps.length) { 11169 const { lo , hi } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aQ)(timestamps, time); 11170 const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi]; 11171 ticks[timestamp] = true; 11172 } 11173} 11174 function setMajorTicks(scale, ticks, map, majorUnit) { 11175 const adapter = scale._adapter; 11176 const first = +adapter.startOf(ticks[0].value, majorUnit); 11177 const last = ticks[ticks.length - 1].value; 11178 let major, index; 11179 for(major = first; major <= last; major = +adapter.add(major, 1, majorUnit)){ 11180 index = map[major]; 11181 if (index >= 0) { 11182 ticks[index].major = true; 11183 } 11184 } 11185 return ticks; 11186} 11187 function ticksFromTimestamps(scale, values, majorUnit) { 11188 const ticks = []; 11189 const map = {}; 11190 const ilen = values.length; 11191 let i, value; 11192 for(i = 0; i < ilen; ++i){ 11193 value = values[i]; 11194 map[value] = i; 11195 ticks.push({ 11196 value, 11197 major: false 11198 }); 11199 } 11200 return ilen === 0 || !majorUnit ? ticks : setMajorTicks(scale, ticks, map, majorUnit); 11201} 11202class TimeScale extends Scale { 11203 static id = 'time'; 11204 static defaults = { 11205 bounds: 'data', 11206 adapters: {}, 11207 time: { 11208 parser: false, 11209 unit: false, 11210 round: false, 11211 isoWeekday: false, 11212 minUnit: 'millisecond', 11213 displayFormats: {} 11214 }, 11215 ticks: { 11216 source: 'auto', 11217 callback: false, 11218 major: { 11219 enabled: false 11220 } 11221 } 11222 }; 11223 constructor(props){ 11224 super(props); 11225 this._cache = { 11226 data: [], 11227 labels: [], 11228 all: [] 11229 }; 11230 this._unit = 'day'; 11231 this._majorUnit = undefined; 11232 this._offsets = {}; 11233 this._normalized = false; 11234 this._parseOpts = undefined; 11235 } 11236 init(scaleOpts, opts = {}) { 11237 const time = scaleOpts.time || (scaleOpts.time = {}); 11238 const adapter = this._adapter = new adapters._date(scaleOpts.adapters.date); 11239 adapter.init(opts); 11240 (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.ab)(time.displayFormats, adapter.formats()); 11241 this._parseOpts = { 11242 parser: time.parser, 11243 round: time.round, 11244 isoWeekday: time.isoWeekday 11245 }; 11246 super.init(scaleOpts); 11247 this._normalized = opts.normalized; 11248 } 11249 parse(raw, index) { 11250 if (raw === undefined) { 11251 return null; 11252 } 11253 return parse(this, raw); 11254 } 11255 beforeLayout() { 11256 super.beforeLayout(); 11257 this._cache = { 11258 data: [], 11259 labels: [], 11260 all: [] 11261 }; 11262 } 11263 determineDataLimits() { 11264 const options = this.options; 11265 const adapter = this._adapter; 11266 const unit = options.time.unit || 'day'; 11267 let { min , max , minDefined , maxDefined } = this.getUserBounds(); 11268 function _applyBounds(bounds) { 11269 if (!minDefined && !isNaN(bounds.min)) { 11270 min = Math.min(min, bounds.min); 11271 } 11272 if (!maxDefined && !isNaN(bounds.max)) { 11273 max = Math.max(max, bounds.max); 11274 } 11275 } 11276 if (!minDefined || !maxDefined) { 11277 _applyBounds(this._getLabelBounds()); 11278 if (options.bounds !== 'ticks' || options.ticks.source !== 'labels') { 11279 _applyBounds(this.getMinMax(false)); 11280 } 11281 } 11282 min = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit); 11283 max = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.g)(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1; 11284 this.min = Math.min(min, max - 1); 11285 this.max = Math.max(min + 1, max); 11286 } 11287 _getLabelBounds() { 11288 const arr = this.getLabelTimestamps(); 11289 let min = Number.POSITIVE_INFINITY; 11290 let max = Number.NEGATIVE_INFINITY; 11291 if (arr.length) { 11292 min = arr[0]; 11293 max = arr[arr.length - 1]; 11294 } 11295 return { 11296 min, 11297 max 11298 }; 11299 } 11300 buildTicks() { 11301 const options = this.options; 11302 const timeOpts = options.time; 11303 const tickOpts = options.ticks; 11304 const timestamps = tickOpts.source === 'labels' ? this.getLabelTimestamps() : this._generate(); 11305 if (options.bounds === 'ticks' && timestamps.length) { 11306 this.min = this._userMin || timestamps[0]; 11307 this.max = this._userMax || timestamps[timestamps.length - 1]; 11308 } 11309 const min = this.min; 11310 const max = this.max; 11311 const ticks = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.aP)(timestamps, min, max); 11312 this._unit = timeOpts.unit || (tickOpts.autoSkip ? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min)) : determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max)); 11313 this._majorUnit = !tickOpts.major.enabled || this._unit === 'year' ? undefined : determineMajorUnit(this._unit); 11314 this.initOffsets(timestamps); 11315 if (options.reverse) { 11316 ticks.reverse(); 11317 } 11318 return ticksFromTimestamps(this, ticks, this._majorUnit); 11319 } 11320 afterAutoSkip() { 11321 if (this.options.offsetAfterAutoskip) { 11322 this.initOffsets(this.ticks.map((tick)=>+tick.value)); 11323 } 11324 } 11325 initOffsets(timestamps = []) { 11326 let start = 0; 11327 let end = 0; 11328 let first, last; 11329 if (this.options.offset && timestamps.length) { 11330 first = this.getDecimalForValue(timestamps[0]); 11331 if (timestamps.length === 1) { 11332 start = 1 - first; 11333 } else { 11334 start = (this.getDecimalForValue(timestamps[1]) - first) / 2; 11335 } 11336 last = this.getDecimalForValue(timestamps[timestamps.length - 1]); 11337 if (timestamps.length === 1) { 11338 end = last; 11339 } else { 11340 end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2; 11341 } 11342 } 11343 const limit = timestamps.length < 3 ? 0.5 : 0.25; 11344 start = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(start, 0, limit); 11345 end = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.S)(end, 0, limit); 11346 this._offsets = { 11347 start, 11348 end, 11349 factor: 1 / (start + 1 + end) 11350 }; 11351 } 11352 _generate() { 11353 const adapter = this._adapter; 11354 const min = this.min; 11355 const max = this.max; 11356 const options = this.options; 11357 const timeOpts = options.time; 11358 const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min)); 11359 const stepSize = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.v)(options.ticks.stepSize, 1); 11360 const weekday = minor === 'week' ? timeOpts.isoWeekday : false;
vendor: 4,747 bytes, lines 11361-11468
11361 const hasWeekday = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.x)(weekday) || weekday === true; 11362 const ticks = {}; 11363 let first = min; 11364 let time, count; 11365 if (hasWeekday) { 11366 first = +adapter.startOf(first, 'isoWeek', weekday); 11367 } 11368 first = +adapter.startOf(first, hasWeekday ? 'day' : minor); 11369 if (adapter.diff(max, min, minor) > 100000 * stepSize) { 11370 throw new Error(min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor); 11371 } 11372 const timestamps = options.ticks.source === 'data' && this.getDataTimestamps(); 11373 for(time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++){ 11374 addTick(ticks, time, timestamps); 11375 } 11376 if (time === max || options.bounds === 'ticks' || count === 1) { 11377 addTick(ticks, time, timestamps); 11378 } 11379 return Object.keys(ticks).sort(sorter).map((x)=>+x); 11380 } 11381 getLabelForValue(value) { 11382 const adapter = this._adapter; 11383 const timeOpts = this.options.time; 11384 if (timeOpts.tooltipFormat) { 11385 return adapter.format(value, timeOpts.tooltipFormat); 11386 } 11387 return adapter.format(value, timeOpts.displayFormats.datetime); 11388 } 11389 format(value, format) { 11390 const options = this.options; 11391 const formats = options.time.displayFormats; 11392 const unit = this._unit; 11393 const fmt = format || formats[unit]; 11394 return this._adapter.format(value, fmt); 11395 } 11396 _tickFormatFunction(time, index, ticks, format) { 11397 const options = this.options; 11398 const formatter = options.ticks.callback; 11399 if (formatter) { 11400 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.Q)(formatter, [ 11401 time, 11402 index, 11403 ticks 11404 ], this); 11405 } 11406 const formats = options.time.displayFormats; 11407 const unit = this._unit; 11408 const majorUnit = this._majorUnit; 11409 const minorFormat = unit && formats[unit]; 11410 const majorFormat = majorUnit && formats[majorUnit]; 11411 const tick = ticks[index]; 11412 const major = majorUnit && majorFormat && tick && tick.major; 11413 return this._adapter.format(time, format || (major ? majorFormat : minorFormat)); 11414 } 11415 generateTickLabels(ticks) { 11416 let i, ilen, tick; 11417 for(i = 0, ilen = ticks.length; i < ilen; ++i){ 11418 tick = ticks[i]; 11419 tick.label = this._tickFormatFunction(tick.value, i, ticks); 11420 } 11421 } 11422 getDecimalForValue(value) { 11423 return value === null ? NaN : (value - this.min) / (this.max - this.min); 11424 } 11425 getPixelForValue(value) { 11426 const offsets = this._offsets; 11427 const pos = this.getDecimalForValue(value); 11428 return this.getPixelForDecimal((offsets.start + pos) * offsets.factor); 11429 } 11430 getValueForPixel(pixel) { 11431 const offsets = this._offsets; 11432 const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; 11433 return this.min + pos * (this.max - this.min); 11434 } 11435 _getLabelSize(label) { 11436 const ticksOpts = this.options.ticks; 11437 const tickLabelWidth = this.ctx.measureText(label).width; 11438 const angle = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.t)(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation); 11439 const cosRotation = Math.cos(angle); 11440 const sinRotation = Math.sin(angle); 11441 const tickFontSize = this._resolveTickFontOptions(0).size; 11442 return { 11443 w: tickLabelWidth * cosRotation + tickFontSize * sinRotation, 11444 h: tickLabelWidth * sinRotation + tickFontSize * cosRotation 11445 }; 11446 } 11447 _getLabelCapacity(exampleTime) { 11448 const timeOpts = this.options.time; 11449 const displayFormats = timeOpts.displayFormats; 11450 const format = displayFormats[timeOpts.unit] || displayFormats.millisecond; 11451 const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [ 11452 exampleTime 11453 ], this._majorUnit), format); 11454 const size = this._getLabelSize(exampleLabel); 11455 const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1; 11456 return capacity > 0 ? capacity : 1; 11457 } 11458 getDataTimestamps() { 11459 let timestamps = this._cache.data || []; 11460 let i, ilen; 11461 if (timestamps.length) { 11462 return timestamps; 11463 } 11464 const metas = this.getMatchingVisibleMetas(); 11465 if (this._normalized && metas.length) { 11466 return this._cache.data = metas[0].controller.getAllParsedValues(this); 11467 } 11468 for(i = 0, ilen = metas.length; i < ilen; ++i){
vendor: 4,937 bytes, lines 11469-11622
11469 timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this)); 11470 } 11471 return this._cache.data = this.normalize(timestamps); 11472 } 11473 getLabelTimestamps() { 11474 const timestamps = this._cache.labels || []; 11475 let i, ilen; 11476 if (timestamps.length) { 11477 return timestamps; 11478 } 11479 const labels = this.getLabels(); 11480 for(i = 0, ilen = labels.length; i < ilen; ++i){ 11481 timestamps.push(parse(this, labels[i])); 11482 } 11483 return this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps); 11484 } 11485 normalize(values) { 11486 return (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__._)(values.sort(sorter)); 11487 } 11488} 11489 11490function interpolate(table, val, reverse) { 11491 let lo = 0; 11492 let hi = table.length - 1; 11493 let prevSource, nextSource, prevTarget, nextTarget; 11494 if (reverse) { 11495 if (val >= table[lo].pos && val <= table[hi].pos) { 11496 ({ lo , hi } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.B)(table, 'pos', val)); 11497 } 11498 ({ pos: prevSource , time: prevTarget } = table[lo]); 11499 ({ pos: nextSource , time: nextTarget } = table[hi]); 11500 } else { 11501 if (val >= table[lo].time && val <= table[hi].time) { 11502 ({ lo , hi } = (0,_chunks_helpers_dataset_js__WEBPACK_IMPORTED_MODULE_0__.B)(table, 'time', val)); 11503 } 11504 ({ time: prevSource , pos: prevTarget } = table[lo]); 11505 ({ time: nextSource , pos: nextTarget } = table[hi]); 11506 } 11507 const span = nextSource - prevSource; 11508 return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget; 11509} 11510class TimeSeriesScale extends TimeScale { 11511 static id = 'timeseries'; 11512 static defaults = TimeScale.defaults; 11513 constructor(props){ 11514 super(props); 11515 this._table = []; 11516 this._minPos = undefined; 11517 this._tableRange = undefined; 11518 } 11519 initOffsets() { 11520 const timestamps = this._getTimestampsForTable(); 11521 const table = this._table = this.buildLookupTable(timestamps); 11522 this._minPos = interpolate(table, this.min); 11523 this._tableRange = interpolate(table, this.max) - this._minPos; 11524 super.initOffsets(timestamps); 11525 } 11526 buildLookupTable(timestamps) { 11527 const { min , max } = this; 11528 const items = []; 11529 const table = []; 11530 let i, ilen, prev, curr, next; 11531 for(i = 0, ilen = timestamps.length; i < ilen; ++i){ 11532 curr = timestamps[i]; 11533 if (curr >= min && curr <= max) { 11534 items.push(curr); 11535 } 11536 } 11537 if (items.length < 2) { 11538 return [ 11539 { 11540 time: min, 11541 pos: 0 11542 }, 11543 { 11544 time: max, 11545 pos: 1 11546 } 11547 ]; 11548 } 11549 for(i = 0, ilen = items.length; i < ilen; ++i){ 11550 next = items[i + 1]; 11551 prev = items[i - 1]; 11552 curr = items[i]; 11553 if (Math.round((next + prev) / 2) !== curr) { 11554 table.push({ 11555 time: curr, 11556 pos: i / (ilen - 1) 11557 }); 11558 } 11559 } 11560 return table; 11561 } 11562 _generate() { 11563 const min = this.min; 11564 const max = this.max; 11565 let timestamps = super.getDataTimestamps(); 11566 if (!timestamps.includes(min) || !timestamps.length) { 11567 timestamps.splice(0, 0, min); 11568 } 11569 if (!timestamps.includes(max) || timestamps.length === 1) { 11570 timestamps.push(max); 11571 } 11572 return timestamps.sort((a, b)=>a - b); 11573 } 11574 _getTimestampsForTable() { 11575 let timestamps = this._cache.all || []; 11576 if (timestamps.length) { 11577 return timestamps; 11578 } 11579 const data = this.getDataTimestamps(); 11580 const label = this.getLabelTimestamps(); 11581 if (data.length && label.length) { 11582 timestamps = this.normalize(data.concat(label)); 11583 } else { 11584 timestamps = data.length ? data : label; 11585 } 11586 timestamps = this._cache.all = timestamps; 11587 return timestamps; 11588 } 11589 getDecimalForValue(value) { 11590 return (interpolate(this._table, value) - this._minPos) / this._tableRange; 11591 } 11592 getValueForPixel(pixel) { 11593 const offsets = this._offsets; 11594 const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; 11595 return interpolate(this._table, decimal * this._tableRange + this._minPos, true); 11596 } 11597} 11598 11599var scales = /*#__PURE__*/Object.freeze({ 11600__proto__: null, 11601CategoryScale: CategoryScale, 11602LinearScale: LinearScale, 11603LogarithmicScale: LogarithmicScale, 11604RadialLinearScale: RadialLinearScale, 11605TimeScale: TimeScale, 11606TimeSeriesScale: TimeSeriesScale 11607}); 11608 11609const registerables = [ 11610 controllers, 11611 elements, 11612 plugins, 11613 scales 11614]; 11615 11616 11617//# sourceMappingURL=chart.js.map 11618 11619 11620/***/ }) 11621 11622}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.